content_sync-8.x-2.x-dev/src/DependencyResolver/ImportQueueResolver.php

src/DependencyResolver/ImportQueueResolver.php
<?php

namespace Drupal\content_sync\DependencyResolver;

use Drupal\Core\Serialization\Yaml;

/**
 * Class ImportQueueResolver.
 *
 * @package Drupal\content_sync\DependencyResolver
 */
class ImportQueueResolver implements ContentSyncResolverInterface {

  /**
   * The normalized data.
   * @var array
   */
  protected $normalizedEntities;

  /**
   * Entities with references to ancestors.
   * @var array
   */
  protected $rebuild;

  /**
   * Queue variable.
   * @var array
   */
  protected $q;

  /**
   * Constructs an ImportQueueResolver object.
   *
   * @param array $normalized_entities
   *   The normalized data.
   */
  public function __construct(array $normalized_entities) {
    $this->normalizedEntities = $normalized_entities;
    $this->rebuild = [];
    $this->q = [];
  }

  /**
   * Creates a queue.
   *
   * @return array
   *   Queue to be processed within a batch process.
   */
  public function resolve() {
    $ancestors = [];
    foreach ($this->normalizedEntities as $identifier => $entity) {
      $this->processEntity($identifier, $entity, $ancestors);
    }
    return array_reverse(array_merge($this->q, $this->rebuild));
  }

  /**
   * Get entities dependencies - it considers redundancies.
   */
  public function processEntity(string $identifier, array $entity, array $ancestors) {
    $q = array_column($this->q, 'identifier');
    if (in_array($identifier, $q)) {
      return;
    }
    $ancestors[] = $identifier;
    $dependencies = $this->getDependencies($entity);
    foreach ($dependencies as $dependency) {
      $dependency_entity = $this->fetchEntity($dependency);
      if (in_array($dependency, $ancestors)) {
        $this->rebuild[] = [
          'identifier' => $identifier,
          'entity_type_id' => $entity['_content_sync']['entity_type'],
          'decoded_entity' => $entity,
        ];
      }
      else {
        $this->processEntity($dependency, $dependency_entity, $ancestors);
      }
    }
    $this->q[] = [
      'identifier' => $identifier,
      'entity_type_id' => $entity['_content_sync']['entity_type'],
      'decoded_entity' => $entity,
    ];
  }

  /**
   * Get dependencies of a given entity.
   *
   * @return array
   *   Dependencies of an entity.
   */
  public function getDependencies($entity) {
    $dependencies = [];
    if (!empty($entity['_content_sync']['entity_dependencies'])) {
      foreach ($entity['_content_sync']['entity_dependencies'] as $ref_entity_type_id => $references) {
        $dependencies = array_merge($dependencies, $references);
      }
    }
    return $dependencies;
  }

  /**
   * Fetch an entity - normalized data.
   *
   * @return array
   *   Entity normalized data.
   */
  public function fetchEntity($identifier) {
    try {
      $entity = $this->getEntity($identifier, $this->normalizedEntities);
    }
    catch (\Exception $e) {
      $entity = [];
      // TODO: notice/log of what entity is missing.
      // TODO: should the import of the parent entity abort?
    }
    return $entity;
  }

  /**
   * Gets an entity.
   *
   * @param $identifier
   *   An entity identifier to process.
   * @param $normalized_entities
   *   An array of entity identifiers to process.
   *
   * @return bool|mixed
   *   Decoded entity or FALSE if an entity already exists and doesn't require to be imported.
   *
   * @throws \Exception
   */
  protected function getEntity($identifier, $normalized_entities) {
    if (!empty($normalized_entities[$identifier])) {
      $entity = $normalized_entities[$identifier];
      return $entity;
    }
    else {
      // Check the entity in the content directory.
      [$entity_type_id, $bundle, $uuid] = explode('.', $identifier);
      $file_path = content_sync_get_content_directory('sync') . "/entities/" . $entity_type_id . "/" . $bundle . "/" . $identifier . ".yml";
      $raw_entity = file_get_contents($file_path);

      // Problems to open the .yml file.
      if (!$raw_entity) {
        throw new \Exception("Dependency {$identifier} is missing.");
      }

      $entity = Yaml::decode($raw_entity);
    }

    // TODO: else if Check the entity exists in the snapshot

    // TODO: else if Check if the entity exist in the site.

    // TODO: better notice about missing dependency
    //       - should the parent import be aborted or not?

    return $entity;
  }

  /**
   * Checks if a dependency exists in the site.
   *
   * @param $identifier
   *   An entity identifier to process.
   *
   * @return bool
   */
  protected function entityExists($identifier) {
    return (bool) \Drupal::database()
      ->queryRange('SELECT 1 FROM {cs_db_snapshot} WHERE name = :name', 0, 1, [
        ':name' => $identifier])
      ->fetchField();
  }

}

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

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