function OEmbedFormatter::viewElements

Same name and namespace in other branches
  1. 9 core/modules/media/src/Plugin/Field/FieldFormatter/OEmbedFormatter.php \Drupal\media\Plugin\Field\FieldFormatter\OEmbedFormatter::viewElements()
  2. 8.9.x core/modules/media/src/Plugin/Field/FieldFormatter/OEmbedFormatter.php \Drupal\media\Plugin\Field\FieldFormatter\OEmbedFormatter::viewElements()
  3. 11.x core/modules/media/src/Plugin/Field/FieldFormatter/OEmbedFormatter.php \Drupal\media\Plugin\Field\FieldFormatter\OEmbedFormatter::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/modules/media/src/Plugin/Field/FieldFormatter/OEmbedFormatter.php, line 162

Class

OEmbedFormatter
Plugin implementation of the 'oembed' formatter.

Namespace

Drupal\media\Plugin\Field\FieldFormatter

Code

public function viewElements(FieldItemListInterface $items, $langcode) {
  $element = [];
  $max_width = $this->getSetting('max_width');
  $max_height = $this->getSetting('max_height');
  foreach ($items as $delta => $item) {
    $main_property = $item->getFieldDefinition()
      ->getFieldStorageDefinition()
      ->getMainPropertyName();
    $value = $item->{$main_property};
    if (empty($value)) {
      continue;
    }
    try {
      $resource_url = $this->urlResolver
        ->getResourceUrl($value, $max_width, $max_height);
      $resource = $this->resourceFetcher
        ->fetchResource($resource_url);
    } catch (ResourceException $exception) {
      $this->logger
        ->error("Could not retrieve the remote URL (@url): %error", [
        '@url' => $value,
        '%error' => $exception->getPrevious() ? $exception->getPrevious()
          ->getMessage() : $exception->getMessage(),
        'exception' => $exception,
      ]);
      continue;
    }
    if ($resource->getType() === Resource::TYPE_LINK) {
      $element[$delta] = [
        '#title' => $resource->getTitle(),
        '#type' => 'link',
        '#url' => Url::fromUri($value),
      ];
    }
    elseif ($resource->getType() === Resource::TYPE_PHOTO) {
      $element[$delta] = [
        '#theme' => 'image',
        '#uri' => $resource->getUrl()
          ->toString(),
        '#width' => $resource->getWidth(),
        '#height' => $resource->getHeight(),
        '#attributes' => [
          'loading' => $this->getSetting('loading')['attribute'],
        ],
      ];
    }
    else {
      $url = Url::fromRoute('media.oembed_iframe', [], [
        'absolute' => TRUE,
        'query' => [
          'url' => $value,
          'max_width' => $max_width,
          'max_height' => $max_height,
          'hash' => $this->iFrameUrlHelper
            ->getHash($value, $max_width, $max_height),
        ],
      ]);
      $domain = $this->config
        ->get('iframe_domain');
      if ($domain) {
        $url->setOption('base_url', $domain);
      }
      // Render videos and rich content in an iframe for security reasons.
      // @see: https://oembed.com/#section3
      $element[$delta] = [
        '#type' => 'html_tag',
        '#tag' => 'iframe',
        '#attributes' => [
          'src' => $url->toString(),
          'scrolling' => FALSE,
          // External service is not supposed to send something larger
          // than the max width or max height, so those values should be used.
'width' => $resource->getWidth() ?: $max_width,
          'height' => $resource->getHeight() ?: $max_height,
          'class' => [
            'media-oembed-content',
          ],
          'loading' => $this->getSetting('loading')['attribute'],
        ],
        '#attached' => [
          'library' => [
            'media/oembed.formatter',
          ],
        ],
      ];
      // An empty title attribute will disable title inheritance, so only
      // add it if the resource has a title.
      $title = $resource->getTitle();
      if ($title) {
        $element[$delta]['#attributes']['title'] = $title;
      }
      CacheableMetadata::createFromObject($resource)->addCacheTags($this->config
        ->getCacheTags())
        ->applyTo($element[$delta]);
    }
  }
  return $element;
}

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