diff --git a/core/lib/Drupal/Core/Field/FieldItemBase.php b/core/lib/Drupal/Core/Field/FieldItemBase.php index 3eb6b4e..1dd8bf8 100644 --- a/core/lib/Drupal/Core/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Field/FieldItemBase.php @@ -105,10 +105,7 @@ protected function getSetting($setting_name) { } /** - * Overrides \Drupal\Core\TypedData\TypedData::setValue(). - * - * @param array|null $values - * An array of property values. + * {@inheritdoc} */ public function setValue($values, $notify = TRUE) { // Treat the values as property value of the first property, if no array is @@ -117,20 +114,7 @@ public function setValue($values, $notify = TRUE) { $keys = array_keys($this->definition->getPropertyDefinitions()); $values = array($keys[0] => $values); } - $this->values = $values; - // Update any existing property objects. - foreach ($this->properties as $name => $property) { - $value = NULL; - if (isset($values[$name])) { - $value = $values[$name]; - } - $property->setValue($value, FALSE); - unset($this->values[$name]); - } - // Notify the parent of any changes. - if ($notify && isset($this->parent)) { - $this->parent->onChange($this->name); - } + parent::setValue($values, $notify); } /** @@ -139,33 +123,32 @@ public function setValue($values, $notify = TRUE) { public function __get($name) { // There is either a property object or a plain value - possibly for a // not-defined property. If we have a plain value, directly return it. - if (isset($this->values[$name])) { - return $this->values[$name]; - } - elseif (isset($this->properties[$name])) { + if (isset($this->properties[$name])) { return $this->properties[$name]->getValue(); } + elseif (isset($this->values[$name])) { + return $this->values[$name]; + } } /** - * {@inheritdoc} + * Writes the value of a property without handling changes. + * + * @param string $property_name + * The name of the property to be written. + * @param $value + * The value to set. */ - public function set($property_name, $value, $notify = TRUE) { + protected function writePropertyValue($property_name, $value) { // For defined properties there is either a property object or a plain // value that needs to be updated. if (isset($this->properties[$property_name])) { $this->properties[$property_name]->setValue($value, FALSE); - unset($this->values[$property_name]); } // Allow setting plain values for not-defined properties also. else { $this->values[$property_name] = $value; } - // Directly notify ourselves. - if ($notify) { - $this->onChange($property_name); - } - return $this; } /** @@ -184,7 +167,10 @@ public function __set($name, $value) { * {@inheritdoc} */ public function __isset($name) { - return isset($this->values[$name]) || (isset($this->properties[$name]) && $this->properties[$name]->getValue() !== NULL); + if (isset($this->properties[$name])) { + return $this->properties[$name]->getValue() !== NULL; + } + return isset($this->values[$name]); } /** @@ -202,21 +188,6 @@ public function __unset($name) { } /** - * Overrides \Drupal\Core\TypedData\Map::onChange(). - */ - public function onChange($property_name) { - // Notify the parent of changes. - if (isset($this->parent)) { - $this->parent->onChange($this->name); - } - // Remove the plain value, such that any further __get() calls go via the - // updated property object. - if (isset($this->properties[$property_name])) { - unset($this->values[$property_name]); - } - } - - /** * {@inheritdoc} */ public function view($display_options = array()) { diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php index 317befd..31dac70 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php @@ -140,14 +140,10 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) * {@inheritdoc} */ public function setValue($values, $notify = TRUE) { + // Treat the values as property value of the entity property, if no array + // is given as this handles entity ids and objects. if (isset($values) && !is_array($values)) { - // Directly update the property instead of invoking the parent, so it can - // handle objects and IDs. - $this->properties['entity']->setValue($values, $notify); - // If notify was FALSE, ensure the target_id property gets synched. - if (!$notify) { - $this->set('target_id', $this->properties['entity']->getTargetIdentifier(), FALSE); - } + $this->set('entity', $values, $notify); } else { // Make sure that the 'entity' property gets set as 'target_id'. @@ -176,22 +172,14 @@ public function getValue($include_computed = FALSE) { * {@inheritdoc} */ public function onChange($property_name, $notify = TRUE) { - // Let the parent class do its work first, such that $this->values and - // $this->properties are in sync. - parent::onChange($property_name, FALSE); - // Make sure that the target ID and the target property stay in sync. if ($property_name == 'target_id') { - $this->properties['entity']->setValue($this->target_id, FALSE); + $this->writePropertyValue('entity', $this->target_id); } elseif ($property_name == 'entity') { - $this->set('target_id', $this->properties['entity']->getTargetIdentifier(), FALSE); - } - - // Notify the parent of changes. - if (isset($this->parent) && $notify) { - $this->parent->onChange($this->name); + $this->writePropertyValue('target_id', $this->get('entity')->getTargetIdentifier()); } + parent::onChange($property_name, $notify); } /** diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php index 7d0329b..851b818 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php @@ -69,14 +69,7 @@ public function setValue($values, $notify = TRUE) { // Treat the values as property value of the language property, if no array // is given as this handles language codes and objects. if (isset($values) && !is_array($values)) { - // Directly update the property instead of invoking the parent, so that - // the language property can take care of updating the language code - // property. - $this->properties['language']->setValue($values, $notify); - // If notify was FALSE, ensure the value property gets synched. - if (!$notify) { - $this->set('value', $this->properties['language']->getTargetIdentifier(), FALSE); - } + $this->set('language', $values, $notify); } else { // Make sure that the 'language' property gets set as 'value'. @@ -101,22 +94,14 @@ public function applyDefaultValue($notify = TRUE) { * {@inheritdoc} */ public function onChange($property_name, $notify = TRUE) { - // Let the parent class do its work first, such that $this->values and - // $this->properties are in sync. - parent::onChange($property_name, FALSE); - // Make sure that the value and the language property stay in sync. if ($property_name == 'value') { - $this->properties['language']->setValue($this->value, FALSE); + $this->writePropertyValue('language', $this->value); } elseif ($property_name == 'language') { - $this->set('value', $this->properties['language']->getTargetIdentifier(), FALSE); - } - - // Notify the parent of changes. - if (isset($this->parent) && $notify) { - $this->parent->onChange($this->name); + $this->writePropertyValue('value', $this->get('language')->getTargetIdentifier()); } + parent::onChange($property_name, $notify); } } diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php index 408c0cc..374d083 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php @@ -134,21 +134,32 @@ public function get($property_name) { } /** - * Implements \Drupal\Core\TypedData\ComplexDataInterface::set(). + * {@inheritdoc} */ public function set($property_name, $value, $notify = TRUE) { + // Separate the writing in a protected method, such that onChange + // implementations can make use of it. + $this->writePropertyValue($property_name, $value); + $this->onChange($property_name, $notify); + return $this; + } + + /** + * Writes the value of a property without handling changes. + * + * @param string $property_name + * The name of the property to be written. + * @param $value + * The value to set. + */ + protected function writePropertyValue($property_name, $value) { if ($this->definition->getPropertyDefinition($property_name)) { - $this->get($property_name)->setValue($value, $notify); + $this->get($property_name)->setValue($value, FALSE); } else { // Just set the plain value, which allows adding a new entry to the map. $this->values[$property_name] = $value; - // Directly notify ourselves. - if ($notify) { - $this->onChange($property_name, $value); - } } - return $this; } /**