datafield-1.x-dev/src/Plugin/DataField/FieldFormatter/ImageFormatter.php

src/Plugin/DataField/FieldFormatter/ImageFormatter.php
<?php

namespace Drupal\datafield\Plugin\DataField\FieldFormatter;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Attribute\FieldFormatter;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\datafield\Plugin\DataFieldFormatterInterface;
use Drupal\file\FileUsage\FileUsageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the 'image' formatter.
 */
#[FieldFormatter(
  id: 'image',
  label: new TranslatableMarkup('Image'),
  field_types: ['image', 'file'],
)]
class ImageFormatter implements DataFieldFormatterInterface, ContainerFactoryPluginInterface {
  use StringTranslationTrait;

  /**
   * Constructs a TableFileFormatter object.
   *
   * @param string $plugin_id
   *   The plugin_id for the formatter.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param mixed $field_definition
   *   The definition of the field to which the formatter is associated.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\file\FileUsage\FileUsageInterface $fileUsage
   *   The file usage service.
   * @param \Drupal\Core\File\FileUrlGeneratorInterface $fileUrlGenerator
   *   The file url generator.
   * @param \Drupal\Core\Session\AccountInterface $currentUser
   *   The current user service.
   */
  public function __construct($plugin_id, $plugin_definition, $field_definition, protected EntityTypeManagerInterface $entityTypeManager, protected readonly FileUsageInterface $fileUsage, protected readonly FileUrlGeneratorInterface $fileUrlGenerator, protected readonly AccountInterface $currentUser) {
    unset($plugin_id, $plugin_definition, $field_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration,
      $container->get('entity_type.manager'),
      $container->get('file.usage'),
      $container->get('file_url_generator'),
      $container->get('current_user'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return [
      'image_style' => 'thumbnail',
      'image_link' => '',
      'image_loading' => [
        'attribute' => 'lazy',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $settings = $form['#settings'];
    $image_styles = image_style_options(FALSE);
    $description_link = Link::fromTextAndUrl(
      $this->t('Configure Image Styles'),
      Url::fromRoute('entity.image_style.collection')
    );
    $element['image_style'] = [
      '#title' => $this->t('Image style'),
      '#type' => 'select',
      '#default_value' => $settings['image_style'] ?? self::defaultSettings()['image_style'],
      '#empty_option' => $this->t('None (original image)'),
      '#options' => $image_styles,
      '#description' => $description_link->toRenderable() + [
        '#access' => $this->currentUser->hasPermission('administer image styles'),
      ],
    ];
    $link_types = [
      'content' => $this->t('Content'),
      'file' => $this->t('File'),
      'modal' => $this->t('Open with colorbox'),
    ];
    $element['image_link'] = [
      '#title' => $this->t('Link image to'),
      '#type' => 'select',
      '#default_value' => $settings['image_link'] ?? self::defaultSettings()['image_link'],
      '#empty_option' => $this->t('Nothing'),
      '#options' => $link_types,
    ];

    $image_loading = $settings['image_loading'] ?? self::defaultSettings()['image_loading'];
    $element['image_loading'] = [
      '#type' => 'details',
      '#title' => $this->t('Image loading'),
      '#weight' => 10,
      '#description' => $this->t('Lazy render images with native image loading attribute (<em>loading="lazy"</em>). This improves performance by allowing browsers to lazily load images.'),
    ];
    $loading_attribute_options = [
      'lazy' => $this->t('Lazy (<em>loading="lazy"</em>)'),
      'eager' => $this->t('Eager (<em>loading="eager"</em>)'),
    ];
    $element['image_loading']['attribute'] = [
      '#title' => $this->t('Image loading attribute'),
      '#type' => 'radios',
      '#default_value' => $image_loading['attribute'] ?? 'lazy',
      '#options' => $loading_attribute_options,
      '#description' => $this->t('Select the loading attribute for images. <a href=":link">Learn more about the loading attribute for images.</a>', [
        ':link' => 'https://html.spec.whatwg.org/multipage/urls-and-fetching.html#lazy-loading-attributes',
      ]),
    ];
    $element['image_loading']['attribute']['lazy']['#description'] = $this->t('Delays loading the image until that section of the page is visible in the browser. When in doubt, lazy loading is recommended.');
    $element['image_loading']['attribute']['eager']['#description'] = $this->t('Force browsers to download an image as soon as possible. This is the browser default for legacy reasons. Only use this option when the image is always expected to render.');

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary($settings = []) {
    $summary = [];

    $image_styles = image_style_options(FALSE);
    // Unset possible 'No defined styles' option.
    unset($image_styles['']);
    // Styles could be lost because of enabled/disabled modules that defines
    // their styles in code.
    $image_style_setting = $settings['image_style'] ?? 'thumbnail';
    if (isset($image_styles[$image_style_setting])) {
      $summary[] = $this->t('Image style: @style', ['@style' => $image_styles[$image_style_setting]]);
    }
    else {
      $summary[] = $this->t('Original image');
    }

    $link_types = [
      'content' => $this->t('Linked to content'),
      'file' => $this->t('Linked to file'),
      'modal' => $this->t('Open with colorbox'),
    ];
    // Display this setting only if image is linked.
    $image_link_setting = $settings['image_link'] ?? self::defaultSettings()['image_link'];
    if (isset($link_types[$image_link_setting])) {
      $summary[] = $link_types[$image_link_setting];
    }

    $image_loading = $settings['image_loading'] ?? self::defaultSettings()['image_loading'];
    $summary[] = $this->t('Image loading: @attribute', [
      '@attribute' => $image_loading['attribute'],
    ]);

    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements($item, $langcode) {
    if (empty($item->value) || !is_numeric($item->value)) {
      return $item->value;
    }
    $fid = $item->value;
    if (empty($fid)) {
      return $item->value;
    }
    $file = $this->entityTypeManager->getStorage('file')->load($fid);
    if (empty($file)) {
      return $item->value;
    }
    $url = NULL;
    $title = '';
    $image_link_setting = $item->settings['image_link'] ?? self::defaultSettings()['image_link'];
    // Check if the formatter involves a link.
    $image_uri = $file->getFileUri();
    $mime = $file->getMimeType();
    $usage = $this->fileUsage->listUsage($file);
    if (empty($usage)) {
      $entity = $item->entity ?? $item->getEntity();
      $this->fileUsage->add($file, 'datafield', $entity->getEntityTypeId(), $entity->id());
    }
    if (strpos($mime, 'image/') !== 0) {
      return [
        '#theme' => 'file_link',
        '#file' => $file,
        '#description' => !empty($item->description) ? $item->description : NULL,
        '#cache' => ['tags' => $file->getCacheTags()],
      ];
    }
    if ($image_link_setting == 'content') {
      $entity = $item->entity;
      $url = $entity->hasLinkTemplate('canonical') ? $entity->toUrl() : '';
      $label_field = $entity->getEntityType()->getKey('label');
      $title = $label_field ? $entity->get($label_field)?->value : '';
      if (empty($title) && method_exists($entity, 'getDisplayName')) {
        $title = $entity->getDisplayName();
      }
    }
    else {
      $url = $this->fileUrlGenerator->generate($image_uri);
    }

    $image_style_setting = $item->settings['image_style'] ?? 'thumbnail';

    // Collect cache tags to be added for each item in the field.
    $base_cache_tags = [];
    if (!empty($image_style_setting)) {
      $image_style = $this->entityTypeManager->getStorage('image_style')
        ->load($image_style_setting);
      $base_cache_tags = $image_style->getCacheTags();
    }

    $cache_tags = Cache::mergeTags($base_cache_tags, $file->getCacheTags());
    $image_loading_settings = $item->settings['image_loading'] ?? ['attribute' => 'lazy'];
    $item_attributes['loading'] = $image_loading_settings['attribute'] ?? 'lazy';
    $item_attributes['class'] = ['img-fluid'];
    switch ($image_link_setting) {
      case 'content':
        return [
          '#theme' => 'image_formatter',
          '#item' => (object) [
            'entity' => $file,
            'uri' => $image_uri,
            'alt' => $title,
            'title' => $title,
            'width' => 100,
            'height' => 100,
          ],
          '#item_attributes' => $item_attributes,
          '#image_style' => $image_style_setting,
          '#url' => $url,
          '#attributes' => [
            'class' => [
              'use-ajax',
            ],
            'data-dialog-type' => 'modal',
            'data-dialog-options' => Json::encode([
              'width' => '80%',
              'title' => $title,
            ]),
          ],
          '#cache' => [
            'tags' => $cache_tags,
          ],
        ];

      case 'file':
        return [
          '#theme' => 'image',
          '#uri' => $file->getFileUri(),
          "#attributes" => ['class' => ['img-fluid']],
          '#url' => $url,
        ];

      case 'modal':
        return [
          '#type' => 'link',
          '#title' => [
            '#theme' => 'image_style',
            '#style_name' => $image_style_setting,
            '#uri' => $file->getFileUri(),
            "#attributes" => [
              'class' => ['img-fluid', 'img-thumbnail'],
            ],
          ],
          '#attached' => ['library' => ['colorbox/colorbox']],
          '#attributes' => [
            'class' => ['colorbox'],
            'data-colorbox-gallery' => 'gallery-image',
            'data-dialog-type' => 'modal',
            'data-dialog-options' => Json::encode(['width' => '80%']),
          ],
          '#url' => $url,
        ];

      default:
        return [
          '#theme' => 'image_style',
          '#style_name' => $image_style_setting,
          '#uri' => $file->getFileUri(),
          "#attributes" => [
            'class' => ['img-fluid', 'img-thumbnail'],
          ],
          '#url' => $url,
          '#cache' => [
            'tags' => $file->getCacheTags(),
          ],
        ];
    }

  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc