You are here

function mvf_feeds_set_target in Measured Value Field 7

MVF callback for mapping.

When the callback is invoked, $target contains the name of the field the user has decided to map to and $value contains the value of the feed item element the user has picked as a source.

Parameters

$source: A FeedsSource object.

$entity: The entity to map to.

$target: The target key on $entity to map to.

$values: The value to map. MUST be an array.

array $mapping: Array of mapping settings

1 string reference to 'mvf_feeds_set_target'
mvf_feeds_processor_targets in ./mvf.feeds.inc
Implements hook_feeds_processor_targets().

File

./mvf.feeds.inc, line 66
Integration with Feeds of MVF module.

Code

function mvf_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) {
  if (empty($values)) {
    return;
  }
  $language = $mapping['language'];

  // This function can be invoked in 2 different ways. To map MVF from one cell,
  // or to map MVF from 2 cells. In the former case the $target is just field
  // name. In the latter case, the $target is $field_name:$column, where
  // $column identifies which of the 2 columns right now we are mapping.
  $tmp = explode(':', $target);
  $field_name = array_shift($tmp);
  $columns = empty($tmp) ? array(
    'value',
    'unit',
  ) : $tmp;
  $field = isset($entity->{$field_name}) ? $entity->{$field_name} : array(
    $language => array(),
  );

  // Converting from string value into array with the 2 keys:
  // - value: decimal part of the MVF value
  // - unit: unit measure part of the MVF value
  // Depending on the case, only one column may be present in the array
  // representation.
  $exploded_values = array();
  foreach ($values as $value) {
    if (count($columns) == 2) {
      $value = array_map('trim', explode(' ', $value));
      $value = array(
        'value' => $value[0],
        'unit' => $value[1],
      );
    }
    else {
      $value = array(
        reset($columns) => $value,
      );
    }
    $exploded_values[] = $value;
  }
  if (in_array('unit', $columns)) {

    // First, collect a full list of the encountered units, so we can load them
    // later on more efficiently in a single batch.
    $hash_map = array();
    foreach ($exploded_values as $value) {
      $hash_map[$value['unit']] = $value['unit'];
    }

    // Now let's load the units all in a single batch.
    if (!isset($mapping['unit_notation'])) {
      $options = array_keys(mvf_feeds_mapper_unit_notation_options());
      $mapping['unit_notation'] = reset($options);
    }
    switch ($mapping['unit_notation']) {
      case 'umid':

        // Nothing to do. $hash_map already contains perfect hash map for us, as
        // it maps from incoming format to unmid.
        break;
      case 'symbol':
      case 'label':
      case 'machine_name':

        // Construct the hash map for the encountered units.
        $measure = mvf_measure_extract(field_info_field($field_name));
        $hash_map = db_select('units_unit', 'u')
          ->fields('u', array(
          $mapping['unit_notation'],
          'umid',
        ))
          ->condition('measure', $measure->measure)
          ->condition($mapping['unit_notation'], array_keys($hash_map))
          ->execute()
          ->fetchAllKeyed();
        break;
    }
  }

  // Now we are ready to actually fill in the MVF field values.
  $i = 0;
  foreach ($exploded_values as $value) {
    if (!in_array('unit', $columns) || isset($hash_map[$value['unit']])) {
      if (in_array('unit', $columns)) {
        $field[$language][$i][mvf_subfield_to_column('unit')] = $hash_map[$value['unit']];
      }
      if (in_array('value', $columns)) {
        $field[$language][$i][mvf_subfield_to_column('value')] = $value['value'];
      }
      $i++;
    }
    else {
      $source
        ->log('mvf', 'Encountered unknown unit @unit', array(
        '@unit' => $value['unit'],
      ));
    }
  }
  $entity->{$field_name} = $field;
}