Commit da33162e authored by catch's avatar catch

Issue #2368807 by yched: Remove special support for NULL values in FieldItemList

parent 37e7d708
......@@ -802,21 +802,25 @@ public function __set($name, $value) {
* Implements the magic method for isset().
*/
public function __isset($name) {
// "Official" Field API fields are always set.
if ($this->hasField($name)) {
return $this->get($name)->getValue() !== NULL;
return TRUE;
}
// For non-field properties, check the internal values.
else {
return isset($this->values[$name]);
}
}
/**
* Implements the magic method for unset.
* Implements the magic method for unset().
*/
public function __unset($name) {
// Unsetting a field means emptying it.
if ($this->hasField($name)) {
$this->get($name)->setValue(NULL);
$this->get($name)->setValue(array());
}
// For non-field properties, unset the internal value.
else {
unset($this->values[$name]);
}
......
......@@ -125,7 +125,7 @@ public function getValue($include_computed = FALSE) {
*/
public function setValue($values, $notify = TRUE) {
if (!isset($values) || $values === array()) {
$this->list = $values;
$this->list = array();
}
else {
// Support passing in only the value of the first item.
......
......@@ -152,15 +152,6 @@ public function denormalize($data, $class, $format = NULL, array $context = arra
$entity = $this->entityManager->getStorage($typed_data_ids['entity_type'])->create($values);
// Special handling for PATCH: destroy all possible default values that
// might have been set on entity creation. We want an "empty" entity that
// will only get filled with fields from the data array.
if (isset($context['request_method']) && $context['request_method'] == 'patch') {
foreach ($entity as $field_name => $field) {
$entity->set($field_name, NULL);
}
}
// Remove links from data array.
unset($data['_links']);
// Get embedded resources and remove from data array.
......@@ -179,6 +170,12 @@ public function denormalize($data, $class, $format = NULL, array $context = arra
}
}
// Special handling for PATCH: pass the names of the fields whose values
// should be merged.
if (isset($context['request_method']) && $context['request_method'] == 'patch') {
$entity->_restPatchFields = array_keys($data);
}
// Iterate through remaining items in data array. These should all
// correspond to fields.
foreach ($data as $field_name => $field_data) {
......
......@@ -176,7 +176,7 @@ public function testBasicFieldDenormalization() {
}
/**
* Verifies that only specified properties get populated in the PATCH context.
* Verifies that the denormalized entity is correct in the PATCH context.
*/
public function testPatchDenormailzation() {
$data = array(
......@@ -195,15 +195,7 @@ public function testPatchDenormailzation() {
$denormalized = $this->serializer->denormalize($data, $this->entityClass, $this->format, array('request_method' => 'patch'));
// Check that the one field got populated as expected.
$this->assertEqual($data['field_test_text'], $denormalized->get('field_test_text')->getValue());
// Unset that field so that now all fields are NULL.
$denormalized->set('field_test_text', NULL);
// Assert that all fields are NULL and not set to default values. Example:
// the UUID field is NULL and not initialized as usual.
foreach ($denormalized as $field_name => $field) {
// The 'langcode' field always has a value.
if ($field_name != 'langcode') {
$this->assertFalse(isset($denormalized->$field_name), "$field_name is not set.");
}
}
// Check the custom property that contains the list of fields to merge.
$this->assertEqual($denormalized->_restPatchFields, ['field_test_text']);
}
}
......@@ -187,7 +187,7 @@ protected function buildEntity(array $form, FormStateInterface $form_state) {
// @todo Refine automated log messages and abstract them to all entity
// types: http://drupal.org/node/1678002.
if ($entity->getEntityTypeId() == 'node' && $entity->isNewRevision() && !isset($entity->revision_log)) {
if ($entity->getEntityTypeId() == 'node' && $entity->isNewRevision() && $entity->revision_log->isEmpty()) {
$entity->revision_log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $entity->get($field_name)->getFieldDefinition()->getLabel()));
}
......
......@@ -134,22 +134,21 @@ public function patch(EntityInterface $original_entity, EntityInterface $entity
}
// Overwrite the received properties.
foreach ($entity as $field_name => $field) {
if (isset($entity->{$field_name})) {
// It is not possible to set the language to NULL as it is automatically
// re-initialized. As it must not be empty, skip it if it is.
// @todo: Use the langcode entity key when available. See
// https://drupal.org/node/2143729.
if ($field_name == 'langcode' && $field->isEmpty()) {
continue;
}
if ($field->isEmpty() && !$original_entity->get($field_name)->access('delete')) {
throw new AccessDeniedHttpException(String::format('Access denied on deleting field ', array('@field' => $field_name)));
}
$original_entity->set($field_name, $field->getValue());
if (!$original_entity->get($field_name)->access('update')) {
throw new AccessDeniedHttpException(String::format('Access denied on updating field ', array('@field' => $field_name)));
}
foreach ($entity->_restPatchFields as $field_name) {
$field = $entity->get($field_name);
// It is not possible to set the language to NULL as it is automatically
// re-initialized. As it must not be empty, skip it if it is.
// @todo: Use the langcode entity key when available. See
// https://drupal.org/node/2143729.
if ($field_name == 'langcode' && $field->isEmpty()) {
continue;
}
if ($field->isEmpty() && !$original_entity->get($field_name)->access('delete')) {
throw new AccessDeniedHttpException(String::format('Access denied on deleting field @field.', array('@field' => $field_name)));
}
$original_entity->set($field_name, $field->getValue());
if (!$original_entity->get($field_name)->access('update')) {
throw new AccessDeniedHttpException(String::format('Access denied on updating field @field.', array('@field' => $field_name)));
}
}
......
......@@ -141,7 +141,7 @@ protected function doTestReadWrite($entity_type) {
$this->assertEqual($new_user2->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type)));
$this->assertEqual($new_user2->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated username value can be read.', array('%entity_type' => $entity_type)));
// Try unsetting a field.
// Try unsetting a field property.
$entity->name->value = NULL;
$entity->user_id->target_id = NULL;
$this->assertNull($entity->name->value, format_string('%entity_type: Name field is not set.', array('%entity_type' => $entity_type)));
......@@ -199,25 +199,27 @@ protected function doTestReadWrite($entity_type) {
$this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type)));
$this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type)));
$entity->name = array();
$this->assertTrue(isset($entity->name), 'Name field is set.');
$this->assertFalse(isset($entity->name[0]), 'Name field item is not set.');
$this->assertFalse(isset($entity->name[0]->value), 'First name item value is not set.');
$this->assertFalse(isset($entity->name->value), 'Name value is not set.');
$entity->name = NULL;
$this->assertFalse(isset($entity->name), 'Name field is not set.');
$this->assertFalse(isset($entity->name[0]), 'Name field item is not set.');
$this->assertFalse(isset($entity->name[0]->value), 'First name item value is not set.');
$this->assertFalse(isset($entity->name->value), 'Name value is not set.');
$entity->name->value = 'a value';
$this->assertTrue(isset($entity->name->value), format_string('%entity_type: Name is set.', array('%entity_type' => $entity_type)));
unset($entity->name);
$this->assertFalse(isset($entity->name), format_string('%entity_type: Name field is not set.', array('%entity_type' => $entity_type)));
$this->assertFalse(isset($entity->name[0]), format_string('%entity_type: Name field item is not set.', array('%entity_type' => $entity_type)));
$this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type)));
$this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type)));
// Test emptying a field by assigning an empty value. NULL and array()
// behave the same.
foreach ([NULL, array(), 'unset'] as $empty) {
// Make sure a value is present
$entity->name->value = 'a value';
$this->assertTrue(isset($entity->name->value), format_string('%entity_type: Name is set.', array('%entity_type' => $entity_type)));
// Now, empty the field.
if ($empty === 'unset') {
unset($entity->name);
}
else {
$entity->name = $empty;
}
$this->assertTrue(isset($entity->name), format_string('%entity_type: Name field is set.', array('%entity_type' => $entity_type)));
$this->assertTrue($entity->name->isEmpty(), format_string('%entity_type: Name field is set.', array('%entity_type' => $entity_type)));
$this->assertIdentical(count($entity->name), 0, format_string('%entity_type: Name field contains no items.', array('%entity_type' => $entity_type)));
$this->assertIdentical($entity->name->getValue(), array(), format_string('%entity_type: Name field value is an empty array.', array('%entity_type' => $entity_type)));
$this->assertFalse(isset($entity->name[0]), format_string('%entity_type: Name field item is not set.', array('%entity_type' => $entity_type)));
$this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: First name item value is not set.', array('%entity_type' => $entity_type)));
$this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name value is not set.', array('%entity_type' => $entity_type)));
}
// Access the language field.
$this->assertEqual($langcode, $entity->langcode->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type)));
......@@ -301,18 +303,6 @@ protected function doTestReadWrite($entity_type) {
$this->assertEqual($entity->name[0]->value, 'foo', format_string('%entity_type: The items were renumbered.', array('%entity_type' => $entity_type)));
$this->assertEqual($entity->name[0]->getName(), 0, format_string('%entity_type: The deltas were updated in the items.', array('%entity_type' => $entity_type)));
// Test removing all list items by assigning an empty array.
$entity->name = array();
$this->assertIdentical(count($entity->name), 0, format_string('%entity_type: Name field contains no items.', array('%entity_type' => $entity_type)));
$this->assertIdentical($entity->name->getValue(), array(), format_string('%entity_type: Name field value is an empty array.', array('%entity_type' => $entity_type)));
$entity->name->value = 'foo';
$this->assertEqual($entity->name->value, 'foo', format_string('%entity_type: Name field set.', array('%entity_type' => $entity_type)));
// Test removing all list items by setting it to NULL.
$entity->name = NULL;
$this->assertIdentical(count($entity->name), 0, format_string('%entity_type: Name field contains no items.', array('%entity_type' => $entity_type)));
$this->assertNull($entity->name->getValue(), format_string('%entity_type: Name field value is an empty array.', array('%entity_type' => $entity_type)));
// Test get and set field values.
$entity->name = 'foo';
$this->assertEqual($entity->name[0]->toArray(), array('value' => 'foo'), format_string('%entity_type: Field value has been retrieved via toArray()', array('%entity_type' => $entity_type)));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment