Hi,

I have a migration on which I want to combine a callback with a sourceMigration:

    $this->addFieldMapping('field_my_field', 'ID')
         ->callbacks(array($this, 'convertOldIDToMigrationID'))
         ->separator(',')
         ->sourceMigration(array('another_migration'));

The function convertOldIDToMigrationID returns a comma separated string with migration ID's from another_migration. If I run

    $this->addFieldMapping('field_my_field', 'ID')
         ->callbacks(array($this, 'convertOldIDToMigrationID'))
         ->separator(',');

then I see some dpm's which are located in the callback. However if I add the sourceMigration as well, these dpm's doesn't show up anymore, so it looks like the callback is not executed anymore.

What am I doing wrong? Is it possible to combine a callbacks with a sourceMigration at all?

Comments

mikeryan’s picture

Status: Active » Postponed (maintainer needs more info)

The order these options are executed in applyMappings() is:

  1. separator()
  2. sourceMigration()
  3. callbacks()

So, what's happening is:

  1. The raw data is separated out according to any commas that are present.
  2. sourceMigration() is applied to the raw data. Since you're expecting convertOldIDToMigrationID to properly set up the IDs, it's probably not finding any matches and thus returning NULL.
  3. Since we're now dealing with NULL data, the callbacks are not called.

In this instance, since you need to call convertOldIDToMigrationID before separator() and sourceMigration(), you should be calling it in prepareRow() rather than via a callback.

ToRum’s picture

Status: Postponed (maintainer needs more info) » Closed (fixed)

Thanks! FYI, I got it working by using prepareRow($row):

   $this->addFieldMapping('field_my_field', 'custom_variable_name');
   public function prepareRow($row) {
    parent::prepareRow($row);

    $source_ids = $this->convertOldIDToMigrationID($row->ID);
    foreach ($source_ids as $key => $value) {
      $row->custom_variable_name[] = $this->handleSourceMigration('another_migration', $value);
    }
   }
joseph.olstad’s picture

Issue summary: View changes

Mikeryan suggestion was good for me.

My use case: events (evènements) , two fields, one source.
the field_evenement_themes will hold the first categorie
the field_evenement_secondaire will hold all the rest of the categories (if there are any)

Here's my code snippet.

class EvenementsMigration extends CalendrierBaseMigration {

  public function __construct($arguments) {
    parent::__construct($arguments);
//.........
//.........
//.........
//.........
    // field_evenement_themes.
    $this->addFieldMapping('field_evenement_themes', 'categories')->sourceMigration('categories')
      ->callbacks(array($this, 'categoriePrincipale'));
     $this->addFieldMapping('field_evenement_themes:source_type')->defaultValue('tid');
    // field_evenement_theme_secondaire.
    $this->addFieldMapping('field_evenement_theme_secondaire', 'categories')->sourceMigration('categories')
      ->callbacks(array($this, 'categorieSecondaire'));
    $this->addFieldMapping('field_evenement_theme_secondaire:source_type')->defaultValue('tid');
  }

  protected function categoriePrincipale($categories) {
    if (is_array($categories)) {
      return current($categories);
    } else {
      return $categories;
    }
  }
  protected function categorieSecondaire($categories) {
    if (is_array($categories)) {
      return array_shift($categories);
    } else {
      // Si ce n'est pas un tableau c'est pareil que évenement principale donc sécondaire deviens RIEN.
      return NULL;
    }
  }

seems to work well so far.