diff --git a/core/modules/migrate/src/Plugin/migrate/process/Iterator.php b/core/modules/migrate/src/Plugin/migrate/process/Iterator.php index 2a41c4a..5ae94f6 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Iterator.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Iterator.php @@ -7,9 +7,114 @@ use Drupal\migrate\Row; /** - * This plugin iterates and processes an array. + * Iterates and processes an array. * - * @link https://www.drupal.org/node/2135345 Online handbook documentation for iterator process plugin @endlink + * The iterator process plugin allows processing of a list of associative arrays + * Often source data will include multiple-value properties as associative arrays. + * For example, for filter formats on Drupal 6, the filters property contains a + * list of filters belonging to that format, identified by a numeric delta + * (a delta of 2 indicates the URL filter, a delta of 1 indicates automatic + * breaking, etc.): + * + * Available configuration keys: + * - process: + * + * Examples: + * + * @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 iterator process plugin will take these arrays one at a time and run its + * own process over each one: + * + * @code + * process: + * filters: + * plugin: iterator + * 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 + * + * So, plugin: iterator and source: filters means we take each array + * element in the source filters field, and apply the static_map + * plugin to it. We take the first ([0]) array: + * + * @code + * Array + * ( + * [module] => filter + * [delta] => 2 + * [weight] => 0 + * ) + * @endcode + * + * The map source keys are module and delta, so in the map key, since the + * [module] value is filter, we index the array using the delta value of 2 and + * arrive at filter_url as our value - this will be the first value in the array + * assigned to the destination filters. Similarly, we will take the 0 value for + * the weight in the second array to generate a second value of filter_html_escape. + * + * There's one more problem that needs to be solved: often the key of the arrays + * need to be changed. In this case, the new id property needs to be the key. + * It'd be possible to just add key: "@id" to the iterator process but that + * would require special casing the key property and somehow escape it when + * there is actually a destination called key. Instead, it is moved out of the + * process and key is in the configuration of iterator itself: + * + * @code + * process: + * filters: + * plugin: iterator + * source: filters + * key: "@id" + * process: + * id: + * plugin: static_map + * @endcode + * + * The process pipeline for key is special in two ways: first, it runs after + * the normal process is done. Because of this, key: "@key" is also valid. + * Second, the pipeline does not start with NULL but the value of the current key. + * This way, the value of key can come from the other properties or the current + * key. For the latter, omit the source from the first plugin in the pipeline + * for key. + * + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "iterator",