Problem/Motivation

When trying to group aggregate on a field that isn't in all bundles, you get an error. " Fatal error: Call to a member function view() on a non-object in .../core/modules/views/src/Plugin/views/field/Field.php on line 822"

Proposed resolution

Check for the field before trying to access it's method (view).

Remaining tasks

1. Write a test.
2. Submit the patch.
3. Review.

User interface changes

none

API changes

none

Data model changes

none

Reproduction instructions

1. Create a new site based on 8.0.x (standard install).
2. Generate some content.
3. Import the test-aggregation-view.yml view.
4. Visit example.com/test-aggregation

uuid: ba25d54f-5130-4d7d-8f00-f584ab13e3df
langcode: en
status: true
... File attached ⩒⩒
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Jaesin created an issue. See original summary.

Jaesin’s picture

Status: Active » Needs review
FileSize
839 bytes

Checks for the field before accessing it.

Jaesin’s picture

Issue summary: View changes
FileSize
4.61 KB
Jaesin’s picture

Title: Views aggregation: Grouping a field that doesn't exist on all bundler causes an error. » Views aggregation: Grouping a field that doesn't exist on all bundles causes an error.
Jaesin’s picture

FileSize
1.71 KB
2.28 KB

I found another spot were the filed wasn't being checked for existence.

dawehner’s picture

Issue tags: +Needs tests
  1. +++ b/core/modules/views/src/Plugin/views/field/Field.php
    @@ -817,9 +817,8 @@ public function getItems(ResultRow $values) {
    +      $entity = $this->createEntityForGroupBy($this->getEntity($values), $values);
    +      $build_list = isset($entity->{$this->definition['field_name']}) ? $entity->{$this->definition['field_name']}->view($display) : NULL;
    
    @@ -999,18 +998,28 @@ protected function getTableMapping() {
    +    $field_item_list = isset($entity->{$this->definition['field_name']}) ? $entity->{$this->definition['field_name']} : NULL;
    

    We need to document how this can happen ...

  2. +++ b/core/modules/views/src/Plugin/views/field/Field.php
    @@ -999,18 +998,28 @@ protected function getTableMapping() {
    +    // Get the entity.
    +    $entity = $this->getEntity($values);
    

    Pointless documentation.

  3. +++ b/core/modules/views/src/Plugin/views/field/Field.php
    @@ -999,18 +998,28 @@ protected function getTableMapping() {
    +    // Make sure the field exists.
    +    if (!$field_item_list) {
    +      // There isn't anything we can do without a valid field.
    +      return NULL;
    +    } else {
    +      $values = [];
    +
    +      $field_item_definition = $field_item_list->getFieldDefinition();
     
    -    $values = [];
    -    foreach ($field_item_list as $field_item) {
    -      $values[] = $field ? $field_item->$field : $field_item->value;
    +      if ($field_item_definition->getFieldStorageDefinition()->getCardinality() == 1) {
    +        return $field ? $field_item_list->$field : $field_item_list->value;
    +      }
    +      foreach ($field_item_list as $field_item) {
    +        $values[] = $field ? $field_item->$field : $field_item->value;
    +      }
         }
    +
    

    You can make the code easier to read by just using if (!isset($field_item_list)) { return NULL; } and don't deal with an else at all

dawehner’s picture

Status: Needs review » Needs work
dawehner’s picture

Wow, I would not have expected that its that hard to reproduce the problem with a normal field, not an image field.
This is still not failing.

Jaesin’s picture

Status: Needs work » Needs review

Test ME!

Status: Needs review » Needs work

The last submitted patch, 8: 2616816-8.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
4.29 KB
3.46 KB
6.1 KB

There we go.

The last submitted patch, 11: 2616816-11-fai.patch, failed testing.

Lendude’s picture

Status: Needs review » Needs work
+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -1002,8 +1003,17 @@ protected function getTableMapping() {
+    $entity = $this->getEntity($values);
+    // Some bundles might not have a specific field, in which case the faked
+    // entity doesn't have it either.

I don't think we should call the entity loaded here 'faked', that only goes for entities created by createEntityForGroupBy right?

+++ b/core/modules/views/src/Tests/QueryGroupByTest.php
@@ -292,4 +292,45 @@ public function testGroupByFieldWithCardinality() {
+  public function testGroupByWithFieldsNotExistingOnBundle() {
...
+    $entities = [];
+    $entity = EntityTestMul::create([
+      'field_test' => [1],
+      'type' => 'entity_test_mul',
+    ]);
+    $entity->save();
+    $entities[] = $entity;
+
+    $entity = EntityTestMul::create([
+      'type' => 'entity_test_mul2',
+    ]);
+    $entity->save();
+    $entities[] = $entity;

missing docblock and maybe give some explanation as to what is being set up here.

dawehner’s picture

Status: Needs work » Needs review
FileSize
6.19 KB
1.49 KB

Thank you for the review @Lendude!

missing docblock and maybe give some explanation as to what is being set up here.

Well, the method is quite self descriptive to be honest, but well, here is a one line comment.

Lendude’s picture

Status: Needs review » Needs work

Well, the method is quite self descriptive to be honest, but well, here is a one line comment.

Don't think the docblocks for methods are optional :)

+++ b/core/modules/views/src/Tests/QueryGroupByTest.php
@@ -25,14 +25,14 @@ class QueryGroupByTest extends ViewKernelTestBase {
+  public static $modules = array('entity_test', 'system', 'field', 'user', 'language', 'image');

sorry missed this the first time, don't think the image module is needed? Tests pass fine without it.

dawehner’s picture

Status: Needs work » Needs review
FileSize
5.93 KB
597 bytes

Don't think the docblocks for methods are optional :)

Feel free to look at some examples in \Drupal\Tests\UnitTestCase :)

sorry missed this the first time, don't think the image module is needed? Tests pass fine without it.

Nor do I, good catch!

Lendude’s picture

Status: Needs review » Reviewed & tested by the community

This now looks good to me.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.1.x and cherry-picked to 8.0.x. Thanks!

  • catch committed e8a4f8b on 8.1.x
    Issue #2616816 by dawehner, Jaesin: Views aggregation: Grouping a field...

  • catch committed e11e926 on
    Issue #2616816 by dawehner, Jaesin: Views aggregation: Grouping a field...

Status: Fixed » Closed (fixed)

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