Updated: Comment #N

Problem/Motivation

Right now, \Drupal\Core\TypedData\ListInterface only allows access to it's items through \ArrayAccess. That's nice where you can use and I think we should continue to support it, but it would be useful to have better methods instead of offsetGet(0), that's just weird.

Proposed resolution

Add first() and get($index). There's also a method for an toArray() (right now called getValue()), let's leave that out here.

Remaining tasks

Implement it.

User interface changes

None

API changes

Only additions.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Berdir’s picture

Status: Active » Needs review
FileSize
22.73 KB

This adds get(), set() and first() and uses them where appropriate.

Also simplified some of the current usages, there's often no need to go through all those method calls and right now, magic is often the faster, due to internal optimizations.

Status: Needs review » Needs work

The last submitted patch, list-methods-2110467-1.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
769 bytes
22.7 KB

Ups.

Status: Needs review » Needs work

The last submitted patch, list-methods-2110467-3.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
2.2 KB
24.21 KB

Innteresting. So FieldItemListInterface already had a get() that forwarded to get() of the first item. That's kinda weird I don't think I've ever used that, let's see what happens if we remove it.

Status: Needs review » Needs work

The last submitted patch, list-methods-2110467-5.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
824 bytes
23.41 KB

Can we add that gmail plugin that asks you math questions before letting you upload a patch at late hours to d.o, please? :)

Accidently added in an unrelated, weird change, must have been an accidental ctrl+v...

Status: Needs review » Needs work

The last submitted patch, list-methods-2110467-7.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
554 bytes
23.41 KB

More stupid mistakes.

Status: Needs review » Needs work
Issue tags: -Entity Field API, -Typed sanity

The last submitted patch, list-methods-2110467-9.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
2.21 KB
25.04 KB

This gets embarassing. This actually passes all entity tests. Actually found two cases in EFQ that used the old get().

The last submitted patch, list-methods-2110467-11.patch, failed testing.

Berdir’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
27.35 KB
2.84 KB

Re-roll and fixing tests.

Berdir’s picture

13: list-methods-2110467-13.patch queued for re-testing.

