3 namespace Drupal\Core\Field;
5 use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
6 use Drupal\Core\Entity\EntityFieldManagerInterface;
7 use Drupal\Core\Entity\EntityTypeManagerInterface;
8 use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
9 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12 * Reacts to field storage definition CRUD on behalf of the Entity system.
14 * @see \Drupal\Core\Field\FieldStorageDefinitionEvents
16 class FieldStorageDefinitionListener implements FieldStorageDefinitionListenerInterface {
19 * The entity type manager.
21 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
23 protected $entityTypeManager;
26 * The event dispatcher.
28 * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
30 protected $eventDispatcher;
33 * The entity definition manager.
35 * @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface
37 protected $entityLastInstalledSchemaRepository;
40 * The entity field manager.
42 * @var \Drupal\Core\Entity\EntityFieldManagerInterface
44 protected $entityFieldManager;
47 * Constructs a new FieldStorageDefinitionListener.
49 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
50 * The entity type manager.
51 * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
52 * The event dispatcher.
53 * @param \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository
54 * The entity last installed schema repository.
55 * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
56 * The entity field manager.
58 public function __construct(EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository, EntityFieldManagerInterface $entity_field_manager) {
59 $this->entityTypeManager = $entity_type_manager;
60 $this->eventDispatcher = $event_dispatcher;
61 $this->entityLastInstalledSchemaRepository = $entity_last_installed_schema_repository;
62 $this->entityFieldManager = $entity_field_manager;
68 public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition) {
69 $entity_type_id = $storage_definition->getTargetEntityTypeId();
71 // @todo Forward this to all interested handlers, not only storage, once
72 // iterating handlers is possible: https://www.drupal.org/node/2332857.
73 $storage = clone $this->entityTypeManager->getStorage($entity_type_id);
75 // Entity type definition updates can change the schema by adding or
76 // removing entity tables (for example when switching an entity type from
77 // non-revisionable to revisionable), so CRUD operations on a field storage
78 // definition need to use the last installed entity type schema.
79 if ($storage instanceof SqlContentEntityStorage
80 && ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
81 $storage->setEntityType($last_installed_entity_type);
84 if ($storage instanceof FieldStorageDefinitionListenerInterface) {
85 $storage->onFieldStorageDefinitionCreate($storage_definition);
88 $this->eventDispatcher->dispatch(FieldStorageDefinitionEvents::CREATE, new FieldStorageDefinitionEvent($storage_definition));
90 $this->entityLastInstalledSchemaRepository->setLastInstalledFieldStorageDefinition($storage_definition);
91 $this->entityFieldManager->clearCachedFieldDefinitions();
97 public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) {
98 $entity_type_id = $storage_definition->getTargetEntityTypeId();
100 // @todo Forward this to all interested handlers, not only storage, once
101 // iterating handlers is possible: https://www.drupal.org/node/2332857.
102 $storage = clone $this->entityTypeManager->getStorage($entity_type_id);
104 // Entity type definition updates can change the schema by adding or
105 // removing entity tables (for example when switching an entity type from
106 // non-revisionable to revisionable), so CRUD operations on a field storage
107 // definition need to use the last installed entity type schema.
108 if ($storage instanceof SqlContentEntityStorage
109 && ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
110 $storage->setEntityType($last_installed_entity_type);
113 if ($storage instanceof FieldStorageDefinitionListenerInterface) {
114 $storage->onFieldStorageDefinitionUpdate($storage_definition, $original);
117 $this->eventDispatcher->dispatch(FieldStorageDefinitionEvents::UPDATE, new FieldStorageDefinitionEvent($storage_definition, $original));
119 $this->entityLastInstalledSchemaRepository->setLastInstalledFieldStorageDefinition($storage_definition);
120 $this->entityFieldManager->clearCachedFieldDefinitions();
126 public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) {
127 $entity_type_id = $storage_definition->getTargetEntityTypeId();
129 // @todo Forward this to all interested handlers, not only storage, once
130 // iterating handlers is possible: https://www.drupal.org/node/2332857.
131 $storage = clone $this->entityTypeManager->getStorage($entity_type_id);
133 // Entity type definition updates can change the schema by adding or
134 // removing entity tables (for example when switching an entity type from
135 // non-revisionable to revisionable), so CRUD operations on a field storage
136 // definition need to use the last installed entity type schema.
137 if ($storage instanceof SqlContentEntityStorage
138 && ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
139 $storage->setEntityType($last_installed_entity_type);
142 if ($storage instanceof FieldStorageDefinitionListenerInterface) {
143 $storage->onFieldStorageDefinitionDelete($storage_definition);
146 $this->eventDispatcher->dispatch(FieldStorageDefinitionEvents::DELETE, new FieldStorageDefinitionEvent($storage_definition));
148 $this->entityLastInstalledSchemaRepository->deleteLastInstalledFieldStorageDefinition($storage_definition);
149 $this->entityFieldManager->clearCachedFieldDefinitions();