migmag-1.0.x-dev/migmag_rollbackable/src/Traits/RollbackableTargetTrait.php

migmag_rollbackable/src/Traits/RollbackableTargetTrait.php
<?php

declare(strict_types=1);

namespace Drupal\migmag_rollbackable\Traits;

use Drupal\Core\Config\Config;
use Drupal\migrate\Plugin\migrate\destination\Config as DefaultConfigDestination;
use Drupal\migrate\Row;

/**
 * Target related common operations for rollbackable migration destinations.
 */
trait RollbackableTargetTrait {

  /**
   * Determines the target ID from the given destination IDs or migration row.
   *
   * @param \Drupal\migrate\Row|array $row_or_destination_ids
   *   A migration row or an array of the destination IDs.
   *
   * @return string
   *   The ID of the target (object).
   */
  protected function getTargetObjectId($row_or_destination_ids): string {
    if ($row_or_destination_ids instanceof Row) {
      $destination_ids = [];
      foreach (array_keys($this->getIds()) as $id) {
        $destination_ids[] = $row_or_destination_ids->getDestinationProperty($id);
      }
    }

    return implode('.', array_slice($destination_ids ?? $row_or_destination_ids, 0, 3));
  }

  /**
   * Determines the component from the given destination IDs or migration row.
   *
   * @param \Drupal\migrate\Row|array $row_or_destination_ids
   *   A migration row or an array of the destination IDs.
   *
   * @return string
   *   The component of the target (object).
   */
  protected function getTargetComponent($row_or_destination_ids): string {
    return '';
  }

  /**
   * Determines the language code of the actual target.
   *
   * @param \Drupal\migrate\Row|array $row_or_destination_ids
   *   A migration row or an array of the destination IDs.
   *
   * @return string
   *   The language code. Optional, defaults to ''.
   */
  protected function getTargetLangcode($row_or_destination_ids): string {
    return '';
  }

  /**
   * Returns the target object of the rollbackable destination plugin.
   *
   * @param string $target_object_id
   *   The ID of the target object (a configuration, entity etc).
   * @param string $langcode
   *   The language code.
   *
   * @return object|null
   *   The target object (a config entity or module settings). NULL is allowed
   *   because not every destination plugin operates on objects.
   *
   * @see \Drupal\shortcut\Plugin\migrate\destination\ShortcutSetUsers
   */
  protected function getTargetObject(string $target_object_id, string $langcode) {
    return $this->configFactory->getEditable($target_object_id);
  }

  /**
   * Returns the destination IDs to save.
   *
   * @param true|array $parent_destination_ids
   *   The destination IDs returned by the original destination plugin.
   * @param string $target_object_id
   *   The ID of the target object.
   * @param string $component
   *   The ID of the target component. Might be an empty string.
   * @param string $langcode
   *   The language code of the target object. Might be an empty string.
   *
   * @return array
   *   The destination IDs to save.
   */
  protected function generateDestinationIds($parent_destination_ids, string $target_object_id, string $component, string $langcode): array {
    return $parent_destination_ids;
  }

  /**
   * Deletes the target object of the rollbackable destination plugin.
   *
   * @param string $target_object_id
   *   The ID of the target object (a configuration, entity etc).
   * @param string $langcode
   *   The language code.
   */
  protected function deleteTargetObject(string $target_object_id, string $langcode): void {
    $this->getTargetObject($target_object_id, $langcode)->delete();
  }

  /**
   * Determines whether the target is new.
   *
   * @param string $target_object_id
   *   The ID of the target object (a configuration, entity etc).
   * @param string $langcode
   *   The language code.
   *
   * @return bool
   *   TRUE when the target is evaluated as being new, FALSE otherwise.
   */
  protected function targetObjectIsNew(string $target_object_id, string $langcode): bool {
    return $this->getTargetObject($target_object_id, $langcode)->isNew();
  }

  /**
   * Determines whether the target component is new.
   *
   * @param string $target_object_id
   *   The ID of the target object (a configuration, entity etc).
   * @param string $component
   *   The name (an internal unique identifier) of the component.
   * @param string $langcode
   *   The language code.
   *
   * @return bool
   *   TRUE when the target component is evaluated as being new, FALSE
   *   otherwise.
   */
  protected function targetObjectComponentIsNew(string $target_object_id, string $component, string $langcode): bool {
    $target_object = $this->getTargetObject($target_object_id, $langcode);
    return !array_key_exists($component, $target_object->get());
  }

  /**
   * Returns the previous value of the target before the actual migration.
   *
   * @param \Drupal\migrate\Row $row
   *   The processed migration row.
   * @param string $target_object_id
   *   The ID of the target (object).
   * @param string $component
   *   The component.
   * @param string $langcode
   *   The language code.
   *
   * @return mixed
   *   The previous value of the target before the actual migration.
   */
  protected function getPreviousValues(Row $row, string $target_object_id, string $component, string $langcode) {
    if ($this->targetObjectIsNew($target_object_id, $langcode)) {
      return NULL;
    }
    $target_object = $this->getTargetObject($target_object_id, $langcode);

    // If we have a component, we have to return only the component's
    // previous value.
    if ($component) {
      return $target_object instanceof Config
        ? $target_object->getOriginal($component, FALSE)
        : $target_object->get($component);
    }

    // If the current configuration is a pre-existing config, we only have to
    // restore the original values if the migration is rolled back. However, if
    // the config was created by a migration, then we have to delete it if we
    // cannot find any other rollbackable data that was stored by other
    // migrations.
    $rollback_data = [];
    foreach ($row->getRawDestination() as $key => $value) {
      // Destination which are instances of "config" have a special
      // configuration for storing null values.
      if (
        $this instanceof DefaultConfigDestination &&
        is_null($value) &&
        empty($this->configuration['store null'])
      ) {
        continue;
      }

      if ($mapped_key = $this->getMappedKey($key)) {
        $top_level_key = explode(Row::PROPERTY_SEPARATOR, $this->getMappedKey($key))[0];

        $rollback_data[$top_level_key] = $target_object instanceof Config
          ? $target_object->getOriginal($top_level_key, FALSE)
          : $target_object->get($top_level_key);
      }
    }

    return $rollback_data;
  }

  /**
   * Returns a key of the target object based on the migration destination key.
   *
   * @param string $destination_key
   *   The destination property of the actual migration.
   *
   * @return string
   *   The corresponding configuration key of the target object.
   */
  protected function getMappedKey(string $destination_key): ?string {
    return $destination_key;
  }

  /**
   * Restores the target's previous status and persists the change.
   *
   * @param mixed $rollback_data
   *   The data of the given target (or target component) before this migration
   *   was executed.
   * @param string $target_object_id
   *   The ID of the target (object).
   * @param string $component
   *   The component.
   * @param string $langcode
   *   The language code.
   */
  protected function doDataRollback($rollback_data, string $target_object_id, string $component, string $langcode): void {
    // If there are previous values (aka "rollback data"), restore those. If
    // there aren't, the component may be removed.
    $target_object = $this->getTargetObject($target_object_id, $langcode);

    if ($component) {
      $rollback_data = [
        $component => $rollback_data,
      ];
    }

    if (is_array($rollback_data)) {
      foreach ($rollback_data as $config_key => $original_value) {
        if ($original_value === NULL) {
          $target_object->clear($config_key);
          continue;
        }

        $target_object->set($config_key, $original_value);
      }

      $target_object->save();
    }
  }

}

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

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