diff --git a/core/lib/Drupal/Core/TypedData/ListDataDefinition.php b/core/lib/Drupal/Core/TypedData/ListDataDefinition.php index b710a75..15fc998 100644 --- a/core/lib/Drupal/Core/TypedData/ListDataDefinition.php +++ b/core/lib/Drupal/Core/TypedData/ListDataDefinition.php @@ -6,6 +6,7 @@ */ namespace Drupal\Core\TypedData; +use ReflectionClass; /** * A typed data definition class for defining lists. @@ -112,4 +113,43 @@ public function setItemDefinition(DataDefinitionInterface $definition) { $this->itemDefinition = $definition; return $this; } + + /** + * {@inheritdoc} + */ + public function isComputed() { + if ($this->isComputedByClassInheritance()) { + return TRUE; + } + return parent::isComputed(); + } + + /** + * {@inheritdoc} + * @throws \LogicException + * Thrown if computed is to be set to FALSE for a field that requires to be computed by it's list class. + */ + public function setComputed($computed) { + if (!$computed && $this->isComputedByClassInheritance()) { + throw new \LogicException("The list class used enforces this field to be a computed field."); + } + return parent::setComputed($computed); + } + + /** + * Helper to deduce whether the the field should be computed based on it's list class. + * + * @return bool + * + * @see \Drupal\Core\Field\FieldItemListComputed + */ + protected function isComputedByClassInheritance() { + $class = $this->getClass(); + if (!empty($class)) { + $reflectionClass = new ReflectionClass($class); + return $reflectionClass->isSubclassOf('\Drupal\Core\Field\FieldItemListComputed'); + } + return FALSE; + + } } diff --git a/core/modules/field/tests/modules/field_computed_test/field_computed_test.module b/core/modules/field/tests/modules/field_computed_test/field_computed_test.module index 61fefe4..28bd677 100644 --- a/core/modules/field/tests/modules/field_computed_test/field_computed_test.module +++ b/core/modules/field/tests/modules/field_computed_test/field_computed_test.module @@ -21,9 +21,10 @@ function field_computed_test_entity_base_field_info(EntityTypeInterface $entity) )) ->setDisplayConfigurable('form', TRUE); + // set a custom list class an explicitly define the field to be computed $fields['field_dice_result'] = BaseFieldDefinition::create('integer') ->setLabel(t('Dice result')) - ->setClass('\Drupal\field_computed_test\Plugin\Field\FieldType\DiceFieldItemList') + ->setClass('\Drupal\field_computed_test\Plugin\Field\FieldType\DiceItemList') ->setComputed(TRUE) ->setDisplayOptions('view', array( 'label' => 'inline', @@ -31,6 +32,28 @@ function field_computed_test_entity_base_field_info(EntityTypeInterface $entity) 'weight' => 0, )); + // set a custom list class and rely on that class to mark the field as computed + $fields['field_dice_result_v2'] = BaseFieldDefinition::create('integer') + ->setLabel(t('Dice result V2')) + ->setClass('\Drupal\field_computed_test\Plugin\Field\FieldType\DiceItemList') + ->setDisplayOptions('view', array( + 'label' => 'inline', + 'type' => 'number_integer', + 'weight' => 0, + )); + + // use a field type which uses a list class that marks the field as computed + $fields['field_dice_result_v3'] = BaseFieldDefinition::create('dice') + ->setLabel(t('Dice result V3')) + ->setDisplayOptions('view', array( + 'label' => 'inline', + 'weight' => 0, + )) + ->setDisplayOptions('form', array( + 'type' => 'integer', + 'weight' => 10, + )); + return $fields; } diff --git a/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldFormatter/DiceFormatter.php b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldFormatter/DiceFormatter.php new file mode 100644 index 0000000..09a106b --- /dev/null +++ b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldFormatter/DiceFormatter.php @@ -0,0 +1,32 @@ + $item) { + $elements[$delta] = [ + '#markup' => 'The value: '. $item->value, + ]; + } + return $elements; + } +} diff --git a/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceFieldItemList.php b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceFieldItemList.php deleted file mode 100644 index 5b4e087..0000000 --- a/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceFieldItemList.php +++ /dev/null @@ -1,24 +0,0 @@ -getEntity()->field_dice_count->value; - $values = []; - foreach (range(0, $items_count - 1) as $delta) { - $values[$delta] = [ - 'value' => rand(1, 6) - ]; - } - return $values; - } -} diff --git a/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceItem.php b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceItem.php new file mode 100644 index 0000000..c0061b1 --- /dev/null +++ b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceItem.php @@ -0,0 +1,35 @@ +setLabel(t('Integer value')); + return $properties; + } + + /** + * {@inheritdoc} + */ + public static function schema(FieldStorageDefinitionInterface $field_definition) { + return []; + } +} diff --git a/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceItemList.php b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceItemList.php new file mode 100644 index 0000000..a71f274 --- /dev/null +++ b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/DiceItemList.php @@ -0,0 +1,24 @@ +getEntity()->field_dice_count->value; + $values = []; + foreach (range(0, $items_count - 1) as $delta) { + $values[$delta] = [ + 'value' => rand(1, 6) + ]; + } + return $values; + } +} diff --git a/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldWidget/DiceWidget.php b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldWidget/DiceWidget.php new file mode 100644 index 0000000..9e22a97 --- /dev/null +++ b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldWidget/DiceWidget.php @@ -0,0 +1,30 @@ + 'This is a computed field that contains a number of random values where the amount of items depends on value of the field_dice_count field on the same entity.', + ]; + return $element; + } +}