Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x

SubProcess.php

Namespace

Drupal\migrate\Plugin\migrate\process

File

core/modules/migrate/src/Plugin/migrate/process/SubProcess.php

View source
<?php

namespace Drupal\migrate\Plugin\migrate\process;

use Drupal\migrate\Attribute\MigrateProcess;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * Runs an array of arrays through its own process pipeline.
 *
 * The sub_process plugin accepts an array of associative arrays and runs each
 * one through its own process pipeline, producing a newly keyed associative
 * array of transformed values.
 *
 * Available configuration keys:
 *   - process: the plugin(s) that will process each element of the source.
 *   - key: runs the process pipeline for the key to determine a new dynamic
 *     name. If the new dynamic name is NULL then the result of the sub_process
 *     pipeline is ignored.
 *   - include_source: (optional) If TRUE, all source plugin configuration and
 *     values will be copied into the sub-processed row in a new property named
 *     for the source_key configuration value (see below). Defaults to FALSE.
 *   - source_key: (optional) If include_source is TRUE, this
 *     is the name of the property of the sub-processed row which will contain
 *     the source configuration and values. Ignored if include_source is
 *     FALSE. Defaults to 'source' if no value is provided.
 *
 * Example 1:
 *
 * This example demonstrates how migration_lookup process plugin can be applied
 * on the following source data.
 * @code
 * source: Array
 * (
 *   [upload] => Array
 *     (
 *       [0] => Array
 *         (
 *           [fid] => 1
 *           [list] => 0
 *           [description] => "File number 1"
 *         )
 *       [1] => Array
 *         (
 *           [fid] => 2
 *           [list] => 1
 *           [description] => "File number 2"
 *         )
 *     )
 * )
 * ...
 * @endcode
 * The sub_process process plugin will take these arrays one at a time and run
 * its own process for each of them:
 * @code
 * process:
 *   upload:
 *     plugin: sub_process
 *     source: upload
 *     process:
 *       target_id:
 *         plugin: migration_lookup
 *         migration: d6_file
 *         source: fid
 *       display: list
 *       description: description
 * @endcode
 * In this case, each item in the upload array will be processed by the
 * sub_process process plugin. The target_id will be found by looking up the
 * destination value from a previous migration using the migration_lookup
 * process plugin. The display and description fields will be mapped directly.
 *
 * Example 2.
 *
 * Drupal 6 filter formats contain a list of filters belonging to that format
 * identified by a numeric delta. A delta of 1 indicates automatic linebreaks,
 * delta of 2 indicates the URL filter and so on. This example demonstrates how
 * static_map process plugin can be applied on the following source data.
 * @code
 * source: Array
 * (
 *   [format] => 1
 *   [name] => Filtered HTML
 * ...
 *   [filters] => Array
 *     (
 *       [0] => Array
 *         (
 *           [module] => filter
 *           [delta] => 2
 *           [weight] => 0
 *         )
 *       [1] => Array
 *         (
 *           [module] => filter
 *           [delta] => 0
 *           [weight] => 1
 *         )
 *    )
 * )
 * ...
 * @endcode
 * The sub_process will take these arrays one at a time and run its own process
 * for each of them:
 * @code
 * process:
 *   filters:
 *     plugin: sub_process
 *     source: filters
 *     process:
 *       id:
 *         plugin: static_map
 *         source:
 *           - module
 *           - delta
 *         map:
 *           filter:
 *             0: filter_html_escape
 *             1: filter_autop
 *             2: filter_url
 *             3: filter_htmlcorrector
 *             4: filter_html_escape
 *           php:
 *             0: php_code
 * @endcode
 * The example above means that we take each array element ([0], [1], etc.) from
 * the source filters field and apply the static_map plugin on it. Let's have a
 * closer look at the first array at index 0:
 * @code
 * Array
 * (
 *    [module] => filter
 *    [delta] => 2
 *    [weight] => 0
 * )
 * @endcode
 * The static_map process plugin results to value 'filter_url' for this input
 * based on the 'module' and 'delta' map.
 *
 * Example 3.
 *
 * Normally the array returned from sub_process will have its original keys. If
 * you need to change the key, it is possible for the returned array to be keyed
 * by one of the transformed values in the sub-array. For the same source data
 * used in the previous example, the migration below would result to keys
 * 'filter_2' and 'filter_0'. If the value for 'id' is NULL the result of the
 * sub_process pipeline is ignored.
 * @code
 * process:
 *   filters:
 *     plugin: sub_process
 *     source: filters
 *     key: "@id"
 *     process:
 *       id:
 *         plugin: concat
 *         source:
 *           - module
 *           - delta
 *         delimiter: _
 * @endcode
 *
 * @see \Drupal\migrate\Plugin\migrate\process\MigrationLookup
 * @see \Drupal\migrate\Plugin\migrate\process\StaticMap
 * @see \Drupal\migrate\Plugin\MigrateProcessInterface
 */
class SubProcess extends ProcessPluginBase {
    
    /**
     * SubProcess constructor.
     *
     * @param array $configuration
     *   A configuration array containing information about the plugin instance.
     * @param string $plugin_id
     *   The plugin ID for the plugin instance.
     * @param mixed $plugin_definition
     *   The plugin implementation definition.
     */
    public function __construct(array $configuration, $plugin_id, $plugin_definition) {
        $configuration += [
            'include_source' => FALSE,
            'source_key' => 'source',
        ];
        parent::__construct($configuration, $plugin_id, $plugin_definition);
    }
    
    /**
     * {@inheritdoc}
     */
    public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
        $return = $source = [];
        if ($this->configuration['include_source']) {
            $key = $this->configuration['source_key'];
            $source[$key] = $row->getSource();
        }
        if (is_iterable($value)) {
            foreach ($value as $key => $new_value) {
                if (!is_array($new_value)) {
                    throw new MigrateException(sprintf("Input array should hold elements of type array, instead element was of type '%s'", gettype($new_value)));
                }
                $new_row = new Row($new_value + $source);
                try {
                    $migrate_executable->processRow($new_row, $this->configuration['process']);
                } catch (MigrateSkipRowException) {
                    continue;
                }
                $destination = $new_row->getDestination();
                if (array_key_exists('key', $this->configuration)) {
                    $key = $this->transformKey($key, $migrate_executable, $new_row);
                }
                // Do not save the result if the key is NULL. The configured process
                // pipeline used in transformKey() will return NULL if the key can not
                // be transformed.
                if ($key !== NULL) {
                    $return[$key] = $destination;
                }
            }
        }
        return $return;
    }
    
    /**
     * Runs the process pipeline for the key to determine its dynamic name.
     *
     * @param string|int $key
     *   The current key.
     * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable
     *   The migrate executable helper class.
     * @param \Drupal\migrate\Row $row
     *   The current row after processing.
     *
     * @return mixed
     *   The transformed key.
     */
    protected function transformKey($key, MigrateExecutableInterface $migrate_executable, Row $row) {
        $process = [
            'key' => $this->configuration['key'],
        ];
        $migrate_executable->processRow($row, $process, $key);
        return $row->getDestinationProperty('key');
    }
    
    /**
     * {@inheritdoc}
     */
    public function multiple() {
        return TRUE;
    }

}

Classes

Title Deprecated Summary
SubProcess Runs an array of arrays through its own process pipeline.

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal