I love feed_tamper and would like to make a plugin that converts textual 'true'/'false' to real bool true/false, however my first attempts are not going very well, my plugin callback does not seem to be called at all, do you have any idea why?

The code is as follows (in /plugins/convert_boolean.inc):

<?php

$plugin = array(
  'form' => 'feeds_tamper_convert_boolean_form',
  'callback' => 'feeds_tamper_convert_boolean_callback',
  'name' => 'Convert boolean',
  'multi' => 'loop',
  'category' => 'Text',
  'description' => 'feeds_tamper_convert_boolean_description',
);

function feeds_tamper_convert_boolean_form($importer, $element_key, $settings) {
 $form = array();
  $form['convert_boolean']['#markup'] = t('Convert textual boolean "true" to true and "false" to false');
  return $form;
}

function feeds_tamper_convert_boolean_description($settings) {
  $text = t('Convert textual boolean "true" to true and "false" to false');
  return $text;
}

function feeds_tamper_convert_boolean_callback($result, $item_key, $element_key, &$field, $settings) {
    if(0 != preg_match('/^true$/i',$field))
        $field = true;
    else
        $field = false;
}

The original reason for wanting the plugin came about when i was trying to import XML feeds, and having issue accepting that boolean data needs to be imported as text in order to preserve the data value.

E.g. given the XML element <some-element type="boolean">false</some-element> Directly reading the feed kept resulting in a value of 'true' (due to PHP type conversion rules i think).

Any help or advice anyone can offer on this would be greatly appreciated.

CommentFileSizeAuthor
#6 convert_boolean.zip updated 4/3/2012961 bytesmiltonsp

Comments

PartTimer’s picture

Have you tried mapping 'true' => 1, 'false' => 0? At least in the select box issue posted elsewhere this works for me.

twistor’s picture

Assigned: Unassigned » twistor
Category: support » feature

I like this idea. Here's a 2 minute sketch of what this might look like.

<?php

$plugin = array(
  'form' => 'feeds_tamper_convert_boolean_form',
  'callback' => 'feeds_tamper_convert_boolean_callback',
  'validate' => 'feeds_tamper_convert_boolean_validate',
  'name' => 'Convert boolean',
  'multi' => 'loop',
  'category' => 'Text',
);

function feeds_tamper_convert_boolean_form($importer, $element_key, $settings) {
  $form = array();
  $form['true_value'] = array(
    '#type' => 'textfield',
    '#title' => t('Truth value'),
    '#default_value' => isset($settings['true_value']) ? $settings['true_value'] : 'true'
  );
  $form['false_value'] = array(
    '#type' => 'textfield',
    '#title' => t('False value'),
    '#default_value' => isset($settings['false_value']) ? $settings['false_value'] : 'false',
  );
  $form['match_case'] = array(
    '#type' => 'checkbox',
    '#title' => t('Match case'),
    '#default_value' => isset($settings['match_case']) ? $settings['match_case'] : FALSE,
  );
  $form['no_match'] = array(
    '#type' => 'radios',
    '#title' => t('If no match'),
    '#default_value' => isset($settings['no_match']) ? $settings['no_match'] : 'false',
    '#options' => array('true' => ('True'), 'false' => t('False'), 'null' => t('Null'), 'pass' => t('Do not modify')),
    '#description' => t('The value to set if the true and false values do not match.'),
  );
  return $form;
}

function feeds_tamper_convert_boolean_validate(&$settings) {
  if (!$settings['match_case']) {
    $settings['false_value'] = drupal_strtolower($settings['false_value']);
    $settings['true_value'] = drupal_strtolower($settings['true_value']);
  }
  switch ($settings['no_match']) {
    case 'true':
      $settings['no_match_value'] = TRUE;
      break;
    case 'false':
      $settings['no_match_value'] = FALSE;
      break;
    case 'null':
      $settings['no_match_value'] = NULL;
  }
}

function feeds_tamper_convert_boolean_callback($result, $item_key, $element_key, &$field, $settings) {
  if (!$settings['match_case']) {
    $field = drupal_strtolower($field);
  }
  if ($field == $settings['true_value']) {
    $field = TRUE;
    return;
  }
  if ($field == $settings['false_value']) {
    $field = FALSE;
    return;
  }
  if ($settings['no_match'] == 'pass') {
    return;
  }
  $field = $settings['no_match_value'];
}

The thing it really needs is a 'FileNotFound' value.

iccle’s picture

This looks ideal, and keen to test it i swapped out the code i have written and gave it a shot.

It still looks like the callback is never being called, i added a watchdog entry at the start of the function (feeds_tamper_convert_boolean_validate) and it never shows up, i cleared my logs and tried again and the only error/warning that appeared was the following:

Type	php
Date	Saturday 12th March 2011, 10:21:27 (GMT +0000)
User	iccle
Location	http://myip/d7/batch?id=615&op=do
Referrer	http://myip/d7/batch?op=start&id=615
Message	Warning: Parameter 2 to feeds_tamper_feeds_after_parse() expected to be a reference, value given in module_invoke_all() (line 817 of E:\xampp\htdocs\d7\includes\module.inc).
Severity	warning
Hostname	myip :P
Operations	

There are two issues i would like to check here:

  1. Any idea why the callback does not get called?
  2. Can you confirm that path and filename i should work? (feeds_tamper/plugins/convert_boolean.inc)
twistor’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

miltonsp’s picture

Title: Help writing a plugin to convert boolean values. » Plugin for converting to boolean values.
Category: feature » bug
Status: Closed (fixed) » Fixed
StatusFileSize
new961 bytes

The 'Convert to boolean' plug-in does not work out-of-the-box in Drupal 7.
Specifically, during an import to a node, a boolean field was not being set.

Here is a small patch to make it work.

Index: .../feeds/feeds_tamper/plugins/convert_boolean.inc
===================================================================
--- ... /feeds/feeds_tamper/plugins/convert_boolean.inc	
+++ ... /feeds/feeds_tamper/plugins/convert_boolean.inc	
@@ -79,11 +79,11 @@
     $match_field = drupal_strtolower($match_field);
   }
   if ($match_field == $settings['true_value']) {
-    $field = TRUE;
+    $field = 1;
     return;
   }
   if ($match_field == $settings['false_value']) {
-    $field = FALSE;
+    $field = 0;
     return;
   }
   if ($settings['no_match'] == 'pass') {
twistor’s picture

Committed to 7.x
http://drupalcode.org/project/feeds_tamper.git/commit/0e42495

I'm somewhat confused by this, but not that concerned since 1 and 0 will work.

Does this need to be ported to 6.x?

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.