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

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

namespace Drupal\improvements\Plugin\Field\FieldFormatter;

use Drupal\breakpoint\BreakpointInterface;
use Drupal\breakpoint\BreakpointManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\FileInterface;
use Drupal\image\Entity\ImageStyle;
use Drupal\image\ImageStyleInterface;
use Drupal\image\Plugin\Field\FieldType\ImageItem;

/**
 * @FieldFormatter(
 *   id = "image_with_mobile_alternative_one_field",
 *   label = @Translation("Image with mobile alternative (one field)"),
 *   field_types = {
 *     "image",
 *   }
 * )
 */
class ImageWithMobileAlternativeOneFieldFormatter extends FormatterBase {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings(): array {
    return [
      'image_style' => '',
      'breakpoint_group' => '',
      'mobile_breakpoint' => '',
      'mobile_image_style' => '',
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritDoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state): array {
    $image_styles_options = image_style_options(FALSE);
    $breakpoint_manager = \Drupal::service('breakpoint.manager'); /** @var BreakpointManagerInterface $breakpoint_manager */
    $breakpoint_group = $this->getSetting('breakpoint_group');

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

    // Breakpoint group
    $elements['breakpoint_group'] = [
      '#type' => 'select',
      '#title' => t('Breakpoint group'),
      '#options' => $breakpoint_manager->getGroups(),
      '#default_value' => $breakpoint_group,
    ];

    // @TODO Add update form on ajax
    if ($breakpoint_group) {
      // Mobile breakpoint
      $elements['mobile_breakpoint'] = [
        '#type' => 'select',
        '#title' => t('Mobile breakpoint'),
        '#options' => $this->getMobileBreakpointOptions($breakpoint_group),
        '#default_value' => $this->getSetting('mobile_breakpoint'),
      ];

      // Mobile image style
      $elements['mobile_image_style'] = [
        '#type' => 'select',
        '#title' => t('Mobile image style'),
        '#options' => $image_styles_options,
        '#empty_option' => t('None (original image)'),
        '#default_value' => $this->getSetting('mobile_image_style'),
      ];
    }

    return $elements;
  }

  /**
   * {@inheritDoc}
   */
  public function settingsSummary(): array {
    $summary = [];

    if ($image_style = $this->getSetting('image_style')) {
      $summary[] = t('Default image style') . ': ' . $this->getSetting('image_style');
    }
    if ($breakpoint_group = $this->getSetting('breakpoint_group')) {
      $summary[] = t('Breakpoint group') . ': ' . $breakpoint_group;
    }
    if ($mobile_breakpoint = $this->getSetting('mobile_breakpoint')) {
      $summary[] = t('Mobile breakpoint') . ': ' . $mobile_breakpoint;
    }
    if ($mobile_image_style = $this->getSetting('mobile_image_style')) {
      $summary[] = t('Mobile image style') . ': ' . $mobile_image_style;
    }

    return $summary;
  }

  /**
   * {@inheritDoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode): array {
    $elements = [];

    if ($items->isEmpty()) {
      return $elements;
    }

    $formatter_settigns = $this->getSettings();
    $breakpoint_manager = \Drupal::service('breakpoint.manager'); /** @var BreakpointManagerInterface $breakpoint_manager */
    $mobile_breakpoint = $breakpoint_manager->getBreakpointsByGroup($formatter_settigns['breakpoint_group'])[$formatter_settigns['mobile_breakpoint']];
    /** @var ImageStyleInterface $default_image_style */
    $default_image_style = $formatter_settigns['image_style'] ? ImageStyle::load($formatter_settigns['image_style']) : NULL;

    $default_image_item = $items->get(0); /** @var ImageItem $default_image_item */
    $mobile_image_item = $items->get(1); /** @var ImageItem $mobile_image_item */

    $default_image_entity = $default_image_item->entity; /** @var FileInterface $default_image_entity */
    $mobile_image_entity = $mobile_image_item ? $mobile_image_item->entity : NULL; /** @var FileInterface $mobile_image_entity */

    $default_image_url = $this->getImageStyleUrl($default_image_entity->getFileUri(), $formatter_settigns['image_style']);
    $default_image_dimensions = ['width' => $default_image_item->width, 'height' => $default_image_item->height];

    if ($default_image_style) {
      $default_image_style->transformDimensions($default_image_dimensions, $default_image_entity->getFileUri());
    }

    $elements[0] = [
      '#theme' => 'picture',
      // Default image
      '#img' => [
        'src' => $default_image_url,
        'alt' => '',
      ] + $default_image_dimensions,
    ];

    if ($mobile_image_entity) {
      $mobile_image_url = $this->getImageStyleUrl($mobile_image_entity->getFileUri(), $formatter_settigns['mobile_image_style']);

      // Mobile image
      $elements[0]['#source'] = [
        'mobile' => [
          'srcset' => $mobile_image_url,
          'type' => $mobile_image_entity->getMimeType(),
          'media' => $mobile_breakpoint->getMediaQuery(),
        ],
      ];
    }

    $elements['#all_in_one'] = TRUE;

    return $elements;
  }

  /**
   * {@inheritDoc}
   */
  public static function isApplicable(FieldDefinitionInterface $field_definition): bool {
    return $field_definition->getFieldStorageDefinition()->isMultiple();
  }

  /**
   * Return options for "mobile breakpoint" setting.
   */
  private function getMobileBreakpointOptions(string $breakpoint_group): array {
    $breakpoint_manager = \Drupal::service('breakpoint.manager'); /** @var BreakpointManagerInterface $breakpoint_manager */
    $breakpoints = $breakpoint_manager->getBreakpointsByGroup($breakpoint_group);
    return array_map(function ($breakpoint) {
      /** @var BreakpointInterface $breakpoint */
      return $breakpoint->getLabel();
    }, $breakpoints);
  }

  /**
   * Return url for image with image style.
   */
  private function getImageStyleUrl(string $path, string $style_name): string {
    $file_url_generator = \Drupal::service('file_url_generator');

    if ($style_name && ($image_style = ImageStyle::load($style_name))) {
      return $file_url_generator->transformRelative($image_style->buildUrl($path));
    }

    return $file_url_generator->generateString($path);
  }

}

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

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