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 0737733..f46780e 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php @@ -162,14 +162,13 @@ public function setValue($values, $notify = TRUE) { parent::setValue($values, FALSE); // Support setting the field item with only one property, but make sure // values stay in sync if only property is passed. - if (isset($values['target_id']) && !isset($values['entity'])) { + // NULL is a valid value, so we use array_key_exists(). + if (is_array($values) && array_key_exists('target_id', $values) && !isset($values['entity'])) { $this->onChange('target_id', FALSE); } - // NULL is a valid value, so we use array_key_exists(). elseif (is_array($values) && !array_key_exists('target_id', $values) && isset($values['entity'])) { $this->onChange('entity', FALSE); } - // NULL is a valid value, so we use array_key_exists(). elseif (is_array($values) && array_key_exists('target_id', $values) && isset($values['entity'])) { // If both properties are passed, verify the passed values match. The // only exception we allow is when we have a new entity: in this case @@ -215,7 +214,7 @@ public function onChange($property_name, $notify = TRUE) { $target_id = $property->isTargetNew() ? NULL : $property->getTargetIdentifier(); $this->writePropertyValue('target_id', $target_id); } - elseif ($property_name == 'target_id' && $this->target_id !== NULL) { + elseif ($property_name == 'target_id') { $this->writePropertyValue('entity', $this->target_id); } parent::onChange($property_name, $notify); diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceItemTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceItemTest.php index d7b7980..dbc9037 100644 --- a/core/modules/field/src/Tests/EntityReference/EntityReferenceItemTest.php +++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceItemTest.php @@ -310,4 +310,41 @@ public function testSelectionHandlerSettings() { $this->assertTrue($field->getSetting('handler') == 'views'); } + /** + * Tests validation constraint. + */ + public function testValidation() { + // The term entity is unsaved here. + $term = Term::create(array( + 'name' => $this->randomMachineName(), + 'vid' => $this->term->bundle(), + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + )); + $entity = EntityTest::create([ + 'field_test_taxonomy_term' => [ + 'entity' => $term, + 'target_id' => NULL, + ], + ]); + $errors = $entity->validate(); + // Using target_id of NULL is valid with an unsaved entity. + $this->assertEqual(0, count($errors)); + // Using target_id of NULL is not valid with a saved entity. + $term->save(); + $entity = EntityTest::create([ + 'field_test_taxonomy_term' => [ + 'entity' => $term, + 'target_id' => NULL, + ], + ]); + $errors = $entity->validate(); + $this->assertEqual(1, count($errors)); + $this->assertEqual($errors[0]->getMessage(), 'This value should not be null.'); + $this->assertEqual($errors[0]->getPropertyPath(), 'field_test_taxonomy_term'); + // This should rectify the issue, favoring the entity over the target_id. + $entity->save(); + $errors = $entity->validate(); + $this->assertEqual(0, count($errors)); + } + } diff --git a/core/modules/system/src/Tests/Entity/EntityReferenceFieldTest.php b/core/modules/system/src/Tests/Entity/EntityReferenceFieldTest.php index 01dd0c1..53de70a 100644 --- a/core/modules/system/src/Tests/Entity/EntityReferenceFieldTest.php +++ b/core/modules/system/src/Tests/Entity/EntityReferenceFieldTest.php @@ -238,7 +238,6 @@ function testAutocreateApi() { }); $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { $entity->user_id[0]->get('entity')->setValue($user); - $entity->user_id[0]->get('target_id')->setValue(NULL); }); $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { $entity->user_id->setValue(array('entity' => $user, 'target_id' => NULL)); @@ -273,7 +272,6 @@ function testAutocreateApi() { }); $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { $entity->user_role[0]->get('entity')->setValue($role); - $entity->user_role[0]->get('target_id')->setValue(NULL); }); $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { $entity->user_role->setValue(array('entity' => $role, 'target_id' => NULL));