4d23c9eedbb860d15ecbebac06f59d08dd40bd95
[yaffs-website] / web / core / modules / field / src / FieldStorageConfigStorage.php
1 <?php
2
3 namespace Drupal\field;
4
5 use Drupal\Component\Uuid\UuidInterface;
6 use Drupal\Core\Cache\MemoryCache\MemoryCacheInterface;
7 use Drupal\Core\Config\Entity\ConfigEntityStorage;
8 use Drupal\Core\Entity\EntityInterface;
9 use Drupal\Core\Entity\EntityManagerInterface;
10 use Drupal\Core\Entity\EntityTypeInterface;
11 use Drupal\Core\Field\DeletedFieldsRepositoryInterface;
12 use Drupal\Core\Field\FieldTypePluginManagerInterface;
13 use Drupal\Core\Language\LanguageManagerInterface;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15 use Drupal\Core\Config\ConfigFactoryInterface;
16 use Drupal\Core\Extension\ModuleHandlerInterface;
17
18 /**
19  * Storage handler for "field storage" configuration entities.
20  */
21 class FieldStorageConfigStorage extends ConfigEntityStorage {
22
23   /**
24    * The module handler.
25    *
26    * @var \Drupal\Core\Extension\ModuleHandlerInterface
27    */
28   protected $moduleHandler;
29
30   /**
31    * The entity manager.
32    *
33    * @var \Drupal\Core\Entity\EntityManagerInterface
34    */
35   protected $entityManager;
36
37   /**
38    * The field type plugin manager.
39    *
40    * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
41    */
42   protected $fieldTypeManager;
43
44   /**
45    * The deleted fields repository.
46    *
47    * @var \Drupal\Core\Field\DeletedFieldsRepositoryInterface
48    */
49   protected $deletedFieldsRepository;
50
51   /**
52    * Constructs a FieldStorageConfigStorage object.
53    *
54    * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
55    *   The entity type definition.
56    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
57    *   The config factory service.
58    * @param \Drupal\Component\Uuid\UuidInterface $uuid_service
59    *   The UUID service.
60    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
61    *   The language manager.
62    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
63    *   The entity manager.
64    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
65    *   The module handler.
66    * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
67    *   The field type plugin manager.
68    * @param \Drupal\Core\Field\DeletedFieldsRepositoryInterface $deleted_fields_repository
69    *   The deleted fields repository.
70    * @param \Drupal\Core\Cache\MemoryCache\MemoryCacheInterface $memory_cache
71    *   The memory cache.
72    */
73   public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, LanguageManagerInterface $language_manager, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, FieldTypePluginManagerInterface $field_type_manager, DeletedFieldsRepositoryInterface $deleted_fields_repository, MemoryCacheInterface $memory_cache) {
74     parent::__construct($entity_type, $config_factory, $uuid_service, $language_manager, $memory_cache);
75     $this->entityManager = $entity_manager;
76     $this->moduleHandler = $module_handler;
77     $this->fieldTypeManager = $field_type_manager;
78     $this->deletedFieldsRepository = $deleted_fields_repository;
79   }
80
81   /**
82    * {@inheritdoc}
83    */
84   public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
85     return new static(
86       $entity_type,
87       $container->get('config.factory'),
88       $container->get('uuid'),
89       $container->get('language_manager'),
90       $container->get('entity.manager'),
91       $container->get('module_handler'),
92       $container->get('plugin.manager.field.field_type'),
93       $container->get('entity_field.deleted_fields_repository'),
94       $container->get('entity.memory_cache')
95     );
96   }
97
98   /**
99    * {@inheritdoc}
100    */
101   public function loadByProperties(array $conditions = []) {
102     // Include deleted fields if specified in the $conditions parameters.
103     $include_deleted = isset($conditions['include_deleted']) ? $conditions['include_deleted'] : FALSE;
104     unset($conditions['include_deleted']);
105
106     /** @var \Drupal\field\FieldStorageConfigInterface[] $storages */
107     $storages = [];
108
109     // Get field storages living in configuration. If we are explicitly looking
110     // for deleted storages only, this can be skipped, because they will be
111     // retrieved from the deleted fields repository below.
112     if (empty($conditions['deleted'])) {
113       if (isset($conditions['entity_type']) && isset($conditions['field_name'])) {
114         // Optimize for the most frequent case where we do have a specific ID.
115         $id = $conditions['entity_type'] . $conditions['field_name'];
116         $storages = $this->loadMultiple([$id]);
117       }
118       else {
119         // No specific ID, we need to examine all existing storages.
120         $storages = $this->loadMultiple();
121       }
122     }
123
124     // Merge deleted field storage definitions from the deleted fields
125     // repository if needed.
126     if ($include_deleted || !empty($conditions['deleted'])) {
127       $deleted_storage_definitions = $this->deletedFieldsRepository->getFieldStorageDefinitions();
128       foreach ($deleted_storage_definitions as $id => $field_storage_definition) {
129         if ($field_storage_definition instanceof FieldStorageConfigInterface) {
130           $storages[$id] = $field_storage_definition;
131         }
132       }
133     }
134
135     // Collect matching fields.
136     $matches = [];
137     foreach ($storages as $field) {
138       foreach ($conditions as $key => $value) {
139         // Extract the actual value against which the condition is checked.
140         $checked_value = $field->get($key);
141         // Skip to the next field as soon as one condition does not match.
142         if ($checked_value != $value) {
143           continue 2;
144         }
145       }
146
147       // When returning deleted fields, key the results by UUID since they can
148       // include several fields with the same ID.
149       $key = $include_deleted ? $field->uuid() : $field->id();
150       $matches[$key] = $field;
151     }
152
153     return $matches;
154   }
155
156   /**
157    * {@inheritdoc}
158    */
159   protected function mapFromStorageRecords(array $records) {
160     foreach ($records as $id => &$record) {
161       $class = $this->fieldTypeManager->getPluginClass($record['type']);
162       if (empty($class)) {
163         $config_id = $this->getPrefix() . $id;
164         throw new \RuntimeException("Unable to determine class for field type '{$record['type']}' found in the '$config_id' configuration");
165       }
166       $record['settings'] = $class::storageSettingsFromConfigData($record['settings']);
167     }
168     return parent::mapFromStorageRecords($records);
169   }
170
171   /**
172    * {@inheritdoc}
173    */
174   protected function mapToStorageRecord(EntityInterface $entity) {
175     $record = parent::mapToStorageRecord($entity);
176     $class = $this->fieldTypeManager->getPluginClass($record['type']);
177     $record['settings'] = $class::storageSettingsToConfigData($record['settings']);
178     return $record;
179   }
180
181 }