Currently, if you map to a field more than one time, each successive mapping will override the previous one. This can even lead to odd behavior if the first source contained more values than the second.

As per some discussion in #860748: Config for mappers?.

Files: 
CommentFileSizeAuthor
#21 feeds-multiple-mappings-982150-21.patch3.19 KBosopolar
FAILED: [[SimpleTest]]: [MySQL] 4,503 pass(es), 0 fail(s), and 11 exception(s).
[ View ]
#1 982150-1-Allow_multiple_mappings_to_targets_in_field_inc.patch1.06 KBtwistor

Comments

twistor’s picture

This patch tries to change as little of the logic as possible. I think it might be better to check the type in field_feeds_set_target_text and not in _field_feeds_set_target at all. It comes down to whether we should try to enforce type or let the field implementations handle it.

If we go this route, most (guessing) of the target mappers will have to change and we should be careful as these will be references for anyone else implementing them. Most of them are copy-paste jobs as it is. It should also be documented that this is the required behavior.

twistor’s picture

Title:Allow multiple mappings to targets in field.inc» Multiple mappings to the same target
NicolasH’s picture

subscribe

hansrossel’s picture

This is how it was done for the 6.x version: #873198: Import multiple values to tag vocabulary

Ericmaster’s picture

subscribe

maureen’s picture

I'm not a programmer, and I still don't know how to create a patch after all this time. But here is how I solved this problem when I ran up against it today. Since I was using a semicolon as my field deliminator, I could use a comma to separate the multiple values. I know it's not a final solution, but thought it might help someone.

I changed the follow function in the mappers/field.inc.

/**
* Callback for mapping text fields.
*/
function field_feeds_set_target_text($source, $entity, $target, $value) {
  $info = field_info_field($target);
  if ($info['cardinality'] == -1) {
    $value = preg_split("/[,]/", $value);
  }
  if (!is_array($value)) {
    $value = array($value);
  }
  _field_feeds_set_target($source, $entity, $target, $value, TRUE);
}
puhig’s picture

Version:7.x-2.x-dev» 6.x-1.x-dev

Hi , Exist a equivalent on drupal 6.x for field_info_field($target) ?

Thanks

juampynr’s picture

hook_feeds_after_parse() may be of help here. Please read http://drupal.org/node/1360518.

colan’s picture

chrisroditis’s picture

Version:6.x-1.x-dev» 7.x-2.x-dev

Tested patch in #1 and works great for mapping multiple sources to the same target field (tested with a multivalue text field)

danon1981’s picture

I Was looking for a solution for this as well and found that using Feeds tamper you can accomplish this through the following procedure.

Because the last field overwrites all previous submissions when mapping multiple fields to one field (in my case a free tagging multiple value taxonomy field)

Step 1 Use the "rewrite" filter on de last mapper that submits to the field you map to your target field. Select al the required fields that you like to include using the replacement patterns and separate them by a comma,

Step 2 Add a "Explode" filter, and leave the comma as "String separator"

Make sure these filters are in this order ( 1.rewrite 2.explode) that's it you can now map multiple value sources to one target field.

gravit’s picture

There is one additional caveat here -

It seems feeds tamper goes in alphabetical order for some things - If you are using Feeds Tamper to do any sort of field alteration (find and replace, convert to boolean, etc) You need to make sure the "last mapper" is also the last field alphabetically. Otherwise your field alterations will not happen before the "rewrite" filter on the "last mapper".

anibal’s picture

Feeds tamper does it in perfection. its kind of weird, the logic i mean, but in the end it will do the job.
Great module.
Thanks for the tip.

Matt B’s picture

#11 - great tip - thank you!

capono’s picture

#11 is a nice tip. Tested on a free tagging multiple value taxonomy field.

One thing though: the first field is inserted without the explode. So if I have a first field with (term1,term2) and a second field with (term3,term4) the inserted terms will be:
- term1,term2
- term1
- term2
- term3
- term4

If I set an explode tamper on the first field, and use that in the second field, the inserted terms will be:
- array
- term1
- term2
- term3
- term4

capono’s picture

hook_feeds_after_parse() from #8 helped me here. Thanks.

naeluh’s picture

Has this functionality been committed to the module d7 version or does it require the patch ?

does patch in #1 work for d7 dev

Because i cannot get this to work

I am trying to import a csv

I have a 5 radio button field that I am trying to populate

