component_schema-1.0.x-dev/src/Component/TypedComponentManager.php

src/Component/TypedComponentManager.php
<?php

namespace Drupal\component_schema\Component;

use Drupal\Component\Graph\Graph;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\TypedConfigManager;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Template\TwigEnvironment;

/**
 * Extends TypedConfigManager for use with component template data.
 */
class TypedComponentManager extends TypedConfigManager implements TypedComponentManagerInterface {

  /**
   * The Twig environment.
   *
   * @var \Drupal\Core\Template\TwigEnvironment
   */
  protected $twig;

  /**
   * The directed acyclic graph.
   *
   * @var array
   */
  protected $graph;

  /**
   * The component schema wrapper objects for components.
   *
   * @var \Drupal\Core\Config\Schema\Element[]
   */
  protected $schemas = [];

  /**
   * Creates a new typed configuration manager.
   *
   * @param \Drupal\Core\Config\StorageInterface $configStorage
   *   The storage object to use for reading schema data
   * @param \Drupal\Core\Config\StorageInterface $schemaStorage
   *   The storage object to use for reading schema data
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
   *   The cache backend to use for caching the definitions.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
   *   The class resolver.
   */
  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, CacheBackendInterface $cache, ModuleHandlerInterface $module_handler, ClassResolverInterface $class_resolver) {
    parent::__construct($configStorage, $schemaStorage, $cache, $module_handler, $class_resolver);

    $this->setCacheBackend($cache, 'typed_component_definitions');
    $this->alterInfo('component_schema_info');
  }

  /**
   * {@inheritdoc}
   */
  public function getComponentDefinitions() {
    $definitions = $this->getDefinitions();
    // The definitions include base types. We only want the component types.
    $definitions = array_filter($definitions, function($definition) {
      return !empty($definition['type']) && ($definition['type'] === 'type_mapping');
    });

    return $definitions;
  }

  /**
   * {@inheritdoc}
   */
  public function getComponentTypeSchema($component_type) {
    if (!isset($this->schemas[$component_type])) {
      $this->schemas[$component_type] = $this
        ->createFromNameAndData($component_type, []);
    }
    return $this->schemas[$component_type];
  }

  /**
   * {@inheritdoc}
   */
  public function setTwigEnvironment(TwigEnvironment $twig) {
    $this->twig = $twig;
  }

  /**
   * {@inheritdoc}
   */
  public function getTwigEnvironment() {
    return $this->twig;
  }

  /**
   * {@inheritdoc}
   */
  public function handleTwigDebug() {
    // If in debug mode, we don't want caching.
    if ($this->twig->isDebug()) {
      $this->clearCachedDefinitions();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function clearCachedDefinitions() {
    // Parent calls $this->schemaStorage->reset(), a method that doesn't
    // exist on our storage.
    // Therefore, fork the ::clearCachedDefinitions() code from all ancestors
    // except the parent.
    $this->prototypes = [];
    if ($this->cacheBackend) {
      if ($this->cacheTags) {

        // Use the cache tags to clear the cache.
        Cache::invalidateTags($this->cacheTags);
      }
      else {
        $this->cacheBackend
          ->delete($this->cacheKey);
      }
    }
    $this->definitions = NULL;
  }

  /**
   * {@inheritdoc}
   */
  protected function alterDefinitions(&$definitions) {
    parent::alterDefinitions($definitions);
    // Apply inheritance to fully altered component definitions.
    $this->applyInheritance($definitions);
  }

  /**
   * Gets the dependency graph of all the components.
   *
   * @param mixed[] &$definitions
   *   An array of plugin definitions (empty array if no definitions were
   *   found). Keys are plugin IDs.
   */
  protected function applyInheritance(array &$definitions) {
    // Inherit the variable definitions.
    $graph = $this->getGraph($definitions);
    foreach ($graph as $destination_component_type => $data) {
      foreach ($data['edges'] as $source_component_type) {
        if (!empty($definitions[$source_component_type]['mapping'])) {
          // Allow variables to be designated as non-inheritable.
          // Unlike other properties, this one is not inherited from parent
          // component variable types because we're acting at the definition
          // stage, before the data objects are built.
          $inheritable_variables = array_filter($definitions[$source_component_type]['mapping'], function($variable) {
            return $variable['is_inheritable'] ?? TRUE;
          });
          // Record the inheritance source.
          foreach ($inheritable_variables as &$variable) {
            $variable['inherited_from'][] = $source_component_type;
          }
          $definitions[$destination_component_type]['mapping'] += $inheritable_variables;
        }
      }
    }
  }

  /**
   * Gets the dependency graph of all the components.
   *
   * @param mixed[] $definitions
   *   An array of plugin definitions (empty array if no definitions were
   *   found). Keys are plugin IDs.
   *
   * @return array
   *   The dependency graph of all the components.
   */
  protected function getGraph(array $definitions) {
    if (!isset($this->graph)) {
      // Generate a graph object in order to generate and sort a dependency graph.
      $graph = [];
      foreach ($definitions as $component_type => $definition) {
        if (!empty($definition['inherits_from'])) {
          if (!isset($graph[$component_type])) {
            $graph[$component_type] = [
              'edges' => [],
            ];
          }
          foreach ($definition['inherits_from'] as $extended_component_type) {
            $graph[$component_type]['edges'][$extended_component_type] = $extended_component_type;
          }
        }
      }
      $this->graph = (new Graph($graph))
        ->searchAndSort();
    }

    return $this->graph;
  }

}

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

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