Модуль Feeds - простое и мощное решение для организации импорта данных. Даный модуль имеет возможность работать с разными стандартами данных, в частности с CSV, XML, OPML.
При организации импорта часто появляется необходимость проводить обработку данных перед их подачей на сайт. Для обработки данных в процессе импорта предназначен модуль Feeds Tamper. Этот модуль позволяет определить для каждого поля действие (или совокупность действий) по обработке данных.
Список стандартных операций довольно большой (рис. 1.):
Каждое действие технически реализуется в виде отдельного плагина, который подключается к модулю Feeds Tamper, и после подключения становится доступен в списке "The plugin to add".
Список встроенных плагинов уже довольно большой. Среди прочих упомяну плагин для выполнения произвольного РНР-кода, который позволяет использовать нужные снипеты. Этот плагин пока не включен в ядро модуля. Но уже вполне работоспособен:
Иногда возникают задачи, которые не решаются с помощью встроенных плагинов. Использование РНР-сниппетов тоже не совсем решает задачу, поскольку при многократном использовании сниппета в разных импортерах, пропадает возможность централизированой и синхронной правки кода.
В таком случае наиболее подходящим решением будет создание собственного плагина с нужным функционалом. Рассмотрим этот процесс более детально.
Рассмотрим процесс создания плагина на практическом примере:
Исходные данные:
CSV-файл с данными для импорта данных в сущность товара Drupal Commerce. Формат представления поля стоимости - число. Точность - 2 знака после запятой. Разделитель целой и дробной части - точка.
Суть проблемы:
Drupal commerce использует собственный формат хранения поля стоимости. Стоимость сохраняется в минорной единице валюты. Т.е. на примере рубля, стоимость в поле БД должна быть записана в копейках.
Задача:
Необходимо конвертировать сумму из стандартной числовой записи во внутренний стандарт Drupal Сommerce.
Алгоритм:
1. Получаем значение суммы.
2. Проверяем на правильность (является ли значение поля числом)
3. Конвертируем рубли в копейки, умножением на кратность единиц (в случае рубля умножаем на 100).
4. Отдаем результат в импорт.
Реализация:
Поскольку плагины находятся в папке модуля Feeds Tamper: feeds_tamper/plugins/, устанавливать свой плагин в эту же системную папку не рационально, поскольку в процессе обновления модуля вероятна утрата кастомных плагинов.
Правильным подходом будет создать модуль, который позволит зарегистрировать плагин в системе, не размещая его в системной папке. Для этого воспользуемся хуком hook_ctools_plugin_directory(), поскольку Feeds Tamper использует ctools.
Согласно http://drupalcontrib.org/api/drupal/contributions!ctools!ctools.api.php/... АРІ эта функция имеет следующие аргументы: hook_ctools_plugin_directory($owner, $plugin_type)
Реализация хука будет иметь вид:
<?php
function MYMODULE_ctools_plugin_directory($owner, $plugin_type) {
if ($owner == 'feeds_tamper' && $plugin_type == 'plugins') {
return 'plugins/';
}
}
?>
Этот хук задаст размещение кастомного плагина в папке MYMODULE/plugins
Далее создадим собственно, сам плагин. Назовем его MYMODULE_dc_price_converter.inc
Всего в тексте плагина будет находится объявление одной конфигурационной переменной, и двух функций.
Прежде всего объявим конфигурационную переменную, в которой зададим форму настройки плагина, и реализацию метода обработки данных.
<?php
$plugin = array(
'form' => 'MYMODULE_dc_price_converter_form',
'callback' => 'MYMODULE_dc_price_converter_callback',
'name' => 'DC price converter',
'category' => 'Other',
);
?>
Значения параметров:
'form' - название функции, в которой мы объявляем конфигурационную форму. Форма создается стандартными средствами FormAPI http://api.drupal.org/api/drupal/includes--form.inc/group/form_api/7
'callback' - название функции, в которой находится реализация обработчика данных
'name' - название плагина в списке "The plugin to add"
'category' - категория плагина в этом же списке
Рассмотрим реализацию конфигурационной формы плагина:
<?php
/**
* Plugin settings form
*/
function MYMODULE_dc_price_converter_form($importer, $element_key, $settings) {
$form = array();
$form['operation'] = array(
'#type' => 'select',
'#title' => t('Type of price convertation'),
'#options' => array(
0 => t('Float to Commerce'),
1 => t('Commerce to Float'),
),
'#description' => t('Set type of price converation.'),
);
return $form;
}
?>
В результате конфигурационная форма будет иметь вид (рис. 2.):
Рассмотрим обработчик данных:
<?php
function MYMODULE_dc_price_converter_callback($result, $item_key, $element_key, &$field, $settings) {
if (!empty(
$field) && is_numeric($field))
switch($settings['operation']) {
case '0':
$field = ((float)$field)*100;
break;
case '1':
$field = ((float)$field)/100;
break;
}
}
?>
Итоги:
Решение этой задачи приведено в качестве примера разработки плагина. Для решения именно этой задачи также можно воспользоваться и встроенным плагином.
Создание собственных плагинов позволяет дополнить встроенный функционал методами, которых нет в ядре модуля. Также в отдельный плагин можно вынести функционал однотипных операций, которые многократно вызываются в разных импортерах, и требуют централизированого управления функционалом.
Вложение | Размер |
---|---|
1.jpg | 19.87 КБ |
2.jpg | 15.42 КБ |
mymodule.zip | 1.48 КБ |
Комментарии
Отличный пример я то же самое делал для создания плагина выполняющего любой php код c импортируемым значением
http://drupal.org/node/1297968#comment-5272726
cosmos
Ончто-то в ошибку выпадает
Parse error: syntax error, unexpected ' : eval()'d code on line 1
<?
Всё есть.
Оригинальный патч обрабатывает, а форк от cosmos отваливается.
Поищите лишнее в этих двух строках
А всё, уже написал плагин по методу Sun-fire.
Вот только почему-то если выбрать case '1', при последующем редактировании поле находится в положении case '0', хотя всё работает, т.е. положение "включено" сохраняется.
Если посмотреть в MYMODULE_dc_price_converter_form, то можно увидеть, что там значения для виджета задаются фиксированные. В коде нет проверки текущего установленного значения с дальнейшей установкой в качестве дефолтового значения виджета.
Этот функционал я не указывал в примере, чтобы максимально упростить код. То есть в примере всегда при загрузке формы будет отображаться первый заданный в списке аргумент.
решение:
rewrite [поле_цены]00
Кагбе, если внимательно читать статью, то можно прочесть, что:
То есть целью статьи было не решить поставленную задачу максимально красиво/быстро/оптимально/еще_как_то, а показать на примере, каким образом можно создавать собственные плагины для Feeds Tamper.
[quote=Sun-fire][quote="multpix"]решение:
rewrite [поле_цены]00
А что будете делать если поле цены 85.2 ? После вашей обработки будет так 85.200
Спасибо за статью,
а свой костылик озвучил - уж не сердитесь)))
Вариантов решения, как правило, большое множество
Кстати, Ваш вариант решения позволяет все сделать наиболее быстро.
Такой уж внутренний формат хранения данных у коммерца. Не всегда удобно с нима работать. Например, некоторое время назад, было довольно трудно заставить работать Search API Ranges, пока не создали под него патч.
ой как я вас понимаю))
кстати у search_api если использовать solr масса дополнительных вкусняшек + тот-же аякс, но пилить....
я уже на друорг английский выучил)))
p.s
вопрос:
пробовали подружить search_api_ranges и search_api_ajax,
успешно ?
Еще не пробовал, но планирую в ближайшем времени.
хуже будет) уже наступил и получил...
сделал модулек - спасибо еще раз камраду Sun-fire
Не работало пока не додумался в функции MYMODULE_ctools_plugin_directory убрать слеш в пути:
return 'plugins/';return 'plugins';
Подскажите, а нет ли, случаем, плагина, который позволяет добавлять значение в множественное поле, если этого значения там еще нет?
[module=feeds_tamper_php] Готовый модуль.