diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index 826193b..b776608 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -375,9 +375,9 @@ protected function getTranslatedField($name, $langcode) { * {@inheritdoc} */ public function set($name, $value, $notify = TRUE) { - // If default language or an entity key changes we need to react to that. - $notify = $name == 'langcode' || in_array($name, $this->getEntityType()->getKeys()); - $this->get($name)->setValue($value, $notify); + $this->get($name)->setValue($value, FALSE); + // Directly notify ourselves, so we can take changes into account. + $this->onChange($name); } /** diff --git a/core/lib/Drupal/Core/Field/FieldItemBase.php b/core/lib/Drupal/Core/Field/FieldItemBase.php index b9c90d9..62d1a3d 100644 --- a/core/lib/Drupal/Core/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Field/FieldItemBase.php @@ -191,26 +191,26 @@ public function __isset($name) { * {@inheritdoc} */ public function __unset($name) { - // Explicitly unset the property in $this->values if a non-defined - // property is unset, such that its key is removed from $this->values. - if (!$this->definition->getPropertyDefinition($name)) { - unset($this->values[$name]); + if ($this->definition->getPropertyDefinition($name)) { + $this->set($name, NULL); } else { - $this->set($name, NULL); + // Explicitly unset the property in $this->values if a non-defined + // property is unset, such that its key is removed from $this->values. + unset($this->values[$name]); } } /** * {@inheritdoc} */ - public function onChange($property_name) { + public function onChange($property_name, $notify = TRUE) { // 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]); } - parent::onChange($property_name); + parent::onChange($property_name, $notify); } /** 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 a6c6bed..317befd 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php @@ -175,7 +175,11 @@ public function getValue($include_computed = FALSE) { /** * {@inheritdoc} */ - public function onChange($property_name) { + 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); @@ -183,7 +187,11 @@ public function onChange($property_name) { elseif ($property_name == 'entity') { $this->set('target_id', $this->properties['entity']->getTargetIdentifier(), FALSE); } - parent::onChange($property_name); + + // Notify the parent of changes. + if (isset($this->parent) && $notify) { + $this->parent->onChange($this->name); + } } /** 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 961eb67..7d0329b 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php @@ -100,7 +100,11 @@ public function applyDefaultValue($notify = TRUE) { /** * {@inheritdoc} */ - public function onChange($property_name) { + 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); @@ -108,6 +112,11 @@ public function onChange($property_name) { elseif ($property_name == 'language') { $this->set('value', $this->properties['language']->getTargetIdentifier(), FALSE); } - parent::onChange($property_name); + + // Notify the parent of changes. + if (isset($this->parent) && $notify) { + $this->parent->onChange($this->name); + } } + } diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php index e17e072..408c0cc 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php @@ -213,11 +213,16 @@ public function __clone() { } /** - * Implements \Drupal\Core\TypedData\ComplexDataInterface::onChange(). + * {@inheritdoc} + * + * @param bool $notify + * (optional) Whether to forward the notification to the parent. Defaults to + * TRUE. By passing FALSE overriding implementations can re-use the logic + * of parent classes without triggering the parent notification. */ - public function onChange($property_name) { + public function onChange($property_name, $notify = TRUE) { // Notify the parent of changes. - if (isset($this->parent)) { + if (isset($this->parent) && $notify) { $this->parent->onChange($this->name); } } diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php index d24f1c2..6ecf319 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php +++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php @@ -131,12 +131,12 @@ public function isEmpty() { /** * {@inheritdoc} */ - public function onChange($property_name) { + public function onChange($property_name, $notify = TRUE) { // Enforce that the computed date is recalculated. if ($property_name == 'value') { $this->date = NULL; } - parent::onChange($property_name); + parent::onChange($property_name, $notify); } } diff --git a/core/modules/system/src/Tests/Entity/EntityFieldTest.php b/core/modules/system/src/Tests/Entity/EntityFieldTest.php index e975e9f..45709b9 100644 --- a/core/modules/system/src/Tests/Entity/EntityFieldTest.php +++ b/core/modules/system/src/Tests/Entity/EntityFieldTest.php @@ -169,12 +169,12 @@ protected function doTestReadWrite($entity_type) { // Create a fresh entity so target_id does not get its property object // instantiated, then verify setting a new value via typed data API works. $entity2 = entity_create($entity_type, array( - 'user_id' => array('target_id' => $new_user2->id()), + 'user_id' => array('target_id' => $new_user1->id()), )); // Access the property object, and set a value. $entity2->user_id->first()->get('target_id')->setValue($new_user2->id()); $this->assertEqual($new_user2->id(), $entity2->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($new_user2->getUsername(), $entity2->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user2->name->value, $entity2->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); // Test using isset(), empty() and unset(). $entity->name->value = 'test unset'; diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php index 3d81f31..17b7ef0 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php @@ -59,7 +59,7 @@ public function isEmpty() { /** * {@inheritdoc} */ - public function onChange($property_name) { + public function onChange($property_name, $notify = TRUE) { // Unset processed properties that are affected by the change. foreach ($this->definition->getPropertyDefinitions() as $property => $definition) { if ($definition->getClass() == '\Drupal\text\TextProcessed') { @@ -68,7 +68,7 @@ public function onChange($property_name) { } } } - parent::onChange($property_name); + parent::onChange($property_name, $notify); } /**