4

I'm working on a project that requires a CSV of speaking engagements to be migrated to Drupal. With Migrate, I've been able to migrate over basic fields, like name, title, etc.

However, the speaker field is a field collection, which is driving me nuts. While the field collection allows unlimited speakers, the CSV only has one per event. I've tried using the node_insert hook, as described here but to no avail. Is there a better/easier way to migrate a single speaker into the speaker field collection?

5

There is a Field Collection issue with a Field Collection Migrate destination (in the patch in comment #222). The added field_collection.migrate.inc file contain a bit of documentation on how to use it.

In you case, I guess you have a speaking engagements migration class which load your CSV file and create Speaking engagement nodes. You will then need a speaker migration class to load the same CSV file and create Speaker field collections. This second migration class depends on the first one, so when a Speaker is created, it will be linked to its Speaking engagement.

Something like

class SpeakerMigration extends Migration {

  public function __construct($arguments) {
    parent::__construct($arguments);
    $this->dependencies = array('SpeakingEngagementMigration');
    $this->source = new MigrateSourceCSV('path/to/speaking/engagement.csv', array(), array());
    $this->destination = new MigrateDestinationFieldCollection('field_speakers',array('host_entity_type' => 'node'));
    $this->map = new MigrateSQLMap($this->machineName, array(
      'id' => array(
        'type' => 'char',
        'length' => 40,
        'not null' => TRUE,
        'description' => t("Speaking Engagement's identifier"),
      )), MigrateDestinationFieldCollection::getKeySchema());
    $this->addFieldMapping('host_entity_id', 'id')
      ->sourceMigration('SpeakingEngagementMigration');

    // ... Add field mapping here.
  }
}
2

Another option is the implement the complete method of the Migration class and populate the field collection programmatically there.

public function complete($entity, $row) {

  // load the newly created node (just in case entity isn't fully populated).
  $node = node_load($entity->nid);

  // set the values of all field collection fields
  $values = array(
    'field_name' => 'FIELD_COLLECTION_ITEM_FIELD_NAME',
    'field1'     => array(LANGUAGE_NONE => array(array('value' => 'VALUE'))),
    'field3'     => array(LANGUAGE_NONE => array(array('value' => 'VALUE'))),
  );

  // create the field collection item entity
  $item = entity_create('field_collection_item', $values);

  // attach it to the node loaded above
  $item->setHostEntity('node', $node);

  // save the entity
  $item->save();
}

NOTE: If you are adding files to the field collection item, they will not be removed on a rollback unless you explicitly do that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.