improvements-2.x-dev/src/Plugin/Field/FieldFormatter/ExtendedImageFormatter.php

src/Plugin/Field/FieldFormatter/ExtendedImageFormatter.php
<?php

namespace Drupal\improvements\Plugin\Field\FieldFormatter;

use Drupal\Core\Cache\Cache;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\druhels\EntityHelper;
use Drupal\image\Entity\ImageStyle;
use Drupal\image\ImageStyleInterface;
use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatterBase;

/**
 * @FieldFormatter(
 *   id = "extended_image_formatter",
 *   label = @Translation("Extended image formatter"),
 *   field_types = {
 *     "image",
 *   },
 * )
 */
class ExtendedImageFormatter extends ImageFormatterBase {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings(): array {
    return [
      'image_style' => '',
      'first_image_style' => '',
      'image_link' => '',
      'image_link_source_field' => '',
      'image_link_style' => '',
      'items_limit' => 0,
      'default_image_type' => 'default',
      'default_image_custom' => '',
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state): array {
    $form = parent::settingsForm($form, $form_state);
    $field_name = $this->fieldDefinition->getName();
    $image_styles_options = image_style_options(FALSE);

    $form['image_style'] = [
      '#type' => 'select',
      '#title' => t('Image style'),
      '#options' => $image_styles_options,
      '#empty_option' => t('None (original image)'),
      '#default_value' => $this->getSetting('image_style'),
    ];

    $form['first_image_style'] = [
      '#type' => 'select',
      '#title' => t('First image style'),
      '#options' => $image_styles_options,
      '#empty_option' => t('None (original image)'),
      '#default_value' => $this->getSetting('first_image_style'),
    ];

    $form['image_link'] = [
      '#type' => 'select',
      '#title' => t('Link image to'),
      '#empty_option' => t('Nothing'),
      '#options' => [
        'content' => t('Content'),
        'file' => t('File'),
        'url_from_field' => t('Url from field'),
      ],
      '#default_value' => $this->getSetting('image_link'),
    ];

    $link_fields_definitions = EntityHelper::getBundleFieldDefinitionsByType($this->fieldDefinition->getTargetEntityTypeId(), $this->fieldDefinition->getTargetBundle(), 'link');
    $image_link_source_field_options = array_map(fn($field_definition) => $field_definition->getLabel(), $link_fields_definitions);
    $form['image_link_source_field'] = [
      '#type' => 'select',
      '#title' => t('Image link source field'),
      '#options' => $image_link_source_field_options,
      '#default_value' => $this->getSetting('image_link_source_field'),
      '#states' => [
        'visible' => [
          'select[name="fields[' . $field_name . '][settings_edit_form][settings][image_link]"]' => [
            'value' => 'url_from_field',
          ],
        ],
      ],
    ];

    $form['image_link_style'] = [
      '#type' => 'select',
      '#title' => t('Image link style'),
      '#options' => $image_styles_options,
      '#empty_option' => t('None (original image)'),
      '#default_value' => $this->getSetting('image_link_style'),
      '#states' => [
        'visible' => [
          'select[name="fields[' . $field_name . '][settings_edit_form][settings][image_link]"]' => [
            'value' => 'file',
          ],
        ],
      ],
    ];

    $form['default_image_type'] = [
      '#type' => 'select',
      '#title' => t('Default image'),
      '#options' => [
        'default' => t('Default'),
        'custom' => t('Custom'),
      ],
      '#default_value' => $this->getSetting('default_image_type'),
    ];

    $form['default_image_custom'] = [
      '#type' => 'textfield',
      '#title' => t('Custom default image'),
      '#default_value' => $this->getSetting('default_image_custom'),
      '#states' => [
        'visible' => [
          'select[name="fields[' . $field_name . '][settings_edit_form][settings][default_image_type]"]' => [
            'value' => 'custom',
          ],
        ],
      ],
    ];

    $form['items_limit'] = [
      '#type' => 'number',
      '#title' => t('Items limit'),
      '#min' => 0,
      '#default_value' => $this->getSetting('items_limit'),
    ];

    return $form;
  }

