Issue #2332935 by plach, alexpott, dawehner: Allow code to respond to entity/field schema changes.
parent
22c82583c9
commit
47e0030705
|
@ -287,13 +287,13 @@ services:
|
|||
arguments: ['@container.namespaces', '@cache.discovery', '@module_handler']
|
||||
module_handler:
|
||||
class: Drupal\Core\Extension\ModuleHandler
|
||||
arguments: ['%container.modules%', '@cache.bootstrap']
|
||||
arguments: ['%container.modules%', '@kernel', '@cache.bootstrap']
|
||||
theme_handler:
|
||||
class: Drupal\Core\Extension\ThemeHandler
|
||||
arguments: ['@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder_indicator']
|
||||
entity.manager:
|
||||
class: Drupal\Core\Entity\EntityManager
|
||||
arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@language_manager', '@string_translation', '@class_resolver', '@typed_data_manager', '@entity.definitions.installed']
|
||||
arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@language_manager', '@string_translation', '@class_resolver', '@typed_data_manager', '@entity.definitions.installed', '@event_dispatcher']
|
||||
parent: container.trait
|
||||
tags:
|
||||
- { name: plugin_manager_cache_clear }
|
||||
|
|
|
@ -52,7 +52,8 @@ interface DrupalKernelInterface extends HttpKernelInterface {
|
|||
/**
|
||||
* Gets the current container.
|
||||
*
|
||||
* @return ContainerInterface A ContainerInterface instance
|
||||
* @return \Symfony\Component\DependencyInjection\ContainerInterface
|
||||
* A ContainerInterface instance.
|
||||
*/
|
||||
public function getContainer();
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
namespace Drupal\Core\Entity;
|
||||
|
||||
use Drupal\Core\Entity\Schema\EntityStorageSchemaInterface;
|
||||
use Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface;
|
||||
use Drupal\Core\Entity\Schema\EntityStorageSchemaInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
|
|
|
@ -10,25 +10,28 @@ namespace Drupal\Core\Entity;
|
|||
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\DependencyInjection\ClassResolverInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\DependencyInjection\ClassResolverInterface;
|
||||
use Drupal\Core\Entity\Exception\AmbiguousEntityClassException;
|
||||
use Drupal\Core\Entity\Exception\NoCorrespondingEntityClassException;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionEvent;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionEvents;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionListenerInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Plugin\DefaultPluginManager;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Plugin\DefaultPluginManager;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Drupal\Core\TypedData\TranslatableInterface;
|
||||
use Drupal\Core\TypedData\TypedDataManager;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* Manages entity type plugin definitions.
|
||||
|
@ -122,6 +125,13 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
*/
|
||||
protected $installedDefinitions;
|
||||
|
||||
/**
|
||||
* The event dispatcher.
|
||||
*
|
||||
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
|
||||
*/
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* Static cache of bundle information.
|
||||
*
|
||||
|
@ -183,8 +193,10 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
* The typed data manager.
|
||||
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $installed_definitions
|
||||
* The keyvalue collection for tracking installed definitions.
|
||||
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
|
||||
* The event dispatcher.
|
||||
*/
|
||||
public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, TranslationInterface $translation_manager, ClassResolverInterface $class_resolver, TypedDataManager $typed_data_manager, KeyValueStoreInterface $installed_definitions) {
|
||||
public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, TranslationInterface $translation_manager, ClassResolverInterface $class_resolver, TypedDataManager $typed_data_manager, KeyValueStoreInterface $installed_definitions, EventDispatcherInterface $event_dispatcher) {
|
||||
parent::__construct('Entity', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityInterface', 'Drupal\Core\Entity\Annotation\EntityType');
|
||||
|
||||
$this->setCacheBackend($cache, 'entity_type', array('entity_types'));
|
||||
|
@ -195,6 +207,7 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
$this->classResolver = $class_resolver;
|
||||
$this->typedDataManager = $typed_data_manager;
|
||||
$this->installedDefinitions = $installed_definitions;
|
||||
$this->eventDispatcher = $event_dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -986,6 +999,8 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
$storage->onEntityTypeCreate($entity_type);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(EntityTypeEvents::CREATE, new EntityTypeEvent($entity_type));
|
||||
|
||||
$this->setLastInstalledDefinition($entity_type);
|
||||
if ($entity_type->isSubclassOf('\Drupal\Core\Entity\FieldableEntityInterface')) {
|
||||
$this->setLastInstalledFieldStorageDefinitions($entity_type_id, $this->getFieldStorageDefinitions($entity_type_id));
|
||||
|
@ -1005,6 +1020,8 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
$storage->onEntityTypeUpdate($entity_type, $original);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(EntityTypeEvents::UPDATE, new EntityTypeEvent($entity_type, $original));
|
||||
|
||||
$this->setLastInstalledDefinition($entity_type);
|
||||
}
|
||||
|
||||
|
@ -1021,6 +1038,8 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
$storage->onEntityTypeDelete($entity_type);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(EntityTypeEvents::DELETE, new EntityTypeEvent($entity_type));
|
||||
|
||||
$this->deleteLastInstalledDefinition($entity_type_id);
|
||||
}
|
||||
|
||||
|
@ -1037,6 +1056,8 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
$storage->onFieldStorageDefinitionCreate($storage_definition);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(FieldStorageDefinitionEvents::CREATE, new FieldStorageDefinitionEvent($storage_definition));
|
||||
|
||||
$this->setLastInstalledFieldStorageDefinition($storage_definition);
|
||||
$this->clearCachedFieldDefinitions();
|
||||
}
|
||||
|
@ -1054,6 +1075,8 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
$storage->onFieldStorageDefinitionUpdate($storage_definition, $original);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(FieldStorageDefinitionEvents::UPDATE, new FieldStorageDefinitionEvent($storage_definition, $original));
|
||||
|
||||
$this->setLastInstalledFieldStorageDefinition($storage_definition);
|
||||
$this->clearCachedFieldDefinitions();
|
||||
}
|
||||
|
@ -1071,6 +1094,8 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
$storage->onFieldStorageDefinitionDelete($storage_definition);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(FieldStorageDefinitionEvents::DELETE, new FieldStorageDefinitionEvent($storage_definition));
|
||||
|
||||
$this->deleteLastInstalledFieldStorageDefinition($storage_definition);
|
||||
$this->clearCachedFieldDefinitions();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Entity\EntityTypeEvent.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Entity;
|
||||
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
/**
|
||||
* Defines a base class for all entity type events.
|
||||
*/
|
||||
class EntityTypeEvent extends GenericEvent {
|
||||
|
||||
/**
|
||||
* The entity type.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeInterface
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* The original entity type.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeInterface
|
||||
*/
|
||||
protected $original;
|
||||
|
||||
/**
|
||||
* Constructs a new EntityTypeEvent.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The field storage definition.
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $original
|
||||
* (optional) The original entity type. This should be passed only when
|
||||
* updating the entity type.
|
||||
*/
|
||||
public function __construct(EntityTypeInterface $entity_type, EntityTypeInterface $original = NULL) {
|
||||
$this->entityType = $entity_type;
|
||||
$this->original = $original;
|
||||
}
|
||||
|
||||
/**
|
||||
* The entity type the event refers to.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityTypeInterface
|
||||
*/
|
||||
public function getEntityType() {
|
||||
return $this->entityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The original entity type.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityTypeInterface
|
||||
*/
|
||||
public function getOriginal() {
|
||||
return $this->original;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Entity\EntityTypeEventSubscriberTrait.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Entity;
|
||||
|
||||
/**
|
||||
* Helper methods for EntityTypeListenerInterface.
|
||||
*
|
||||
* This allows a class implementing EntityTypeListenerInterface to subscribe and
|
||||
* react to entity type events.
|
||||
*
|
||||
* @see \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
* @see \Drupal\Core\Entity\EntityTypeListenerInterface
|
||||
*/
|
||||
trait EntityTypeEventSubscriberTrait {
|
||||
|
||||
/**
|
||||
* Returns the subscribed events.
|
||||
*
|
||||
* @return array
|
||||
* An array of subscribed event names.
|
||||
*
|
||||
* @see \Symfony\Component\EventDispatcher\EventSubscriberInterface::getSubscribedEvents()
|
||||
*/
|
||||
public static function getEntityTypeEvents() {
|
||||
$event = array('onEntityTypeEvent', 100);
|
||||
$events[EntityTypeEvents::CREATE][] = $event;
|
||||
$events[EntityTypeEvents::UPDATE][] = $event;
|
||||
$events[EntityTypeEvents::DELETE][] = $event;
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener method for any entity type definition event.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeEvent $event
|
||||
* The field storage definition event object.
|
||||
* @param string $event_name
|
||||
* The event name.
|
||||
*/
|
||||
public function onEntityTypeEvent(EntityTypeEvent $event, $event_name) {
|
||||
switch ($event_name) {
|
||||
case EntityTypeEvents::CREATE:
|
||||
$this->onEntityTypeCreate($event->getEntityType());
|
||||
break;
|
||||
|
||||
case EntityTypeEvents::UPDATE:
|
||||
$this->onEntityTypeUpdate($event->getEntityType(), $event->getOriginal());
|
||||
break;
|
||||
|
||||
case EntityTypeEvents::DELETE:
|
||||
$this->onEntityTypeDelete($event->getEntityType());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function onEntityTypeCreate(EntityTypeInterface $entity_type);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeInterface $original);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function onEntityTypeDelete(EntityTypeInterface $entity_type);
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Entity\EntityTypeEvents.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Entity;
|
||||
|
||||
/**
|
||||
* Contains all events thrown while handling entity types.
|
||||
*/
|
||||
final class EntityTypeEvents {
|
||||
|
||||
/**
|
||||
* Event name for entity type creation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const CREATE = 'entity_type.definition.create';
|
||||
|
||||
/**
|
||||
* Event name for entity type update.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const UPDATE = 'entity_type.definition.update';
|
||||
|
||||
/**
|
||||
* Event name for entity type deletion.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DELETE = 'entity_type.definition.delete';
|
||||
|
||||
}
|
|
@ -12,7 +12,7 @@ use Drupal\Component\Serialization\Yaml;
|
|||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\DrupalKernelInterface;
|
||||
|
||||
/**
|
||||
* Class that manages modules in a Drupal installation.
|
||||
|
@ -64,6 +64,13 @@ class ModuleHandler implements ModuleHandlerInterface {
|
|||
*/
|
||||
protected $hookInfo;
|
||||
|
||||
/**
|
||||
* The drupal kernel.
|
||||
*
|
||||
* @var \Drupal\Core\DrupalKernelInterface
|
||||
*/
|
||||
protected $kernel;
|
||||
|
||||
/**
|
||||
* Cache backend for storing module hook implementation information.
|
||||
*
|
||||
|
@ -92,17 +99,20 @@ class ModuleHandler implements ModuleHandlerInterface {
|
|||
* An associative array whose keys are the names of installed modules and
|
||||
* whose values are Extension class parameters. This is normally the
|
||||
* %container.modules% parameter being set up by DrupalKernel.
|
||||
* @param \Drupal\Core\DrupalKernelInterface $kernel
|
||||
* The drupal kernel.
|
||||
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
|
||||
* Cache backend for storing module hook implementation information.
|
||||
*
|
||||
* @see \Drupal\Core\DrupalKernel
|
||||
* @see \Drupal\Core\CoreServiceProvider
|
||||
*/
|
||||
public function __construct(array $module_list = array(), CacheBackendInterface $cache_backend) {
|
||||
public function __construct(array $module_list = array(), DrupalKernelInterface $kernel, CacheBackendInterface $cache_backend) {
|
||||
$this->moduleList = array();
|
||||
foreach ($module_list as $name => $module) {
|
||||
$this->moduleList[$name] = new Extension($module['type'], $module['pathname'], $module['filename']);
|
||||
}
|
||||
$this->kernel = $kernel;
|
||||
$this->cacheBackend = $cache_backend;
|
||||
}
|
||||
|
||||
|
@ -792,14 +802,7 @@ class ModuleHandler implements ModuleHandlerInterface {
|
|||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
// Update the kernel to include it.
|
||||
// This reboots the kernel to register the module's bundle and its
|
||||
// services in the service container. The $module_filenames argument is
|
||||
// taken over as %container.modules% parameter, which is passed to a
|
||||
// fresh ModuleHandler instance upon first retrieval.
|
||||
// @todo install_begin_request() creates a container without a kernel.
|
||||
if ($kernel = \Drupal::service('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
|
||||
$kernel->updateModules($module_filenames, $module_filenames);
|
||||
}
|
||||
$this->updateKernel($module_filenames);
|
||||
|
||||
// Refresh the schema to include it.
|
||||
drupal_get_schema(NULL, TRUE);
|
||||
|
@ -822,10 +825,10 @@ class ModuleHandler implements ModuleHandlerInterface {
|
|||
$version = max(max($versions), $version);
|
||||
}
|
||||
|
||||
// Notify the entity manager that this module's entity types are new,
|
||||
// so that it can notify all interested handlers. For example, a
|
||||
// SQL-based storage handler can use this as an opportunity to create
|
||||
// the necessary database tables.
|
||||
// Notify interested components that this module's entity types are new.
|
||||
// For example, a SQL-based storage handler can use this as an
|
||||
// opportunity to create the necessary database tables.
|
||||
// @todo Clean this up in https://www.drupal.org/node/2350111.
|
||||
$entity_manager = \Drupal::entityManager();
|
||||
foreach ($entity_manager->getDefinitions() as $entity_type) {
|
||||
if ($entity_type->getProvider() == $module) {
|
||||
|
@ -950,6 +953,7 @@ class ModuleHandler implements ModuleHandlerInterface {
|
|||
|
||||
// Clean up all entity bundles (including fields) of every entity type
|
||||
// provided by the module that is being uninstalled.
|
||||
// @todo Clean this up in https://www.drupal.org/node/2350111.
|
||||
foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) {
|
||||
if ($entity_type->getProvider() == $module) {
|
||||
foreach (array_keys($entity_manager->getBundleInfo($entity_type_id)) as $bundle) {
|
||||
|
@ -968,10 +972,10 @@ class ModuleHandler implements ModuleHandlerInterface {
|
|||
// Remove all configuration belonging to the module.
|
||||
\Drupal::service('config.manager')->uninstall('module', $module);
|
||||
|
||||
// Notify the entity manager that this module's entity types are being
|
||||
// deleted, so that it can notify all interested handlers. For example,
|
||||
// a SQL-based storage handler can use this as an opportunity to drop
|
||||
// the corresponding database tables.
|
||||
// Notify interested components that this module's entity types are being
|
||||
// deleted. For example, a SQL-based storage handler can use this as an
|
||||
// opportunity to drop the corresponding database tables.
|
||||
// @todo Clean this up in https://www.drupal.org/node/2350111.
|
||||
foreach ($entity_manager->getDefinitions() as $entity_type) {
|
||||
if ($entity_type->getProvider() == $module) {
|
||||
$entity_manager->onEntityTypeDelete($entity_type);
|
||||
|
@ -1004,7 +1008,7 @@ class ModuleHandler implements ModuleHandlerInterface {
|
|||
\Drupal::service('router.builder_indicator')->setRebuildNeeded();
|
||||
|
||||
// Update the kernel to exclude the uninstalled modules.
|
||||
\Drupal::service('kernel')->updateModules($module_filenames, $module_filenames);
|
||||
$this->updateKernel($module_filenames);
|
||||
|
||||
// Update the theme registry to remove the newly uninstalled module.
|
||||
drupal_theme_rebuild();
|
||||
|
@ -1084,4 +1088,23 @@ class ModuleHandler implements ModuleHandlerInterface {
|
|||
$module_data = system_rebuild_module_data();
|
||||
return $module_data[$module]->info['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the kernel module list.
|
||||
*
|
||||
* @param string $module_filenames
|
||||
* The list of installed modules.
|
||||
*/
|
||||
protected function updateKernel($module_filenames) {
|
||||
// This reboots the kernel to register the module's bundle and its services
|
||||
// in the service container. The $module_filenames argument is taken over as
|
||||
// %container.modules% parameter, which is passed to a fresh ModuleHandler
|
||||
// instance upon first retrieval.
|
||||
$this->kernel->updateModules($module_filenames, $module_filenames);
|
||||
// After rebuilding the container we need to update the injected
|
||||
// dependencies.
|
||||
$container = $this->kernel->getContainer();
|
||||
$this->cacheBackend = $container->get('cache.bootstrap');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Field\FieldStorageDefinitionEvent.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Field;
|
||||
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
/**
|
||||
* Defines a base class for all field storage definition events.
|
||||
*/
|
||||
class FieldStorageDefinitionEvent extends GenericEvent {
|
||||
|
||||
/**
|
||||
* The field storage definition.
|
||||
*
|
||||
* @var \Drupal\Core\Field\FieldStorageDefinitionInterface
|
||||
*/
|
||||
protected $fieldStorageDefinition;
|
||||
|
||||
/**
|
||||
* The original field storage definition.
|
||||
*
|
||||
* @var \Drupal\Core\Field\FieldStorageDefinitionInterface
|
||||
*/
|
||||
protected $original;
|
||||
|
||||
/**
|
||||
* Constructs a new FieldStorageDefinitionEvent.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_definition
|
||||
* The field storage definition.
|
||||
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $original
|
||||
* (optional) The original field storage definition. This should be passed
|
||||
* only when updating the storage definition.
|
||||
*/
|
||||
public function __construct(FieldStorageDefinitionInterface $field_storage_definition, FieldStorageDefinitionInterface $original = NULL) {
|
||||
$this->fieldStorageDefinition = $field_storage_definition;
|
||||
$this->original = $original;
|
||||
}
|
||||
|
||||
/**
|
||||
* The field storage definition.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldStorageDefinitionInterface
|
||||
*/
|
||||
public function getFieldStorageDefinition() {
|
||||
return $this->fieldStorageDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* The original field storage definition.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldStorageDefinitionInterface
|
||||
*/
|
||||
public function getOriginal() {
|
||||
return $this->original;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Field\FieldStorageDefinitionEventSubscriberTrait.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Field;
|
||||
|
||||
/**
|
||||
* Helper methods for FieldStorageDefinitionListenerInterface.
|
||||
*
|
||||
* This allows a class implementing FieldStorageDefinitionListenerInterface to
|
||||
* subscribe and react to field storage definition events.
|
||||
*
|
||||
* @see \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
* @see \Drupal\Core\Field\FieldStorageDefinitionListenerInterface
|
||||
*/
|
||||
trait FieldStorageDefinitionEventSubscriberTrait {
|
||||
|
||||
/**
|
||||
* Returns the subscribed events.
|
||||
*
|
||||
* @return array
|
||||
* An array of subscribed event names.
|
||||
*
|
||||
* @see \Symfony\Component\EventDispatcher\EventSubscriberInterface::getSubscribedEvents()
|
||||
*/
|
||||
public static function getFieldStorageDefinitionEvents() {
|
||||
$event = array('onFieldStorageDefinitionEvent', 100);
|
||||
$events[FieldStorageDefinitionEvents::CREATE][] = $event;
|
||||
$events[FieldStorageDefinitionEvents::UPDATE][] = $event;
|
||||
$events[FieldStorageDefinitionEvents::DELETE][] = $event;
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener method for any field storage definition event.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldStorageDefinitionEvent $event
|
||||
* The field storage definition event object.
|
||||
* @param string $event_name
|
||||
* The event name.
|
||||
*/
|
||||
public function onFieldStorageDefinitionEvent(FieldStorageDefinitionEvent $event, $event_name) {
|
||||
switch ($event_name) {
|
||||
case FieldStorageDefinitionEvents::CREATE:
|
||||
$this->onFieldStorageDefinitionCreate($event->getFieldStorageDefinition());
|
||||
break;
|
||||
|
||||
case FieldStorageDefinitionEvents::UPDATE:
|
||||
$this->onFieldStorageDefinitionUpdate($event->getFieldStorageDefinition(), $event->getOriginal());
|
||||
break;
|
||||
|
||||
case FieldStorageDefinitionEvents::DELETE:
|
||||
$this->onFieldStorageDefinitionDelete($event->getFieldStorageDefinition());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition);
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Field\FieldStorageDefinitionEvent.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Field;
|
||||
|
||||
/**
|
||||
* Contains all events thrown while handling field storage definitions.
|
||||
*/
|
||||
final class FieldStorageDefinitionEvents {
|
||||
|
||||
/**
|
||||
* Event name for field storage definition creation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const CREATE = 'field_storage.definition.create';
|
||||
|
||||
/**
|
||||
* Event name for field storage definition update.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const UPDATE = 'field_storage.definition.update';
|
||||
|
||||
/**
|
||||
* Event name for field storage definition deletion.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DELETE = 'field_storage.definition.delete';
|
||||
|
||||
}
|
|
@ -11,6 +11,7 @@ use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
|||
use Drupal\Component\Plugin\LazyPluginCollection;
|
||||
use Drupal\Component\Plugin\PluginManagerInterface;
|
||||
use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
|
||||
/**
|
||||
* Provides a default plugin collection for a plugin type.
|
||||
|
@ -21,6 +22,7 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
|||
* self::$pluginKey.
|
||||
*/
|
||||
class DefaultLazyPluginCollection extends LazyPluginCollection {
|
||||
use DependencySerializationTrait;
|
||||
|
||||
/**
|
||||
* The manager used to instantiate the plugins.
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\Core\Plugin;
|
|||
use Drupal\Component\Plugin\PluginManagerInterface;
|
||||
use Drupal\Component\Plugin\LazyPluginCollection;
|
||||
use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
|
||||
/**
|
||||
* Provides a default plugin collection for a plugin type.
|
||||
|
@ -21,6 +22,7 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
|||
* in self::initializePlugin().
|
||||
*/
|
||||
class DefaultSingleLazyPluginCollection extends LazyPluginCollection {
|
||||
use DependencySerializationTrait;
|
||||
|
||||
/**
|
||||
* The manager used to instantiate the plugins.
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
namespace Drupal\system\Tests\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Entity\EntityTypeEvents;
|
||||
use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionEvents;
|
||||
use Drupal\entity_test\FieldStorageDefinition;
|
||||
|
||||
/**
|
||||
|
@ -442,6 +444,39 @@ class EntityDefinitionUpdateTest extends EntityUnitTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests entity type and field storage definition events.
|
||||
*/
|
||||
public function testDefinitionEvents() {
|
||||
/** @var \Drupal\entity_test\EntityTestDefinitionSubscriber $event_subscriber */
|
||||
$event_subscriber = $this->container->get('entity_test.definition.subscriber');
|
||||
$event_subscriber->enableEventTracking();
|
||||
|
||||
// Test field storage definition events.
|
||||
$storage_definition = current($this->entityManager->getFieldStorageDefinitions('entity_test_rev'));
|
||||
$this->assertFalse($event_subscriber->hasEventFired(FieldStorageDefinitionEvents::DELETE), 'Entity type delete was not dispatched yet.');
|
||||
$this->entityManager->onFieldStorageDefinitionDelete($storage_definition);
|
||||
$this->assertTrue($event_subscriber->hasEventFired(FieldStorageDefinitionEvents::DELETE), 'Entity type delete event successfully dispatched.');
|
||||
$this->assertFalse($event_subscriber->hasEventFired(FieldStorageDefinitionEvents::CREATE), 'Entity type create was not dispatched yet.');
|
||||
$this->entityManager->onFieldStorageDefinitionCreate($storage_definition);
|
||||
$this->assertTrue($event_subscriber->hasEventFired(FieldStorageDefinitionEvents::CREATE), 'Entity type create event successfully dispatched.');
|
||||
$this->assertFalse($event_subscriber->hasEventFired(FieldStorageDefinitionEvents::UPDATE), 'Entity type update was not dispatched yet.');
|
||||
$this->entityManager->onFieldStorageDefinitionUpdate($storage_definition, $storage_definition);
|
||||
$this->assertTrue($event_subscriber->hasEventFired(FieldStorageDefinitionEvents::UPDATE), 'Entity type update event successfully dispatched.');
|
||||
|
||||
// Test entity type events.
|
||||
$entity_type = $this->entityManager->getDefinition('entity_test_rev');
|
||||
$this->assertFalse($event_subscriber->hasEventFired(EntityTypeEvents::CREATE), 'Entity type create was not dispatched yet.');
|
||||
$this->entityManager->onEntityTypeCreate($entity_type);
|
||||
$this->assertTrue($event_subscriber->hasEventFired(EntityTypeEvents::CREATE), 'Entity type create event successfully dispatched.');
|
||||
$this->assertFalse($event_subscriber->hasEventFired(EntityTypeEvents::UPDATE), 'Entity type update was not dispatched yet.');
|
||||
$this->entityManager->onEntityTypeUpdate($entity_type, $entity_type);
|
||||
$this->assertTrue($event_subscriber->hasEventFired(EntityTypeEvents::UPDATE), 'Entity type update event successfully dispatched.');
|
||||
$this->assertFalse($event_subscriber->hasEventFired(EntityTypeEvents::DELETE), 'Entity type delete was not dispatched yet.');
|
||||
$this->entityManager->onEntityTypeDelete($entity_type);
|
||||
$this->assertTrue($event_subscriber->hasEventFired(EntityTypeEvents::DELETE), 'Entity type delete event successfully dispatched.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the 'entity_test_update' entity type to revisionable.
|
||||
*/
|
||||
|
|
|
@ -47,7 +47,7 @@ abstract class PluginTestBase extends KernelTestBase {
|
|||
// as derivatives and ReflectionFactory.
|
||||
$this->testPluginManager = new TestPluginManager();
|
||||
$this->mockBlockManager = new MockBlockManager();
|
||||
$module_handler = new ModuleHandler(array(), new MemoryBackend('plugin'));
|
||||
$module_handler = new ModuleHandler(array(), $this->container->get('kernel'), new MemoryBackend('plugin'), $this->container->get('event_dispatcher'));
|
||||
$this->defaultsTestPluginManager = new DefaultsTestPluginManager($module_handler);
|
||||
|
||||
// The expected plugin definitions within each manager. Several tests assert
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
services:
|
||||
entity_test.definition.subscriber:
|
||||
class: Drupal\entity_test\EntityTestDefinitionSubscriber
|
||||
arguments: ['@state']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_test\EntityTestDefinitionSubscriber.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_test;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeEvents;
|
||||
use Drupal\Core\Entity\EntityTypeEventSubscriberTrait;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityTypeListenerInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionEvents;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionEventSubscriberTrait;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionListenerInterface;
|
||||
use Drupal\Core\State\StateInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Test entity type and field storage definition event subscriber.
|
||||
*/
|
||||
class EntityTestDefinitionSubscriber implements EventSubscriberInterface, EntityTypeListenerInterface, FieldStorageDefinitionListenerInterface {
|
||||
|
||||
use EntityTypeEventSubscriberTrait;
|
||||
use FieldStorageDefinitionEventSubscriberTrait;
|
||||
|
||||
/**
|
||||
* The state service.
|
||||
*
|
||||
* @var \Drupal\Core\State\StateInterface
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Flag determining whether events should be tracked.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $trackEvents = FALSE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function __construct(StateInterface $state) {
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
return static::getEntityTypeEvents() + static::getFieldStorageDefinitionEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onEntityTypeCreate(EntityTypeInterface $entity_type) {
|
||||
$this->storeEvent(EntityTypeEvents::CREATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeInterface $original) {
|
||||
$this->storeEvent(EntityTypeEvents::UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onEntityTypeDelete(EntityTypeInterface $entity_type) {
|
||||
$this->storeEvent(EntityTypeEvents::DELETE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition) {
|
||||
$this->storeEvent(FieldStorageDefinitionEvents::CREATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) {
|
||||
$this->storeEvent(FieldStorageDefinitionEvents::UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) {
|
||||
$this->storeEvent(FieldStorageDefinitionEvents::DELETE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables event tracking.
|
||||
*/
|
||||
public function enableEventTracking() {
|
||||
$this->trackEvents = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an event has been dispatched.
|
||||
*
|
||||
* @param string $event_name
|
||||
* The event name.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the event has been dispatched, FALSE otherwise.
|
||||
*/
|
||||
public function hasEventFired($event_name) {
|
||||
return (bool) $this->state->get($event_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the specified event.
|
||||
*
|
||||
* @param string $event_name
|
||||
* The event name.
|
||||
*/
|
||||
protected function storeEvent($event_name) {
|
||||
if ($this->trackEvents) {
|
||||
$this->state->set($event_name, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
namespace Drupal\update;
|
||||
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
|
@ -17,6 +18,7 @@ use Drupal\Core\Utility\ProjectInfo;
|
|||
* Default implementation of UpdateManagerInterface.
|
||||
*/
|
||||
class UpdateManager implements UpdateManagerInterface {
|
||||
use DependencySerializationTrait;
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,6 +100,13 @@ class EntityManagerTest extends UnitTestCase {
|
|||
*/
|
||||
protected $installedDefinitions;
|
||||
|
||||
/**
|
||||
* The event dispatcher.
|
||||
*
|
||||
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
|
||||
*/
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -140,6 +147,8 @@ class EntityManagerTest extends UnitTestCase {
|
|||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->eventDispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
|
||||
$this->installedDefinitions = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreInterface');
|
||||
}
|
||||
|
||||
|
@ -171,7 +180,7 @@ class EntityManagerTest extends UnitTestCase {
|
|||
->method('getDefinitions')
|
||||
->will($this->returnValue($definitions));
|
||||
|
||||
$this->entityManager = new TestEntityManager(new \ArrayObject(), $this->moduleHandler, $this->cache, $this->languageManager, $this->translationManager, $this->getClassResolverStub(), $this->typedDataManager, $this->installedDefinitions);
|
||||
$this->entityManager = new TestEntityManager(new \ArrayObject(), $this->moduleHandler, $this->cache, $this->languageManager, $this->translationManager, $this->getClassResolverStub(), $this->typedDataManager, $this->installedDefinitions, $this->eventDispatcher);
|
||||
$this->entityManager->setContainer($this->container);
|
||||
$this->entityManager->setDiscovery($this->discovery);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,13 @@ use Drupal\Tests\UnitTestCase;
|
|||
*/
|
||||
class ModuleHandlerTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The mocked drupal kernel.
|
||||
*
|
||||
* @var \Drupal\Core\DrupalKernelInterface
|
||||
*/
|
||||
protected $kernel;
|
||||
|
||||
/**
|
||||
* The mocked cache backend.
|
||||
*
|
||||
|
@ -24,7 +31,6 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
*/
|
||||
protected $cacheBackend;
|
||||
|
||||
|
||||
/**
|
||||
* The tested module handler.
|
||||
*
|
||||
|
@ -38,6 +44,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
* @covers ::__construct
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->kernel = $this->getMock('Drupal\Core\DrupalKernelInterface');
|
||||
$this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
|
||||
$this->moduleHandler = new ModuleHandler(array(
|
||||
'module_handler_test' => array(
|
||||
|
@ -45,7 +52,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml',
|
||||
'filename' => 'module_handler_test.module',
|
||||
)
|
||||
), $this->cacheBackend);
|
||||
), $this->kernel, $this->cacheBackend);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,7 +103,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml',
|
||||
'filename' => 'module_handler_test.module',
|
||||
)
|
||||
), $this->cacheBackend
|
||||
), $this->kernel, $this->cacheBackend
|
||||
))
|
||||
->setMethods(array('load'))
|
||||
->getMock();
|
||||
|
@ -164,7 +171,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
public function testSetModuleList() {
|
||||
$module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
|
||||
->setConstructorArgs(array(
|
||||
array(), $this->cacheBackend
|
||||
array(), $this->kernel, $this->cacheBackend
|
||||
))
|
||||
->setMethods(array('resetImplementations'))
|
||||
->getMock();
|
||||
|
@ -192,7 +199,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
|
||||
$module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
|
||||
->setConstructorArgs(array(
|
||||
array(), $this->cacheBackend
|
||||
array(), $this->kernel, $this->cacheBackend
|
||||
))
|
||||
->setMethods(array('resetImplementations'))
|
||||
->getMock();
|
||||
|
@ -214,7 +221,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
|
||||
$module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
|
||||
->setConstructorArgs(array(
|
||||
array(), $this->cacheBackend
|
||||
array(), $this->kernel, $this->cacheBackend
|
||||
))
|
||||
->setMethods(array('resetImplementations'))
|
||||
->getMock();
|
||||
|
@ -250,7 +257,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml',
|
||||
'filename' => 'module_handler_test.module',
|
||||
)
|
||||
), $this->cacheBackend
|
||||
), $this->kernel, $this->cacheBackend
|
||||
))
|
||||
->setMethods(array('loadInclude'))
|
||||
->getMock();
|
||||
|
@ -331,7 +338,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml',
|
||||
'filename' => 'module_handler_test.module',
|
||||
)
|
||||
), $this->cacheBackend
|
||||
), $this->kernel, $this->cacheBackend
|
||||
))
|
||||
->setMethods(array('buildImplementationInfo', 'loadInclude'))
|
||||
->getMock();
|
||||
|
@ -366,7 +373,7 @@ class ModuleHandlerTest extends UnitTestCase {
|
|||
'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml',
|
||||
'filename' => 'module_handler_test.module',
|
||||
)
|
||||
), $this->cacheBackend
|
||||
), $this->kernel, $this->cacheBackend
|
||||
))
|
||||
->setMethods(array('buildImplementationInfo'))
|
||||
->getMock();
|
||||
|
|
Loading…
Reference in New Issue