migrate_plus-8.x-5.x-dev/src/Plugin/migrate/process/ArrayTemplate.php

src/Plugin/migrate/process/ArrayTemplate.php
<?php

declare(strict_types=1);

namespace Drupal\migrate_plus\Plugin\migrate\process;

use Drupal\Component\Utility\NestedArray;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;

/**
 * Builds an array based on configuration, source, destination, and pipeline.
 *
 * Usage:
 *
 * @code
 * process:
 *   bar:
 *     plugin: array_template
 *     source: foo
 *     template:
 *       key: literal string
 *       properties:
 *         - source:field_body/0/value
 *         - dest:field_body/0/value
 *         - pipeline:some/nested/key
 * @endcode
 *
 * The result is an array with the same structure (string and numeric keys,
 * nesting) as the template. Any string value starting with 'source:' or 'dest:'
 * is replaced by the corresponding source or destination property. Do not
 * prefix destination properties with '@'. The string value 'pipeline:' is
 * replaced with the source, or the previous value from the process pipeline.
 * You can also extract keys using the '/' separator.
 *
 * For example, to convert an indexed array to a keyed array,
 *
 * @code
 * process:
 *   field_paragraph:
 *     - plugin: migration_lookup
 *       # ...
 *     - plugin: array_template
 *       template:
 *         target_id: pipeline:0
 *         target_revision_id: pipeline:1
 * @endcode
 *
 * If you want a literal string like 'source:foo' in the result, then a
 * work-around is to define a constant in the source configuration:
 *
 * @code
 * source:
 *   # ...
 *   constants:
 *     do_not_process_me: source:foo
 *   process:
 *     some_field:
 *       - plugin: array_template
 *         template:
 *           - source:constants/do_not_process_me
 * @endcode
 *
 * @MigrateProcessPlugin(id = "array_template")
 */
final class ArrayTemplate extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
    if (!is_array($configuration['template'] ?? NULL)) {
      throw new \InvalidArgumentException('The "template" must be set to an array.');
    }

    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property): array {
    $template = $this->configuration['template'] ?? NULL;
    $args = ['row' => $row, 'pipeline' => $value];
    array_walk_recursive($template, [$this, 'process'], $args);

    return $template;
  }

  /**
   * Replaces source, destination, or pipeline with the correct value.
   *
   * @param mixed $value
   *   The array value as provided by array_walk_recursive. Any type other than
   *   array passed by reference.
   * @param string $key
   *   The array key as provided by array_walk_recursive(): ignored.
   * @param array $args
   *   An array with the keys
   *   - row: the current Row object;
   *   - pipeline: the pipeline or source value for the process.
   */
  protected function process(&$value, string $key, array $args): void {
    if (!is_string($value)) {
      return;
    }

    [$type, $key] = explode(':', "$value:", 2);
    if ($key === '') {
      return;
    }

    // Strip the added ':'.
    $key = substr($key, 0, -1);
    ['row' => $row, 'pipeline' => $pipeline] = $args;
    assert($row instanceof Row);
    $value = match($type) {
      'source' => $row->getSourceProperty($key),
      'dest' => $row->getDestinationProperty($key),
      'pipeline' => $key === '' ? $pipeline : NestedArray::getValue($pipeline, explode('/', $key)),
      default => $value,
    };
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc