diff --git a/core/modules/views/src/Entity/Render/EntityFieldRenderer.php b/core/modules/views/src/Entity/Render/EntityFieldRenderer.php index 39ab8d0..f5923a6 100644 --- a/core/modules/views/src/Entity/Render/EntityFieldRenderer.php +++ b/core/modules/views/src/Entity/Render/EntityFieldRenderer.php @@ -126,51 +126,45 @@ public function query(QueryPluginBase $query, $relationship = NULL) { protected function buildFields(array $values) { $build = []; if ($values && $renderable_fields = $this->getRenderableFieldIds()) { - // Identify all relationships. We will also need one representative field - // for each relationship. - $relationhips = []; + // Group fields by relationship. + $fields_by_relationship = []; foreach ($renderable_fields as $field_id) { /** @var \Drupal\views\Plugin\views\field\Field $field */ $field = $this->view->field[$field_id]; - $relationhips[$field->options['relationship']] = $field; + $fields_by_relationship[$field->options['relationship']][$field_id] = $field; } - // For each row, and each relationship in the row, retrieve the entity to - // be processed, and take the correct translation. + // For each relationship and each result row, collect the entities to + // display, fetch the right translation, and group them by bundle. $entities = []; - foreach ($relationhips as $relationhip_id => $field) { + foreach ($fields_by_relationship as $relationhip_id => $fields) { $entities[$relationhip_id] = []; + $field = current($fields); foreach ($values as $result_row) { $entity = $field->getEntity($result_row); $entities[$relationhip_id][$entity->bundle()][$result_row->index] = $this->getEntityTranslation($entity, $result_row); } - } - // @todo Note : given the current code in EVD->buildFieldMultiple(), we don't - // actually need to create an EVD for each entity_type / bundle. This shows - // that EVD->buildFieldMultiple() should rather go in a stateless service, - // since it does in fact not depend on the values in the EVD. - $display = new EntityViewDisplay([ - 'targetEntityType' => $this->getEntityTypeId(), - 'bundle' => FALSE, - 'status' => TRUE, - ], 'entity_view_display'); - - // Render each field - foreach ($renderable_fields as $field_id) { - /** @var \Drupal\views\Plugin\views\field\Field $field */ - $field = $this->view->field[$field_id]; - - // Run the formatter across all entities for the field's relationship, - // grouping entities by bundle. - foreach ($entities[$field->options['relationship']] as $bundle => $bundle_entities) { - // At this point, we can use the "real" field definition for the bundle - // we are rendering. - $field_definition = $this->entityManager->getFieldDefinitions($this->getEntityTypeId(), $bundle)[$field->definition['field_name']]; - $field_build = $display->buildFieldMultiple($bundle_entities, $field_definition, $field->options['type'], $field->options['settings']); - array_walk($field_build, function ($value, $index) use (&$build, $field_id) { - $build[$index][$field_id] = $value; - }); + foreach ($entities[$relationhip_id] as $bundle => $bundle_entities) { + // Create the Display. + $display = new EntityViewDisplay([ + 'targetEntityType' => $this->getEntityTypeId(), + 'bundle' => $bundle, + 'status' => TRUE, + ], 'entity_view_display'); + foreach ($fields as $field_id => $field) { + $display->setComponent($field->definition['field_name'], [ + 'type' => $field->options['type'], + 'settings' => $field->options['settings'], + ]); + } + // Let the Display do the rendering. + $display_build = $display->buildMultiple($bundle_entities); + foreach ($display_build as $row_index => $entity_build) { + foreach ($fields as $field_id => $field) { + $build[$row_index][$field_id] = $entity_build[$field->definition['field_name']]; + } + } } } }