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