You are here

protected function EntityFieldRenderer::buildFields in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/views/src/Entity/Render/EntityFieldRenderer.php \Drupal\views\Entity\Render\EntityFieldRenderer::buildFields()
  2. 9 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

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)) {
        $entities_by_bundles[$entity
          ->bundle()][$result_row->index] = $this
          ->getEntityTranslation($entity, $result_row);
      }
    }

    // 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;
}