 multifield.feeds.inc | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)

diff --git a/multifield.feeds.inc b/multifield.feeds.inc
new file mode 100644
index 0000000..ec40c9d
--- /dev/null
+++ b/multifield.feeds.inc
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * @file
+ * Feeds mapping implementation for the Multifield module
+ */
+
+/**
+ * Implements hook_feeds_processor_targets_alter().
+ *
+ * @see FeedsNodeProcessor::getMappingTargets().
+ */
+function multifield_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
+
+  foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
+    $info = field_info_field($name);
+    if ($info['type'] == 'multifield') {
+      // We don't use ":guid" in key, not to break existing configurations.
+      $targets[$name] = array(
+        'name'        => check_plain($instance['label'] . t(' (Multifield: ') . $instance['field_name'] . ')'),
+        'callback'    => 'multifield_feeds_set_target',
+        'description' => t('The field instance @label.', array(
+          '@label' => $instance['label'],
+          '@id'    => $name,
+        )),
+      );
+    }
+  }
+}
+
+/**
+ * Entity reference callback for mapping.
+ *
+ * When the callback is invoked, $target contains the name of the field the
+ * user has decided to map to and $values contains the value of the feed item
+ * element the user has picked as a source.
+ *
+ * @param $source
+ *   A FeedsSource object.
+ * @param $entity
+ *   The entity to map to.
+ * @param $target
+ *   The target key on $entity to map to.
+ * @param $values
+ *   The value to map. MUST be an array.
+ */
+function multifield_feeds_set_target($source, $entity, $target, $values, $mapping) {
+
+  // Don't do anything if we weren't given any data.
+  if (empty($values)) {
+    return;
+  }
+
+  // Assume that the passed in value could really be any number of values.
+  if (is_array($values)) {
+    $valuess = explode("|", $values[0]);
+  }
+  else {
+    $valuess = explode("|", $values);
+  }
+  // Get some useful field information.
+  $info = field_info_field($target);
+
+  // Set the language of the field depending on the mapping.
+  $language = isset($mapping['language']) ? $mapping['language'] : LANGUAGE_NONE;
+
+  // Iterate over all values.
+  $iterator = 0;
+  $field = isset($entity->$target) ? $entity->$target : array();
+
+  $subfields = field_info_instances('multifield', $target);
+  foreach ($valuess as $values) {
+
+    // Only process if this value was set for this instance.
+    if ($values) {
+      $subvalues = explode(",", $values);
+      $delta = 0;
+      foreach($subfields as $subfield => $subinstance) {
+        $subinfo = field_info_field($subfield);
+        $dummyObj = new stdclass();
+        switch ($subinfo['type']) {
+          case 'date':
+          case 'datestamp':
+          case 'datetime':
+            $function = 'text_feeds_set_target';
+            break;
+          case 'file':
+          case 'image':
+            $function = 'file_feeds_set_target';
+            break;
+          case 'list_text':
+          case 'text':
+          case 'text_long':
+          case 'text_with_summary':
+            $function = 'text_feeds_set_target';
+            break;
+          case 'list_integer':
+          case 'list_float':
+          case 'list_boolean':
+          case 'number_integer':
+          case 'number_decimal':
+          case 'number_float':
+            $function = 'number_feeds_set_target';
+            break;
+          case 'entityreference':
+            $function = 'entityreference_feeds_set_target';
+            break;
+          case 'taxonomy_term_reference':
+            $function = 'taxonomy_feeds_set_target';
+            break;
+        }
+
+        if(function_exists($function)) {
+          if($function == 'text_feeds_set_target'){
+            // text_feeds_set_target needs new mapping argument:
+            $function($source, $dummyObj, $subfield, array($subvalues[$delta]), $mapping);
+          } else {
+            $function($source, $dummyObj, $subfield, array($subvalues[$delta]));
+          }
+        }
+
+        if(!empty($dummyObj->$subfield)) {
+          $field[$language][$iterator][$subfield] = $dummyObj->$subfield;
+        }
+        else /* there is no $entity_id, no mapping */ {
+          /*
+           * Feeds stores a hash of every line imported from CSVs in order to
+           * make the import process more efficient by ignoring lines it's
+           * already seen.  We need to short-circuit this process in this case
+           * because users may want to re-import the same line as an update later
+           * when (and if) a map to a reference exists.  So in order to provide
+           * this opportunity later, we need to destroy the hash.
+           */
+          unset($entity->feeds_item->hash);
+        }
+        $delta++;
+      }
+    }
+
+    // Break out of the loop if this field is single-valued.
+    if ($info['cardinality'] == 1) {
+      break;
+    }
+    $iterator++;
+  }
+  // Add the field to the entity definition.
+  $entity->{$target} = $field;
+}
