You are here

function field_collection_feeds_set_target in Field collection 7

Process Field Collection items.

Parameters

[type] $source [description]:

[type] $entity [description]:

[type] $target [description]:

[type] $value [description]:

[type] $main_mapping [description]:

Return value

[type] [description]

1 string reference to 'field_collection_feeds_set_target'
field_collection_feeds_processor_targets_alter in ./field_collection.module
Implements hook_feeds_processor_targets_alter().

File

./field_collection.module, line 2279
Module implementing field collection field type.

Code

function field_collection_feeds_set_target($source, $entity, $target, $value, $main_mapping) {
  $sub_targets =& drupal_static(__FUNCTION__, array());
  $args = explode(':', $target);
  $target = array_shift($args);
  $sub_target = implode(':', $args);
  $sub_type = 'field_collection_item';
  $new_targets = module_invoke_all('feeds_processor_targets', $sub_type, $target);
  drupal_alter('feeds_processor_targets', $new_targets, $sub_type, $target);

  // Now we retrieve old callbacks and keep then on a static cache.
  if (!isset($sub_targets[$target])) {
    $sub_targets[$target] = array();
    drupal_alter('feeds_processor_targets', $sub_targets[$target], $sub_type, $target);
  }
  $_sub_targets = $new_targets;
  $value = is_array($value) ? $value : array(
    $value,
  );
  $info = field_info_field($target);

  // Iterate over all values.
  $delta = 0;
  $field = isset($entity->{$target}) ? $entity->{$target} : array();
  try {

    // $delta = which FC instance.
    // We iterate by subfield, not by FC.
    while (isset($value[$delta])) {

      // Zero out.
      $field_collection_item = NULL;

      // FC is already set on host entity.
      if (isset($field[LANGUAGE_NONE][$delta]['entity'])) {
        $field_collection_item = $field[LANGUAGE_NONE][$delta]['entity'];
      }
      elseif (isset($field[LANGUAGE_NONE][$delta]['value'])) {
        $field_collection_item = field_collection_item_load($field[LANGUAGE_NONE][$delta]['value']);

        // Zero out field so that we don't just keep accumulating values.
        unset($field_collection_item->{$sub_target}[LANGUAGE_NONE]);
      }

      // Host entity does not have any attached FCs yet.
      if (empty($field_collection_item)) {
        $field_collection_item = entity_create('field_collection_item', array(
          'field_name' => $target,
        ));
        $field_collection_item
          ->setHostEntity($entity->feeds_item->entity_type, $entity);
      }
      $sub_mapping = array();
      $config = $source
        ->importer()
        ->getConfig();
      if (!empty($config['processor']['config']['mappings'])) {
        foreach ($config['processor']['config']['mappings'] as $mapping) {
          if ($mapping['target'] === $target . ':' . $sub_target) {
            $sub_mapping = $mapping;
            $sub_mapping['target'] = $sub_target;

            // Needs language or feeds mappers shout php notices.
            $sub_mapping['language'] = !empty($config['processor']['config']['language']) ? $config['processor']['config']['language'] : LANGUAGE_NONE;
            break;
          }
        }
      }
      if (isset($_sub_targets[$sub_target]['callback']) && function_exists($_sub_targets[$sub_target]['callback'])) {
        $callback = $_sub_targets[$sub_target]['callback'];

        // Normalize.
        if (!is_array($value[$delta])) {
          $value[$delta] = array(
            $value[$delta],
          );
        }

        // Check for a limit and force that limit.
        if ($info['cardinality'] !== '-1') {
          $value[$delta] = array_slice($value[$delta], 0, $info['cardinality']);
        }

        // HiJack the file callback so we can make it work.
        if ($callback === 'file_feeds_set_target') {
          $callback = 'field_collection_file_feeds_set_target';
        }

        // Allow altering with many parameters. Cannot use drupal_alter here.
        $implements = module_implements('sub_target_pre_callback_parse');
        foreach ($implements as $module_name) {
          $hook = $module_name . '_' . 'sub_target_pre_callback_parse';
          $hook($target, $sub_target, $entity, $field, $field_collection_item, $value[$delta]);
        }
        $callback($source, $field_collection_item, $sub_target, $value[$delta], $sub_mapping);
      }

      // No need to save the field collection here. Just wait until the node is saved.
      // If we save the FC here we get a huge performance degregation.
      $field[LANGUAGE_NONE][$delta]['entity'] = $field_collection_item;

      // Break when only hitting the max delta.
      if ($info['cardinality'] == $delta) {
        break;
      }
      $delta++;
    }
  } catch (Exception $e) {
    drupal_set_message($e
      ->getMessage(), 'error');
    watchdog_exception('field_collection', $e, $e
      ->getMessage());
    throw $e;
  }
  $entity->{$target} = $field;
}