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