public function ParagraphsLookup::transform

File

paragraphs/src/Plugin/migrate/process/ParagraphsLookup.php, line 96

Class

ParagraphsLookup
Looks up the value of a paragraph property based on previous migrations.

Namespace

Drupal\paragraphs\Plugin\migrate\process

Code

public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
  $source_id_values = [];
  $destination_ids = NULL;
  $migrations = [];
  if (isset($this->configuration['tags'])) {
    $tags = (array) $this->configuration['tags'];
    foreach ($tags as $tag) {

      /** @var \Drupal\migrate\Plugin\MigrationInterface[] $tag_migrations */
      $tag_migrations = $this->migrationPluginManager
        ->createInstancesByTag($tag);
      $migrations += $tag_migrations;
      if (isset($this->configuration['tag_ids'][$tag])) {
        $configuration = [
          'source' => $this->configuration['tag_ids'][$tag],
        ];
        try {
          $get_process_plugin = $this->processPluginManager
            ->createInstance('get', $configuration, $this->migration);
        } catch (PluginException $e) {
          continue;
        }
        $value = $get_process_plugin
          ->transform(NULL, $migrate_executable, $row, $destination_property);
      }
      foreach ($tag_migrations as $migration_id => $migration) {
        $source_id_values[$migration_id] = (array) $value;
        $destination_ids = $this
          ->lookupDestination($migration, $value);
        if ($destination_ids) {
          break 2;
        }
      }
    }
  }
  elseif (!empty($this->configuration['migration'])) {
    $destination_ids = parent::transform($value, $migrate_executable, $row, $destination_property);
    $migration_ids = $this->configuration['migration'];
    if (!is_array($migration_ids)) {
      $migration_ids = (array) $migration_ids;
    }

    /** @var \Drupal\migrate\Plugin\MigrationInterface[] $migrations */
    $migrations = $this->migrationPluginManager
      ->createInstances($migration_ids);
    foreach ($migrations as $migration_id => $migration) {
      if (isset($this->configuration['source_ids'][$migration_id])) {
        $configuration = [
          'source' => $this->configuration['source_ids'][$migration_id],
        ];
        $value = $this->processPluginManager
          ->createInstance('get', $configuration, $this->migration)
          ->transform(NULL, $migrate_executable, $row, $destination_property);
      }
      $source_id_values[$migration_id] = (array) $value;
      $destination_ids = $this
        ->lookupDestination($migration, $value);
      if ($destination_ids) {
        break;
      }
    }
  }
  else {
    throw new MigrateException("Either Migration or Tags must be defined.");
  }
  if (!$destination_ids && !empty($this->configuration['no_stub'])) {
    return NULL;
  }
  if (!$destination_ids) {

    // If the lookup didn't succeed, figure out which migration will do the
    // stubbing.
    if (isset($this->configuration['stub_id'])) {
      $migration = $this->migrationPluginManager
        ->createInstance($this->configuration['stub_id']);
      assert($migration instanceof MigrationInterface);
    }
    else {
      $migration = reset($migrations);
    }
    $destination_plugin = $migration
      ->getDestinationPlugin(TRUE);

    // Only keep the process necessary to produce the destination ID.
    $process = $migration
      ->getProcess();

    // We already have the source ID values but need to key them for the Row
    // constructor.
    $source_ids = $migration
      ->getSourcePlugin()
      ->getIds();
    $values = [];
    foreach (array_keys($source_ids) as $index => $source_id) {
      $values[$source_id] = $source_id_values[$migration
        ->getPluginId()][$index];
    }

    // @todo use the migration.stub service.
    $stub_row = new Row($values + $migration
      ->getSourceConfiguration(), $source_ids, TRUE);

    // Do a normal migration with the stub row.
    $migrate_executable
      ->processRow($stub_row, $process);
    $destination_ids = [];
    $id_map = $migration
      ->getIdMap();
    try {
      $destination_ids = $destination_plugin
        ->import($stub_row);
    } catch (\Exception $e) {
      $id_map
        ->saveMessage($stub_row
        ->getSourceIdValues(), $e
        ->getMessage());
    }
    if ($destination_ids) {
      $id_map
        ->saveIdMapping($stub_row, $destination_ids, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
    }
  }
  if ($destination_ids) {
    if (count($destination_ids) == 1) {
      return reset($destination_ids);
    }
    else {
      return $destination_ids;
    }
  }
  throw new MigrateException("Paragraphs lookup wasn't able to find the corresponding property for paragraph with source ID {$value} for the destination property {$destination_property}.");
}