  /**
   * {@inheritDoc}
   */
  public function settingsSummary(): array {
    $summary[] = t('Image style') . ': ' . ($this->getSetting('image_style') ?: '~');
    $summary[] = t('First image style') . ': ' . ($this->getSetting('first_image_style') ?: '~');
    $summary[] = t('Link image to') . ': ' . ($this->getSetting('image_link') ?: '~');
    $summary[] = t('Image link style') . ': ' . ($this->getSetting('image_link_style') ?: '~');
    $summary[] = t('Default image type') . ': ' . $this->getSetting('default_image_type');
    $summary[] = t('Items limit') . ': ' . $this->getSetting('items_limit');

    return $summary;
  }

  /**
   * {@inheritdoc}
   *
   * @see \Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter::viewElements()
   */
  public function viewElements(FieldItemListInterface $items, $langcode): array {
    $formatter_settings = $this->getSettings();
    $elements = [];

    // Custom default image
    if ($items->isEmpty() && $formatter_settings['default_image_type'] == 'custom') {
      $elements[0] = [
        '#markup' => $formatter_settings['default_image_custom'],
      ];
      return $elements;
    }

    $files = $this->getEntitiesToView($items, $langcode);

    if (!$files) {
      return $elements;
    }

    $image_style_name = $formatter_settings['image_style'];
    $first_image_style_name = $formatter_settings['first_image_style'];
    $image_link_source = $formatter_settings['image_link'];
    $image_link_source_field = $formatter_settings['image_link_source_field'];
    $image_link_style_name = $formatter_settings['image_link_style'];
    $image_link_style = $image_link_style_name ? ImageStyle::load($image_link_style_name) : NULL; /** @var ImageStyleInterface $image_link_style */
    $items_limit = $formatter_settings['items_limit'];

    // Items limit
    if ($items_limit && count($files) > $items_limit) {
      $files = array_slice($files, 0, $items_limit);
    }

    // Get image link url
    $image_link_url = NULL;
    if ($image_link_source == 'content') {
      $entity = $items->getEntity();
      if (!$entity->isNew()) {
        $image_link_url = $entity->toUrl();
      }
    }
    elseif ($image_link_source == 'url_from_field') {
      $entity = $items->getEntity();
      if (
        !$entity->isNew() &&
        $image_link_source_field &&
        $entity->hasField($image_link_source_field) &&
        !($image_link_source_field_items = $entity->get($image_link_source_field))->isEmpty()
      ) {
        $image_link_url = $image_link_source_field_items[0]->getUrl();
      }
    }

    // Collect cache tags to be added for each item in the field
    $cache_tags = $this->getImageStylesCacheTags($image_style_name, $first_image_style_name);

    foreach ($files as $delta => $file) {
      // 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 = $file->_referringItem;
      $item_attributes = $item->_attributes;
      unset($item->_attributes);

      $elements[$delta] = [
        '#theme' => 'image_formatter',
        '#item' => $item,
        '#item_attributes' => $item_attributes,
        '#image_style' => ($first_image_style_name && $delta == 0) ? $first_image_style_name : $image_style_name,
        '#url' => $image_link_url,
        '#cache' => [
          'tags' => Cache::mergeTags($cache_tags, $file->getCacheTags()),
        ],
      ];
    }

    return $elements;
  }

  /**
   * Return image styles cache tags.
   */
  protected function getImageStylesCacheTags(...$image_style_names): array {
    $cache_tags = [];

    foreach ($image_style_names as $image_style_name) {
      if (
        $image_style_name &&
        ($image_style_cache_tags = ImageStyle::load($image_style_name)?->getCacheTags())
      ) {
        $cache_tags = Cache::mergeTags($cache_tags, $image_style_cache_tags);
      }
    }

    return $cache_tags;
  }

}

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

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