cache_entity_type-1.x-dev/src/CacheEntityTypeServiceProvider.php

src/CacheEntityTypeServiceProvider.php
<?php

declare(strict_types=1);

namespace Drupal\cache_entity_type;

use Drupal\cache_entity_type\Entity\Cache\CacheBinNameFactory;
use Drupal\cache_entity_type\Entity\Cache\CacheEntityStorage;
use Drupal\cache_entity_type\Utility\ClassInheritance;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Drupal\Core\Entity\Annotation\EntityType;
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Creates cache bins for all entity types that use the "CacheEntityStorage" as storage backend.
 *
 * Only checks for entity types that use the "EntityType" annotation.
 *
 * @package Drupal\cache_entity_type
 */
class CacheEntityTypeServiceProvider extends ServiceProviderBase {

  /**
   * Discovers all entity type classes.
   *
   * Classes that are inside the src/Entity directory.
   * And have the @EntityType annotation.
   *
   * Basically does the same as it is done in the Entity Type Manager.
   * See \Drupal\Core\Entity\EntityTypeManager::__construct().
   *
   * @param \Drupal\Core\DependencyInjection\ContainerBuilder $container
   *   The DI container builder.
   *
   * @return \Drupal\Core\Entity\EntityTypeInterface[]
   *   Entity type definitions.
   */
  protected function discoverEntityTypeDefinitions(ContainerBuilder $container) {
    $containerNamespacesArray = $container->getParameter('container.namespaces');
    if (!is_array($containerNamespacesArray)) {
      throw new \InvalidArgumentException('The container.namespaces parameter is not an array.');
    }
    $namespaces = new \ArrayObject($containerNamespacesArray);
    $entityTypeClassDiscovery = new AnnotatedClassDiscovery('Entity', $namespaces, EntityType::class);

    return $entityTypeClassDiscovery->getDefinitions();
  }

  /**
   * Returns the cache entity type IDs contained in given definitions.
   *
   * @param \Drupal\Core\Entity\EntityTypeInterface[] $entityTypeDefinitions
   *   Entity type definitions.
   *
   * @return string[]
   *   Cache entity type IDs.
   */
  protected function selectCacheEntityTypeIds(array $entityTypeDefinitions): array {
    $cacheEntityTypeIds = [];
    foreach ($entityTypeDefinitions as $entityTypeDefinition) {
      $storageHandlerClassName = $entityTypeDefinition->getHandlerClass('storage');
      if (!is_string($storageHandlerClassName)) {
        continue;
      }

      if (ClassInheritance::isSameOrDoesExtend($storageHandlerClassName, CacheEntityStorage::class)) {
        $cacheEntityTypeIds[] = $entityTypeDefinition->id();
      }
    }
    return $cacheEntityTypeIds;
  }

  /**
   * Creates a cache bin service definition.
   *
   * @param string $binName
   *   The name of the cache bin.
   *
   * @return \Symfony\Component\DependencyInjection\Definition
   *   The cache bin service definition.
   */
  protected function createCacheBinServiceDefinition(string $binName): Definition {
    $serviceDefinition = new Definition(CacheBackendInterface::class);
    $serviceDefinition->addTag('cache.bin');
    $serviceDefinition->setFactory([new Reference('cache_factory'), 'get']);
    $serviceDefinition->addArgument(CacheBinNameFactory::binName($binName));

    return $serviceDefinition;
  }

  /**
   * Entity cache bins have to be tagged to ensure they are included on a Drupal cache clear.
   *
   * They are discovered via the "cache.bin" service tag.
   * See \Drupal\Core\Cache\ListCacheBinsPass::process().
   *
   * @param \Drupal\Core\DependencyInjection\ContainerBuilder $container
   *   The container builder.
   *
   * @phpstan-ignore-next-line
   */
  public function register(ContainerBuilder $container) {
    parent::register($container);

    $entityTypeDefinitions = $this->discoverEntityTypeDefinitions($container);
    $cacheEntityTypeIds = $this->selectCacheEntityTypeIds($entityTypeDefinitions);

    foreach ($cacheEntityTypeIds as $cacheEntityTypeId) {
      $cacheBinServiceId = CacheBinNameFactory::binServiceName($cacheEntityTypeId);
      /* We do not want to override already defined cache bins.
      In case a custom bin configuration is used for an entity type. */
      if (!$container->hasDefinition($cacheBinServiceId)) {
        $container->setDefinition($cacheBinServiceId, $this->createCacheBinServiceDefinition($cacheEntityTypeId));
      }
    }

  }

}

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

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