Articles

How to create a custom feeds tamper plugin

Learning session

It is very common that sometimes when you import content from a file (eg. CSV or XML file) which is provided by someone else, you are not pleased with the format. You might see many inconsistent values which need improvements in order to have a clean import.

That is when Feeds Tamper module comes to save your day. It comes with multiple plugins which manipulate values before mapping them. That gives great power for site builders to have clean feeds imports with consistent values.

However, sometimes you will not find your plugin to do something you want and that is why I wrote this blog post about how to write your custom plugin for feeds tamper.

Let’s use products as a real-life example. I have a CSV file which contains product’s EAN code, product ID, title and colour. I find out that CSV file has inconsistent product ID’s where some of them are prefixed with zeros and some of them are not.

products.csv

product id;product ean;product title;product color
001;123456;Black mug;Black
002;123457;Grey mug;grey
3;123458;Green mug;Green
04;123459;Drupal T-shirt;White, Blue
05;;Mystery product;
10;1234510;iPad;
999;1234511;Audi TT Coupé;

Product ID’s appear to be three-digit numbers prefixed by zeros. We would like to have products imported with consistent ID’s so we want to make sure that they have IDs like ‘001’, ‘003’, ‘003’, ‘010’ and ‘999’, etc.

When I wrote this custom plugin first time (before 7.x-1.0-beta3) there was no plugin for pad strings so I wrote my own plugin. That’s the one I’m going to use now in this example.

Feeds Tamper uses ctools plugin system to let other modules determine their tamper plugins. To let Feeds Tamper module know about the new plugin we need to implement hook_ctools_plugin_directory() to tell ctools that our tamper plugins are found in a specified path. In this case that would be ‘custom_plugins/’.

example_tamper_plugin/example_tamper_plugin.module

function example_tamper_plugin_ctools_plugin_directory($owner, $plugin_type) {
if ($owner == 'feeds_tamper' && $plugin_type == 'plugins') {
return 'custom_plugins/';
}
}

Next step is to describe our plugin so Feeds Tamper knows what to call in certain events. You do that by creating a PHP file into the plugins directory and determining $plugin variable as follow:

example_tamper_plugin/custom_plugins/example_str_pad.inc

$plugin = array(
'form' => 'example_tamper_plugin_str_pad_form',
'callback' => 'example_tamper_plugin_str_pad_callback',
'name' => 'Custom pad',
);

form – is the function name which gets called when feeds tamper look for plugin settings
callback – is the function name where the actual magic happens
name – the name of the plugin for UI

Now let’s implement settings form for our plugin. The whole magic will happen using str_pad() function so we will take look for all available parameters and figure out settings from those. The length will be required setting and optional settings could be string and type. Length tells how long the string should be at least. String is the character which will be used to complete the string length when string length condition is not met. Type tells which side it will fill the string.

example_tamper_plugin/custom_plugins/example_str_pad.inc

function example_tamper_plugin_str_pad_form($importer, $element_key, $settings) {
$form = array();
$form['length'] = array(
'#type' => 'textfield',
'#title' => t('Length'),
'#description' => t('If the value of length is negative, less than, or equal to the length of the input string, no padding takes place.'),
'#default_value' => isset($settings['length']) ? $settings['length'] : '',
'#size' => 4,
'#required' => TRUE,
);
$form['string'] = array(
'#type' => 'textfield',
'#title' => t('String'),
'#size' => 10,
'#description' => t('The string may be truncated if the required number of padding characters can\'t be evenly divided by the string\'s length.'),
'#default_value' => isset($settings['string']) ? $settings['string'] : ' ',
);
$form['type'] = array(
'#type' => 'radios',
'#title' => t('Type'),
'#options' => array(STR_PAD_RIGHT => t('Right'), STR_PAD_LEFT => t('Left'), STR_PAD_BOTH => t('Both')),
'#default_value' => isset($settings['type']) ? $settings['type'] : STR_PAD_RIGHT,
);
return $form;
}

If you would now clear your caches you should already have your plugin listed in the dropdown list of available plugins.

View of custom pad plugin settings form.

View of custom pad plugin settings form.

Next step is to implement the actual callback function which gets called when feeds tamper deals with the import. Feeds Tamper will take action when hook_feeds_after_parse() is invoked. It looks for enabled plugins for each element and then call the callback functions. We have determined the callback function to be

example_tamper_plugin_str_pad_callback so lets implement that.

example_tamper_plugin/custom_plugins/example_str_pad.inc

function example_tamper_plugin_str_pad_callback($result, $item_key, $element_key, &$field, $settings) {
$type = isset($settings['type']) && in_array($settings['type'], array(STR_PAD_RIGHT, STR_PAD_LEFT, STR_PAD_BOTH)) ? $settings['type'] : STR_PAD_RIGHT;
$field = str_pad($field, intval($settings['length']), $type);
}

Not that bad, huh? $field is the value which was parsed by feeds and since it’s passed as reference, you just edit the value and that’s all. You’ll get $settings to use your settings you earlier implemented.