You are here

public function EntityReferenceEntityFormatter::viewElements in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php \Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceEntityFormatter::viewElements()
  2. 10 core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php \Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceEntityFormatter::viewElements()

Builds a renderable array for a field value.

Parameters

\Drupal\Core\Field\FieldItemListInterface $items: The field values to be rendered.

string $langcode: The language that should be used to render the field.

Return value

array A renderable array for $items, as an array of child elements keyed by consecutive numeric indexes starting from 0.

Overrides FormatterInterface::viewElements

File

core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php, line 157

Class

EntityReferenceEntityFormatter
Plugin implementation of the 'entity reference rendered entity' formatter.

Namespace

Drupal\Core\Field\Plugin\Field\FieldFormatter

Code

public function viewElements(FieldItemListInterface $items, $langcode) {
  $view_mode = $this
    ->getSetting('view_mode');
  $elements = [];
  foreach ($this
    ->getEntitiesToView($items, $langcode) as $delta => $entity) {

    // Due to render caching and delayed calls, the viewElements() method
    // will be called later in the rendering process through a '#pre_render'
    // callback, so we need to generate a counter that takes into account
    // all the relevant information about this field and the referenced
    // entity that is being rendered.
    $recursive_render_id = $items
      ->getFieldDefinition()
      ->getTargetEntityTypeId() . $items
      ->getFieldDefinition()
      ->getTargetBundle() . $items
      ->getName() . $items
      ->getEntity()
      ->id() . $entity
      ->getEntityTypeId() . $entity
      ->id();
    if (isset(static::$recursiveRenderDepth[$recursive_render_id])) {
      static::$recursiveRenderDepth[$recursive_render_id]++;
    }
    else {
      static::$recursiveRenderDepth[$recursive_render_id] = 1;
    }

    // Protect ourselves from recursive rendering.
    if (static::$recursiveRenderDepth[$recursive_render_id] > static::RECURSIVE_RENDER_LIMIT) {
      $this->loggerFactory
        ->get('entity')
        ->error('Recursive rendering detected when rendering entity %entity_type: %entity_id, using the %field_name field on the %parent_entity_type:%parent_bundle %parent_entity_id entity. Aborting rendering.', [
        '%entity_type' => $entity
          ->getEntityTypeId(),
        '%entity_id' => $entity
          ->id(),
        '%field_name' => $items
          ->getName(),
        '%parent_entity_type' => $items
          ->getFieldDefinition()
          ->getTargetEntityTypeId(),
        '%parent_bundle' => $items
          ->getFieldDefinition()
          ->getTargetBundle(),
        '%parent_entity_id' => $items
          ->getEntity()
          ->id(),
      ]);
      return $elements;
    }
    $view_builder = $this->entityTypeManager
      ->getViewBuilder($entity
      ->getEntityTypeId());
    $elements[$delta] = $view_builder
      ->view($entity, $view_mode, $entity
      ->language()
      ->getId());

    // Add a resource attribute to set the mapping property's value to the
    // entity's url. Since we don't know what the markup of the entity will
    // be, we shouldn't rely on it for structured data such as RDFa.
    if (!empty($items[$delta]->_attributes) && !$entity
      ->isNew() && $entity
      ->hasLinkTemplate('canonical')) {
      $items[$delta]->_attributes += [
        'resource' => $entity
          ->toUrl()
          ->toString(),
      ];
    }
  }
  return $elements;
}