FieldDefinitionListener.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace Drupal\Core\Field;
  3. use Drupal\Core\Cache\CacheBackendInterface;
  4. use Drupal\Core\Entity\EntityFieldManagerInterface;
  5. use Drupal\Core\Entity\EntityTypeManagerInterface;
  6. use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
  7. /**
  8. * Reacts to field definition CRUD on behalf of the Entity system.
  9. */
  10. class FieldDefinitionListener implements FieldDefinitionListenerInterface {
  11. /**
  12. * The entity type manager.
  13. *
  14. * @var \Drupal\Core\Entity\EntityTypeManagerInterface
  15. */
  16. protected $entityTypeManager;
  17. /**
  18. * The key-value factory.
  19. *
  20. * @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface
  21. */
  22. protected $keyValueFactory;
  23. /**
  24. * Cache backend instance.
  25. *
  26. * @var \Drupal\Core\Cache\CacheBackendInterface
  27. */
  28. protected $cacheBackend;
  29. /**
  30. * The entity field manager.
  31. *
  32. * @var \Drupal\Core\Entity\EntityFieldManagerInterface
  33. */
  34. protected $entityFieldManager;
  35. /**
  36. * Constructs a new FieldDefinitionListener.
  37. *
  38. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
  39. * The entity type manager.
  40. * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
  41. * The entity field manager.
  42. * @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value_factory
  43. * The key-value factory.
  44. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
  45. * The cache backend.
  46. */
  47. public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, KeyValueFactoryInterface $key_value_factory, CacheBackendInterface $cache_backend) {
  48. $this->entityTypeManager = $entity_type_manager;
  49. $this->entityFieldManager = $entity_field_manager;
  50. $this->keyValueFactory = $key_value_factory;
  51. $this->cacheBackend = $cache_backend;
  52. }
  53. /**
  54. * {@inheritdoc}
  55. */
  56. public function onFieldDefinitionCreate(FieldDefinitionInterface $field_definition) {
  57. $entity_type_id = $field_definition->getTargetEntityTypeId();
  58. $bundle = $field_definition->getTargetBundle();
  59. $field_name = $field_definition->getName();
  60. // Notify the storage about the new field.
  61. $this->entityTypeManager->getStorage($entity_type_id)->onFieldDefinitionCreate($field_definition);
  62. // Update the bundle field map key value collection, add the new field.
  63. $bundle_field_map = $this->keyValueFactory->get('entity.definitions.bundle_field_map')->get($entity_type_id);
  64. if (!isset($bundle_field_map[$field_name])) {
  65. // This field did not exist yet, initialize it with the type and empty
  66. // bundle list.
  67. $bundle_field_map[$field_name] = [
  68. 'type' => $field_definition->getType(),
  69. 'bundles' => [],
  70. ];
  71. }
  72. $bundle_field_map[$field_name]['bundles'][$bundle] = $bundle;
  73. $this->keyValueFactory->get('entity.definitions.bundle_field_map')->set($entity_type_id, $bundle_field_map);
  74. // Delete the cache entry.
  75. $this->cacheBackend->delete('entity_field_map');
  76. // If the field map is initialized, update it as well, so that calls to it
  77. // do not have to rebuild it again.
  78. if ($field_map = $this->entityFieldManager->getFieldMap()) {
  79. if (!isset($field_map[$entity_type_id][$field_name])) {
  80. // This field did not exist yet, initialize it with the type and empty
  81. // bundle list.
  82. $field_map[$entity_type_id][$field_name] = [
  83. 'type' => $field_definition->getType(),
  84. 'bundles' => [],
  85. ];
  86. }
  87. $field_map[$entity_type_id][$field_name]['bundles'][$bundle] = $bundle;
  88. $this->entityFieldManager->setFieldMap($field_map);
  89. }
  90. }
  91. /**
  92. * {@inheritdoc}
  93. */
  94. public function onFieldDefinitionUpdate(FieldDefinitionInterface $field_definition, FieldDefinitionInterface $original) {
  95. // Notify the storage about the updated field.
  96. $this->entityTypeManager->getStorage($field_definition->getTargetEntityTypeId())->onFieldDefinitionUpdate($field_definition, $original);
  97. }
  98. /**
  99. * {@inheritdoc}
  100. */
  101. public function onFieldDefinitionDelete(FieldDefinitionInterface $field_definition) {
  102. $entity_type_id = $field_definition->getTargetEntityTypeId();
  103. $bundle = $field_definition->getTargetBundle();
  104. $field_name = $field_definition->getName();
  105. // Notify the storage about the field deletion.
  106. $this->entityTypeManager->getStorage($entity_type_id)->onFieldDefinitionDelete($field_definition);
  107. // Unset the bundle from the bundle field map key value collection.
  108. $bundle_field_map = $this->keyValueFactory->get('entity.definitions.bundle_field_map')->get($entity_type_id);
  109. unset($bundle_field_map[$field_name]['bundles'][$bundle]);
  110. if (empty($bundle_field_map[$field_name]['bundles'])) {
  111. // If there are no bundles left, remove the field from the map.
  112. unset($bundle_field_map[$field_name]);
  113. }
  114. $this->keyValueFactory->get('entity.definitions.bundle_field_map')->set($entity_type_id, $bundle_field_map);
  115. // Delete the cache entry.
  116. $this->cacheBackend->delete('entity_field_map');
  117. // If the field map is initialized, update it as well, so that calls to it
  118. // do not have to rebuild it again.
  119. if ($field_map = $this->entityFieldManager->getFieldMap()) {
  120. unset($field_map[$entity_type_id][$field_name]['bundles'][$bundle]);
  121. if (empty($field_map[$entity_type_id][$field_name]['bundles'])) {
  122. unset($field_map[$entity_type_id][$field_name]);
  123. }
  124. $this->entityFieldManager->setFieldMap($field_map);
  125. }
  126. }
  127. }