I have have a field collection set up and added to a host entity of type 'commerce_product'. I have an initial migration (ProductMigration) which imports the Product entities. The destination handler for this migration returns a key schema with two keys - product_id and revision_id.

When I run the migration for the field collection attached to the product entity, I get the error

array_flip(): Can only flip STRING and INTEGER values! 
File includes/entity.inc, line 179

When I dpm() the $collection object in the migrate import() function, I get:

    [host_entity_id] => Array
        (
            [destid1] => 89
            [destid2] => 89
        )

This $collection->host_entity_id is then passed as a param to entity_load_single() which can't handle that structure.

I added in a check before the call to entity_load_single() to see if it's an array, and if it is set the host entity id to be just destid1. There's might be a better way, but this at least makes my migrations work.

Comments

Status: Needs review » Needs work

The last submitted patch, field_collection_migrate_sourcemigration_multiple_keys.patch, failed testing.

bdziewierz’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new767 bytes

#2 works for me

aaronbauman’s picture

Status: Needs review » Reviewed & tested by the community

#2 Does what it says.
Without this patch, field collection migration doesn't work at all.

Thanks for the patch

jmuzz’s picture

Status: Reviewed & tested by the community » Needs review

I look at migration classes like this as examples to be extended rather than something that is supposed to be a robust solution by itself. The field collections migration class makes the assumption that the destination key for its host will be one numeric key and it will be the host entity's key, but it has no way to know if that's true or not. There might be a single numeric key which the destination class for the host knows how to handle but it might not be the entity's key, or a multiple value key with the entity id in another position than the first.

I'd say if your situation is anything other than the basic case you should make your own migration class and override the functions in a way that will handle your case.

class myMigrateDestinationFieldCollection extends MigrateDestinationFieldCollection {
  public function import(stdClass $collection, stdClass $row) {
    $collection->host_entity_id = $collection->host_entity_id['destid1'];
    return parent::import($collection, $row);
  }
}
aaronbauman’s picture

The field collections migration class makes the assumption that the destination key for its host will be one numeric key and it will be the host entity's key, but it has no way to know if that's true or not.

Unless I'm misinterpreting (or misremembering) the issue, the MigrateDestinationFieldCollection is broken for the case when the host entity has a single key, because MigrateDestinationFieldCollection assumes the host entity has multiple keys.

The patch updates MigrateDestinationFieldCollection to assume the host has a single key.

If i'm remembering correctly, field collection migration is not working at all for the majority of cases -- even when the host entity is a node.

jmuzz’s picture

The patch adds a check to see if the key is an array and it picks the first value if it is. If you look at the line in field_collections.migrate.inc that leads to the error you can see it's assuming a single key.

$host_entity = entity_load_single($this->hostEntityType, $collection->host_entity_id);
ndeet’s picture

Hi, just ran into the same issue and wanted to confirm that migrating a field collection into a previously migrated commerce_product causes the $collection->host_entity_id to be an array with multiple values instead of a single value like e.g. on nodes.
See:


// $collection->host_entity_id on a commerce product with string sku as unique id
// from the product source migration.
 
Array
(
    [sourceid1] => xxx-xxx-xxx
    [destid1] => 1202
    [destid2] => 1082
    [needs_update] => 0
    [rollback_action] => 0
    [last_imported] => 0
    [hash] => 
)

ndeet’s picture

StatusFileSize
new786 bytes

I ran into an issue with the patch. If in the source migration the import was skipped for some reason and the destid1 mapping is therefore 'NULL' the check if entity_host_id is an array is too late because it should be above the check if the host_entity_id is empty so that it can properly skip that entry too. I moved the previous fix above the empty check here:

// Skip the collection if it has no host.
if (empty($collection->host_entity_id)) {
  throw new MigrateException('Could not find host entity of the field collection to import.');
}
mlanning’s picture

I have been trying to migrate field collections into a custom entity from a csv file, and I was stuck on this for many hours. I kept getting the same error. Thank you for the solution, #8 worked for me!

mlanning’s picture

StatusFileSize
new675 bytes

The patch in #8 is no longer working for me with the latest dev version. It won't patch. I used the same code and made a patch against the latest dev version and this is now working for me. This is the first patch I've ever made or contributed, so apologies if I didn't do it appropriately.

nitesh sethia’s picture

Status: Needs review » Needs work

Tried using this patch. But it didnt work. So changing the status to Needs work.

r_morgan’s picture

StatusFileSize
new675 bytes

I ran into this issue migrating data into a field collection that is on an entity.
The code from #8 and #10 worked to fix my issue.
As was the case in #10, the a patch needed to be re-rolled so that it would apply to the current code base.

r_morgan’s picture

Status: Needs work » Needs review