view_mode_crop-1.0.x-dev/src/Plugin/Field/FieldFormatter/ViewModeCropImageFormatterTrait.php

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

namespace Drupal\view_mode_crop\Plugin\Field\FieldFormatter;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\field\FieldConfigInterface;
use Drupal\file\FileInterface;
use Drupal\media\MediaInterface;
use Drupal\view_mode_crop\CropImageHelper;
use Drupal\view_mode_crop\Plugin\Field\FieldType\ViewModeCropEntityReferenceItem;

/**
 * Trait to support cropped images.
 */
trait ViewModeCropImageFormatterTrait {

  /**
   * Get the entities to be viewed.
   *
   * This overrides the file uri's to point to the cropped image files.
   *
   * @param \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items
   *   The items.
   * @param mixed $langcode
   *   The langcode.
   *
   * @return \Drupal\Core\Entity\EntityInterface[]
   *   The entities to view.
   *
   * @throws \Drupal\Core\TypedData\Exception\MissingDataException
   */
  protected function getEntitiesToView(EntityReferenceFieldItemListInterface $items, $langcode) {
    $entities = [];

    // Add the default image if needed.
    if ($items->isEmpty()) {
      $default_image = $this->getFieldSetting('default_image');
      // If we are dealing with a configurable field, look in both
      // instance-level and field-level settings.
      if (empty($default_image['uuid']) && $this->fieldDefinition instanceof FieldConfigInterface) {
        $default_image = $this->fieldDefinition->getFieldStorageDefinition()
          ->getSetting('default_image');
      }
      if (!empty($default_image['uuid']) && $file = \Drupal::service('entity.repository')
        ->loadEntityByUuid('file', $default_image['uuid'])) {
        // 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,
        ]);
        // @phpstan-ignore-next-line
        $file->_referringItem = $items[0];
      }
    }

    foreach ($items as $delta => $item) {
      // Ignore items where no entity could be loaded in prepareView().
      if (!empty($item->_loaded)) {
        if (!isset($item->entity)) {
          throw new \RuntimeException('Missing entity');
        }
        $entity = clone $item->entity;

        // Set the entity in the correct language for display.
        if ($entity instanceof TranslatableInterface) {
          $entity = \Drupal::service('entity.repository')->getTranslationFromContext($entity, $langcode);
        }

        $access = $this->checkAccess($entity);
        // Add the access result's cacheability, ::view() needs it.
        // @phpstan-ignore-next-line
        $item->_accessCacheability = CacheableMetadata::createFromObject($access);
        if ($access->isAllowed()) {
          // Add the referring item, in case the formatter needs it.
          $entity->_referringItem = $items[$delta];
          $entities[$delta] = $entity;
        }
      }
    }

    $referring_item = NULL;
    $items_entity = $items->getEntity();

    if ($items_entity instanceof MediaInterface && isset($items_entity->_referringItem)) {
      $referring_item = $items_entity->_referringItem;
    }

    foreach ($entities as $delta => $entity) {
      if (!$entity instanceof FileInterface) {
        continue;
      }
      $image_item = $items->get($delta);

      if ($referring_item instanceof ViewModeCropEntityReferenceItem) {
        $crop_data = $referring_item->getViewModeCropData();
        // Get the delta from the parent entity of the referencing field.
        foreach ($referring_item->getParent() as $parent_entity_field_item_delta => $parent_entity_field_item) {
          if ($parent_entity_field_item->getPropertyPath() === $referring_item->getPropertyPath()) {
            $delta = $parent_entity_field_item_delta;
            break;
          }
        }
      }
      else {
        /**
         * @var \Drupal\view_mode_crop\Plugin\Field\FieldType\ViewModeCropImageItem $image_item
         */
        $crop_data = $image_item->getViewModeCropData();
      }
      $view_mode = $this->viewMode;
      if (!isset($crop_data[$view_mode])) {
        // View mode is not set. Fall back to default.
        $view_mode = 'default';
      }

      if (
        !isset($crop_data[$view_mode]) ||
        $crop_data[$view_mode]->x === NULL ||
        $crop_data[$view_mode]->y === NULL ||
        $crop_data[$view_mode]->w === NULL ||
        $crop_data[$view_mode]->h === NULL
      ) {
        continue;
      }

      $uri = CropImageHelper::getUri($image_item, $delta, $view_mode);

      if (file_exists($uri)) {
        if (!isset($entity->_initialUri)) {
          // @phpstan-ignore-next-line
          $entity->_initialUri = $entity->get('uri')->getString();
        }
        $entity->set('uri', $uri);
      }

      // Save the cropped dimensions, This will be used in
      // ViewModeCropImageFormatter::viewElements.
      /**
       * @var object $entity
       */
      $entity->viewModeCropWidth = $crop_data[$view_mode]->w;
      $entity->viewModeCropHeight = $crop_data[$view_mode]->h;
    }

    return $entities;
  }

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

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

    $items_entity = $items->getEntity();
    $referring_item = NULL;
    if ($items_entity instanceof MediaInterface) {
      if (!isset($items_entity->_referringItem)) {
        throw new \RuntimeException('Missing referringItem');
      }
      $referring_item = $items_entity->_referringItem;
    }

    $field_name = $items->getFieldDefinition()->getName();

    foreach ($files as $delta => $file) {
      if (isset($elements[$delta]['#item'])) {
        if (!empty($file->viewModeCropWidth) && !empty($file->viewModeCropHeight)) {
          // Update the dimensions which are saved in
          // ViewModeCropImageFormatterGetEntitiesToViewTrait::getEntitiesToView.
          $elements[$delta]['#item']->width = $file->viewModeCropWidth;
          $elements[$delta]['#item']->height = $file->viewModeCropHeight;
        }
      }

      foreach ($items->getEntity()->getCacheTags() as $tag) {
        $elements[$delta]['#cache']['tags'][] = $tag;
        $elements[$delta]['#cache']['tags'][] = $tag . ':' . $field_name;
        $elements[$delta]['#cache']['tags'][] = $tag . ':' . $field_name . ':' . $delta;
      }

      if ($referring_item) {
        foreach ($referring_item->getEntity()->getCacheTags() as $tag) {
          $elements[$delta]['#cache']['tags'][] = $tag;
          $elements[$delta]['#cache']['tags'][] = $tag . ':' . $field_name;
          $elements[$delta]['#cache']['tags'][] = $tag . ':' . $field_name . ':' . $delta;
        }
      }

      $elements[$delta]['#cache']['tags'][] = $items->getFieldDefinition()
        ->getName();
    }

    return $elements;
  }

}

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

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