core_extend-8.x-1.0-alpha3/src/ConfigEntityConditionRepository.php

src/ConfigEntityConditionRepository.php
<?php

namespace Drupal\core_extend;

use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Condition\ConditionAccessResolverTrait;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextHandlerInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface;

/**
 * Provides a repository for config entities with conditions.
 */
class ConfigEntityConditionRepository {

  use ConditionAccessResolverTrait;

  /**
   * The cache backend.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   *
   * @todo maybe remove this. Unsure how to cache, other than possible mapping.
   */
  protected $cacheFactory;

  /**
   * The context handler.
   *
   * @var \Drupal\Core\Plugin\Context\ContextHandlerInterface
   */
  protected $contextHandler;

  /**
   * The context manager service.
   *
   * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
   */
  protected $contextRepository;

  /**
   * The entity type id.
   *
   * @var string
   */
  protected $entityTypeId;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The config entity storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $storage;

  /**
   * Constructs a new ConfigEntityConditionRepository.
   *
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_factory
   *   The Organization cache backend.
   * @param \Drupal\Core\Plugin\Context\ContextHandlerInterface $context_handler
   *   The plugin context handler.
   * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository
   *   The lazy context repository service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity-type manager.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param string $entity_type_id
   *   (optional) An entity-type id to set for storage.
   */
  public function __construct(CacheBackendInterface $cache_factory, ContextHandlerInterface $context_handler, ContextRepositoryInterface $context_repository, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, $entity_type_id = '') {
    $this->cacheFactory = $cache_factory;
    $this->contextHandler = $context_handler;
    $this->contextRepository = $context_repository;
    $this->entityTypeId = $entity_type_id;
    $this->moduleHandler = $module_handler;

    if (!empty($entity_type_id) && $entity_type_manager->hasHandler($entity_type_id, 'storage')) {
      $this->storage = $entity_type_manager->getStorage($entity_type_id);
    }
  }

  /**
   * Loaded config entities with conditions.
   *
   * @return \Drupal\core_extend\Entity\ConfigEntityConditionInterface[]|\Drupal\Core\Entity\EntityInterface[]
   *   The loaded config entities.
   */
  protected function loadEntities() {
    return $this->storage->loadMultiple();
  }

  /**
   * Retrieves context mapping for a context-aware plugin.
   *
   * @param \Drupal\Core\Plugin\ContextAwarePluginInterface $plugin
   *   The context-aware plugin.
   * @param \Drupal\Component\Plugin\Context\ContextInterface[] $contexts
   *   An array of contexts.
   *
   * @return \Drupal\Core\Plugin\Context\ContextInterface[]
   *   An array of contexts, keyed by plugin context slot key.
   */
  protected function getContextMapping(ContextAwarePluginInterface $plugin, array $contexts = []) {
    // Use runtime contexts if context is empty.
    $runtime_contexts = (empty($contexts));

    // Mapping is on plugin. Return loaded runtime contexts.
    if ($runtime_contexts && !empty($plugin->getContextMapping())) {
      return $this->contextRepository->getRuntimeContexts(array_values($plugin->getContextMapping()));;
    }

    // Get all available contexts to match required contexts.
    if ($runtime_contexts) {
      $contexts = $this->contextRepository->getAvailableContexts();
    }

    $mapping = [];
    foreach ($plugin->getContextDefinitions() as $context_slot => $definition) {
      $matches = $this->contextHandler->getMatchingContexts($contexts, $definition);

      // Replace matches with runtime values.
      if ($runtime_contexts) {
        $matches = $this->contextRepository->getRuntimeContexts(array_keys($matches));
      }

      // Place in context slot for contexts with set values.
      foreach ($matches as $match_id => $match) {
        if (!is_null($match->getContextData()->getValue())) {
          $mapping[$context_slot] = $match;
          break;
        }
      }
    }

    return $mapping;
  }

  /**
   * Load config entities based on a passed-in entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The contextual entity to match against loaded config entities.
   *
   * @return \Drupal\core_extend\Entity\ConfigEntityConditionInterface[]|\Drupal\Core\Entity\EntityInterface[]
   *   The matched config.
   */
  protected function getConfigByEntity(EntityInterface $entity) {
    // Create an optional context definition for organization entities.
    $context_definition = new ContextDefinition('entity:' . $entity->getEntityTypeId(), $entity->getEntityType()->getLabel(), FALSE);
    $contexts[$entity->getEntityTypeId()] = new Context($context_definition, $entity);

    // Allow other modules to attach related contexts based on current entity.
    $this->moduleHandler->alter([
      'config_entity_condition_contexts',
      "config_{$this->entityTypeId}_condition_contexts",
    ], $contexts, $entity);

    // @todo cache this based on passed-in entity & user or serialized contexts?

    return $this->getConfigByContext($contexts);
  }

  /**
   * Load config entities based on a passed-in contexts.
   *
   * @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts
   *   (optional) An array of contexts. If empty, defaults to any available
   *   contexts. @todo could allow it back-fill additional available contexts.
   *
   * @return \Drupal\core_extend\Entity\ConfigEntityConditionInterface[]|\Drupal\Core\Entity\EntityInterface[]
   *   The matched config.
   */
  protected function getConfigByContext(array $contexts = []) {
    $config = [];

    // Validate each config entity before adding to available config array.
    foreach ($this->loadEntities() as $entity_id => $entity) {
      // Run through conditions if any are set.
      if ($entity->getConditions()->count() > 0) {
        $conditions = [];
        foreach ($entity->getConditions()->getIterator() as $condition_id => $condition) {
          // Compile conditions.
          try {
            $mapping = $this->getContextMapping($condition, $contexts);
            $this->contextHandler->applyContextMapping($condition, $mapping);
            $conditions[] = $condition;
          }
          // Skip role if it doesn't match every condition.
          catch (ContextException $e) {
            continue 2;
          }
        }
        // Skip this entity if contexts don't apply.
        if ($this->resolveConditions($conditions, 'and') === FALSE) {
          continue;
        }
      }

      // Add to available config.
      $config[$entity_id] = $entity;
    }

    return $config;
  }

}

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

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