diff --git a/feeds.api.php b/feeds.api.php index e0dfc12..78c0cbd 100644 --- a/feeds.api.php +++ b/feeds.api.php @@ -297,17 +297,16 @@ function hook_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam * An entity object, for instance a node object. * @param $target * A string identifying the target on the node. - * @param $value + * @param $values * The value to populate the target with. * @param $mapping * Associative array of the mapping settings from the per mapping * configuration form. */ -function my_module_set_target($source, $entity, $target, $value, $mapping) { - $entity->{$target}[$entity->language][0]['value'] = $value; +function my_module_set_target($source, $entity, $target, array $values, $mapping) { + $entity->{$target}[$entity->language][0]['value'] = reset($values); if (isset($source->importer->processor->config['input_format'])) { - $entity->{$target}[$entity->language][0]['format'] = - $source->importer->processor->config['input_format']; + $entity->{$target}[$entity->language][0]['format'] = $source->importer->processor->config['input_format']; } } diff --git a/mappers/date.inc b/mappers/date.inc index 8ff4cbb..061962d 100644 --- a/mappers/date.inc +++ b/mappers/date.inc @@ -33,41 +33,28 @@ function date_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam } /** - * Implements hook_feeds_set_target(). - * - * @param $node - * The target node. - * @param $field_name - * The name of field on the target node to map to. - * @param $feed_element - * The value to be mapped. Should be either a (flexible) date string - * or a FeedsDateTimeElement object. - * + * Callback for setting target values. */ -function date_feeds_set_target($source, $entity, $target, $feed_element) { +function date_feeds_set_target($source, $entity, $target, array $values) { list($field_name, $sub_field) = explode(':', $target, 2); - if (!is_array($feed_element)) { - $feed_element = array($feed_element); - } - $delta = 0; - foreach ($feed_element as $f) { + foreach ($values as $value) { - if (!($feed_element instanceof FeedsDateTimeElement)) { + if (!($value instanceof FeedsDateTimeElement)) { - if (empty($f) || !is_numeric($f) && is_string($f) && !date_create($f)) { - $f = new FeedsDateTimeElement(NULL, NULL); + if (empty($value) || !is_numeric($value) && is_string($value) && !date_create($value)) { + $value = new FeedsDateTimeElement(NULL, NULL); } elseif ($sub_field == 'end') { - $f = new FeedsDateTimeElement(NULL, $f); + $value = new FeedsDateTimeElement(NULL, $value); } else { - $f = new FeedsDateTimeElement($f, NULL); + $value = new FeedsDateTimeElement($value, NULL); } } - $f->buildDateField($entity, $field_name, $delta); + $value->buildDateField($entity, $field_name, $delta); $delta++; } } diff --git a/mappers/file.inc b/mappers/file.inc index aa967b9..e9cbc26 100644 --- a/mappers/file.inc +++ b/mappers/file.inc @@ -48,57 +48,45 @@ function file_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam * user has decided to map to and $value contains the value of the feed item * element the user has picked as a source. */ -function file_feeds_set_target($source, $entity, $target, $value) { - if (empty($value)) { - return; - } - - // Make sure $value is an array of objects of type FeedsEnclosure. - if (!is_array($value)) { - $value = array($value); - } - +function file_feeds_set_target($source, $entity, $target, array $values) { // Add default of uri for backwards compatibility. list($field_name, $sub_field) = explode(':', $target . ':uri'); $info = field_info_field($field_name); if ($sub_field == 'uri') { - foreach ($value as $k => $v) { + foreach ($values as $k => $v) { if (!($v instanceof FeedsEnclosure)) { if (is_string($v)) { - $value[$k] = new FeedsEnclosure($v, file_get_mimetype($v)); + $values[$k] = new FeedsEnclosure($v, file_get_mimetype($v)); } else { - unset($value[$k]); + // Set the value for FALSE rather than remove it to keep our deltas + // correct. + $values[$k] = FALSE; } } } - if (empty($value)) { - return; - } - static $destination; - if (!$destination) { - $entity_type = $source->importer->processor->entityType(); - $bundle = $source->importer->processor->bundle(); + $entity_type = $source->importer->processor->entityType(); + $bundle = $source->importer->processor->bundle(); - $instance_info = field_info_instance($entity_type, $field_name, $bundle); + $instance_info = field_info_instance($entity_type, $field_name, $bundle); - // Determine file destination. - // @todo This needs review and debugging. - $data = array(); - if (!empty($entity->uid)) { - $data[$entity_type] = $entity; - } - $destination = file_field_widget_uri($info, $instance_info, $data); + // Determine file destination. + // @todo This needs review and debugging. + $data = array(); + if (!empty($entity->uid)) { + $data[$entity_type] = $entity; } + + $destination = file_field_widget_uri($info, $instance_info, $data); } // Populate entity. $field = isset($entity->$field_name) ? $entity->$field_name : array(LANGUAGE_NONE => array()); $delta = 0; - foreach ($value as $v) { + foreach ($values as $v) { if ($info['cardinality'] == $delta) { break; } @@ -114,14 +102,16 @@ function file_feeds_set_target($source, $entity, $target, $value) { break; case 'uri': - try { - $file = $v->getFile($destination); - $field[LANGUAGE_NONE][$delta] += (array) $file; - // @todo: Figure out how to properly populate this field. - $field[LANGUAGE_NONE][$delta]['display'] = 1; - } - catch (Exception $e) { - watchdog_exception('Feeds', $e, nl2br(check_plain($e))); + if ($v) { + try { + $file = $v->getFile($destination); + $field[LANGUAGE_NONE][$delta] += (array) $file; + // @todo: Figure out how to properly populate this field. + $field[LANGUAGE_NONE][$delta]['display'] = 1; + } + catch (Exception $e) { + watchdog_exception('Feeds', $e, nl2br(check_plain($e))); + } } break; } diff --git a/mappers/link.inc b/mappers/link.inc index 45a86f7..90b5268 100644 --- a/mappers/link.inc +++ b/mappers/link.inc @@ -41,36 +41,22 @@ function link_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam * user has decided to map to and $value contains the value of the feed item * element the user has picked as a source. */ -function link_feeds_set_target($source, $entity, $target, $value) { - if (empty($value)) { - return; - } - - // Handle non-multiple value fields. - if (!is_array($value)) { - $value = array($value); - } - - // Iterate over all values. +function link_feeds_set_target($source, $entity, $target, array $values) { list($field_name, $column) = explode(':', $target); - $info = field_info_field($field_name); - $field = isset($entity->$field_name) ? $entity->$field_name : array(); + $field = isset($entity->$field_name) ? $entity->$field_name : array('und' => array()); $delta = 0; - foreach ($value as $v) { - if ($info['cardinality'] == $delta) { - break; + foreach ($values as $value) { + if (is_object($value) && ($value instanceof FeedsElement)) { + $value = $value->getValue(); } - if (is_object($v) && ($v instanceof FeedsElement)) { - $v = $v->getValue(); - } - - if (is_scalar($v)) { - $field['und'][$delta][$column] = $v; - $delta++; + if (is_scalar($value)) { + $field['und'][$delta][$column] = (string) $value; } + $delta++; } + $entity->$field_name = $field; } diff --git a/mappers/number.inc b/mappers/number.inc index b64c4ee..338d569 100644 --- a/mappers/number.inc +++ b/mappers/number.inc @@ -37,36 +37,18 @@ function number_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_n * * Ensure that $value is a numeric to avoid database errors. */ -function number_feeds_set_target($source, $entity, $target, $value) { - - // Do not perform the regular empty() check here. 0 is a valid value. That's - // really just a performance thing anyway. - - if (!is_array($value)) { - $value = array($value); - } - - $info = field_info_field($target); - +function number_feeds_set_target($source, $entity, $target, array $values) { // Iterate over all values. $field = isset($entity->$target) ? $entity->$target : array('und' => array()); - // Allow for multiple mappings to the same target. - $delta = count($field['und']); - - foreach ($value as $v) { - - if ($info['cardinality'] == $delta) { - break; - } + foreach ($values as $value) { - if (is_object($v) && ($v instanceof FeedsElement)) { - $v = $v->getValue(); + if (is_object($value) && ($value instanceof FeedsElement)) { + $value = $value->getValue(); } - if (is_numeric($v)) { - $field['und'][$delta]['value'] = $v; - $delta++; + if (is_numeric($value)) { + $field['und'][] = array('value' => $value); } } diff --git a/mappers/path.inc b/mappers/path.inc index 47ae0fc..cd39fb1 100644 --- a/mappers/path.inc +++ b/mappers/path.inc @@ -33,14 +33,15 @@ function path_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam * user has decided to map to and $value contains the value of the feed item * element the user has picked as a source. */ -function path_feeds_set_target($source, $entity, $target, $value, $mapping) { - if (empty($value)) { - $value = ''; - } - - // Path alias cannot be multi-valued, so use the first value. - if (is_array($value)) { - $value = $value[0]; +function path_feeds_set_target($source, $entity, $target, array $values, $mapping) { + $alias = FALSE; + // Path alias cannot be multi-valued, so use the first non-empty value. + foreach ($values as $value) { + $value = ltrim(trim($value), '/'); + if (strlen($value)) { + $alias = $value; + break; + } } $entity->path = array(); @@ -58,15 +59,11 @@ function path_feeds_set_target($source, $entity, $target, $value, $mapping) { } } - $entity->path['pathauto'] = FALSE; - // Allow pathauto to set the path alias if the option is set, and this value - // is empty. - if (!empty($mapping['pathauto_override']) && !$value) { - $entity->path['pathauto'] = TRUE; - } - else { - $entity->path['alias'] = ltrim($value, '/'); - } + // Allow pathauto to set the path alias if the option is set, and the value is + // empty. + $entity->path['pathauto'] = !empty($mapping['pathauto_override']) && $alias === FALSE; + + $entity->path['alias'] = (string) $alias; } /** diff --git a/mappers/profile.inc b/mappers/profile.inc index 0dd62de..00fdf3a 100644 --- a/mappers/profile.inc +++ b/mappers/profile.inc @@ -30,6 +30,6 @@ function profile_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_ /** * Set the user profile target after import. */ -function profile_feeds_set_target($source, $entity, $target, $value, $mapping) { - $entity->$target = $value; +function profile_feeds_set_target($source, $entity, $target, array $values, $mapping) { + $entity->$target = reset($values); } diff --git a/mappers/taxonomy.inc b/mappers/taxonomy.inc index b395df9..088a558 100644 --- a/mappers/taxonomy.inc +++ b/mappers/taxonomy.inc @@ -82,18 +82,7 @@ function taxonomy_feeds_processor_targets_alter(&$targets, $entity_type, $bundle * * @todo Do not create new terms for non-autotag fields. */ -function taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping = array()) { - - // Allow mapping the string '0' to a term name. - if (empty($terms) && $terms != 0) { - return; - } - - // Handle non-multiple values. - if (!is_array($terms)) { - $terms = array($terms); - } - +function taxonomy_feeds_set_target($source, $entity, $target, array $terms, $mapping = array()) { // Add in default values. $mapping += array( 'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_NAME, @@ -144,13 +133,14 @@ function taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping = // Lookup by name. case FEEDS_TAXONOMY_SEARCH_TERM_NAME: + $term = trim($term); $name_query = clone $query; - if ($tids = $name_query->propertyCondition('name', $term)->execute()) { + if (strlen($term) && $tids = $name_query->propertyCondition('name', $term)->execute()) { $tid = key($tids['taxonomy_term']); } - elseif ($mapping['autocreate'] && strlen(trim($term))) { + elseif ($mapping['autocreate'] && strlen($term)) { $term = (object) array( - 'name' => drupal_substr(trim($term), 0, 255), + 'name' => drupal_substr($term, 0, 255), 'vid' => key($cache['allowed_vocabularies'][$target]), 'vocabulary_machine_name' => reset($cache['allowed_vocabularies'][$target]), ); @@ -176,7 +166,7 @@ function taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping = } if ($tid && isset($cache['allowed_values'][$target][$tid])) { - $field['und'][$delta]['tid'] = $tid; + $field['und'][] = array('tid' => $tid); $delta++; } } diff --git a/mappers/text.inc b/mappers/text.inc index 48447d7..5646753 100644 --- a/mappers/text.inc +++ b/mappers/text.inc @@ -33,45 +33,27 @@ function text_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam /** * Callback for mapping text fields. */ -function text_feeds_set_target($source, $entity, $target, $value) { - if (empty($value)) { - return; - } - - if (!is_array($value)) { - $value = array($value); - } - +function text_feeds_set_target($source, $entity, $target, array $values) { if (isset($source->importer->processor->config['input_format'])) { $format = $source->importer->processor->config['input_format']; } - $info = field_info_field($target); - - // Iterate over all values. $field = isset($entity->$target) ? $entity->$target : array('und' => array()); - // Allow for multiple mappings to the same target. - $delta = count($field['und']); - - foreach ($value as $v) { - - if ($info['cardinality'] == $delta) { - break; - } + // Iterate over all values. + foreach ($values as $value) { - if (is_object($v) && ($v instanceof FeedsElement)) { - $v = $v->getValue(); + if (is_object($value) && ($value instanceof FeedsElement)) { + $value = $value->getValue(); } - if (is_scalar($v)) { - $field['und'][$delta]['value'] = $v; - + if (is_scalar($value) && strlen($value)) { + $value = array('value' => (string) $value); if (isset($format)) { - $field['und'][$delta]['format'] = $format; + $value['format'] = $format; } - $delta++; + $field['und'][] = $value; } } diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc index 3c8c4a5..6666276 100755 --- a/plugins/FeedsProcessor.inc +++ b/plugins/FeedsProcessor.inc @@ -570,12 +570,19 @@ abstract class FeedsProcessor extends FeedsPlugin { isset($targets[$this->id][$mapping['target']]['callback']) && function_exists($targets[$this->id][$mapping['target']]['callback'])) { $callback = $targets[$this->id][$mapping['target']]['callback']; + + // All target callbacks expect an array. + if (!is_array($value)) { + $value = array($value); + } + $callback($source, $target_item, $mapping['target'], $value, $mapping); } else { $this->setTargetElement($source, $target_item, $mapping['target'], $value, $mapping); } } + return $target_item; }