Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / lib / Drupal / Core / Field / Entity / BaseFieldOverride.php
1 <?php
2
3 namespace Drupal\Core\Field\Entity;
4
5 use Drupal\Core\Entity\EntityStorageInterface;
6 use Drupal\Core\Field\BaseFieldDefinition;
7 use Drupal\Core\Field\FieldConfigBase;
8 use Drupal\Core\Field\FieldException;
9
10 /**
11  * Defines the base field override entity.
12  *
13  * Allows base fields to be overridden on the bundle level.
14  *
15  * @ConfigEntityType(
16  *   id = "base_field_override",
17  *   label = @Translation("Base field override"),
18  *   handlers = {
19  *     "storage" = "Drupal\Core\Field\BaseFieldOverrideStorage",
20  *     "access" = "Drupal\Core\Field\BaseFieldOverrideAccessControlHandler",
21  *   },
22  *   config_prefix = "base_field_override",
23  *   entity_keys = {
24  *     "id" = "id",
25  *     "label" = "label"
26  *   },
27  *   config_export = {
28  *     "id",
29  *     "field_name",
30  *     "entity_type",
31  *     "bundle",
32  *     "label",
33  *     "description",
34  *     "required",
35  *     "translatable",
36  *     "default_value",
37  *     "default_value_callback",
38  *     "settings",
39  *     "field_type",
40  *   }
41  * )
42  */
43 class BaseFieldOverride extends FieldConfigBase {
44
45   /**
46    * The base field definition.
47    *
48    * @var \Drupal\Core\Field\BaseFieldDefinition
49    */
50   protected $baseFieldDefinition;
51
52   /**
53    * Creates a base field override object.
54    *
55    * @param \Drupal\Core\Field\BaseFieldDefinition $base_field_definition
56    *   The base field definition to override.
57    * @param string $bundle
58    *   The bundle to which the override applies.
59    *
60    * @return \Drupal\Core\Field\Entity\BaseFieldOverride
61    *   A new base field override object.
62    */
63   public static function createFromBaseFieldDefinition(BaseFieldDefinition $base_field_definition, $bundle) {
64     $values = $base_field_definition->toArray();
65     $values['bundle'] = $bundle;
66     $values['baseFieldDefinition'] = $base_field_definition;
67     return \Drupal::entityManager()->getStorage('base_field_override')->create($values);
68   }
69
70   /**
71    * Constructs a BaseFieldOverride object.
72    *
73    * In most cases, base field override entities are created via
74    * BaseFieldOverride::createFromBaseFieldDefinition($definition, 'bundle')
75    *
76    * @param array $values
77    *   An array of base field bundle override properties, keyed by property
78    *   name. The field to override is specified by referring to an existing
79    *   field with:
80    *   - field_name: The field name.
81    *   - entity_type: The entity type.
82    *   Additionally, a 'bundle' property is required to indicate the entity
83    *   bundle to which the bundle field override is attached to. Other array
84    *   elements will be used to set the corresponding properties on the class;
85    *   see the class property documentation for details.
86    * @param string $entity_type
87    *   (optional) The type of the entity to create. Defaults to
88    *   'base_field_override'.
89    *
90    * @see entity_create()
91    *
92    * @throws \Drupal\Core\Field\FieldException
93    *   Exception thrown if $values does not contain a field_name, entity_type or
94    *   bundle value.
95    */
96   public function __construct(array $values, $entity_type = 'base_field_override') {
97     if (empty($values['field_name'])) {
98       throw new FieldException('Attempt to create a base field bundle override of a field without a field_name');
99     }
100     if (empty($values['entity_type'])) {
101       throw new FieldException("Attempt to create a base field bundle override of field {$values['field_name']} without an entity_type");
102     }
103     if (empty($values['bundle'])) {
104       throw new FieldException("Attempt to create a base field bundle override of field {$values['field_name']} without a bundle");
105     }
106
107     parent::__construct($values, $entity_type);
108   }
109
110   /**
111    * {@inheritdoc}
112    */
113   public function getFieldStorageDefinition() {
114     return $this->getBaseFieldDefinition()->getFieldStorageDefinition();
115   }
116
117   /**
118    * {@inheritdoc}
119    */
120   public function isDisplayConfigurable($context) {
121     return $this->getBaseFieldDefinition()->isDisplayConfigurable($context);
122   }
123
124   /**
125    * {@inheritdoc}
126    */
127   public function getDisplayOptions($display_context) {
128     return $this->getBaseFieldDefinition()->getDisplayOptions($display_context);
129   }
130
131   /**
132    * {@inheritdoc}
133    */
134   public function isReadOnly() {
135     return $this->getBaseFieldDefinition()->isReadOnly();
136   }
137
138   /**
139    * {@inheritdoc}
140    */
141   public function isComputed() {
142     return $this->getBaseFieldDefinition()->isComputed();
143   }
144
145   /**
146    * {@inheritdoc}
147    */
148   public function getClass() {
149     return $this->getBaseFieldDefinition()->getClass();
150   }
151
152   /**
153    * {@inheritdoc}
154    */
155   public function getUniqueIdentifier() {
156     return $this->getBaseFieldDefinition()->getUniqueIdentifier();
157   }
158
159   /**
160    * Gets the base field definition.
161    *
162    * @return \Drupal\Core\Field\BaseFieldDefinition
163    */
164   protected function getBaseFieldDefinition() {
165     if (!isset($this->baseFieldDefinition)) {
166       $fields = $this->entityManager()->getBaseFieldDefinitions($this->entity_type);
167       $this->baseFieldDefinition = $fields[$this->getName()];
168     }
169     return $this->baseFieldDefinition;
170   }
171
172   /**
173    * {@inheritdoc}
174    *
175    * @throws \Drupal\Core\Field\FieldException
176    *   If the bundle is being changed.
177    */
178   public function preSave(EntityStorageInterface $storage) {
179     // Filter out unknown settings and make sure all settings are present, so
180     // that a complete field definition is passed to the various hooks and
181     // written to config.
182     $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
183     $default_settings = $field_type_manager->getDefaultFieldSettings($this->getType());
184     $this->settings = array_intersect_key($this->settings, $default_settings) + $default_settings;
185
186     // Call the parent's presave method to perform validate and calculate
187     // dependencies.
188     parent::preSave($storage);
189
190     if ($this->isNew()) {
191       // @todo This assumes that the previous definition isn't some
192       //   non-config-based override, but that might not be the case:
193       //   https://www.drupal.org/node/2321071.
194       $previous_definition = $this->getBaseFieldDefinition();
195     }
196     else {
197       // Some updates are always disallowed.
198       if ($this->entity_type != $this->original->entity_type) {
199         throw new FieldException("Cannot change the entity_type of an existing base field bundle override (entity type:{$this->entity_type}, bundle:{$this->original->bundle}, field name: {$this->field_name})");
200       }
201       if ($this->bundle != $this->original->bundle) {
202         throw new FieldException("Cannot change the bundle of an existing base field bundle override (entity type:{$this->entity_type}, bundle:{$this->original->bundle}, field name: {$this->field_name})");
203       }
204       $previous_definition = $this->original;
205     }
206     // Notify the entity storage.
207     $this->entityManager()->getStorage($this->getTargetEntityTypeId())->onFieldDefinitionUpdate($this, $previous_definition);
208   }
209
210   /**
211    * {@inheritdoc}
212    */
213   public static function postDelete(EntityStorageInterface $storage, array $field_overrides) {
214     $entity_manager = \Drupal::entityManager();
215     // Clear the cache upfront, to refresh the results of getBundles().
216     $entity_manager->clearCachedFieldDefinitions();
217     /** @var \Drupal\Core\Field\Entity\BaseFieldOverride $field_override */
218     foreach ($field_overrides as $field_override) {
219       // Inform the system that the field definition is being updated back to
220       // its non-overridden state.
221       // @todo This assumes that there isn't a non-config-based override that
222       //   we're returning to, but that might not be the case:
223       //   https://www.drupal.org/node/2321071.
224       $entity_manager->getStorage($field_override->getTargetEntityTypeId())->onFieldDefinitionUpdate($field_override->getBaseFieldDefinition(), $field_override);
225     }
226   }
227
228   /**
229    * Loads a base field bundle override config entity.
230    *
231    * @param string $entity_type_id
232    *   ID of the entity type.
233    * @param string $bundle
234    *   Bundle name.
235    * @param string $field_name
236    *   Name of the field.
237    *
238    * @return static
239    *   The base field bundle override config entity if one exists for the
240    *   provided field name, otherwise NULL.
241    */
242   public static function loadByName($entity_type_id, $bundle, $field_name) {
243     return \Drupal::entityManager()->getStorage('base_field_override')->load($entity_type_id . '.' . $bundle . '.' . $field_name);
244   }
245
246   /**
247    * Implements the magic __sleep() method.
248    */
249   public function __sleep() {
250     // Only serialize necessary properties, excluding those that can be
251     // recalculated.
252     unset($this->baseFieldDefinition);
253     return parent::__sleep();
254   }
255
256 }