yched’s picture

  1. +++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
    @@ -151,7 +151,7 @@ public function addField($field, $type, $langcode) {
    -            if (!$column && isset($propertyDefinitions[$relationship_specifier]) && $entity->{$field->getFieldName()}->get('entity') instanceof EntityReference) {
    +            if (!$column && isset($propertyDefinitions[$relationship_specifier]) && $entity->{$field->getFieldName()}->first()->get('entity') instanceof EntityReference) {
    

    This means we limit the "default reroute to the 1st item" sugar syntax strictly to $items->property_name ?
    Why not, just pointing that out.

    Also, this code here could then just be $entity->{$field_name}->entity ?

  2. +++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
    @@ -202,7 +202,7 @@ public function addField($field, $type, $langcode) {
    -        if (isset($propertyDefinitions[$relationship_specifier]) && $entity->{$specifier}->get('entity') instanceof EntityReference) {
    +        if (isset($propertyDefinitions[$relationship_specifier]) && $entity->get($specifier)->first()->get('entity') instanceof EntityReference) {
    

    Same here ?
    (and possibly in other places, didn't check all)

Berdir’s picture

1. Yes, that's what currently happens in this patch, which was also the main problem @fago had with the patch. I actually never expected get() to work like this, was suprised to see that. We could either add a special method for that use case on FieldItemList or we could rename get() on ListInterface() to something else. But I don't have any good names for either of those options. Thoughts?

yched’s picture

I think I personally could live with ItemList->get() being just about retrieving a list item by its key, and have the "implicit route to delta 0" DX sugar restricted to just $list->property.

But I'm not sure what the impact would be on the TypedData side ? I'm thinking of "generic code" like validation or normalization, that uses the $item as a TypedData and maybe relies on the current get() behavior ?

Berdir’s picture

TypedData/ComplexData never had that get() shortcut, that only existed in FieldItemListInterface.

And for generic code, the new behavior IMHO makes more sense, because you don't want to special case the single value case anyway, you should foreach over each level taht is complexData or ListInterface.

yched’s picture

Assigned: Unassigned » fago

Oh - then yes, I'm +1 on that.
This is still for @fago to sign off, though. Assigning to him.

Berdir’s picture

13: list-methods-2110467-13.patch queued for re-testing.

The last submitted patch, 13: list-methods-2110467-13.patch, failed testing.

Berdir’s picture

Re-roll, still needs @fago's sign off.

Status: Needs review » Needs work

The last submitted patch, 22: list-methods-2110467-22.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
28.8 KB
1.4 KB

Fixing those new test fails. The code incorrectly assumed that it's working with a field_item not a list, as visible in the variable name.

fago’s picture

Status: Needs review » Needs work

And for generic code, the new behavior IMHO makes more sense, because you don't want to special case the single value case anyway, you should foreach over each level taht is complexData or ListInterface.

Generic code would have no knowledge of get() on a list. Anyway I like the consistency brought to get method. If the little extra-magic within the magic doesn't bother you, it should be fine to others also. I'm not feeling strong about it either, so let's do it so then!

  1. +++ b/core/lib/Drupal/Core/TypedData/ListInterface.php
    @@ -43,4 +43,34 @@ public function getItemDefinition();
    +   * @return
    +   *   The item at the specified position in this list.
    +   */
    +  public function get($index);
    

    Misses the return doc of returning a typed data object. Also, what does it return if the item does not exist?

    For field items we chose to always instantiate empty items, thus I guess we should document it that way here. If it's not set, then the returned object is empty (or contains NULL).

  2. +++ b/core/lib/Drupal/Core/TypedData/ListInterface.php
    @@ -43,4 +43,34 @@ public function getItemDefinition();
    +  public function set($index, $item);
    

    Usually we do setters which return "static", so we can chain through. I'd suggest doing that here as well.

  3. +++ b/core/lib/Drupal/Core/TypedData/ListInterface.php
    @@ -43,4 +43,34 @@ public function getItemDefinition();
    +   * @return
    

    Misses the interface, it's always a typed data object.

Berdir’s picture

Status: Needs work » Needs review
FileSize
28.99 KB
1.09 KB

Ok, fixed that.

fago’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/TypedData/ListInterface.php
    @@ -43,4 +43,38 @@ public function getItemDefinition();
    +   * @return self
    

    according to amateescu's experiences that should be static

  2. +++ b/core/lib/Drupal/Core/Config/Schema/Sequence.php
    @@ -49,4 +50,26 @@ public function onChange($delta) {
    +    $this->offsetSet($index, $value);
    

    violates the interface as it misses the return.

Berdir’s picture

Status: Needs work » Needs review
FileSize
29.03 KB
1.46 KB

Ok, better now? :)

Berdir’s picture

28: list-methods-2110467-28.patch queued for re-testing.

fago’s picture

Status: Needs review » Reviewed & tested by the community

Yep, thanks. Setting RTBC, assuming bot stays green.

xjm’s picture

28: list-methods-2110467-28.patch queued for re-testing.

The last submitted patch, 28: list-methods-2110467-28.patch, failed testing.

Berdir’s picture

Sequence introduced a get() method and I have no idea what it does, any pointers?

fago’s picture

Sequences seem to be the same as lists. I've no idea how the get() is intended to be used though, but given that it's just a list I'd assume it should map to the proposed meaning already.

Berdir’s picture

Status: Reviewed & tested by the community » Needs work

Except it doesn't and seems to be doing something special by calling $this->parse() ?

fago’s picture

all the typed config objects do that parsing, e.g. see the Mapping class. Not sure why it is required, but it seems to do nothing else than creating contained typed-data objects but just via the typed-config factory.

Berdir’s picture

Status: Needs work » Needs review
FileSize
29.72 KB

Ah, you are right, I got confused by the slightly different (and better) implementation in offsetGet(), but it is essentially the same.

Here's a re-roll.

yched’s picture

Berdir’s picture

Could use a quick check from someone before setting back to RTBC as this wasn't just a re-roll, I merged in the new get() method on Sequence, no relevant changes in other files, though.

fago’s picture

+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
@@ -616,3 +616,6 @@ protected function assertComputedProperties($entity_type) {
 }
+    $definition = FieldDefinition::create('entity_reference')
+      ->setLabel('Test entity')
+      ->setSetting('target_type', 'entity_test');
 

Is adding this here intentional?

Else, the patch looks good to me.

Berdir’s picture

Uh, no, not sure how that happened.

fago’s picture

Assigned: fago » Unassigned
Status: Needs review » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Needs a reroll

git ac https://drupal.org/files/issues/list-methods-2110467-41.patch
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 30008  100 30008    0     0  21261      0  0:00:01  0:00:01 --:--:-- 24258
error: patch failed: core/lib/Drupal/Core/Config/Schema/Sequence.php:51
error: core/lib/Drupal/Core/Config/Schema/Sequence.php: patch does not apply

Plus...

+++ b/core/lib/Drupal/Core/Config/Schema/Sequence.php
@@ -8,6 +8,7 @@
+use Drupal\Core\TypedData\TypedDataInterface;

Unused use.

Berdir’s picture

Status: Needs work » Needs review
FileSize
29.05 KB
455 bytes
Berdir’s picture

Status: Needs review » Reviewed & tested by the community

Re-roll was trivial this time, so back to RTBC unless testbot for some strange reason disagrees.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Hopefully the reroll is trivial again...

git ac https://drupal.org/files/issues/list-methods-2110467-44.patch
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 29744  100 29744    0     0  15011      0  0:00:01  0:00:01 --:--:-- 16977
error: patch failed: core/lib/Drupal/Core/Field/FieldItemListInterface.php:77
error: core/lib/Drupal/Core/Field/FieldItemListInterface.php: patch does not apply
error: core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LegacyConfigFieldItemList.php: does not exist in index
Berdir’s picture

Status: Needs work » Needs review
FileSize
27.99 KB

Yeah, LegacyFieldItemList doesn't exist anymore :)

Berdir’s picture

Status: Needs review » Reviewed & tested by the community

The patches are identical apart from changes in the patch context and the removed file.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 19e8cf3 and pushed to 8.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.