diff -u b/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php --- b/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -443,7 +443,9 @@ // Get the values of instantiated field objects, only serialize the values. foreach ($this->fields as $name => $fields) { foreach ($fields as $langcode => $field) { - $this->values[$name][$langcode] = $field->getValue(); + if(!$field->isComputed()){ + $this->values[$name][$langcode] = $field->getValue(); + } } } $this->fields = []; diff -u b/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php --- b/core/lib/Drupal/Core/Field/FieldItemList.php +++ b/core/lib/Drupal/Core/Field/FieldItemList.php @@ -163,14 +163,14 @@ * {@inheritdoc} */ public function isComputed() { - return $this instanceof FieldItemListComputedInterface; + return $this->getFieldDefinition()->isComputed(); } /** * {@inheritdoc} */ public function setComputedValues() { - $this->list = $this->computeValues(); + $this->setValue($this->getValue()); $errors = $this->validate()->getIterator(); if ($errors->current()) { throw new FieldException($errors->current()->getMessage()); reverted: --- b/core/lib/Drupal/Core/Field/FieldItemListComputedInterface.php +++ /dev/null @@ -1,20 +0,0 @@ -setValue($value, FALSE); } - elseif ($property instanceof FieldItemListComputedInterface) { + elseif ($property instanceof FieldItemList && $property->isComputed()) { // Populate the computed list with values as there are no initial values // to set. $property->setComputedValues(); diff -u b/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 --- b/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 @@ -28,6 +28,7 @@ ->setClass(ComputedValuesItemList::class) ->setSetting('field', 'valid_computed_timestamp') ->setLabel(t('Request Time')); + break; case 'valid_computed_entity_reference': $fields['valid_computed_entity_reference'] = BaseFieldDefinition::create('entity_reference') ->setComputed(TRUE) @@ -54,4 +55,9 @@ + case 'multiplier': + $fields['multiplier'] = BaseFieldDefinition::create('multiplier') + ->setLabel(t('Multiplied integer')) + ->setSetting('factor', 3); + break; } } return $fields; -} +} \ No newline at end of file diff -u b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/ComputedValuesItemList.php b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/ComputedValuesItemList.php --- b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/ComputedValuesItemList.php +++ b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/ComputedValuesItemList.php @@ -10,46 +10,54 @@ */ -class ComputedValuesItemList extends FieldItemList implements FieldItemListComputedInterface { +class ComputedValuesItemList extends FieldItemList { /** * {@inheritdoc} */ - public function computeValues() { + public function getValue() { switch ($this->getSetting('field')) { case 'valid_computed_timestamp': - $items = []; - $items[] = $this->createItem(0, [ - 'value' => \Drupal::time()->getRequestTime(), - ]); - return $items; - + return [ + 0 => [ + 'value' => \Drupal::time()->getRequestTime(), + ], + ]; + break; case 'valid_computed_entity_reference': - $items = []; $parent = $this->getEntity(); if (!$parent->isNew()) { - $items[] = $this->createItem(0, [ - 'target_id' => $parent->id() === 1 ? 2 : 1, - ]); + return [ + 0 => [ + 'target_id' => $parent->id() == 1 ? 2 : 1, + ], + ]; } - return $items; - + break; case 'non_valid_computed_entity_reference': - $items = []; $parent = $this->getEntity(); if (!$parent->isNew()) { - $items[] = $this->createItem(0, [ - 'target_id' => '3', - ]); + return [ + 0 => [ + 'target_id' => '3', // Non existing entity reference. + ], + ]; } - return $items; - + break; case 'non_valid_computed_timestamp': - $items = []; - $items[] = $this->createItem(0, [ - 'value' => 'A', - ]); - return $items; + return [ + 0 => [ + 'value' => 'A', + ], + ]; + break; + case 'non_valid_computed_entity_reference': + return [ + 0 => [ + 'target_id' => 3, + ], + ]; + break; } - return []; } + } diff -u b/core/modules/field/tests/src/Kernel/FieldComputedTest.php b/core/modules/field/tests/src/Kernel/FieldComputedTest.php --- b/core/modules/field/tests/src/Kernel/FieldComputedTest.php +++ b/core/modules/field/tests/src/Kernel/FieldComputedTest.php @@ -1,11 +1,12 @@ installSchema('system', ['sequences', 'key_value']); + $this->installConfig(['field', 'system']); + $this->installEntitySchema('entity_test'); + $this->installEntitySchema('user'); + + $data = $this->getTestDataForEntities($this->getName()); + + $this->createTestEntities($data); + } + /** * Test a valid computed 'timestamp' field. */ public function testValidComputedTimestamp() { $request_time = \Drupal::time()->getRequestTime(); - $value = $this->entities[0]->get('valid_computed_timestamp')->getValue(); - $this->assertEquals([0 => ['value' => $request_time]], $value); + $value = $this->entities[0]->get('valid_computed_timestamp')->value; + $this->assertEquals($request_time, $value); } /** * Test a valid computed entityreference field. */ public function testValidComputedEntityReference() { - /** @var \Drupal\Core\Entity\EntityInterface $referenced_entity */ - $referenced_entity = $this->entities[0]->get('valid_computed_entity_reference')->entity; - $this->assertInstanceOf(EntityTest::class, $referenced_entity); - $this->assertEquals($this->entities[1]->id(), $referenced_entity->id()); + $referencedEntity = $this->entities[0]->get('valid_computed_entity_reference')->entity; + $this->assertInstanceOf(EntityTest::class, $referencedEntity); + $this->assertEquals($this->entities[1]->id(), $referencedEntity->id()); } /** * Test that a non existing entity reference returns NULL. */ - public function testNonValidComputedEntityReference() { - $referenced_entity = $this->entities[0]->get('non_valid_computed_entity_reference')->entity; - $this->assertNull($referenced_entity); + public function testNonValidComputedEntityReference(){ + $referencedEntity = $this->entities[0]->get('non_valid_computed_entity_reference')->entity; + $this->assertNull($referencedEntity); } /** - * Test that a non valid computed timestamp returns throws an exception. + * @expectedException \Drupal\Core\Field\FieldException + * @expectedExceptionMessage This value should be a valid number. */ public function testNonValidComputedTimestamp() { - $this->setExpectedException(FieldException::class, 'This value should be a valid number.'); - $entities_data = [ + $data = [ [ 'type' => 'non_valid_computed_timestamp', 'title' => 'Entity with a non valid computed timestamp', ], ]; - $this->createTestEntities($entities_data); + $this->createTestEntities($data); } + /** - * {@inheritdoc} + * Test that the processed Multiplier works correctly. */ - protected function setUp() { - parent::setUp(); - $this->installSchema('system', ['sequences', 'key_value']); - $this->installConfig(['field', 'system']); - $this->installEntitySchema('entity_test'); - $this->installEntitySchema('user'); - - $entities_data = $this->getTestDataForEntities($this->getName()); - $this->createTestEntities($entities_data); + public function testMultiplierFieldType(){ + $originalValue = 9; + $factor = 3; + $multipliedValue = $this->entities[0]->get('multiplier')->multipliedValue; + $this->assertEquals($originalValue*$factor, $multipliedValue); } + + /** * Get an array of test data for the creation of entities. * - * @param string $method_name - * The name of the method to test. + * @param $methodName * - * @return array - * Data for creation of test entities. + * @return array Data for creation of test entities. */ - protected function getTestDataForEntities($method_name) { + private function getTestDataForEntities($methodName){ $data = []; - switch ($method_name) { - case 'testValidComputedTimestamp': + switch ($methodName) { + case "testValidComputedTimestamp": $data = [ [ 'type' => 'valid_computed_timestamp', @@ -109,8 +120,7 @@ ], ]; break; - - case 'testNonValidComputedEntityReference': + case "testNonValidComputedEntityReference": $data = [ [ 'type' => 'non_valid_computed_entity_reference', @@ -122,8 +132,7 @@ ], ]; break; - - case 'testValidComputedEntityReference': + case "testValidComputedEntityReference": $data = [ [ 'type' => 'valid_computed_entity_reference', @@ -138,22 +147,29 @@ + case "testMultiplierFieldType": + $data = [ + [ + 'type' => 'multiplier', + 'title' => 'Entity with multiplier field' + ], + ]; + break; } return $data; } /** - * Create some test entities based on an array of data. - * - * @param array $entities_data - * An array containing the data to create entities from. + * Create some Test Entities based on an array of data. */ - protected function createTestEntities(array $entities_data) { - foreach ($entities_data as $item) { + private function createTestEntities($data) { + foreach ($data as $item) { $entity = EntityTest::create([ 'type' => $item['type'], 'title' => $item['title'], ]); + if($entity->bundle() == 'multiplier'){ + $entity->set('multiplier', 9); + } $entity->save(); $this->entities[] = $entity; } } - -} +} \ No newline at end of file only in patch2: unchanged: --- a/core/lib/Drupal/Core/TypedData/TypedData.php +++ b/core/lib/Drupal/Core/TypedData/TypedData.php @@ -112,6 +112,13 @@ public function setValue($value, $notify = TRUE) { /** * {@inheritdoc} */ + public function isComputed(){ + return $this->getDataDefinition()->isComputed(); + } + + /** + * {@inheritdoc} + */ public function getString() { return (string) $this->getValue(); } only in patch2: unchanged: --- a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php @@ -47,6 +47,14 @@ public function getDataDefinition(); public function getValue(); /** + * Checks if typed data is computed. + * + * @return boolean + * TRUE if computed. + */ + public function isComputed(); + + /** * Sets the data value. * * @param mixed|null $value only in patch2: unchanged: --- /dev/null +++ b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/Multiplier.php @@ -0,0 +1,50 @@ +setLabel(t('Original value')); + $properties['multipliedValue'] = DataDefinition::create('integer') + ->setLabel(t('Multiplied value')) + ->setComputed(TRUE) + ->setClass(MultiplierProcessor::class); + return $properties; + } + + + /** + * {@inheritdoc} + */ + public static function schema(FieldStorageDefinitionInterface $field_definition) { + return [ + 'columns' => [ + 'value' => [ + 'type' => 'int', + ], + ], + 'indexes' => [ + 'format' => ['value'], + ], + ]; + } +} \ No newline at end of file only in patch2: unchanged: --- /dev/null +++ b/core/modules/field/tests/modules/field_computed_test/src/Plugin/Field/FieldType/MultiplierProcessor.php @@ -0,0 +1,31 @@ +multipliedValue !== NULL && $this->value !== NULL) { + return $this->multipliedValue; + } + $item = $this->getParent(); + $factor = $item->getDataDefinition()->getSetting('factor'); + + $this->multipliedValue = $item->value * $factor; + return $this->multipliedValue; + } + +} \ No newline at end of file