You are here

public function SvgImageFieldFormatter::viewElements in SVG Image Field 2.1.x

Same name and namespace in other branches
  1. 8 src/Plugin/Field/FieldFormatter/SvgImageFieldFormatter.php \Drupal\svg_image_field\Plugin\Field\FieldFormatter\SvgImageFieldFormatter::viewElements()
  2. 2.0.x src/Plugin/Field/FieldFormatter/SvgImageFieldFormatter.php \Drupal\svg_image_field\Plugin\Field\FieldFormatter\SvgImageFieldFormatter::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

src/Plugin/Field/FieldFormatter/SvgImageFieldFormatter.php, line 208

Class

SvgImageFieldFormatter
Plugin implementation of the 'svg_formatter' formatter.

Namespace

Drupal\svg_image_field\Plugin\Field\FieldFormatter

Code

public function viewElements(FieldItemListInterface $items, $langcode) {
  $elements = [];
  $attributes = [];
  if ($this
    ->getSetting('apply_dimensions')) {
    $attributes['width'] = $this
      ->getSetting('width');
    $attributes['height'] = $this
      ->getSetting('height');
  }
  $url = NULL;
  $image_link_setting = $this
    ->getSetting('link');

  // Check if the formatter involves a link.
  if ($image_link_setting == 'content') {
    $entity = $items
      ->getEntity();
    if (!$entity
      ->isNew()) {
      $url = $entity
        ->toUrl();
    }
  }
  foreach ($items as $delta => $item) {
    if (!$item->entity) {
      continue;
    }
    $uri = $item->entity
      ->getFileUri();
    if (file_exists($uri) === FALSE) {
      $this->logger
        ->error('The specified file %file could not be displayed by image formatter due file not exists.', [
        '%file' => $uri,
      ]);
      continue;
    }
    $filename = $item->entity
      ->getFilename();
    $alt = !empty($item->alt) ? $item->alt : $this
      ->generateAltAttribute($filename);
    if ($this
      ->getSetting('enable_alt')) {
      if ($alt == '""') {
        $alt = '';
      }
      $attributes['alt'] = $alt;
    }
    if ($this
      ->getSetting('enable_title') && !empty($item->title)) {
      $attributes['title'] = $item->title;
    }
    $svg_data = NULL;
    if ($this
      ->getSetting('inline')) {
      $svg_file = file_get_contents($uri);
      $dom = new \DOMDocument();
      libxml_use_internal_errors(TRUE);
      $dom
        ->loadXML($svg_file);
      if ($this
        ->getSetting('force_fill')) {
        $dom->documentElement
          ->setAttribute('fill', 'currentColor');
      }
      if (isset($dom->documentElement)) {
        if ($this
          ->getSetting('apply_dimensions')) {
          $dom->documentElement
            ->setAttribute('height', $attributes['height']);
          $dom->documentElement
            ->setAttribute('width', $attributes['width']);
        }
        $svg_data = $dom
          ->saveXML($dom->documentElement);
      }
      else {
        $svg_data = $dom
          ->saveXML();
      }
      if ($this
        ->getSetting('sanitize')) {
        $svgSanitizer = new Sanitizer();
        if ($this
          ->getSetting('sanitize_remote')) {
          $svgSanitizer
            ->removeRemoteReferences(TRUE);
        }
        $svg_data = $svgSanitizer
          ->sanitize($svg_data);
      }
    }
    $cache_contexts = [];
    if ($image_link_setting == 'file') {

      // @todo Wrap in file_url_transform_relative(). This is currently
      // impossible. As a work-around, we currently add the 'url.site' cache
      // context to ensure different file URLs are generated for different
      // sites in a multisite setup, including HTTP and HTTPS versions of the
      // same site. Fix in https://www.drupal.org/node/2646744.
      $url = Url::fromUri(file_create_url($uri));
      $cache_contexts[] = 'url.site';
    }
    $elements[$delta] = [
      '#theme' => 'svg_image_field_formatter',
      '#inline' => $this
        ->getSetting('inline') ? TRUE : FALSE,
      '#attributes' => $attributes,
      '#uri' => $this
        ->getSetting('inline') ? NULL : $uri,
      '#svg_data' => $svg_data,
      '#link_url' => $url,
      '#cache' => [
        'tags' => $item->entity
          ->getCacheTags(),
        'contexts' => $cache_contexts,
      ],
    ];
  }
  return $elements;
}