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

8.0.x
Alex Pott 2014-01-25 11:26:34 +01:00
parent 3d0c65a8f4
commit 19e8cf3848
18 changed files with 135 additions and 84 deletions

View File

@ -51,17 +51,26 @@ class Sequence extends ArrayElement implements ListInterface {
}
/**
* Gets a typed configuration element from the sequence.
*
* @param string $key
* The key of the sequence to get.
*
* @return \Drupal\Core\Config\Schema\Element
* Typed configuration element.
* {@inheritdoc}
*/
public function get($key) {
$elements = $this->getElements();
return $elements[$key];
}
/**
* {@inheritdoc}
*/
public function first() {
return $this->get(0);
}
/**
* {@inheritdoc}
*/
public function set($index, $item) {
$this->offsetSet($index, $item);
return $this;
}
}

View File

@ -151,7 +151,7 @@ class Tables implements TablesInterface {
// column, i.e. target_id or fid.
// Otherwise, the code executing the relationship will throw an
// 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));
}
// Prepare the next index prefix.
@ -203,7 +203,7 @@ class Tables implements TablesInterface {
$next_index_prefix = $relationship_specifier;
}
// 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.
$entity_type = $propertyDefinitions[$relationship_specifier]->getConstraint('EntityType');
$entity_info = $entity_manager->getDefinition($entity_type);

View File

@ -144,49 +144,42 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
* {@inheritdoc}
*/
public function getPropertyDefinition($name) {
return $this->offsetGet(0)->getPropertyDefinition($name);
return $this->first()->getPropertyDefinition($name);
}
/**
* {@inheritdoc}
*/
public function getPropertyDefinitions() {
return $this->offsetGet(0)->getPropertyDefinitions();
return $this->first()->getPropertyDefinitions();
}
/**
* {@inheritdoc}
*/
public function __get($property_name) {
return $this->offsetGet(0)->__get($property_name);
}
/**
* {@inheritdoc}
*/
public function get($property_name) {
return $this->offsetGet(0)->get($property_name);
return $this->first()->__get($property_name);
}
/**
* {@inheritdoc}
*/
public function __set($property_name, $value) {
$this->offsetGet(0)->__set($property_name, $value);
$this->first()->__set($property_name, $value);
}
/**
* {@inheritdoc}
*/
public function __isset($property_name) {
return $this->offsetGet(0)->__isset($property_name);
return $this->first()->__isset($property_name);
}
/**
* {@inheritdoc}
*/
public function __unset($property_name) {
return $this->offsetGet(0)->__unset($property_name);
return $this->first()->__unset($property_name);
}
/**
@ -215,7 +208,7 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
// are valid default values.
if (!isset($value) || (is_array($value) && empty($value))) {
// Create one field item and apply defaults.
$this->offsetGet(0)->applyDefaultValue(FALSE);
$this->first()->applyDefaultValue(FALSE);
}
else {
$this->setValue($value, $notify);

View File

@ -76,13 +76,6 @@ interface FieldItemListInterface extends ListInterface, AccessibleInterface {
*/
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.
*

View File

@ -43,4 +43,38 @@ interface ListInterface extends TypedDataInterface, \ArrayAccess, \Countable, \T
* The delta of the item which is changed.
*/
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();
}

View File

