I'm working with a Feeds importer that imports to an image field. I have two tamper plugins attached to this column, one is a required filter, the other is a rewrite plugin to prepend private:// to the image name.

If I configure the weights so the required plugin runs first, I get errors like the following as the rewrite plugin tries to rewrite empty rows that have been unset() by the required filter:

Notice: Undefined offset: 13 in feeds_tamper_rewrite_callback() (line 43 of feeds_tamper/plugins/rewrite.inc).
Warning: Invalid argument supplied for foreach() in feeds_tamper_rewrite_callback() (line 44 of feeds_tamper/plugins/rewrite.inc).

If I have the required plugin run second, then I get file errors because now the field is no longer empty and Feeds tries to import an image with a path of "private://".

At first I was thinking the rewrite plugin could just check isset($result->items[$item_key]) but this bug would affect more than just the rewrite plugin, and the fix should probably be baked into the required plugin if possible or enforced on a higher level.

#3 rewrite.zip753 bytesstephane-v
#2 rewrite.zip753 bytesstephane-v


Cottser’s picture

Title:Required plugin can throw notices/warnings when used with other plugins» Required and Keyword filter plugins can throw notices/warnings when used with other plugins

Re-titling, the keyword filter does an unset() as well.

stephane-v’s picture

new753 bytes

I had the same problem so I just made a small modification to the rewrite plugin to solve it.
I added a checkbox in the plugin configuration to ask wether empty fields should be rewritten or not.
So the rewrite plugin must be executed before the required plugin.
Here is the modified rewrite.inc file :


* @file
* Rewrite a field using tokens.

$plugin = array(
  'form'     => 'feeds_tamper_rewrite_form',
  'callback' => 'feeds_tamper_rewrite_callback',
  'name'     => 'Rewrite',
  'multi'    => 'skip',
  'category' => 'Other',

function feeds_tamper_rewrite_form($importer, $element_key, $settings) {
  $form = array();
  $mappings = $importer->processor->config['mappings'];
  $replace = array();

  foreach ($mappings as $mapping) {
    $replace[] = '[' . $mapping['source'] . ']';

  $form['rewrite_empty'] = array(
    '#type' => 'checkbox',
    '#title' => t('Rewrite empty field'),
    '#default_value' => isset($settings['rewrite_empty']) ? $settings['rewrite_empty'] : 1,
  $form['text'] = array(
    '#type' => 'textarea',
    '#title' => t('Replacement pattern'),
    '#default_value' => isset($settings['text']) ? $settings['text'] : '',
  $form['help'] = array(
    '#type' => 'fieldset',
    '#title' => t('Available Replacement Patterns'),
    '#collapsed' => TRUE,
    '#collapsible' => TRUE,
    '#value' => theme('item_list', array('items' => $replace)),
  return $form;

function feeds_tamper_rewrite_callback($result, $item_key, $element_key, &$field, $settings) {
  if (!empty($field) || (empty($field) && $settings['rewrite_empty'] == 1)) {
    $trans = array();
    $item = $result->items[$item_key];
    foreach ($item as $key => $value) {
      $trans['[' . $key . ']'] = $value;
    $field = strtr($settings['text'], $trans);

stephane-v’s picture

new753 bytes

The file in post #2 is not correct. Use this one please.

Ivan Simonov’s picture

Add little check to original function:

function feeds_tamper_rewrite_callback($result, $item_key, $element_key, &$field, $settings, $source) {
  if (isset (
$result->items[$item_key])) {
$trans = array();
$item = $result->items[$item_key];
    foreach (
$item as $key => $value) {
$trans['[' . $key . ']'] = $value;
$field = strtr($settings['text'], $trans);
GaborTorok’s picture

I prefer the solution in #4.

The rewrite plugin only throws a warning, but the Copy plugin recreates the item, because it writes the items array if ($settings['to_from']=='to'), so Copy plugin should also have the isset check.

twistor’s picture

Status:Active» Closed (duplicate)