Создание плагина для Feeds Tamper.

Главные вкладки

Аватар пользователя Sun-fire Sun-fire 19 января 2012 в 18:03

Модуль 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(
      
=> t('Float to Commerce'),
      
=> 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.jpg19.87 КБ
Иконка изображения 2.jpg15.42 КБ
Иконка пакета mymodule.zip1.48 КБ

Комментарии

Аватар пользователя DenisVS DenisVS 15 марта 2012 в 18:01

А всё, уже написал плагин по методу Sun-fire.
Вот только почему-то если выбрать case '1', при последующем редактировании поле находится в положении case '0', хотя всё работает, т.е. положение "включено" сохраняется.

Аватар пользователя Sun-fire Sun-fire 15 марта 2012 в 18:08

Если посмотреть в MYMODULE_dc_price_converter_form, то можно увидеть, что там значения для виджета задаются фиксированные. В коде нет проверки текущего установленного значения с дальнейшей установкой в качестве дефолтового значения виджета.

Этот функционал я не указывал в примере, чтобы максимально упростить код. То есть в примере всегда при загрузке формы будет отображаться первый заданный в списке аргумент.

Аватар пользователя Sun-fire Sun-fire 3 июля 2012 в 23:46

"multpix" wrote:
решение:
rewrite [поле_цены]00

Smile

Кагбе, если внимательно читать статью, то можно прочесть, что:

"sun-fire" wrote:

Итоги:

Решение этой задачи приведено в качестве примера разработки плагина. Для решения именно этой задачи также можно воспользоваться и встроенным плагином.
Создание собственных плагинов позволяет дополнить встроенный функционал методами, которых нет в ядре модуля. Также в отдельный плагин можно вынести функционал однотипных операций, которые многократно вызываются в разных импортерах, и требуют централизированого управления функционалом.

То есть целью статьи было не решить поставленную задачу максимально красиво/быстро/оптимально/еще_как_то, а показать на примере, каким образом можно создавать собственные плагины для Feeds Tamper.

Аватар пользователя yasik yasik 23 июля 2012 в 18:43

[quote=Sun-fire][quote="multpix"]решение:
rewrite [поле_цены]00

Smile

А что будете делать если поле цены 85.2 ? После вашей обработки будет так 85.200

Аватар пользователя Sun-fire Sun-fire 4 июля 2012 в 0:37

Вариантов решения, как правило, большое множество Smile

Кстати, Ваш вариант решения позволяет все сделать наиболее быстро.

Такой уж внутренний формат хранения данных у коммерца. Не всегда удобно с нима работать. Например, некоторое время назад, было довольно трудно заставить работать Search API Ranges, пока не создали под него патч.

Аватар пользователя multpix multpix 4 июля 2012 в 3:33

"Sun-fire" wrote:
Search API Ranges

ой как я вас понимаю))
кстати у search_api если использовать solr масса дополнительных вкусняшек + тот-же аякс, но пилить....
я уже на друорг английский выучил)))

p.s
вопрос:
пробовали подружить search_api_ranges и search_api_ajax,
успешно ?

Аватар пользователя aa2007 aa2007 11 декабря 2012 в 13:25

Подскажите, а нет ли, случаем, плагина, который позволяет добавлять значение в множественное поле, если этого значения там еще нет?