@ -100,11 +100,50 @@ class ItemList extends TypedData implements \IteratorAggregate, ListInterface {
}
}
/**
* {@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().
*/
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 @@ class ItemList extends TypedData implements \IteratorAggregate, ListInterface {
}
/**
* Implements \ArrayAccess::offsetGet().
* {@inheritdoc}
*/
public function offsetGet($offset) {
if (!is_numeric($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];
return $this->get($offset);
}
/**
@ -155,16 +186,7 @@ class ItemList extends TypedData implements \IteratorAggregate, ListInterface {
// The [] operator has been used so point at a new entry.
$offset = $this->list ? max(array_keys($this->list)) + 1 : 0;
}
if (is_numeric($offset)) {
// 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.');
}
$this->set($offset, $value);
}
/**

View File

@ -218,7 +218,7 @@ class CommentFormController extends ContentEntityFormController {
// Add internal comment properties.
$original = $comment->getUntranslated();
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});
}

View File

@ -159,7 +159,7 @@ class ContentTranslationSyncImageTest extends ContentTranslationTestBase {
'alt' => $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.
$values[$default_langcode][$fid] = $item;
@ -185,7 +185,7 @@ class ContentTranslationSyncImageTest extends ContentTranslationTestBase {
'alt' => $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.
$values[$langcode][$fid] = $item;
@ -205,7 +205,7 @@ class ContentTranslationSyncImageTest extends ContentTranslationTestBase {
$fids = array();
foreach ($entity->{$this->fieldName} as $delta => $item) {
$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'];
$this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item->target_id)));
$fids[$item->target_id] = TRUE;
@ -237,7 +237,7 @@ class ContentTranslationSyncImageTest extends ContentTranslationTestBase {
// values instead of the target one.
$fid_langcode = $item->target_id != $removed_fid ? $default_langcode : $langcode;
$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'];
$this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item->target_id)));
}

View File

@ -90,7 +90,7 @@ class DateTimeItemTest extends FieldUnitTestBase {
// Test DateTimeItem::setValue() using string.
$entity = entity_create('entity_test', array());
$value = '2014-01-01T20:00:00Z';
$entity->get('field_datetime')->offsetGet(0)->setValue($value);
$entity->get('field_datetime')->set(0, $value);
$entity->save();
// Load the entity and ensure the field was saved correctly.
$id = $entity->id();
@ -100,7 +100,7 @@ class DateTimeItemTest extends FieldUnitTestBase {
// Test DateTimeItem::setValue() using property array.
$entity = entity_create('entity_test', array());
$value = '2014-01-01T20:00:00Z';
$entity->get('field_datetime')->offsetGet(0)->setValue(array('value' => $value));
$entity->set('field_datetime', $value);
$entity->save();
// Load the entity and ensure the field was saved correctly.
$id = $entity->id();
@ -116,7 +116,7 @@ class DateTimeItemTest extends FieldUnitTestBase {
$entity = entity_create('entity_test', array());
$value = '2014-01-01T20:00:00Z';
$entity->get('field_datetime')->offsetGet(0)->get('value')->setValue($value);
$entity->set('field_datetime', $value);
$entity->save();
// Load the entity and ensure the field was saved correctly.
$id = $entity->id();

View File

@ -90,7 +90,7 @@ class EditorFileUsageTest extends EntityUnitTestBase {
// Test hook_entity_update(): decrement, by modifying the last revision:
// 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();
$new_value = str_replace('data-editor-file-uuid', 'data-editor-file-uuid-modified', $original_value);
$body->setValue($new_value);
@ -99,7 +99,7 @@ class EditorFileUsageTest extends EntityUnitTestBase {
// Test hook_entity_update(): increment, by modifying the last revision:
// 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();
$this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image), 'The image has 3 usages.');

View File

@ -45,7 +45,7 @@ class FieldValidationTest extends FieldUnitTestBase {
$entity = $this->entity;
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.
@ -78,7 +78,7 @@ class FieldValidationTest extends FieldUnitTestBase {
$value = -1;
$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.

View File

@ -158,7 +158,7 @@ class FieldEditForm extends FormBase {
// FieldItem.
$ids = (object) array('entity_type' => $this->instance->entity_type, 'bundle' => $this->instance->bundle, 'entity_id' => NULL);
$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']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save field settings'));

View File

@ -120,7 +120,7 @@ class FieldItemNormalizer extends NormalizerBase {
// Create a new instance at the end of the property path and return it.
$count = $translation->isEmpty() ? 0 : $translation->count();
return $translation->offsetGet($count);
return $translation->get($count);
}
}

View File

@ -75,7 +75,7 @@ class FieldNormalizer extends NormalizerBase {
$count = $field->count();
// Get the next field item instance. The offset will serve as the field
// item name.
$field_item = $field->offsetGet($count);
$field_item = $field->get($count);
$field_item_class = get_class($field_item);
// Pass in the empty field item object as the target instance.
$context['target_instance'] = $field_item;

View File

@ -58,7 +58,7 @@ class LinkItemTest extends FieldUnitTestBase {
$class = $this->randomName();
$entity->field_test->url = $url;
$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->save();
@ -79,7 +79,7 @@ class LinkItemTest extends FieldUnitTestBase {
$new_class = $this->randomName();
$entity->field_test->url = $new_url;
$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->title, $new_title);
$this->assertEqual($entity->field_test->attributes['class'], $new_class);

View File

@ -168,7 +168,7 @@ class StandardProfileTest extends WebTestBase {
// Set URIs.
// Image.
$image_file = file_load($this->article->get('field_image')->offsetGet(0)->get('target_id')->getValue());
$image_file = $this->article->get('field_image')->entity;
$this->imageUri = entity_load('image_style', 'large')->buildUrl($image_file->getFileUri());
// Term.
$term_uri_info = $this->term->uri();
@ -233,7 +233,7 @@ class StandardProfileTest extends WebTestBase {
// @todo Once the image points to the original instead of the processed
// image, move this to testArticleProperties().
$image_file = file_load($this->article->get('field_image')->offsetGet(0)->get('target_id')->getValue());
$image_file = $this->article->get('field_image')->entity;
$image_uri = entity_load('image_style', 'medium')->buildUrl($image_file->getFileUri());
$expected_value = array(
'type' => 'uri',
@ -340,7 +340,7 @@ class StandardProfileTest extends WebTestBase {
// Term name.
$expected_value = array(
'type' => 'literal',
'value' => $this->term->get('name')->offsetGet(0)->get('value')->getValue(),
'value' => $this->term->get('name')->value,
'lang' => 'en',
);
$this->assertTrue($graph->hasProperty($this->termUri, 'http://schema.org/name', $expected_value), "Term name was found (schema:name) on term page.");
@ -366,7 +366,7 @@ class StandardProfileTest extends WebTestBase {
// Title.
$expected_value = array(
'type' => 'literal',
'value' => $node->get('title')->offsetGet(0)->get('value')->getValue(),
'value' => $node->get('title')->value,
'lang' => 'en',
);
$this->assertTrue($graph->hasProperty($uri, 'http://schema.org/name', $expected_value), "$message_prefix title was found (schema:name).");
@ -374,7 +374,7 @@ class StandardProfileTest extends WebTestBase {
// Created date.
$expected_value = array(
'type' => 'literal',
'value' => date_iso8601($node->get('created')->offsetGet(0)->get('value')->getValue()),
'value' => date_iso8601($node->get('created')->value),
'lang' => 'en',
);
$this->assertTrue($graph->hasProperty($uri, 'http://schema.org/dateCreated', $expected_value), "$message_prefix created date was found (schema:dateCreated) in teaser.");
@ -382,7 +382,7 @@ class StandardProfileTest extends WebTestBase {
// Body.
$expected_value = array(
'type' => 'literal',
'value' => $node->get('body')->offsetGet(0)->get('value')->getValue(),
'value' => $node->get('body')->value,
'lang' => 'en',
);
$this->assertTrue($graph->hasProperty($uri, 'http://schema.org/text', $expected_value), "$message_prefix body was found (schema:text) in teaser.");
@ -428,7 +428,7 @@ class StandardProfileTest extends WebTestBase {
// Tag name.
$expected_value = array(
'type' => 'literal',
'value' => $this->term->get('name')->offsetGet(0)->get('value')->getValue(),
'value' => $this->term->get('name')->value,
'lang' => 'en',
);
// @todo enable with https://drupal.org/node/2072791
@ -455,7 +455,7 @@ class StandardProfileTest extends WebTestBase {
// Comment title.
$expected_value = array(
'type' => 'literal',
'value' => $this->articleComment->get('subject')->offsetGet(0)->get('value')->getValue(),
'value' => $this->articleComment->get('subject')->value,
'lang' => 'en',
);
$this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/name', $expected_value), 'Article comment title was found (schema:name).');
@ -463,13 +463,13 @@ class StandardProfileTest extends WebTestBase {
// Comment created date.
$expected_value = array(
'type' => 'literal',
'value' => date_iso8601($this->articleComment->get('created')->offsetGet(0)->get('value')->getValue()),
'value' => date_iso8601($this->articleComment->get('created')->value),
'lang' => 'en',
);
$this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/dateCreated', $expected_value), 'Article comment created date was found (schema:dateCreated).');
// Comment body.
$text = $this->articleComment->get('comment_body')->offsetGet(0)->get('value')->getValue();
$text = $this->articleComment->get('comment_body')->value;
$expected_value = array(
'type' => 'literal',
// There is an extra carriage return in the when parsing comments as
@ -493,7 +493,7 @@ class StandardProfileTest extends WebTestBase {
// Comment author name.
$expected_value = array(
'type' => 'literal',
'value' => $this->webUser->get('name')->offsetGet(0)->get('value')->getValue(),
'value' => $this->webUser->getUsername(),
);
$this->assertTrue($graph->hasProperty($this->commenterUri, 'http://schema.org/name', $expected_value), 'Comment author name was found (schema:name).');
}

View File

@ -81,7 +81,7 @@ class NodeTest extends RESTTestBase {
// Reload the node from the DB and check if the title was correctly updated.
$updated_node = entity_load('node', $node->id(), TRUE);
$this->assertEqual($updated_node->get('title')->get('value')->getValue(), $new_title);
$this->assertEqual($updated_node->getTitle(), $new_title);
// Make sure that the UUID of the node has not changed.
$this->assertEqual($node->get('uuid')->getValue(), $updated_node->get('uuid')->getValue(), 'UUID was not changed.');
}

View File

@ -539,8 +539,8 @@ class EntityFieldTest extends EntityUnitTestBase {
$definition = FieldDefinition::create('entity_reference')
->setLabel('Test entity')
->setSetting('target_type', 'entity_test');
$reference_field_item = \Drupal::typedDataManager()->create($definition);
$reference = $reference_field_item->get('entity');
$reference_field = \Drupal::typedDataManager()->create($definition);
$reference = $reference_field->first()->get('entity');
$reference->setValue($entity);
// Test validation the typed data object.
@ -565,8 +565,8 @@ class EntityFieldTest extends EntityUnitTestBase {
'target_type' => 'node',
'target_bundle' => 'article',
));
$reference_field_item = \Drupal::TypedDataManager()->create($definition);
$reference = $reference_field_item->get('entity');
$reference_field = \Drupal::TypedDataManager()->create($definition);
$reference = $reference_field->first()->get('entity');
$reference->setValue($node);
$violations = $reference->validate();
$this->assertEqual($violations->count(), 1);