1

I know I can use sub_process to iterate over an associative array like

field_categories:
  plugin: sub_process
  source: remote_categories
  process:
    target_id:
      plugin: migration_lookup
      migration: my_existing_taxonomy_migration
      source: name_of_key

But I don't know how to iterate over a numeric / non-associative array. Assume the JSON data structure

{
  remote_categories: [ 'alpha', 'beta', 'gamma' ]
}

how can I pass the values as keys to migration_lookup? I.e. what would be name_of_key in the example above?

5

I've written a process plugin that transforms a sequential list into an array of associative sub-arrays, so sub_process and migration_lookup can use them.

namespace Drupal\my_module\Plugin\migrate\process;

use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * Transforms an array of values into an array of associative arrays.
 *
 * The inner array will be filled with one key. E.g. ['alpha', 'beta'] becomes
 * [[value => 'alpha'], [value => 'beta']]
 *
 * Use this plugin to preprocess a numeric/non-associative array for other
 * plugins that requires an associative array as input, such as the sub_process
 * plugin.
 *
 * Available configuration keys:
 * - source: Source property.
 * - keyname: name of the key to be used for the associative sub-arrays,
 *   defaults to 'value'.
 *
 * Example:
 *
 * @code
 * source:
 *   my_flat_array:
 *     - category1
 *     - category2
 * process:
 *   my_associative_array:
 *     plugin: deepen
 *     source: my_flat_array
 *   field_taxonomy_term:
 *     plugin: sub_process
 *     source: '@my_associative_array'
 *     process:
 *       target_id:
 *         plugin: migration_lookup
 *         migration: my_taxonomy_migration
 *         source: value
 * @endcode
 *
 * @see \Drupal\migrate\Plugin\MigrateProcessInterface
 *
 * @MigrateProcessPlugin(
 *   id = "deepen",
 *   handle_multiples = TRUE
 * )
 */
class Deepen extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $keyname = (is_string($this->configuration['keyname']) && $this->configuration['keyname'] != '') ? $this->configuration['keyname'] : 'value';

    if (is_array($value) || $value instanceof \Traversable) {
      $result = [];
      foreach ($value as $sub_value) {
        $result[] = [$keyname => $sub_value];
      }
      return $result;
    }
    else {
      throw new MigrateException(sprintf('%s is not traversable', var_export($value, TRUE)));
    }
  }

}
|improve this answer|||||
  • Wow, very illuminating. I just ran into this myself dealing with an API that does not consistently return array data in the way sub process would want it. – Kevin Mar 12 '19 at 20:56

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.