- update 02/12/13

I got it to work by just using explode and no rewrite plugin

Balbo’s picture

#11 made my day!

llillf’s picture

I just figured out how to map multi-files (multiple columns in CSV file) to the same target. Hope it helps anyone.

D7 mappers/file.inc

  // @todo This needs review and debugging.
  list($entity_id, $vid, $bundle_name) = entity_extract_ids($entity->feeds_item->entity_type, $entity);
  $instance_info = field_info_instance($entity->feeds_item->entity_type, $target, $bundle_name);
  $info = field_info_field($target);
  $data = array();
  if (!empty($entity->uid)) {
    $data[$entity->feeds_item->entity_type] = $entity;
  }
  $destination = file_field_widget_uri($info, $instance_info, $data);

  // Populate entity.
// $i = 0;
  $field = isset($entity->$target) ? $entity->$target : array();
  foreach ($value as $v) {
    try {
      $file = $v->getFile($destination);
    }
    catch (Exception $e) {
      watchdog_exception('Feeds', $e, nl2br(check_plain($e)));
    }

    $fid = $file->fid;   // ++++++++++++
    if ($file) {

     // $field['und'][$i]= (array)$file;
     // $field['und'][$i]['display'] = 1; // @todo: Figure out how to properly populate this field.
$field['und'][] = array('fid'=> $fid, 'display'=> 1);     //+++++++++++++
if ($info['cardinality'] == 1) {
        break;
      }
   //   $i++;
    }

xpersonas’s picture

#11 is great. My problem though is that i have a few nodes that have multiple images. The rest just have one. So when I run the import, I get failed node imports because the second image field is empty....

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'fid' cannot be null
osopolar’s picture

Issue summary:View changes
Status:Active» Needs review
StatusFileSize
new3.19 KB
FAILED: [[SimpleTest]]: [MySQL] 4,503 pass(es), 0 fail(s), and 11 exception(s).
[ View ]

This patch will make it possible when there are values from different mappings to the same target they will be added as multiple value. It would be also possible to keep alt and title attributes in sync with the file. Last but not least it will use the cardinality more efficient when some files could not be added or if there are empty source fields.

Status:Needs review» Needs work

The last submitted patch, 21: feeds-multiple-mappings-982150-21.patch, failed testing.

The last submitted patch, 21: feeds-multiple-mappings-982150-21.patch, failed testing.

osopolar’s picture

rcodina’s picture

Just added related issue for Drupal 6 version of this module. Could anyone make a patch which passes the tests? I really need this feature.

Thank you!

osopolar’s picture

Due to #2093651: Simplify target callbacks. the patch won't apply anymore to current d7 dev version.

twistor’s picture

#2093651: Simplify target callbacks. Should have actually fixed this for everything it could in 7.x-2.x.

@rcodina, Do you have a specific field that's not behaving correctly? That would be much faster to patch, especially for 6.x.

@everyone, This can't really be fixed generically at this point. It's fixed in 8.x-3.x, which I realize helps no one, but a general fix is too API intensive at at this point.

rcodina’s picture

@twistor, I just need to map multiple fields to same target on D7 (I'm doing a migration from a D6.)

twistor’s picture

@rcodina, It just depends on the field. Fields with multiple columns, for instance the Link field, won't work at this point, but all basic fields should work.

rcodina’s picture

@twistor, In my case I have two different file fields on D6 that I want to map to same field on D7 (a field which can have unlimited values). So as you said I have to wait (my current workaround is having two fields on D7). I'm using dev branch from February 11, 2014.

Eric_A’s picture

Fields with multiple columns, for instance the Link field, won't work at this point, but all basic fields should work.

What is needed for this issue to get closed? Why is it that mappers would not be able to just leave alone already set field items?

twistor’s picture

It's fixed in 8.x-3.x, a backport will happen at some point.

Take the link field as an example. It has a title and url column.

The way that targets currently work, is that they receive title => a, b, c and url => 1, 2, 3 in separate calls, so there's no way to determine if a field value for title was set before, or is empty, when setting the url values.

Eric_A’s picture

@twistor, thanks for the example!

My use case is mapping different XML elements (one for image, one for video) to the same item type. So as long as a target item isn't split up into multiple sub-targets, mappers should account for this, I guess.

Summit’s picture

Hi, @Twistor, thanks for updating! When will it be backported to 7.dev?
Greetings, Martijn