Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/Field/BaseFieldDefinition.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Core\Field; | |
4 | |
5 use Drupal\Core\Cache\UnchangingCacheableDependencyTrait; | |
6 use Drupal\Core\Entity\FieldableEntityInterface; | |
7 use Drupal\Core\Field\Entity\BaseFieldOverride; | |
8 use Drupal\Core\Field\TypedData\FieldItemDataDefinition; | |
9 use Drupal\Core\TypedData\ListDataDefinition; | |
10 use Drupal\Core\TypedData\OptionsProviderInterface; | |
11 | |
12 /** | |
13 * A class for defining entity fields. | |
14 */ | |
15 class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionInterface, FieldStorageDefinitionInterface, RequiredFieldStorageDefinitionInterface { | |
16 | |
17 use UnchangingCacheableDependencyTrait; | |
18 | |
19 /** | |
20 * The field type. | |
21 * | |
22 * @var string | |
23 */ | |
24 protected $type; | |
25 | |
26 /** | |
27 * An array of field property definitions. | |
28 * | |
29 * @var \Drupal\Core\TypedData\DataDefinitionInterface[] | |
30 * | |
31 * @see \Drupal\Core\TypedData\ComplexDataDefinitionInterface::getPropertyDefinitions() | |
32 */ | |
33 protected $propertyDefinitions; | |
34 | |
35 /** | |
36 * The field schema. | |
37 * | |
38 * @var array | |
39 */ | |
40 protected $schema; | |
41 | |
42 /** | |
43 * @var array | |
44 */ | |
45 protected $indexes = []; | |
46 | |
47 /** | |
48 * Creates a new field definition. | |
49 * | |
50 * @param string $type | |
51 * The type of the field. | |
52 * | |
53 * @return static | |
54 * A new field definition object. | |
55 */ | |
56 public static function create($type) { | |
57 $field_definition = new static([]); | |
58 $field_definition->type = $type; | |
59 $field_definition->itemDefinition = FieldItemDataDefinition::create($field_definition); | |
60 // Create a definition for the items, and initialize it with the default | |
61 // settings for the field type. | |
62 // @todo Cleanup in https://www.drupal.org/node/2116341. | |
63 $field_type_manager = \Drupal::service('plugin.manager.field.field_type'); | |
64 $default_settings = $field_type_manager->getDefaultStorageSettings($type) + $field_type_manager->getDefaultFieldSettings($type); | |
65 $field_definition->itemDefinition->setSettings($default_settings); | |
66 return $field_definition; | |
67 } | |
68 | |
69 /** | |
70 * Creates a new field definition based upon a field storage definition. | |
71 * | |
72 * In cases where one needs a field storage definitions to act like full | |
73 * field definitions, this creates a new field definition based upon the | |
74 * (limited) information available. That way it is possible to use the field | |
75 * definition in places where a full field definition is required; e.g., with | |
76 * widgets or formatters. | |
77 * | |
78 * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $definition | |
79 * The field storage definition to base the new field definition upon. | |
80 * | |
81 * @return $this | |
82 */ | |
83 public static function createFromFieldStorageDefinition(FieldStorageDefinitionInterface $definition) { | |
84 return static::create($definition->getType()) | |
85 ->setCardinality($definition->getCardinality()) | |
86 ->setConstraints($definition->getConstraints()) | |
87 ->setCustomStorage($definition->hasCustomStorage()) | |
88 ->setDescription($definition->getDescription()) | |
89 ->setLabel($definition->getLabel()) | |
90 ->setName($definition->getName()) | |
91 ->setProvider($definition->getProvider()) | |
92 ->setRevisionable($definition->isRevisionable()) | |
93 ->setSettings($definition->getSettings()) | |
94 ->setTargetEntityTypeId($definition->getTargetEntityTypeId()) | |
95 ->setTranslatable($definition->isTranslatable()); | |
96 } | |
97 | |
98 /** | |
99 * {@inheritdoc} | |
100 */ | |
101 public static function createFromItemType($item_type) { | |
102 // The data type of a field item is in the form of "field_item:$field_type". | |
103 $parts = explode(':', $item_type, 2); | |
104 return static::create($parts[1]); | |
105 } | |
106 | |
107 /** | |
108 * {@inheritdoc} | |
109 */ | |
110 public function getName() { | |
111 return $this->definition['field_name']; | |
112 } | |
113 | |
114 /** | |
115 * Sets the field name. | |
116 * | |
117 * @param string $name | |
118 * The field name to set. | |
119 * | |
120 * @return static | |
121 * The object itself for chaining. | |
122 */ | |
123 public function setName($name) { | |
124 $this->definition['field_name'] = $name; | |
125 return $this; | |
126 } | |
127 | |
128 /** | |
129 * {@inheritdoc} | |
130 */ | |
131 public function getType() { | |
132 return $this->type; | |
133 } | |
134 | |
135 /** | |
136 * {@inheritdoc} | |
137 */ | |
138 public function getSettings() { | |
139 return $this->getItemDefinition()->getSettings(); | |
140 } | |
141 | |
142 /** | |
143 * {@inheritdoc} | |
144 * | |
145 * Note that the method does not unset existing settings not specified in the | |
146 * incoming $settings array. | |
147 * | |
148 * For example: | |
149 * @code | |
150 * // Given these are the default settings. | |
151 * $field_definition->getSettings() === [ | |
152 * 'fruit' => 'apple', | |
153 * 'season' => 'summer', | |
154 * ]; | |
155 * // Change only the 'fruit' setting. | |
156 * $field_definition->setSettings(['fruit' => 'banana']); | |
157 * // The 'season' setting persists unchanged. | |
158 * $field_definition->getSettings() === [ | |
159 * 'fruit' => 'banana', | |
160 * 'season' => 'summer', | |
161 * ]; | |
162 * @endcode | |
163 * | |
164 * For clarity, it is preferred to use setSetting() if not all available | |
165 * settings are supplied. | |
166 */ | |
167 public function setSettings(array $settings) { | |
168 // Assign settings individually, in order to keep the current values | |
169 // of settings not specified in $settings. | |
170 foreach ($settings as $setting_name => $setting) { | |
171 $this->getItemDefinition()->setSetting($setting_name, $setting); | |
172 } | |
173 return $this; | |
174 } | |
175 | |
176 /** | |
177 * {@inheritdoc} | |
178 */ | |
179 public function getSetting($setting_name) { | |
180 return $this->getItemDefinition()->getSetting($setting_name); | |
181 } | |
182 | |
183 /** | |
184 * {@inheritdoc} | |
185 */ | |
186 public function setSetting($setting_name, $value) { | |
187 $this->getItemDefinition()->setSetting($setting_name, $value); | |
188 return $this; | |
189 } | |
190 | |
191 /** | |
192 * {@inheritdoc} | |
193 */ | |
194 public function getProvider() { | |
195 return isset($this->definition['provider']) ? $this->definition['provider'] : NULL; | |
196 } | |
197 | |
198 /** | |
199 * Sets the name of the provider of this field. | |
200 * | |
201 * @param string $provider | |
202 * The provider name to set. | |
203 * | |
204 * @return $this | |
205 */ | |
206 public function setProvider($provider) { | |
207 $this->definition['provider'] = $provider; | |
208 return $this; | |
209 } | |
210 | |
211 /** | |
212 * {@inheritdoc} | |
213 */ | |
214 public function isTranslatable() { | |
215 return !empty($this->definition['translatable']); | |
216 } | |
217 | |
218 /** | |
219 * Sets whether the field is translatable. | |
220 * | |
221 * @param bool $translatable | |
222 * Whether the field is translatable. | |
223 * | |
224 * @return $this | |
225 * The object itself for chaining. | |
226 */ | |
227 public function setTranslatable($translatable) { | |
228 $this->definition['translatable'] = $translatable; | |
229 return $this; | |
230 } | |
231 | |
232 /** | |
233 * {@inheritdoc} | |
234 */ | |
235 public function isRevisionable() { | |
236 return !empty($this->definition['revisionable']); | |
237 } | |
238 | |
239 /** | |
240 * Sets whether the field is revisionable. | |
241 * | |
242 * @param bool $revisionable | |
243 * Whether the field is revisionable. | |
244 * | |
245 * @return $this | |
246 * The object itself for chaining. | |
247 */ | |
248 public function setRevisionable($revisionable) { | |
249 $this->definition['revisionable'] = $revisionable; | |
250 return $this; | |
251 } | |
252 | |
253 /** | |
254 * {@inheritdoc} | |
255 */ | |
256 public function getCardinality() { | |
257 // @todo: Allow to control this. | |
258 return isset($this->definition['cardinality']) ? $this->definition['cardinality'] : 1; | |
259 } | |
260 | |
261 /** | |
262 * Sets the maximum number of items allowed for the field. | |
263 * | |
264 * Possible values are positive integers or | |
265 * FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED. | |
266 * | |
267 * @param int $cardinality | |
268 * The field cardinality. | |
269 * | |
270 * @return $this | |
271 */ | |
272 public function setCardinality($cardinality) { | |
273 $this->definition['cardinality'] = $cardinality; | |
274 return $this; | |
275 } | |
276 | |
277 /** | |
278 * {@inheritdoc} | |
279 */ | |
280 public function isMultiple() { | |
281 $cardinality = $this->getCardinality(); | |
282 return ($cardinality == static::CARDINALITY_UNLIMITED) || ($cardinality > 1); | |
283 } | |
284 | |
285 /** | |
286 * {@inheritdoc} | |
287 */ | |
288 public function isQueryable() { | |
289 @trigger_error('BaseFieldDefinition::isQueryable() is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, you should use \Drupal\Core\Field\BaseFieldDefinition::hasCustomStorage(). See https://www.drupal.org/node/2856563.', E_USER_DEPRECATED); | |
290 return !$this->hasCustomStorage(); | |
291 } | |
292 | |
293 /** | |
294 * Sets whether the field is queryable. | |
295 * | |
296 * @param bool $queryable | |
297 * Whether the field is queryable. | |
298 * | |
299 * @return static | |
300 * The object itself for chaining. | |
301 * | |
302 * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use | |
303 * \Drupal\Core\Field\BaseFieldDefinition::setCustomStorage() instead. | |
304 * | |
305 * @see https://www.drupal.org/node/2856563 | |
306 */ | |
307 public function setQueryable($queryable) { | |
308 @trigger_error('BaseFieldDefinition::setQueryable() is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, you should use \Drupal\Core\Field\BaseFieldDefinition::setCustomStorage(). See https://www.drupal.org/node/2856563.', E_USER_DEPRECATED); | |
309 $this->definition['queryable'] = $queryable; | |
310 return $this; | |
311 } | |
312 | |
313 /** | |
314 * Sets constraints for a given field item property. | |
315 * | |
316 * Note: this overwrites any existing property constraints. If you need to | |
317 * add to the existing constraints, use | |
318 * \Drupal\Core\Field\BaseFieldDefinition::addPropertyConstraints() | |
319 * | |
320 * @param string $name | |
321 * The name of the property to set constraints for. | |
322 * @param array $constraints | |
323 * The constraints to set. | |
324 * | |
325 * @return static | |
326 * The object itself for chaining. | |
327 */ | |
328 public function setPropertyConstraints($name, array $constraints) { | |
329 $item_constraints = $this->getItemDefinition()->getConstraints(); | |
330 $item_constraints['ComplexData'][$name] = $constraints; | |
331 $this->getItemDefinition()->setConstraints($item_constraints); | |
332 return $this; | |
333 } | |
334 | |
335 /** | |
336 * Adds constraints for a given field item property. | |
337 * | |
338 * Adds a constraint to a property of a base field item. e.g. | |
339 * @code | |
340 * // Limit the field item's value property to the range 0 through 10. | |
341 * // e.g. $node->size->value. | |
342 * $field->addPropertyConstraints('value', [ | |
343 * 'Range' => [ | |
344 * 'min' => 0, | |
345 * 'max' => 10, | |
346 * ] | |
347 * ]); | |
348 * @endcode | |
349 * | |
350 * If you want to add a validation constraint that applies to the | |
351 * \Drupal\Core\Field\FieldItemList, use BaseFieldDefinition::addConstraint() | |
352 * instead. | |
353 * | |
354 * Note: passing a new set of options for an existing property constraint will | |
355 * overwrite with the new options. | |
356 * | |
357 * @param string $name | |
358 * The name of the property to set constraints for. | |
359 * @param array $constraints | |
360 * The constraints to set. | |
361 * | |
362 * @return static | |
363 * The object itself for chaining. | |
364 * | |
365 * @see \Drupal\Core\Field\BaseFieldDefinition::addConstraint() | |
366 */ | |
367 public function addPropertyConstraints($name, array $constraints) { | |
368 $item_constraints = $this->getItemDefinition()->getConstraint('ComplexData') ?: []; | |
369 if (isset($item_constraints[$name])) { | |
370 // Add the new property constraints, overwriting as required. | |
371 $item_constraints[$name] = $constraints + $item_constraints[$name]; | |
372 } | |
373 else { | |
374 $item_constraints[$name] = $constraints; | |
375 } | |
376 $this->getItemDefinition()->addConstraint('ComplexData', $item_constraints); | |
377 return $this; | |
378 } | |
379 | |
380 /** | |
381 * Sets the display options for the field in forms or rendered entities. | |
382 * | |
383 * This enables generic rendering of the field with widgets / formatters, | |
384 * including automated support for "In place editing", and with optional | |
385 * configurability in the "Manage display" / "Manage form display" UI screens. | |
386 * | |
387 * Unless this method is called, the field remains invisible (or requires | |
388 * ad-hoc rendering logic). | |
389 * | |
390 * @param string $display_context | |
391 * The display context. Either 'view' or 'form'. | |
392 * @param array $options | |
393 * An array of display options. Refer to | |
394 * \Drupal\Core\Field\FieldDefinitionInterface::getDisplayOptions() for | |
395 * a list of supported keys. The options should include at least a 'weight', | |
396 * or specify 'type' = 'hidden'. The 'default_widget' / 'default_formatter' | |
397 * for the field type will be used if no 'type' is specified. | |
398 * | |
399 * @return static | |
400 * The object itself for chaining. | |
401 */ | |
402 public function setDisplayOptions($display_context, array $options) { | |
403 $this->definition['display'][$display_context]['options'] = $options; | |
404 return $this; | |
405 } | |
406 | |
407 /** | |
408 * Sets whether the display for the field can be configured. | |
409 * | |
410 * @param string $display_context | |
411 * The display context. Either 'view' or 'form'. | |
412 * @param bool $configurable | |
413 * Whether the display options can be configured (e.g., via the "Manage | |
414 * display" / "Manage form display" UI screens). If TRUE, the options | |
415 * specified via getDisplayOptions() act as defaults. | |
416 * | |
417 * @return static | |
418 * The object itself for chaining. | |
419 */ | |
420 public function setDisplayConfigurable($display_context, $configurable) { | |
421 // If no explicit display options have been specified, default to 'hidden'. | |
422 if (empty($this->definition['display'][$display_context])) { | |
423 $this->definition['display'][$display_context]['options'] = ['region' => 'hidden']; | |
424 } | |
425 $this->definition['display'][$display_context]['configurable'] = $configurable; | |
426 return $this; | |
427 } | |
428 | |
429 /** | |
430 * {@inheritdoc} | |
431 */ | |
432 public function getDisplayOptions($display_context) { | |
433 return isset($this->definition['display'][$display_context]['options']) ? $this->definition['display'][$display_context]['options'] : NULL; | |
434 } | |
435 | |
436 /** | |
437 * {@inheritdoc} | |
438 */ | |
439 public function isDisplayConfigurable($display_context) { | |
440 return isset($this->definition['display'][$display_context]['configurable']) ? $this->definition['display'][$display_context]['configurable'] : FALSE; | |
441 } | |
442 | |
443 /** | |
444 * {@inheritdoc} | |
445 */ | |
446 public function getDefaultValueLiteral() { | |
447 return isset($this->definition['default_value']) ? $this->definition['default_value'] : []; | |
448 } | |
449 | |
450 /** | |
451 * {@inheritdoc} | |
452 */ | |
453 public function getDefaultValueCallback() { | |
454 return isset($this->definition['default_value_callback']) ? $this->definition['default_value_callback'] : NULL; | |
455 } | |
456 | |
457 /** | |
458 * {@inheritdoc} | |
459 */ | |
460 public function getDefaultValue(FieldableEntityInterface $entity) { | |
461 // Allow custom default values function. | |
462 if ($callback = $this->getDefaultValueCallback()) { | |
463 $value = call_user_func($callback, $entity, $this); | |
464 } | |
465 else { | |
466 $value = $this->getDefaultValueLiteral(); | |
467 } | |
468 // Normalize into the "array keyed by delta" format. | |
469 if (isset($value) && !is_array($value)) { | |
470 $properties = $this->getPropertyNames(); | |
471 $property = reset($properties); | |
472 $value = [ | |
473 [$property => $value], | |
474 ]; | |
475 } | |
476 // Allow the field type to process default values. | |
477 $field_item_list_class = $this->getClass(); | |
478 return $field_item_list_class::processDefaultValue($value, $entity, $this); | |
479 } | |
480 | |
481 /** | |
482 * {@inheritdoc} | |
483 */ | |
484 public function setDefaultValue($value) { | |
485 if ($value === NULL) { | |
486 $value = []; | |
487 } | |
488 // Unless the value is an empty array, we may need to transform it. | |
489 if (!is_array($value) || !empty($value)) { | |
490 if (!is_array($value)) { | |
491 $value = [[$this->getMainPropertyName() => $value]]; | |
492 } | |
493 elseif (is_array($value) && !is_numeric(array_keys($value)[0])) { | |
494 $value = [0 => $value]; | |
495 } | |
496 } | |
497 $this->definition['default_value'] = $value; | |
498 return $this; | |
499 } | |
500 | |
501 /** | |
502 * {@inheritdoc} | |
503 */ | |
504 public function setDefaultValueCallback($callback) { | |
505 if (isset($callback) && !is_string($callback)) { | |
506 throw new \InvalidArgumentException('Default value callback must be a string, like "function_name" or "ClassName::methodName"'); | |
507 } | |
508 $this->definition['default_value_callback'] = $callback; | |
509 return $this; | |
510 } | |
511 | |
512 /** | |
513 * Returns the initial value for the field. | |
514 * | |
515 * @return array | |
516 * The initial value for the field, as a numerically indexed array of items, | |
517 * each item being a property/value array (array() for no default value). | |
518 */ | |
519 public function getInitialValue() { | |
520 $value = isset($this->definition['initial_value']) ? $this->definition['initial_value'] : []; | |
521 | |
522 // Normalize into the "array keyed by delta" format. | |
523 if (isset($value) && !is_array($value)) { | |
524 $value = [ | |
525 [$this->getMainPropertyName() => $value], | |
526 ]; | |
527 } | |
528 | |
529 return $value; | |
530 } | |
531 | |
532 /** | |
533 * Sets an initial value for the field. | |
534 * | |
535 * @param mixed $value | |
536 * The initial value for the field. This can be either: | |
537 * - a literal, in which case it will be assigned to the first property of | |
538 * the first item; | |
539 * - a numerically indexed array of items, each item being a property/value | |
540 * array; | |
541 * - a non-numerically indexed array, in which case the array is assumed to | |
542 * be a property/value array and used as the first item; | |
543 * - an empty array for no initial value. | |
544 * | |
545 * @return $this | |
546 */ | |
547 public function setInitialValue($value) { | |
548 // @todo Implement initial value support for multi-value fields in | |
549 // https://www.drupal.org/node/2883851. | |
550 if ($this->isMultiple()) { | |
551 throw new FieldException('Multi-value fields can not have an initial value.'); | |
552 } | |
553 | |
554 if ($value === NULL) { | |
555 $value = []; | |
556 } | |
557 // Unless the value is an empty array, we may need to transform it. | |
558 if (!is_array($value) || !empty($value)) { | |
559 if (!is_array($value)) { | |
560 $value = [[$this->getMainPropertyName() => $value]]; | |
561 } | |
562 elseif (is_array($value) && !is_numeric(array_keys($value)[0])) { | |
563 $value = [0 => $value]; | |
564 } | |
565 } | |
566 $this->definition['initial_value'] = $value; | |
567 | |
568 return $this; | |
569 } | |
570 | |
571 /** | |
572 * Returns the name of the field that will be used for getting initial values. | |
573 * | |
574 * @return string|null | |
575 * The field name. | |
576 */ | |
577 public function getInitialValueFromField() { | |
578 return isset($this->definition['initial_value_from_field']) ? $this->definition['initial_value_from_field'] : NULL; | |
579 } | |
580 | |
581 /** | |
582 * Sets a field that will be used for getting initial values. | |
583 * | |
584 * @param string $field_name | |
585 * The name of the field that will be used for getting initial values. | |
586 * | |
587 * @return $this | |
588 */ | |
589 public function setInitialValueFromField($field_name) { | |
590 $this->definition['initial_value_from_field'] = $field_name; | |
591 | |
592 return $this; | |
593 } | |
594 | |
595 /** | |
596 * {@inheritdoc} | |
597 */ | |
598 public function getOptionsProvider($property_name, FieldableEntityInterface $entity) { | |
599 // If the field item class implements the interface, create an orphaned | |
600 // runtime item object, so that it can be used as the options provider | |
601 // without modifying the entity being worked on. | |
602 if (is_subclass_of($this->getFieldItemClass(), OptionsProviderInterface::class)) { | |
603 $items = $entity->get($this->getName()); | |
604 return \Drupal::service('plugin.manager.field.field_type')->createFieldItem($items, 0); | |
605 } | |
606 // @todo: Allow setting custom options provider, see | |
607 // https://www.drupal.org/node/2002138. | |
608 } | |
609 | |
610 /** | |
611 * {@inheritdoc} | |
612 */ | |
613 public function getPropertyDefinition($name) { | |
614 if (!isset($this->propertyDefinitions)) { | |
615 $this->getPropertyDefinitions(); | |
616 } | |
617 if (isset($this->propertyDefinitions[$name])) { | |
618 return $this->propertyDefinitions[$name]; | |
619 } | |
620 } | |
621 | |
622 /** | |
623 * {@inheritdoc} | |
624 */ | |
625 public function getPropertyDefinitions() { | |
626 if (!isset($this->propertyDefinitions)) { | |
627 $class = $this->getFieldItemClass(); | |
628 $this->propertyDefinitions = $class::propertyDefinitions($this); | |
629 } | |
630 return $this->propertyDefinitions; | |
631 } | |
632 | |
633 /** | |
634 * {@inheritdoc} | |
635 */ | |
636 public function getPropertyNames() { | |
637 return array_keys($this->getPropertyDefinitions()); | |
638 } | |
639 | |
640 /** | |
641 * {@inheritdoc} | |
642 */ | |
643 public function getMainPropertyName() { | |
644 $class = $this->getFieldItemClass(); | |
645 return $class::mainPropertyName(); | |
646 } | |
647 | |
648 /** | |
649 * Helper to retrieve the field item class. | |
650 * | |
651 * @todo: Remove once getClass() adds in defaults. See | |
652 * https://www.drupal.org/node/2116341. | |
653 */ | |
654 protected function getFieldItemClass() { | |
655 if ($class = $this->getItemDefinition()->getClass()) { | |
656 return $class; | |
657 } | |
658 else { | |
659 $type_definition = \Drupal::typedDataManager() | |
660 ->getDefinition($this->getItemDefinition()->getDataType()); | |
661 return $type_definition['class']; | |
662 } | |
663 } | |
664 | |
665 /** | |
666 * {@inheritdoc} | |
667 */ | |
668 public function __sleep() { | |
669 // Do not serialize the statically cached property definitions. | |
670 $vars = get_object_vars($this); | |
671 unset($vars['propertyDefinitions'], $vars['typedDataManager']); | |
672 return array_keys($vars); | |
673 } | |
674 | |
675 /** | |
676 * {@inheritdoc} | |
677 */ | |
678 public function getTargetEntityTypeId() { | |
679 return isset($this->definition['entity_type']) ? $this->definition['entity_type'] : NULL; | |
680 } | |
681 | |
682 /** | |
683 * Sets the ID of the type of the entity this field is attached to. | |
684 * | |
685 * @param string $entity_type_id | |
686 * The name of the target entity type to set. | |
687 * | |
688 * @return $this | |
689 */ | |
690 public function setTargetEntityTypeId($entity_type_id) { | |
691 $this->definition['entity_type'] = $entity_type_id; | |
692 return $this; | |
693 } | |
694 | |
695 /** | |
696 * {@inheritdoc} | |
697 */ | |
698 public function getTargetBundle() { | |
699 return isset($this->definition['bundle']) ? $this->definition['bundle'] : NULL; | |
700 } | |
701 | |
702 /** | |
703 * Sets the bundle this field is defined for. | |
704 * | |
705 * @param string|null $bundle | |
706 * The bundle, or NULL if the field is not bundle-specific. | |
707 * | |
708 * @return $this | |
709 */ | |
710 public function setTargetBundle($bundle) { | |
711 $this->definition['bundle'] = $bundle; | |
712 return $this; | |
713 } | |
714 | |
715 /** | |
716 * {@inheritdoc} | |
717 */ | |
718 public function getSchema() { | |
719 if (!isset($this->schema)) { | |
720 // Get the schema from the field item class. | |
721 $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($this->getType()); | |
722 $class = $definition['class']; | |
723 $schema = $class::schema($this); | |
724 // Fill in default values. | |
725 $schema += [ | |
726 'columns' => [], | |
727 'unique keys' => [], | |
728 'indexes' => [], | |
729 'foreign keys' => [], | |
730 ]; | |
731 | |
732 // Merge custom indexes with those specified by the field type. Custom | |
733 // indexes prevail. | |
734 $schema['indexes'] = $this->indexes + $schema['indexes']; | |
735 | |
736 $this->schema = $schema; | |
737 } | |
738 | |
739 return $this->schema; | |
740 } | |
741 | |
742 /** | |
743 * {@inheritdoc} | |
744 */ | |
745 public function getColumns() { | |
746 $schema = $this->getSchema(); | |
747 // A typical use case for the method is to iterate on the columns, while | |
748 // some other use cases rely on identifying the first column with the key() | |
749 // function. Since the schema is persisted in the Field object, we take care | |
750 // of resetting the array pointer so that the former does not interfere with | |
751 // the latter. | |
752 reset($schema['columns']); | |
753 return $schema['columns']; | |
754 } | |
755 | |
756 /** | |
757 * {@inheritdoc} | |
758 */ | |
759 public function hasCustomStorage() { | |
760 return !empty($this->definition['custom_storage']) || $this->isComputed(); | |
761 } | |
762 | |
763 /** | |
764 * {@inheritdoc} | |
765 */ | |
766 public function isBaseField() { | |
767 return TRUE; | |
768 } | |
769 | |
770 /** | |
771 * Sets the storage behavior for this field. | |
772 * | |
773 * @param bool $custom_storage | |
774 * Pass FALSE if the storage takes care of storing the field, | |
775 * TRUE otherwise. | |
776 * | |
777 * @return $this | |
778 * | |
779 * @throws \LogicException | |
780 * Thrown if custom storage is to be set to FALSE for a computed field. | |
781 */ | |
782 public function setCustomStorage($custom_storage) { | |
783 if (!$custom_storage && $this->isComputed()) { | |
784 throw new \LogicException("Entity storage cannot store a computed field."); | |
785 } | |
786 $this->definition['custom_storage'] = $custom_storage; | |
787 return $this; | |
788 } | |
789 | |
790 /** | |
791 * {@inheritdoc} | |
792 */ | |
793 public function getFieldStorageDefinition() { | |
794 return $this; | |
795 } | |
796 | |
797 /** | |
798 * {@inheritdoc} | |
799 */ | |
800 public function getUniqueStorageIdentifier() { | |
801 return $this->getTargetEntityTypeId() . '-' . $this->getName(); | |
802 } | |
803 | |
804 /** | |
805 * {@inheritdoc} | |
806 */ | |
807 public function getConfig($bundle) { | |
808 $override = BaseFieldOverride::loadByName($this->getTargetEntityTypeId(), $bundle, $this->getName()); | |
809 if ($override) { | |
810 return $override; | |
811 } | |
812 return BaseFieldOverride::createFromBaseFieldDefinition($this, $bundle); | |
813 } | |
814 | |
815 /** | |
816 * {@inheritdoc} | |
817 */ | |
818 public function isStorageRequired() { | |
819 if (isset($this->definition['storage_required'])) { | |
820 return (bool) $this->definition['storage_required']; | |
821 } | |
822 | |
823 // Default to the 'required' property of the base field. | |
824 return $this->isRequired(); | |
825 } | |
826 | |
827 /** | |
828 * Sets whether the field storage is required. | |
829 * | |
830 * @param bool $required | |
831 * Whether the field storage is required. | |
832 * | |
833 * @return static | |
834 * The object itself for chaining. | |
835 */ | |
836 public function setStorageRequired($required) { | |
837 $this->definition['storage_required'] = $required; | |
838 return $this; | |
839 } | |
840 | |
841 } |