reverted: --- b/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ a/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -443,9 +443,7 @@ // 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 = []; @@ -488,7 +486,7 @@ * {@inheritdoc} */ public function get($field_name) { + if (!isset($this->fields[$field_name][$this->activeLangcode])) { - if (!isset($this->fields[$field_name][$this->activeLangcode]) || $this->fields[$field_name][$this->activeLangcode]->isComputed()) { return $this->getTranslatedField($field_name, $this->activeLangcode); } return $this->fields[$field_name][$this->activeLangcode]; @@ -505,9 +503,7 @@ } // Populate $this->fields to speed-up further look-ups and to keep track of // fields objects, possibly holding changes to field values. + if (!isset($this->fields[$name][$langcode])) { - // Computed fields are always computed as their value might be subject to - // changes in the entities' lifecycle. - if (!isset($this->fields[$name][$langcode]) || $this->fields[$name][$langcode]->isComputed()) { $definition = $this->getFieldDefinition($name); if (!$definition) { throw new \InvalidArgumentException("Field $name is unknown."); reverted: --- b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php +++ a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php @@ -108,7 +108,7 @@ if (isset($values[$name])) { $entity->$name = $values[$name]; } + elseif (!array_key_exists($name, $values)) { - elseif (!array_key_exists($name, $values) && !$field->isComputed()) { $entity->get($name)->applyDefaultValue(); } } reverted: --- b/core/lib/Drupal/Core/Field/FieldItemList.php +++ a/core/lib/Drupal/Core/Field/FieldItemList.php @@ -7,9 +7,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Session\AccountInterface; -use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\Plugin\DataType\ItemList; -use Drupal\Core\TypedData\TypedDataInterface; /** * Represents an entity field; that is, a list of field item objects. @@ -162,24 +160,6 @@ /** * {@inheritdoc} */ - public function isComputed() { - return $this->getFieldDefinition()->isComputed(); - } - - /** - * {@inheritdoc} - */ - public function setComputedValues() { - $this->setValue($this->getValue()); - $errors = $this->validate()->getIterator(); - if ($errors->current()) { - throw new FieldException($errors->current()->getMessage()); - } - } - - /** - * {@inheritdoc} - */ public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) { $access_control_handler = \Drupal::entityManager()->getAccessControlHandler($this->getEntity()->getEntityTypeId()); return $access_control_handler->fieldAccess($operation, $this->getFieldDefinition(), $account, $this, $return_as_object); reverted: --- b/core/lib/Drupal/Core/Field/FieldItemListInterface.php +++ a/core/lib/Drupal/Core/Field/FieldItemListInterface.php @@ -125,19 +125,6 @@ public function __unset($property_name); /** - * Determines if the field item List is computed. - * - * @return bool - * TRUE if the field item list is computed. - */ - public function isComputed(); - - /** - * Populate the computed list with values. - */ - public function setComputedValues(); - - /** * Defines custom presave behavior for field values. * * This method is called during the process of saving an entity, just before reverted: --- b/core/lib/Drupal/Core/TypedData/TypedData.php +++ a/core/lib/Drupal/Core/TypedData/TypedData.php @@ -112,13 +112,6 @@ /** * {@inheritdoc} */ - public function isComputed(){ - return $this->getDataDefinition()->isComputed(); - } - - /** - * {@inheritdoc} - */ public function getString() { return (string) $this->getValue(); } reverted: --- b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php +++ a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php @@ -47,14 +47,6 @@ 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 reverted: --- b/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ a/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -7,8 +7,6 @@ use Drupal\Core\DependencyInjection\ClassResolverInterface; use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Field\FieldItemList; -use Drupal\Core\Field\FieldItemListComputedInterface; use Drupal\Core\Plugin\DefaultPluginManager; use Drupal\Core\TypedData\Validation\ExecutionContextFactory; use Drupal\Core\TypedData\Validation\RecursiveValidator; @@ -202,11 +200,6 @@ if (isset($value)) { $property->setValue($value, FALSE); } - elseif ($property instanceof FieldItemList && $property->isComputed()) { - // Populate the computed list with values as there are no initial values - // to set. - $property->setComputedValues(); - } return $property; } 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 @@ -4,60 +4,38 @@ -use Drupal\Core\Field\FieldItemList; +use Drupal\Core\Field\ComputedFieldItemListBase; use Drupal\Core\Field\FieldItemListComputedInterface; -/** - * Represents a configurable dice result. - */ -class ComputedValuesItemList extends FieldItemList { - - /** - * {@inheritdoc} - */ - public function getValue() { - switch ($this->getSetting('field')) { - case 'valid_computed_timestamp': - return [ - 0 => [ - 'value' => \Drupal::time()->getRequestTime(), - ], - ]; - break; - case 'valid_computed_entity_reference': - $parent = $this->getEntity(); - if (!$parent->isNew()) { - return [ - 0 => [ - 'target_id' => $parent->id() == 1 ? 2 : 1, - ], - ]; - } - break; - case 'non_valid_computed_entity_reference': - $parent = $this->getEntity(); - if (!$parent->isNew()) { - return [ - 0 => [ - 'target_id' => '3', // Non existing entity reference. - ], - ]; - } - break; - case 'non_valid_computed_timestamp': - return [ - 0 => [ - 'value' => 'A', - ], - ]; - break; - case 'non_valid_computed_entity_reference': - return [ - 0 => [ - 'target_id' => 3, - ], - ]; - break; + +class ComputedValuesItemList extends ComputedFieldItemListBase { + + protected function computeFieldItemListValues(){ + $index = 0; + if (!isset($this->list[$index]) || $this->list[$index]->isEmpty()) { + + switch ($this->getSetting('field')) { + case 'valid_computed_timestamp': + $this->list[$index] = $this->createItem($index, \Drupal::time()->getRequestTime()); + break; + case 'valid_computed_entity_reference': + $parent = $this->getEntity(); + if (!$parent->isNew()) { + $this->list[$index] = $this->createItem($index, $parent->id() == 1 ? 2 : 1); + } + break; + case 'non_valid_computed_entity_reference': + $parent = $this->getEntity(); + if (!$parent->isNew()) { + $this->list[$index] = $this->createItem($index, 3); + } + break; + case 'non_valid_computed_timestamp': + $this->list[$index] = $this->createItem($index, 'A'); + break; + case 'non_valid_computed_entity_reference': + $this->list[$index] = $this->createItem($index, 'A'); + break; + } } } - } only in patch2: unchanged: --- /dev/null +++ b/core/lib/Drupal/Core/Field/ComputedFieldItemListBase.php @@ -0,0 +1,31 @@ +computeFieldItemListValues(); + $errors = $this->validate()->getIterator(); + if ($errors->current()) { + throw new FieldException($errors->current()->getMessage()); + } + return isset($this->list[$index]) ? $this->list[$index] : NULL; + } + + /** + * {@inheritdoc} + */ + public function getIterator() { + $this->computeFieldItemListValues(); + return parent::getIterator(); + } +}