function EntityFieldRenderer::buildFields

Same name in other branches
  1. 9 core/modules/views/src/Entity/Render/EntityFieldRenderer.php \Drupal\views\Entity\Render\EntityFieldRenderer::buildFields()
  2. 8.9.x core/modules/views/src/Entity/Render/EntityFieldRenderer.php \Drupal\views\Entity\Render\EntityFieldRenderer::buildFields()
  3. 11.x core/modules/views/src/Entity/Render/EntityFieldRenderer.php \Drupal\views\Entity\Render\EntityFieldRenderer::buildFields()

Builds the render arrays for all fields of all result rows.

The output is built using EntityViewDisplay objects to leverage multiple-entity building and ensure a common code path with regular entity view.

  • Each relationship is handled by a separate EntityFieldRenderer instance, since it operates on its own set of entities. This also ensures different entity types are handled separately, as they imply different relationships.
  • Within each relationship, the fields to render are arranged in unique sets containing each field at most once (an EntityViewDisplay can only process a field once with given display options, but a View can contain the same field several times with different display options).
  • For each set of fields, entities are processed by bundle, so that formatters can operate on the proper field definition for the bundle.

Parameters

\Drupal\views\ResultRow[] $values: An array of all ResultRow objects returned from the query.

Return value

array A renderable array for the fields handled by this renderer.

See also

\Drupal\Core\Entity\Entity\EntityViewDisplay

1 call to EntityFieldRenderer::buildFields()
EntityFieldRenderer::render in core/modules/views/src/Entity/Render/EntityFieldRenderer.php
Renders entity field data.

File

core/modules/views/src/Entity/Render/EntityFieldRenderer.php, line 207

Class

EntityFieldRenderer
Renders entity fields.

Namespace

Drupal\views\Entity\Render

Code

protected function buildFields(array $values) {
    $build = [];
    if ($values && ($field_ids = $this->getRenderableFieldIds())) {
        $entity_type_id = $this->getEntityTypeId();
        // Collect the entities for the relationship, fetch the right translation,
        // and group by bundle. For each result row, the corresponding entity can
        // be obtained from any of the fields handlers, so we arbitrarily use the
        // first one.
        $entities_by_bundles = [];
        $field = $this->view->field[current($field_ids)];
        foreach ($values as $result_row) {
            if ($entity = $field->getEntity($result_row)) {
                $relationship = $field->options['relationship'] ?? 'none';
                $entities_by_bundles[$entity->bundle()][$result_row->index] = $this->getEntityTranslationByRelationship($entity, $result_row, $relationship);
            }
        }
        // Determine unique sets of fields that can be processed by the same
        // display. Fields that appear several times in the View open additional
        // "overflow" displays.
        $display_sets = [];
        foreach ($field_ids as $field_id) {
            $field = $this->view->field[$field_id];
            $field_name = $field->definition['field_name'];
            $index = 0;
            while (isset($display_sets[$index]['field_names'][$field_name])) {
                $index++;
            }
            $display_sets[$index]['field_names'][$field_name] = $field;
            $display_sets[$index]['field_ids'][$field_id] = $field;
        }
        // For each set of fields, build the output by bundle.
        foreach ($display_sets as $display_fields) {
            foreach ($entities_by_bundles as $bundle => $bundle_entities) {
                // Create the display, and configure the field display options.
                $display = EntityViewDisplay::create([
                    'targetEntityType' => $entity_type_id,
                    'bundle' => $bundle,
                    'status' => TRUE,
                ]);
                foreach ($display_fields['field_ids'] as $field) {
                    $display->setComponent($field->definition['field_name'], [
                        'type' => $field->options['type'],
                        'settings' => $field->options['settings'],
                    ]);
                }
                // Let the display build the render array for the entities.
                $display_build = $display->buildMultiple($bundle_entities);
                // Collect the field render arrays and index them using our internal
                // row indexes and field IDs.
                foreach ($display_build as $row_index => $entity_build) {
                    foreach ($display_fields['field_ids'] as $field_id => $field) {
                        $build[$row_index][$field_id] = !empty($entity_build[$field->definition['field_name']]) ? $entity_build[$field->definition['field_name']] : [];
                    }
                }
            }
        }
    }
    return $build;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.