3 namespace Drupal\Core\Field;
5 use Drupal\Core\Cache\CacheBackendInterface;
6 use Drupal\Core\Entity\EntityFieldManagerInterface;
7 use Drupal\Core\Entity\EntityTypeManagerInterface;
8 use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
11 * Reacts to field definition CRUD on behalf of the Entity system.
13 class FieldDefinitionListener implements FieldDefinitionListenerInterface {
16 * The entity type manager.
18 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
20 protected $entityTypeManager;
23 * The key-value factory.
25 * @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface
27 protected $keyValueFactory;
30 * Cache backend instance.
32 * @var \Drupal\Core\Cache\CacheBackendInterface
34 protected $cacheBackend;
37 * The entity field manager.
39 * @var \Drupal\Core\Entity\EntityFieldManagerInterface
41 protected $entityFieldManager;
44 * Constructs a new FieldDefinitionListener.
46 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
47 * The entity type manager.
48 * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
49 * The entity field manager.
50 * @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value_factory
51 * The key-value factory.
52 * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
55 public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, KeyValueFactoryInterface $key_value_factory, CacheBackendInterface $cache_backend) {
56 $this->entityTypeManager = $entity_type_manager;
57 $this->entityFieldManager = $entity_field_manager;
58 $this->keyValueFactory = $key_value_factory;
59 $this->cacheBackend = $cache_backend;
65 public function onFieldDefinitionCreate(FieldDefinitionInterface $field_definition) {
66 $entity_type_id = $field_definition->getTargetEntityTypeId();
67 $bundle = $field_definition->getTargetBundle();
68 $field_name = $field_definition->getName();
70 // Notify the storage about the new field.
71 $this->entityTypeManager->getStorage($entity_type_id)->onFieldDefinitionCreate($field_definition);
73 // Update the bundle field map key value collection, add the new field.
74 $bundle_field_map = $this->keyValueFactory->get('entity.definitions.bundle_field_map')->get($entity_type_id);
75 if (!isset($bundle_field_map[$field_name])) {
76 // This field did not exist yet, initialize it with the type and empty
78 $bundle_field_map[$field_name] = [
79 'type' => $field_definition->getType(),
83 $bundle_field_map[$field_name]['bundles'][$bundle] = $bundle;
84 $this->keyValueFactory->get('entity.definitions.bundle_field_map')->set($entity_type_id, $bundle_field_map);
86 // Delete the cache entry.
87 $this->cacheBackend->delete('entity_field_map');
89 // If the field map is initialized, update it as well, so that calls to it
90 // do not have to rebuild it again.
91 if ($field_map = $this->entityFieldManager->getFieldMap()) {
92 if (!isset($field_map[$entity_type_id][$field_name])) {
93 // This field did not exist yet, initialize it with the type and empty
95 $field_map[$entity_type_id][$field_name] = [
96 'type' => $field_definition->getType(),
100 $field_map[$entity_type_id][$field_name]['bundles'][$bundle] = $bundle;
101 $this->entityFieldManager->setFieldMap($field_map);
108 public function onFieldDefinitionUpdate(FieldDefinitionInterface $field_definition, FieldDefinitionInterface $original) {
109 // Notify the storage about the updated field.
110 $this->entityTypeManager->getStorage($field_definition->getTargetEntityTypeId())->onFieldDefinitionUpdate($field_definition, $original);
116 public function onFieldDefinitionDelete(FieldDefinitionInterface $field_definition) {
117 $entity_type_id = $field_definition->getTargetEntityTypeId();
118 $bundle = $field_definition->getTargetBundle();
119 $field_name = $field_definition->getName();
121 // Notify the storage about the field deletion.
122 $this->entityTypeManager->getStorage($entity_type_id)->onFieldDefinitionDelete($field_definition);
124 // Unset the bundle from the bundle field map key value collection.
125 $bundle_field_map = $this->keyValueFactory->get('entity.definitions.bundle_field_map')->get($entity_type_id);
126 unset($bundle_field_map[$field_name]['bundles'][$bundle]);
127 if (empty($bundle_field_map[$field_name]['bundles'])) {
128 // If there are no bundles left, remove the field from the map.
129 unset($bundle_field_map[$field_name]);
131 $this->keyValueFactory->get('entity.definitions.bundle_field_map')->set($entity_type_id, $bundle_field_map);
133 // Delete the cache entry.
134 $this->cacheBackend->delete('entity_field_map');
136 // If the field map is initialized, update it as well, so that calls to it
137 // do not have to rebuild it again.
138 if ($field_map = $this->entityFieldManager->getFieldMap()) {
139 unset($field_map[$entity_type_id][$field_name]['bundles'][$bundle]);
140 if (empty($field_map[$entity_type_id][$field_name]['bundles'])) {
141 unset($field_map[$entity_type_id][$field_name]);
143 $this->entityFieldManager->setFieldMap($field_map);