Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\Field;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Core\Config\Entity\ConfigEntityBase;
|
Chris@0
|
6 use Drupal\Core\Entity\EntityStorageInterface;
|
Chris@0
|
7 use Drupal\Core\Entity\FieldableEntityInterface;
|
Chris@0
|
8 use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@0
|
11 * Base class for configurable field definitions.
|
Chris@0
|
12 */
|
Chris@0
|
13 abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigInterface {
|
Chris@0
|
14
|
Chris@17
|
15 use FieldInputValueNormalizerTrait;
|
Chris@17
|
16
|
Chris@0
|
17 /**
|
Chris@0
|
18 * The field ID.
|
Chris@0
|
19 *
|
Chris@0
|
20 * The ID consists of 3 parts: the entity type, bundle and the field name.
|
Chris@0
|
21 *
|
Chris@0
|
22 * Example: node.article.body, user.user.field_main_image.
|
Chris@0
|
23 *
|
Chris@0
|
24 * @var string
|
Chris@0
|
25 */
|
Chris@0
|
26 protected $id;
|
Chris@0
|
27
|
Chris@0
|
28 /**
|
Chris@0
|
29 * The field name.
|
Chris@0
|
30 *
|
Chris@0
|
31 * @var string
|
Chris@0
|
32 */
|
Chris@0
|
33 protected $field_name;
|
Chris@0
|
34
|
Chris@0
|
35 /**
|
Chris@0
|
36 * The field type.
|
Chris@0
|
37 *
|
Chris@0
|
38 * This property is denormalized from the field storage for optimization of
|
Chris@0
|
39 * the "entity and render cache hits" critical paths. If not present in the
|
Chris@0
|
40 * $values passed to create(), it is populated from the field storage in
|
Chris@0
|
41 * postCreate(), and saved in config records so that it is present on
|
Chris@0
|
42 * subsequent loads.
|
Chris@0
|
43 *
|
Chris@0
|
44 * @var string
|
Chris@0
|
45 */
|
Chris@0
|
46 protected $field_type;
|
Chris@0
|
47
|
Chris@0
|
48 /**
|
Chris@0
|
49 * The name of the entity type the field is attached to.
|
Chris@0
|
50 *
|
Chris@0
|
51 * @var string
|
Chris@0
|
52 */
|
Chris@0
|
53 protected $entity_type;
|
Chris@0
|
54
|
Chris@0
|
55 /**
|
Chris@0
|
56 * The name of the bundle the field is attached to.
|
Chris@0
|
57 *
|
Chris@0
|
58 * @var string
|
Chris@0
|
59 */
|
Chris@0
|
60 protected $bundle;
|
Chris@0
|
61
|
Chris@0
|
62 /**
|
Chris@0
|
63 * The human-readable label for the field.
|
Chris@0
|
64 *
|
Chris@0
|
65 * This will be used as the title of Form API elements for the field in entity
|
Chris@0
|
66 * edit forms, or as the label for the field values in displayed entities.
|
Chris@0
|
67 *
|
Chris@0
|
68 * If not specified, this defaults to the field_name (mostly useful for fields
|
Chris@0
|
69 * created in tests).
|
Chris@0
|
70 *
|
Chris@0
|
71 * @var string
|
Chris@0
|
72 */
|
Chris@0
|
73 protected $label;
|
Chris@0
|
74
|
Chris@0
|
75 /**
|
Chris@0
|
76 * The field description.
|
Chris@0
|
77 *
|
Chris@0
|
78 * A human-readable description for the field when used with this bundle.
|
Chris@0
|
79 * For example, the description will be the help text of Form API elements for
|
Chris@0
|
80 * this field in entity edit forms.
|
Chris@0
|
81 *
|
Chris@0
|
82 * @var string
|
Chris@0
|
83 */
|
Chris@0
|
84 protected $description = '';
|
Chris@0
|
85
|
Chris@0
|
86 /**
|
Chris@0
|
87 * Field-type specific settings.
|
Chris@0
|
88 *
|
Chris@0
|
89 * An array of key/value pairs. The keys and default values are defined by the
|
Chris@0
|
90 * field type.
|
Chris@0
|
91 *
|
Chris@0
|
92 * @var array
|
Chris@0
|
93 */
|
Chris@0
|
94 protected $settings = [];
|
Chris@0
|
95
|
Chris@0
|
96 /**
|
Chris@0
|
97 * Flag indicating whether the field is required.
|
Chris@0
|
98 *
|
Chris@0
|
99 * TRUE if a value for this field is required when used with this bundle,
|
Chris@0
|
100 * FALSE otherwise. Currently, required-ness is only enforced at the Form API
|
Chris@0
|
101 * level in entity edit forms, not during direct API saves.
|
Chris@0
|
102 *
|
Chris@0
|
103 * @var bool
|
Chris@0
|
104 */
|
Chris@0
|
105 protected $required = FALSE;
|
Chris@0
|
106
|
Chris@0
|
107 /**
|
Chris@0
|
108 * Flag indicating whether the field is translatable.
|
Chris@0
|
109 *
|
Chris@0
|
110 * Defaults to TRUE.
|
Chris@0
|
111 *
|
Chris@0
|
112 * @var bool
|
Chris@0
|
113 */
|
Chris@0
|
114 protected $translatable = TRUE;
|
Chris@0
|
115
|
Chris@0
|
116 /**
|
Chris@0
|
117 * Default field value.
|
Chris@0
|
118 *
|
Chris@0
|
119 * The default value is used when an entity is created, either:
|
Chris@0
|
120 * - through an entity creation form; the form elements for the field are
|
Chris@0
|
121 * prepopulated with the default value.
|
Chris@0
|
122 * - through direct API calls (i.e. $entity->save()); the default value is
|
Chris@0
|
123 * added if the $entity object provides no explicit entry (actual values or
|
Chris@0
|
124 * "the field is empty") for the field.
|
Chris@0
|
125 *
|
Chris@0
|
126 * The default value is expressed as a numerically indexed array of items,
|
Chris@0
|
127 * each item being an array of key/value pairs matching the set of 'columns'
|
Chris@0
|
128 * defined by the "field schema" for the field type, as exposed in
|
Chris@0
|
129 * hook_field_schema(). If the number of items exceeds the cardinality of the
|
Chris@0
|
130 * field, extraneous items will be ignored.
|
Chris@0
|
131 *
|
Chris@0
|
132 * This property is overlooked if the $default_value_callback is non-empty.
|
Chris@0
|
133 *
|
Chris@0
|
134 * Example for a integer field:
|
Chris@0
|
135 * @code
|
Chris@0
|
136 * array(
|
Chris@0
|
137 * array('value' => 1),
|
Chris@0
|
138 * array('value' => 2),
|
Chris@0
|
139 * )
|
Chris@0
|
140 * @endcode
|
Chris@0
|
141 *
|
Chris@0
|
142 * @var array
|
Chris@0
|
143 */
|
Chris@0
|
144 protected $default_value = [];
|
Chris@0
|
145
|
Chris@0
|
146 /**
|
Chris@0
|
147 * The name of a callback function that returns default values.
|
Chris@0
|
148 *
|
Chris@0
|
149 * The function will be called with the following arguments:
|
Chris@0
|
150 * - \Drupal\Core\Entity\FieldableEntityInterface $entity
|
Chris@0
|
151 * The entity being created.
|
Chris@0
|
152 * - \Drupal\Core\Field\FieldDefinitionInterface $definition
|
Chris@0
|
153 * The field definition.
|
Chris@0
|
154 * It should return an array of default values, in the same format as the
|
Chris@0
|
155 * $default_value property.
|
Chris@0
|
156 *
|
Chris@0
|
157 * This property takes precedence on the list of fixed values specified in the
|
Chris@0
|
158 * $default_value property.
|
Chris@0
|
159 *
|
Chris@0
|
160 * @var string
|
Chris@0
|
161 */
|
Chris@0
|
162 protected $default_value_callback = '';
|
Chris@0
|
163
|
Chris@0
|
164 /**
|
Chris@0
|
165 * The field storage object.
|
Chris@0
|
166 *
|
Chris@0
|
167 * @var \Drupal\Core\Field\FieldStorageDefinitionInterface
|
Chris@0
|
168 */
|
Chris@0
|
169 protected $fieldStorage;
|
Chris@0
|
170
|
Chris@0
|
171 /**
|
Chris@0
|
172 * The data definition of a field item.
|
Chris@0
|
173 *
|
Chris@0
|
174 * @var \Drupal\Core\Field\TypedData\FieldItemDataDefinition
|
Chris@0
|
175 */
|
Chris@0
|
176 protected $itemDefinition;
|
Chris@0
|
177
|
Chris@0
|
178 /**
|
Chris@0
|
179 * Array of constraint options keyed by constraint plugin ID.
|
Chris@0
|
180 *
|
Chris@0
|
181 * @var array
|
Chris@0
|
182 */
|
Chris@0
|
183 protected $constraints = [];
|
Chris@0
|
184
|
Chris@0
|
185 /**
|
Chris@0
|
186 * Array of property constraint options keyed by property ID. The values are
|
Chris@0
|
187 * associative array of constraint options keyed by constraint plugin ID.
|
Chris@0
|
188 *
|
Chris@0
|
189 * @var array[]
|
Chris@0
|
190 */
|
Chris@0
|
191 protected $propertyConstraints = [];
|
Chris@0
|
192
|
Chris@0
|
193 /**
|
Chris@0
|
194 * {@inheritdoc}
|
Chris@0
|
195 */
|
Chris@0
|
196 public function id() {
|
Chris@0
|
197 return $this->entity_type . '.' . $this->bundle . '.' . $this->field_name;
|
Chris@0
|
198 }
|
Chris@0
|
199
|
Chris@0
|
200 /**
|
Chris@0
|
201 * {@inheritdoc}
|
Chris@0
|
202 */
|
Chris@0
|
203 public function getName() {
|
Chris@0
|
204 return $this->field_name;
|
Chris@0
|
205 }
|
Chris@0
|
206
|
Chris@0
|
207 /**
|
Chris@0
|
208 * {@inheritdoc}
|
Chris@0
|
209 */
|
Chris@0
|
210 public function getType() {
|
Chris@0
|
211 return $this->field_type;
|
Chris@0
|
212 }
|
Chris@0
|
213
|
Chris@0
|
214 /**
|
Chris@0
|
215 * {@inheritdoc}
|
Chris@0
|
216 */
|
Chris@0
|
217 public function getTargetEntityTypeId() {
|
Chris@0
|
218 return $this->entity_type;
|
Chris@0
|
219 }
|
Chris@0
|
220
|
Chris@0
|
221 /**
|
Chris@0
|
222 * {@inheritdoc}
|
Chris@0
|
223 */
|
Chris@0
|
224 public function getTargetBundle() {
|
Chris@0
|
225 return $this->bundle;
|
Chris@0
|
226 }
|
Chris@0
|
227
|
Chris@0
|
228 /**
|
Chris@0
|
229 * {@inheritdoc}
|
Chris@0
|
230 */
|
Chris@0
|
231 public function calculateDependencies() {
|
Chris@0
|
232 parent::calculateDependencies();
|
Chris@0
|
233 // Add dependencies from the field type plugin. We can not use
|
Chris@0
|
234 // self::calculatePluginDependencies() because instantiation of a field item
|
Chris@0
|
235 // plugin requires a parent entity.
|
Chris@0
|
236 /** @var $field_type_manager \Drupal\Core\Field\FieldTypePluginManagerInterface */
|
Chris@0
|
237 $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
Chris@0
|
238 $definition = $field_type_manager->getDefinition($this->getType());
|
Chris@0
|
239 $this->addDependency('module', $definition['provider']);
|
Chris@0
|
240 // Plugins can declare additional dependencies in their definition.
|
Chris@0
|
241 if (isset($definition['config_dependencies'])) {
|
Chris@0
|
242 $this->addDependencies($definition['config_dependencies']);
|
Chris@0
|
243 }
|
Chris@0
|
244 // Let the field type plugin specify its own dependencies.
|
Chris@0
|
245 // @see \Drupal\Core\Field\FieldItemInterface::calculateDependencies()
|
Chris@0
|
246 $this->addDependencies($definition['class']::calculateDependencies($this));
|
Chris@0
|
247
|
Chris@0
|
248 // Create dependency on the bundle.
|
Chris@18
|
249 $bundle_config_dependency = $this->entityTypeManager()->getDefinition($this->entity_type)->getBundleConfigDependency($this->bundle);
|
Chris@0
|
250 $this->addDependency($bundle_config_dependency['type'], $bundle_config_dependency['name']);
|
Chris@0
|
251
|
Chris@0
|
252 return $this;
|
Chris@0
|
253 }
|
Chris@0
|
254
|
Chris@0
|
255 /**
|
Chris@0
|
256 * {@inheritdoc}
|
Chris@0
|
257 */
|
Chris@0
|
258 public function onDependencyRemoval(array $dependencies) {
|
Chris@0
|
259 $changed = parent::onDependencyRemoval($dependencies);
|
Chris@0
|
260 $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
Chris@0
|
261 $definition = $field_type_manager->getDefinition($this->getType());
|
Chris@0
|
262 if ($definition['class']::onDependencyRemoval($this, $dependencies)) {
|
Chris@0
|
263 $changed = TRUE;
|
Chris@0
|
264 }
|
Chris@0
|
265 return $changed;
|
Chris@0
|
266 }
|
Chris@0
|
267
|
Chris@0
|
268 /**
|
Chris@0
|
269 * {@inheritdoc}
|
Chris@0
|
270 */
|
Chris@0
|
271 public function postCreate(EntityStorageInterface $storage) {
|
Chris@0
|
272 parent::postCreate($storage);
|
Chris@0
|
273 // If it was not present in the $values passed to create(), (e.g. for
|
Chris@0
|
274 // programmatic creation), populate the denormalized field_type property
|
Chris@0
|
275 // from the field storage, so that it gets saved in the config record.
|
Chris@0
|
276 if (empty($this->field_type)) {
|
Chris@0
|
277 $this->field_type = $this->getFieldStorageDefinition()->getType();
|
Chris@0
|
278 }
|
Chris@0
|
279 }
|
Chris@0
|
280
|
Chris@0
|
281 /**
|
Chris@0
|
282 * {@inheritdoc}
|
Chris@0
|
283 */
|
Chris@0
|
284 public function postSave(EntityStorageInterface $storage, $update = TRUE) {
|
Chris@0
|
285 // Clear the cache.
|
Chris@18
|
286 \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
|
Chris@0
|
287
|
Chris@0
|
288 // Invalidate the render cache for all affected entities.
|
Chris@0
|
289 $entity_type = $this->getFieldStorageDefinition()->getTargetEntityTypeId();
|
Chris@18
|
290 if ($this->entityTypeManager()->hasHandler($entity_type, 'view_builder')) {
|
Chris@18
|
291 $this->entityTypeManager()->getViewBuilder($entity_type)->resetCache();
|
Chris@0
|
292 }
|
Chris@0
|
293 }
|
Chris@0
|
294
|
Chris@0
|
295 /**
|
Chris@0
|
296 * {@inheritdoc}
|
Chris@0
|
297 */
|
Chris@0
|
298 public function getLabel() {
|
Chris@0
|
299 return $this->label();
|
Chris@0
|
300 }
|
Chris@0
|
301
|
Chris@0
|
302 /**
|
Chris@0
|
303 * {@inheritdoc}
|
Chris@0
|
304 */
|
Chris@0
|
305 public function setLabel($label) {
|
Chris@0
|
306 $this->label = $label;
|
Chris@0
|
307 return $this;
|
Chris@0
|
308 }
|
Chris@0
|
309
|
Chris@0
|
310 /**
|
Chris@0
|
311 * {@inheritdoc}
|
Chris@0
|
312 */
|
Chris@0
|
313 public function getDescription() {
|
Chris@0
|
314 return $this->description;
|
Chris@0
|
315 }
|
Chris@0
|
316
|
Chris@0
|
317 /**
|
Chris@0
|
318 * {@inheritdoc}
|
Chris@0
|
319 */
|
Chris@0
|
320 public function setDescription($description) {
|
Chris@0
|
321 $this->description = $description;
|
Chris@0
|
322 return $this;
|
Chris@0
|
323 }
|
Chris@0
|
324
|
Chris@0
|
325 /**
|
Chris@0
|
326 * {@inheritdoc}
|
Chris@0
|
327 */
|
Chris@0
|
328 public function isTranslatable() {
|
Chris@0
|
329 // A field can be enabled for translation only if translation is supported.
|
Chris@0
|
330 return $this->translatable && $this->getFieldStorageDefinition()->isTranslatable();
|
Chris@0
|
331 }
|
Chris@0
|
332
|
Chris@0
|
333 /**
|
Chris@0
|
334 * {@inheritdoc}
|
Chris@0
|
335 */
|
Chris@0
|
336 public function setTranslatable($translatable) {
|
Chris@0
|
337 $this->translatable = $translatable;
|
Chris@0
|
338 return $this;
|
Chris@0
|
339 }
|
Chris@0
|
340
|
Chris@0
|
341 /**
|
Chris@0
|
342 * {@inheritdoc}
|
Chris@0
|
343 */
|
Chris@0
|
344 public function getSettings() {
|
Chris@0
|
345 return $this->settings + $this->getFieldStorageDefinition()->getSettings();
|
Chris@0
|
346 }
|
Chris@0
|
347
|
Chris@0
|
348 /**
|
Chris@0
|
349 * {@inheritdoc}
|
Chris@0
|
350 */
|
Chris@0
|
351 public function setSettings(array $settings) {
|
Chris@0
|
352 $this->settings = $settings + $this->settings;
|
Chris@0
|
353 return $this;
|
Chris@0
|
354 }
|
Chris@0
|
355
|
Chris@0
|
356 /**
|
Chris@0
|
357 * {@inheritdoc}
|
Chris@0
|
358 */
|
Chris@0
|
359 public function getSetting($setting_name) {
|
Chris@0
|
360 if (array_key_exists($setting_name, $this->settings)) {
|
Chris@0
|
361 return $this->settings[$setting_name];
|
Chris@0
|
362 }
|
Chris@0
|
363 else {
|
Chris@0
|
364 return $this->getFieldStorageDefinition()->getSetting($setting_name);
|
Chris@0
|
365 }
|
Chris@0
|
366 }
|
Chris@0
|
367
|
Chris@0
|
368 /**
|
Chris@0
|
369 * {@inheritdoc}
|
Chris@0
|
370 */
|
Chris@0
|
371 public function setSetting($setting_name, $value) {
|
Chris@0
|
372 $this->settings[$setting_name] = $value;
|
Chris@0
|
373 return $this;
|
Chris@0
|
374 }
|
Chris@0
|
375
|
Chris@0
|
376 /**
|
Chris@0
|
377 * {@inheritdoc}
|
Chris@0
|
378 */
|
Chris@0
|
379 public function isRequired() {
|
Chris@0
|
380 return $this->required;
|
Chris@0
|
381 }
|
Chris@0
|
382
|
Chris@0
|
383 /**
|
Chris@0
|
384 * [@inheritdoc}
|
Chris@0
|
385 */
|
Chris@0
|
386 public function setRequired($required) {
|
Chris@0
|
387 $this->required = $required;
|
Chris@0
|
388 return $this;
|
Chris@0
|
389 }
|
Chris@0
|
390
|
Chris@0
|
391 /**
|
Chris@0
|
392 * {@inheritdoc}
|
Chris@0
|
393 */
|
Chris@0
|
394 public function getDefaultValue(FieldableEntityInterface $entity) {
|
Chris@0
|
395 // Allow custom default values function.
|
Chris@0
|
396 if ($callback = $this->getDefaultValueCallback()) {
|
Chris@0
|
397 $value = call_user_func($callback, $entity, $this);
|
Chris@17
|
398 $value = $this->normalizeValue($value, $this->getFieldStorageDefinition()->getMainPropertyName());
|
Chris@0
|
399 }
|
Chris@0
|
400 else {
|
Chris@0
|
401 $value = $this->getDefaultValueLiteral();
|
Chris@0
|
402 }
|
Chris@0
|
403 // Allow the field type to process default values.
|
Chris@0
|
404 $field_item_list_class = $this->getClass();
|
Chris@0
|
405 return $field_item_list_class::processDefaultValue($value, $entity, $this);
|
Chris@0
|
406 }
|
Chris@0
|
407
|
Chris@0
|
408 /**
|
Chris@0
|
409 * {@inheritdoc}
|
Chris@0
|
410 */
|
Chris@0
|
411 public function getDefaultValueLiteral() {
|
Chris@0
|
412 return $this->default_value;
|
Chris@0
|
413 }
|
Chris@0
|
414
|
Chris@0
|
415 /**
|
Chris@0
|
416 * {@inheritdoc}
|
Chris@0
|
417 */
|
Chris@0
|
418 public function setDefaultValue($value) {
|
Chris@17
|
419 $this->default_value = $this->normalizeValue($value, $this->getFieldStorageDefinition()->getMainPropertyName());
|
Chris@0
|
420 return $this;
|
Chris@0
|
421 }
|
Chris@0
|
422
|
Chris@0
|
423 /**
|
Chris@0
|
424 * {@inheritdoc}
|
Chris@0
|
425 */
|
Chris@0
|
426 public function getDefaultValueCallback() {
|
Chris@0
|
427 return $this->default_value_callback;
|
Chris@0
|
428 }
|
Chris@0
|
429
|
Chris@0
|
430 /**
|
Chris@0
|
431 * {@inheritdoc}
|
Chris@0
|
432 */
|
Chris@0
|
433 public function setDefaultValueCallback($callback) {
|
Chris@0
|
434 $this->default_value_callback = $callback;
|
Chris@0
|
435 return $this;
|
Chris@0
|
436 }
|
Chris@0
|
437
|
Chris@0
|
438 /**
|
Chris@0
|
439 * Implements the magic __sleep() method.
|
Chris@0
|
440 *
|
Chris@0
|
441 * Using the Serialize interface and serialize() / unserialize() methods
|
Chris@0
|
442 * breaks entity forms in PHP 5.4.
|
Chris@0
|
443 * @todo Investigate in https://www.drupal.org/node/2074253.
|
Chris@0
|
444 */
|
Chris@0
|
445 public function __sleep() {
|
Chris@0
|
446 // Only serialize necessary properties, excluding those that can be
|
Chris@0
|
447 // recalculated.
|
Chris@0
|
448 $properties = get_object_vars($this);
|
Chris@0
|
449 unset($properties['fieldStorage'], $properties['itemDefinition'], $properties['original']);
|
Chris@0
|
450 return array_keys($properties);
|
Chris@0
|
451 }
|
Chris@0
|
452
|
Chris@0
|
453 /**
|
Chris@0
|
454 * {@inheritdoc}
|
Chris@0
|
455 */
|
Chris@0
|
456 public static function createFromItemType($item_type) {
|
Chris@0
|
457 // Forward to the field definition class for creating new data definitions
|
Chris@0
|
458 // via the typed manager.
|
Chris@0
|
459 return BaseFieldDefinition::createFromItemType($item_type);
|
Chris@0
|
460 }
|
Chris@0
|
461
|
Chris@0
|
462 /**
|
Chris@0
|
463 * {@inheritdoc}
|
Chris@0
|
464 */
|
Chris@0
|
465 public static function createFromDataType($type) {
|
Chris@0
|
466 // Forward to the field definition class for creating new data definitions
|
Chris@0
|
467 // via the typed manager.
|
Chris@0
|
468 return BaseFieldDefinition::createFromDataType($type);
|
Chris@0
|
469 }
|
Chris@0
|
470
|
Chris@0
|
471 /**
|
Chris@0
|
472 * {@inheritdoc}
|
Chris@0
|
473 */
|
Chris@0
|
474 public function getDataType() {
|
Chris@0
|
475 return 'list';
|
Chris@0
|
476 }
|
Chris@0
|
477
|
Chris@0
|
478 /**
|
Chris@0
|
479 * {@inheritdoc}
|
Chris@0
|
480 */
|
Chris@0
|
481 public function isList() {
|
Chris@0
|
482 return TRUE;
|
Chris@0
|
483 }
|
Chris@0
|
484
|
Chris@0
|
485 /**
|
Chris@0
|
486 * {@inheritdoc}
|
Chris@0
|
487 */
|
Chris@0
|
488 public function getClass() {
|
Chris@0
|
489 // Derive list class from the field type.
|
Chris@0
|
490 $type_definition = \Drupal::service('plugin.manager.field.field_type')
|
Chris@0
|
491 ->getDefinition($this->getType());
|
Chris@0
|
492 return $type_definition['list_class'];
|
Chris@0
|
493 }
|
Chris@0
|
494
|
Chris@0
|
495 /**
|
Chris@0
|
496 * {@inheritdoc}
|
Chris@0
|
497 */
|
Chris@0
|
498 public function getConstraints() {
|
Chris@0
|
499 return \Drupal::typedDataManager()->getDefaultConstraints($this) + $this->constraints;
|
Chris@0
|
500 }
|
Chris@0
|
501
|
Chris@0
|
502 /**
|
Chris@0
|
503 * {@inheritdoc}
|
Chris@0
|
504 */
|
Chris@0
|
505 public function getConstraint($constraint_name) {
|
Chris@0
|
506 $constraints = $this->getConstraints();
|
Chris@0
|
507 return isset($constraints[$constraint_name]) ? $constraints[$constraint_name] : NULL;
|
Chris@0
|
508 }
|
Chris@0
|
509
|
Chris@0
|
510 /**
|
Chris@0
|
511 * {@inheritdoc}
|
Chris@0
|
512 */
|
Chris@0
|
513 public function getItemDefinition() {
|
Chris@0
|
514 if (!isset($this->itemDefinition)) {
|
Chris@0
|
515 $this->itemDefinition = FieldItemDataDefinition::create($this)
|
Chris@0
|
516 ->setSettings($this->getSettings());
|
Chris@0
|
517
|
Chris@0
|
518 // Add any custom property constraints, overwriting as required.
|
Chris@0
|
519 $item_constraints = $this->itemDefinition->getConstraint('ComplexData') ?: [];
|
Chris@0
|
520 foreach ($this->propertyConstraints as $name => $constraints) {
|
Chris@0
|
521 if (isset($item_constraints[$name])) {
|
Chris@0
|
522 $item_constraints[$name] = $constraints + $item_constraints[$name];
|
Chris@0
|
523 }
|
Chris@0
|
524 else {
|
Chris@0
|
525 $item_constraints[$name] = $constraints;
|
Chris@0
|
526 }
|
Chris@0
|
527 $this->itemDefinition->addConstraint('ComplexData', $item_constraints);
|
Chris@0
|
528 }
|
Chris@0
|
529 }
|
Chris@0
|
530
|
Chris@0
|
531 return $this->itemDefinition;
|
Chris@0
|
532 }
|
Chris@0
|
533
|
Chris@0
|
534 /**
|
Chris@0
|
535 * {@inheritdoc}
|
Chris@0
|
536 */
|
Chris@0
|
537 public function getConfig($bundle) {
|
Chris@0
|
538 return $this;
|
Chris@0
|
539 }
|
Chris@0
|
540
|
Chris@0
|
541 /**
|
Chris@0
|
542 * {@inheritdoc}
|
Chris@0
|
543 */
|
Chris@0
|
544 public function setConstraints(array $constraints) {
|
Chris@0
|
545 $this->constraints = $constraints;
|
Chris@0
|
546 return $this;
|
Chris@0
|
547 }
|
Chris@0
|
548
|
Chris@0
|
549 /**
|
Chris@0
|
550 * {@inheritdoc}
|
Chris@0
|
551 */
|
Chris@0
|
552 public function addConstraint($constraint_name, $options = NULL) {
|
Chris@0
|
553 $this->constraints[$constraint_name] = $options;
|
Chris@0
|
554 return $this;
|
Chris@0
|
555 }
|
Chris@0
|
556
|
Chris@0
|
557 /**
|
Chris@0
|
558 * {@inheritdoc}
|
Chris@0
|
559 */
|
Chris@0
|
560 public function setPropertyConstraints($name, array $constraints) {
|
Chris@0
|
561 $this->propertyConstraints[$name] = $constraints;
|
Chris@0
|
562
|
Chris@0
|
563 // Reset the field item definition so the next time it is instantiated it
|
Chris@0
|
564 // will receive the new constraints.
|
Chris@0
|
565 $this->itemDefinition = NULL;
|
Chris@0
|
566
|
Chris@0
|
567 return $this;
|
Chris@0
|
568 }
|
Chris@0
|
569
|
Chris@0
|
570 /**
|
Chris@0
|
571 * {@inheritdoc}
|
Chris@0
|
572 */
|
Chris@0
|
573 public function addPropertyConstraints($name, array $constraints) {
|
Chris@0
|
574 foreach ($constraints as $constraint_name => $options) {
|
Chris@0
|
575 $this->propertyConstraints[$name][$constraint_name] = $options;
|
Chris@0
|
576 }
|
Chris@0
|
577
|
Chris@0
|
578 // Reset the field item definition so the next time it is instantiated it
|
Chris@0
|
579 // will receive the new constraints.
|
Chris@0
|
580 $this->itemDefinition = NULL;
|
Chris@0
|
581
|
Chris@0
|
582 return $this;
|
Chris@0
|
583 }
|
Chris@0
|
584
|
Chris@14
|
585 /**
|
Chris@14
|
586 * {@inheritdoc}
|
Chris@14
|
587 */
|
Chris@14
|
588 public function isInternal() {
|
Chris@14
|
589 // Respect the definition, otherwise default to TRUE for computed fields.
|
Chris@14
|
590 if (isset($this->definition['internal'])) {
|
Chris@14
|
591 return $this->definition['internal'];
|
Chris@14
|
592 }
|
Chris@14
|
593 return $this->isComputed();
|
Chris@14
|
594 }
|
Chris@14
|
595
|
Chris@0
|
596 }
|