3 namespace Drupal\field;
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;
19 * Storage handler for "field storage" configuration entities.
21 class FieldStorageConfigStorage extends ConfigEntityStorage {
26 * @var \Drupal\Core\Extension\ModuleHandlerInterface
28 protected $moduleHandler;
33 * @var \Drupal\Core\Entity\EntityManagerInterface
35 protected $entityManager;
38 * The field type plugin manager.
40 * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
42 protected $fieldTypeManager;
45 * The deleted fields repository.
47 * @var \Drupal\Core\Field\DeletedFieldsRepositoryInterface
49 protected $deletedFieldsRepository;
52 * Constructs a FieldStorageConfigStorage object.
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
60 * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
61 * The language manager.
62 * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
64 * @param \Drupal\Core\Extension\ModuleHandlerInterface $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
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;
84 public static function createInstance(ContainerInterface $container, EntityTypeInterface $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')
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']);
106 /** @var \Drupal\field\FieldStorageConfigInterface[] $storages */
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]);
119 // No specific ID, we need to examine all existing storages.
120 $storages = $this->loadMultiple();
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;
135 // Collect matching fields.
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) {
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;
159 protected function mapFromStorageRecords(array $records) {
160 foreach ($records as $id => &$record) {
161 $class = $this->fieldTypeManager->getPluginClass($record['type']);
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");
166 $record['settings'] = $class::storageSettingsFromConfigData($record['settings']);
168 return parent::mapFromStorageRecords($records);
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']);