Commit 19e8cf38 authored by alexpott's avatar alexpott
Browse files

Issue #2110467 by Berdir: Add first(), get($index) and possibly other methods to ListInterface.

parent 3d0c65a8
...@@ -51,17 +51,26 @@ public function onChange($delta) { ...@@ -51,17 +51,26 @@ public function onChange($delta) {
} }
/** /**
* Gets a typed configuration element from the sequence. * {@inheritdoc}
*
* @param string $key
* The key of the sequence to get.
*
* @return \Drupal\Core\Config\Schema\Element
* Typed configuration element.
*/ */
public function get($key) { public function get($key) {
$elements = $this->getElements(); $elements = $this->getElements();
return $elements[$key]; return $elements[$key];
} }
/**
* {@inheritdoc}
*/
public function first() {
return $this->get(0);
}
/**
* {@inheritdoc}
*/
public function set($index, $item) {
$this->offsetSet($index, $item);
return $this;
}
} }
...@@ -151,7 +151,7 @@ public function addField($field, $type, $langcode) { ...@@ -151,7 +151,7 @@ public function addField($field, $type, $langcode) {
// column, i.e. target_id or fid. // column, i.e. target_id or fid.
// Otherwise, the code executing the relationship will throw an // Otherwise, the code executing the relationship will throw an
// exception anyways so no need to do it here. // exception anyways so no need to do it here.
if (!$column && isset($propertyDefinitions[$relationship_specifier]) && $entity->{$field->getName()}->get('entity') instanceof EntityReference) { if (!$column && isset($propertyDefinitions[$relationship_specifier]) && $entity->{$field->getName()}->first()->get('entity') instanceof EntityReference) {
$column = current(array_keys($propertyDefinitions)); $column = current(array_keys($propertyDefinitions));
} }
// Prepare the next index prefix. // Prepare the next index prefix.
...@@ -203,7 +203,7 @@ public function addField($field, $type, $langcode) { ...@@ -203,7 +203,7 @@ public function addField($field, $type, $langcode) {
$next_index_prefix = $relationship_specifier; $next_index_prefix = $relationship_specifier;
} }
// Check for a valid relationship. // Check for a valid relationship.
if (isset($propertyDefinitions[$relationship_specifier]) && $entity->{$specifier}->get('entity') instanceof EntityReference) { if (isset($propertyDefinitions[$relationship_specifier]) && $entity->get($specifier)->first()->get('entity') instanceof EntityReference) {
// If it is, use the entity type. // If it is, use the entity type.
$entity_type = $propertyDefinitions[$relationship_specifier]->getConstraint('EntityType'); $entity_type = $propertyDefinitions[$relationship_specifier]->getConstraint('EntityType');
$entity_info = $entity_manager->getDefinition($entity_type); $entity_info = $entity_manager->getDefinition($entity_type);
......
...@@ -144,49 +144,42 @@ public function setValue($values, $notify = TRUE) { ...@@ -144,49 +144,42 @@ public function setValue($values, $notify = TRUE) {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getPropertyDefinition($name) { public function getPropertyDefinition($name) {
return $this->offsetGet(0)->getPropertyDefinition($name); return $this->first()->getPropertyDefinition($name);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getPropertyDefinitions() { public function getPropertyDefinitions() {
return $this->offsetGet(0)->getPropertyDefinitions(); return $this->first()->getPropertyDefinitions();
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function __get($property_name) { public function __get($property_name) {
return $this->offsetGet(0)->__get($property_name); return $this->first()->__get($property_name);
}
/**
* {@inheritdoc}
*/
public function get($property_name) {
return $this->offsetGet(0)->get($property_name);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function __set($property_name, $value) { public function __set($property_name, $value) {
$this->offsetGet(0)->__set($property_name, $value); $this->first()->__set($property_name, $value);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function __isset($property_name) { public function __isset($property_name) {
return $this->offsetGet(0)->__isset($property_name); return $this->first()->__isset($property_name);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function __unset($property_name) { public function __unset($property_name) {
return $this->offsetGet(0)->__unset($property_name); return $this->first()->__unset($property_name);
} }
/** /**
...@@ -215,7 +208,7 @@ public function applyDefaultValue($notify = TRUE) { ...@@ -215,7 +208,7 @@ public function applyDefaultValue($notify = TRUE) {
// are valid default values. // are valid default values.
if (!isset($value) || (is_array($value) && empty($value))) { if (!isset($value) || (is_array($value) && empty($value))) {
// Create one field item and apply defaults. // Create one field item and apply defaults.
$this->offsetGet(0)->applyDefaultValue(FALSE); $this->first()->applyDefaultValue(FALSE);
} }
else { else {
$this->setValue($value, $notify); $this->setValue($value, $notify);
......
...@@ -76,13 +76,6 @@ public function defaultAccess($operation = 'view', AccountInterface $account = N ...@@ -76,13 +76,6 @@ public function defaultAccess($operation = 'view', AccountInterface $account = N
*/ */
public function filterEmptyItems(); public function filterEmptyItems();
/**
* Gets a property object from the first field item.
*
* @see \Drupal\Core\Field\FieldItemInterface::get()
*/
public function get($property_name);
/** /**
* Magic method: Gets a property value of to the first field item. * Magic method: Gets a property value of to the first field item.
* *
......
...@@ -43,4 +43,38 @@ public function getItemDefinition(); ...@@ -43,4 +43,38 @@ public function getItemDefinition();
* The delta of the item which is changed. * The delta of the item which is changed.
*/ */
public function onChange($delta); public function onChange($delta);
/**
* Returns the item at the specified position in this list.
*
* @param int $index
* Index of the item to return.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The item at the specified position in this list. An empty item is created
* if it does not exist yet.
*/
public function get($index);
/**
* Replaces the item at the specified position in this list.
*
* @param int $index
* Index of the item to replace.
* @param mixed
* Item to be stored at the specified position.
*
* @return static
* Returns the list.
*/
public function set($index, $item);
/**
* Returns the first item in this list.
*
* @return \Drupal\Core\TypedData\TypedDataInterface
* The first item in this list.
*/
public function first();
} }
...@@ -100,11 +100,50 @@ public function getString() { ...@@ -100,11 +100,50 @@ public function getString() {
} }
} }
/**
* {@inheritdoc}
*/
public function get($index) {
if (!is_numeric($index)) {
throw new \InvalidArgumentException('Unable to get a value with a non-numeric delta in a list.');
}
// Allow getting not yet existing items as well.
// @todo: Maybe add a public createItem() method in addition?
elseif (!isset($this->list[$index])) {
$this->list[$index] = $this->createItem($index);
}
return $this->list[$index];
}
/**
* {@inheritdoc}
*/
public function set($index, $item) {
if (is_numeric($index)) {
// Support setting values via typed data objects.
if ($item instanceof TypedDataInterface) {
$item = $item->getValue();
}
$this->get($index)->setValue($item);
return $this;
}
else {
throw new \InvalidArgumentException('Unable to set a value with a non-numeric delta in a list.');
}
}
/**
* {@inheritdoc}
*/
public function first() {
return $this->get(0);
}
/** /**
* Implements \ArrayAccess::offsetExists(). * Implements \ArrayAccess::offsetExists().
*/ */
public function offsetExists($offset) { public function offsetExists($offset) {
return isset($this->list) && array_key_exists($offset, $this->list) && $this->offsetGet($offset)->getValue() !== NULL; return isset($this->list) && array_key_exists($offset, $this->list) && $this->get($offset)->getValue() !== NULL;
} }
/** /**
...@@ -117,18 +156,10 @@ public function offsetUnset($offset) { ...@@ -117,18 +156,10 @@ public function offsetUnset($offset) {
} }
/** /**
* Implements \ArrayAccess::offsetGet(). * {@inheritdoc}
*/ */
public function offsetGet($offset) { public function offsetGet($offset) {
if (!is_numeric($offset)) { return $this->get($offset);
throw new \InvalidArgumentException('Unable to get a value with a non-numeric delta in a list.');
}
// Allow getting not yet existing items as well.
// @todo: Maybe add a public createItem() method in addition?
elseif (!isset($this->list[$offset])) {
$this->list[$offset] = $this->createItem($offset);
}
return $this->list[$offset];
} }
/** /**
...@@ -155,16 +186,7 @@ public function offsetSet($offset, $value) { ...@@ -155,16 +186,7 @@ public function offsetSet($offset, $value) {
// The [] operator has been used so point at a new entry. // The [] operator has been used so point at a new entry.
$offset = $this->list ? max(array_keys($this->list)) + 1 : 0; $offset = $this->list ? max(array_keys($this->list)) + 1 : 0;
} }
if (is_numeric($offset)) { $this->set($offset, $value);
// Support setting values via typed data objects.
if ($value instanceof TypedDataInterface) {
$value = $value->getValue();
}
$this->offsetGet($offset)->setValue($value);
}
else {
throw new \InvalidArgumentException('Unable to set a value with a non-numeric delta in a list.');
}
} }
/** /**
......
...@@ -218,7 +218,7 @@ public function form(array $form, array &$form_state) { ...@@ -218,7 +218,7 @@ public function form(array $form, array &$form_state) {
// Add internal comment properties. // Add internal comment properties.
$original = $comment->getUntranslated(); $original = $comment->getUntranslated();
foreach (array('cid', 'pid', 'entity_id', 'entity_type', 'field_id', 'uid', 'langcode') as $key) { foreach (array('cid', 'pid', 'entity_id', 'entity_type', 'field_id', 'uid', 'langcode') as $key) {
$key_name = key($comment->$key->offsetGet(0)->getPropertyDefinitions()); $key_name = key($comment->$key->first()->getPropertyDefinitions());
$form[$key] = array('#type' => 'value', '#value' => $original->$key->{$key_name}); $form[$key] = array('#type' => 'value', '#value' => $original->$key->{$key_name});
} }
......
...@@ -159,7 +159,7 @@ function testImageFieldSync() { ...@@ -159,7 +159,7 @@ function testImageFieldSync() {
'alt' => $default_langcode . '_' . $fid . '_' . $this->randomName(), 'alt' => $default_langcode . '_' . $fid . '_' . $this->randomName(),
'title' => $default_langcode . '_' . $fid . '_' . $this->randomName(), 'title' => $default_langcode . '_' . $fid . '_' . $this->randomName(),
); );
$entity->{$this->fieldName}->offsetGet($delta)->setValue($item); $entity->{$this->fieldName}->get($delta)->setValue($item);
// Store the generated values keying them by fid for easier lookup. // Store the generated values keying them by fid for easier lookup.
$values[$default_langcode][$fid] = $item; $values[$default_langcode][$fid] = $item;
...@@ -185,7 +185,7 @@ function testImageFieldSync() { ...@@ -185,7 +185,7 @@ function testImageFieldSync() {
'alt' => $langcode . '_' . $fid . '_' . $this->randomName(), 'alt' => $langcode . '_' . $fid . '_' . $this->randomName(),
'title' => $langcode . '_' . $fid . '_' . $this->randomName(), 'title' => $langcode . '_' . $fid . '_' . $this->randomName(),
); );
$translation->{$this->fieldName}->offsetGet($delta)->setValue($item); $translation->{$this->fieldName}->get($delta)->setValue($item);
// Again store the generated values keying them by fid for easier lookup. // Again store the generated values keying them by fid for easier lookup.
$values[$langcode][$fid] = $item; $values[$langcode][$fid] = $item;
...@@ -205,7 +205,7 @@ function testImageFieldSync() { ...@@ -205,7 +205,7 @@ function testImageFieldSync() {
$fids = array(); $fids = array();
foreach ($entity->{$this->fieldName} as $delta => $item) { foreach ($entity->{$this->fieldName} as $delta => $item) {
$value = $values[$default_langcode][$item->target_id]; $value = $values[$default_langcode][$item->target_id];
$source_item = $translation->{$this->fieldName}->offsetGet($delta); $source_item = $translation->{$this->fieldName}->get($delta);
$assert = $item->target_id == $source_item->target_id && $item->alt == $value['alt'] && $item->title == $value['title']; $assert = $item->target_id == $source_item->target_id && $item->alt == $value['alt'] && $item->title == $value['title'];
$this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item->target_id))); $this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item->target_id)));
$fids[$item->target_id] = TRUE; $fids[$item->target_id] = TRUE;
...@@ -237,7 +237,7 @@ function testImageFieldSync() { ...@@ -237,7 +237,7 @@ function testImageFieldSync() {
// values instead of the target one. // values instead of the target one.
$fid_langcode = $item->target_id != $removed_fid ? $default_langcode : $langcode; $fid_langcode = $item->target_id != $removed_fid ? $default_langcode : $langcode;
$value = $values[$fid_langcode][$item->target_id]; $value = $values[$fid_langcode][$item->target_id];
$source_item = $translation->{$this->fieldName}->offsetGet($delta); $source_item = $translation->{$this->fieldName}->get($delta);
$assert = $item->target_id == $source_item->target_id && $item->alt == $value['alt'] && $item->title == $value['title']; $assert = $item->target_id == $source_item->target_id && $item->alt == $value['alt'] && $item->title == $value['title'];
$this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item->target_id))); $this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item->target_id)));
} }
......
...@@ -90,7 +90,7 @@ public function testSetValue() { ...@@ -90,7 +90,7 @@ public function testSetValue() {
// Test DateTimeItem::setValue() using string. // Test DateTimeItem::setValue() using string.
$entity = entity_create('entity_test', array()); $entity = entity_create('entity_test', array());
$value = '2014-01-01T20:00:00Z'; $value = '2014-01-01T20:00:00Z';
$entity->get('field_datetime')->offsetGet(0)->setValue($value); $entity->get('field_datetime')->set(0, $value);
$entity->save(); $entity->save();
// Load the entity and ensure the field was saved correctly. // Load the entity and ensure the field was saved correctly.
$id = $entity->id(); $id = $entity->id();
...@@ -100,7 +100,7 @@ public function testSetValue() { ...@@ -100,7 +100,7 @@ public function testSetValue() {
// Test DateTimeItem::setValue() using property array. // Test DateTimeItem::setValue() using property array.
$entity = entity_create('entity_test', array()); $entity = entity_create('entity_test', array());
$value = '2014-01-01T20:00:00Z'; $value = '2014-01-01T20:00:00Z';
$entity->get('field_datetime')->offsetGet(0)->setValue(array('value' => $value)); $entity->set('field_datetime', $value);
$entity->save(); $entity->save();
// Load the entity and ensure the field was saved correctly. // Load the entity and ensure the field was saved correctly.
$id = $entity->id(); $id = $entity->id();
...@@ -116,7 +116,7 @@ public function testSetValueProperty() { ...@@ -116,7 +116,7 @@ public function testSetValueProperty() {
$entity = entity_create('entity_test', array()); $entity = entity_create('entity_test', array());
$value = '2014-01-01T20:00:00Z'; $value = '2014-01-01T20:00:00Z';
$entity->get('field_datetime')->offsetGet(0)->get('value')->setValue($value); $entity->set('field_datetime', $value);
$entity->save(); $entity->save();
// Load the entity and ensure the field was saved correctly. // Load the entity and ensure the field was saved correctly.
$id = $entity->id(); $id = $entity->id();
......
...@@ -90,7 +90,7 @@ public function testEditorEntityHooks() { ...@@ -90,7 +90,7 @@ public function testEditorEntityHooks() {
// Test hook_entity_update(): decrement, by modifying the last revision: // Test hook_entity_update(): decrement, by modifying the last revision:
// remove the data- attribute from the body field. // remove the data- attribute from the body field.
$body = $node->get('body')->offsetGet(0)->get('value'); $body = $node->get('body')->first()->get('value');
$original_value = $body->getValue(); $original_value = $body->getValue();
$new_value = str_replace('data-editor-file-uuid', 'data-editor-file-uuid-modified', $original_value); $new_value = str_replace('data-editor-file-uuid', 'data-editor-file-uuid-modified', $original_value);
$body->setValue($new_value); $body->setValue($new_value);
...@@ -99,7 +99,7 @@ public function testEditorEntityHooks() { ...@@ -99,7 +99,7 @@ public function testEditorEntityHooks() {
// Test hook_entity_update(): increment, by modifying the last revision: // Test hook_entity_update(): increment, by modifying the last revision:
// readd the data- attribute to the body field. // readd the data- attribute to the body field.
$node->get('body')->offsetGet(0)->get('value')->setValue($original_value); $node->get('body')->first()->get('value')->setValue($original_value);
$node->save(); $node->save();
$this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image), 'The image has 3 usages.'); $this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image), 'The image has 3 usages.');
......
...@@ -45,7 +45,7 @@ function testCardinalityConstraint() { ...@@ -45,7 +45,7 @@ function testCardinalityConstraint() {
$entity = $this->entity; $entity = $this->entity;
for ($delta = 0; $delta < $cardinality + 1; $delta++) { for ($delta = 0; $delta < $cardinality + 1; $delta++) {
$entity->{$this->field_name}->offsetGet($delta)->set('value', 1); $entity->{$this->field_name}->get($delta)->set('value', 1);
} }
// Validate the field. // Validate the field.
...@@ -78,7 +78,7 @@ function testFieldConstraints() { ...@@ -78,7 +78,7 @@ function testFieldConstraints() {
$value = -1; $value = -1;
$expected_violations[$delta . '.value'][] = t('%name does not accept the value -1.', array('%name' => $this->instance->getLabel())); $expected_violations[$delta . '.value'][] = t('%name does not accept the value -1.', array('%name' => $this->instance->getLabel()));
} }
$entity->{$this->field_name}->offsetGet($delta)->set('value', $value); $entity->{$this->field_name}->get($delta)->set('value', $value);
} }
// Validate the field. // Validate the field.
......
...@@ -158,7 +158,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac ...@@ -158,7 +158,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
// FieldItem. // FieldItem.
$ids = (object) array('entity_type' => $this->instance->entity_type, 'bundle' => $this->instance->bundle, 'entity_id' => NULL); $ids = (object) array('entity_type' => $this->instance->entity_type, 'bundle' => $this->instance->bundle, 'entity_id' => NULL);
$entity = _field_create_entity_from_ids($ids); $entity = _field_create_entity_from_ids($ids);
$form['field']['settings'] += $entity->get($field->getName())->offsetGet(0)->settingsForm($form, $form_state, $field->hasData()); $form['field']['settings'] += $entity->get($field->getName())->first()->settingsForm($form, $form_state, $field->hasData());
$form['actions'] = array('#type' => 'actions'); $form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save field settings')); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save field settings'));
......
...@@ -120,7 +120,7 @@ protected function createTranslatedInstance(FieldItemInterface $field_item, $lan ...@@ -120,7 +120,7 @@ protected function createTranslatedInstance(FieldItemInterface $field_item, $lan
// Create a new instance at the end of the property path and return it. // Create a new instance at the end of the property path and return it.
$count = $translation->isEmpty() ? 0 : $translation->count(); $count = $translation->isEmpty() ? 0 : $translation->count();
return $translation->offsetGet($count); return $translation->get($count);
} }
} }
...@@ -75,7 +75,7 @@ public function denormalize($data, $class, $format = NULL, array $context = arra ...@@ -75,7 +75,7 @@ public function denormalize($data, $class, $format = NULL, array $context = arra
$count = $field->count(); $count = $field->count();
// Get the next field item instance. The offset will serve as the field // Get the next field item instance. The offset will serve as the field
// item name. // item name.
$field_item = $field->offsetGet($count); $field_item = $field->get($count);
$field_item_class = get_class($field_item); $field_item_class = get_class($field_item);
// Pass in the empty field item object as the target instance. // Pass in the empty field item object as the target instance.
$context['target_instance'] = $field_item; $context['target_instance'] = $field_item;
......
...@@ -58,7 +58,7 @@ public function testLinkItem() { ...@@ -58,7 +58,7 @@ public function testLinkItem() {
$class = $this->randomName(); $class = $this->randomName();
$entity->field_test->url = $url; $entity->field_test->url = $url;
$entity->field_test->title = $title; $entity->field_test->title = $title;
$entity->field_test->get('attributes')->set('class', $class); $entity->field_test->first()->get('attributes')->set('class', $class);
$entity->name->value = $this->randomName(); $entity->name->value = $this->randomName();
$entity->save(); $entity->save();
...@@ -79,7 +79,7 @@ public function testLinkItem() { ...@@ -79,7 +79,7 @@ public function testLinkItem() {
$new_class = $this->randomName(); $new_class = $this->randomName();
$entity->field_test->url = $new_url; $entity->field_test->url = $new_url;
$entity->field_test->title = $new_title; $entity->field_test->title = $new_title;
$entity->field_test->get('attributes')->set('class', $new_class); $entity->field_test->first()->get('attributes')->set('class', $new_class);
$this->assertEqual($entity->field_test->url, $new_url); $this->assertEqual($entity->field_test->url, $new_url);