You are here

public function ConfigDefaultImageFormatter::viewElements in Config default image 8

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 ImageFormatter::viewElements

File

src/Plugin/Field/FieldFormatter/ConfigDefaultImageFormatter.php, line 172

Class

ConfigDefaultImageFormatter
Plugin implementation of the 'image' formatter.

Namespace

Drupal\config_default_image\Plugin\Field\FieldFormatter

Code

public function viewElements(FieldItemListInterface $items, $langcode) {
  $elements = parent::viewElements($items, $langcode);
  if (empty($elements)) {
    $default_image = $this
      ->getSetting('default_image');
    $image_path = $default_image['path'];
    if (!empty($image_path)) {
      if ($default_image['use_image_style']) {

        // $image_path must be ready for
        // Drupal\image\Entity\ImageStyle::buildUri().
        // This needs a valid scheme.
        // As long as https://www.drupal.org/project/drupal/issues/1308152 is
        // not fixed, files stored outside from public, private and temporary
        // directories have no scheme.
        // So that if our path has no scheme, we copy the file to the public
        // files directory and add it as scheme.
        if (!StreamWrapperManager::getScheme($image_path)) {
          $image_path = ltrim($image_path, '/');
          $destination = 'public://config_default_image/' . $image_path;
          $directory = $this->fileSystem
            ->dirname($destination);
          $this->fileSystem
            ->prepareDirectory($directory, $this->fileSystem::CREATE_DIRECTORY);
          if (!file_exists($destination)) {
            $image_path = $this->fileSystem
              ->copy($image_path, $destination);
          }
          else {
            $image_path = $destination;
          }
        }
      }
      $file = File::create([
        'uid' => 0,
        'filename' => $this->fileSystem
          ->basename($image_path),
        'uri' => $image_path,
        'status' => 1,
      ]);
      $url = NULL;
      $image_link_setting = $this
        ->getSetting('image_link');

      // Check if the formatter involves a link.
      if ($image_link_setting == 'content') {
        $entity = $items
          ->getEntity();
        if (!$entity
          ->isNew()) {
          $url = $entity
            ->toUrl();
        }
      }
      elseif ($image_link_setting == 'file') {
        $link_file = TRUE;
      }
      $cache_tags = [];
      $cache_contexts = [];
      if (isset($link_file)) {
        $cache_contexts[] = 'url.site';
      }

      // @see ImageFormatterBase
      // Clone the FieldItemList into a runtime-only object for the formatter,
      // so that the fallback image can be rendered without affecting the
      // field values in the entity being rendered.
      $items = clone $items;
      $items
        ->setValue([
        'target_id' => $file
          ->id(),
        'alt' => $default_image['alt'],
        'title' => $default_image['title'],
        'width' => $default_image['width'],
        'height' => $default_image['height'],
        'entity' => $file,
        '_loaded' => TRUE,
        '_is_default' => TRUE,
      ]);
      $item = $items[0];

      // Extract field item attributes for the theme function, and unset them
      // from the $item so that the field template does not re-render them.
      $item_attributes = $item->_attributes;
      unset($item->_attributes);
      $elements[] = [
        '#theme' => 'image_formatter',
        '#item' => $item,
        '#item_attributes' => $item_attributes,
        '#image_style' => $default_image['use_image_style'] ? $this
          ->getSetting('image_style') : FALSE,
        '#url' => $url,
        '#cache' => [
          'tags' => $cache_tags,
          'contexts' => $cache_contexts,
        ],
      ];
    }
  }
  return $elements;
}