collection-8.x-1.x-dev/modules/collection_listings/src/Plugin/paragraphs/Behavior/ParagraphsCollectionListing.php

modules/collection_listings/src/Plugin/paragraphs/Behavior/ParagraphsCollectionListing.php
<?php

namespace Drupal\collection_listings\Plugin\paragraphs\Behavior;

use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\paragraphs\Entity\Paragraph;
use Drupal\paragraphs\Entity\ParagraphsType;
use Drupal\paragraphs\ParagraphInterface;
use Drupal\paragraphs\ParagraphsBehaviorBase;
use Drupal\Core\Entity\ContentEntityType;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a Paragraphs Collection Listing plugin.
 *
 * @ParagraphsBehavior(
 *   id = "collection_listing",
 *   label = @Translation("Collection listing"),
 *   description = @Translation("Configure collection listing settings."),
 *   weight = 1
 * )
 */
class ParagraphsCollectionListing extends ParagraphsBehaviorBase {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManager
   */
  protected $entityTypeManager;

  /**
   * The entity type bundle info service.
   *
   * @var \Drupal\Core\Entity\EntityTypeBundleInfo
   */
  protected $entityTypeBundleInfo;

  /**
   * The entity display repository.
   *
   * @var \Drupal\Core\Entity\EntityDisplayRepository
   */
  protected $entityDisplayRepository;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $instance = new static($configuration, $plugin_id, $plugin_definition, $container->get('entity_field.manager'));
    $instance->entityTypeManager = $container->get('entity_type.manager');
    $instance->entityTypeBundleInfo = $container->get('entity_type.bundle.info');
    $instance->entityDisplayRepository = $container->get('entity_display.repository');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function buildBehaviorForm(ParagraphInterface $paragraph, array &$form, FormStateInterface $form_state) {
    $form['count'] = [
      '#type' => 'number',
      '#title' => $this->t('Number of items'),
      '#description' => $this->t('Leave blank for all items.'),
      '#min' => 1,
      '#default_value' => $paragraph->getBehaviorSetting($this->getPluginId(), 'count'),
    ];

    $form['entity_settings'] = [
      '#type' => 'container',
    ];

    foreach ($this->getContentEntityTypeNames() as $machine_name => $label) {
      $view_mode_options = $this->getViewModesForEntity($machine_name);

      if (empty($view_mode_options)) {
        continue;
      }

      $view_mode_options = ['0' => 'Default'] + $view_mode_options;
      $bundle_opts = $paragraph->getBehaviorSetting($this->getPluginId(), ['entity_settings', $machine_name, 'bundles']) ?? [];

      $form['entity_settings'][$machine_name] = [
        '#type' => 'details',
        '#title' => t($label . ' settings'),
        '#open' => (bool) $bundle_opts,
      ];

      $form['entity_settings'][$machine_name]['bundles'] = [
        '#type' => 'checkboxes',
        '#title' => $this->t('Types to include:'),
        '#options' => $this->getBundlesForEntity($machine_name),
        '#default_value' => $bundle_opts,
      ];

      $form['entity_settings'][$machine_name]['view_mode'] = [
        '#type' => 'select',
        '#title' => $this->t('Display as:'),
        '#options' => $view_mode_options,
        '#default_value' => $paragraph->getBehaviorSetting($this->getPluginId(), ['entity_settings', $machine_name, 'view_mode']),
      ];
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function preprocess(&$variables) {
    $collection_field_names = self::getCollectionReferenceFieldNames($variables['paragraph']->type->entity);
    $collection_item_storage = $this->entityTypeManager->getStorage('collection_item');
    $applicable_entity_types = $this->getContentEntityTypeNames();
    $view_builders = [];

    foreach ($collection_field_names as $collection_field_name) {
      $paragraph = $variables['paragraph'];
      $collection = $paragraph->$collection_field_name->entity;
      $cache_tags = $collection->getCacheTags();
      $items = [];

      $query = $collection_item_storage->getQuery();
      $query->accessCheck(TRUE);
      $query->condition('collection', $paragraph->$collection_field_name->entity->id());

      if ($entity_type_settings = $paragraph->getBehaviorSetting($this->getPluginId(), 'entity_settings')) {
        $group = $query->orConditionGroup();

        foreach ($paragraph->getBehaviorSetting($this->getPluginId(), 'entity_settings') as $entity_type_name => $settings) {
          /** @var \Drupal\Core\Entity\ContentEntityType $entity_type */
          $entity_type = $this->entityTypeManager->getDefinition($entity_type_name);
          $entity_group = $query->andConditionGroup();

          if ($entity_type->getKey('published')) {
            $entity_group->condition('item.entity:' . $entity_type_name . '.' . $entity_type->getKey('published'), 1);
          }

          if ($entity_type->getKey('bundle')) {
            $entity_group->condition('item.entity:' . $entity_type_name . '.' . $entity_type->getKey('bundle'), $settings['bundles'], 'IN');
          }
          else {
            $entity_group->condition('item.target_type', $entity_type_name);
          }

          $group->condition($entity_group);

          // Determine the cache tags for the types of items in this listing.
          // Drupal 8.9 and up allow for more specific tags (per bundle). See
          // https://www.drupal.org/node/3107058.
          if (version_compare(\Drupal::VERSION, '8.9', '>=') && $entity_type->getKey('bundle')) {
            foreach ($settings['bundles'] as $bundle) {
              $cache_tags = array_merge($cache_tags, [$entity_type_name . '_list:' . $bundle]);
            }
          }
          else {
            $cache_tags = array_merge($cache_tags, [$entity_type_name . '_list']);
          }
        }

        $query->condition($group);
      }

      if ($paragraph->getBehaviorSetting($this->getPluginId(), 'count') > 0) {
        $query->range(0, $paragraph->getBehaviorSetting($this->getPluginId(), 'count'));
      }

      $query->sort('weight');
      $result = $query->execute();

      foreach ($collection_item_storage->loadMultiple($result) as $collection_item) {
        $entity_type = $collection_item->item->entity->getEntityTypeId();

        if (!array_key_exists($entity_type, $applicable_entity_types)) {
          continue;
        }

        if (empty($view_builders[$entity_type])) {
          $view_builders[$entity_type] = $this->entityTypeManager->getViewBuilder($entity_type);
        }

        $view_mode = $paragraph->getBehaviorSetting($this->getPluginId(), ['entity_settings', $entity_type, 'view_mode']) ?? 'teaser';
        $items[] = $view_builders[$entity_type]->view($collection_item->item->entity, $view_mode);
      }

      $variables['content'][$collection_field_name] = [
        '#theme' => 'item_list__collection_listing',
        '#items' => $items,
        '#attributes' => ['class' => 'collection-listing cu-grid cu-grid--3col'],
        '#collection_listing' => TRUE,
        '#empty' => $this->t('No items.'),
        '#context' => ['paragraph' => $variables['paragraph']],
        '#cache' => [
          'tags' => $cache_tags
        ],
      ];
    }
  }

  /**
   * @return array
   */
  public static function getCollectionReferenceFieldNames(ParagraphsType $paragraphs_type) {
    $collection_ref_fields = [];
    $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('paragraph', $paragraphs_type->id());

    foreach ($field_definitions as $definition) {
      if ($definition->getType() === 'entity_reference' && $definition instanceof FieldConfig) {
        if ($definition->getFieldStorageDefinition()->getSetting('target_type') === 'collection') {
          $collection_ref_fields[] = $definition->getName();
        }
      }
    }

    return $collection_ref_fields;
  }

  /**
   * {@inheritdoc}
   */
  public function view(array &$build, Paragraph $paragraphs_entity, EntityViewDisplayInterface $display, $view_mode) {}

  /**
   * {@inheritdoc}
   */
  public function settingsSummary(Paragraph $paragraph) {
    $summary = [];
    $summary[] = [
      'label' => 'Items',
      'value' => $paragraph->getBehaviorSetting($this->getPluginId(), 'count') ?? 'All',
    ];

    if ($entity_type_settings = $paragraph->getBehaviorSetting($this->getPluginId(), 'entity_settings')) {
      foreach ($entity_type_settings as $entity_type => $settings) {
        if (empty($settings['bundles'])) {
          continue;
        }

        $summary[] = [
          'label' => $entity_type,
          'value' => implode(', ', $settings['bundles']),
        ];
      }
    }

    return $summary;
  }

  /**
   * {@inheritdoc}
   *
   * This behavior is only applicable to paragraphs that have a single
   * `collection` entity reference field.
   */
  public static function isApplicable(ParagraphsType $paragraphs_type) {
    return count(self::getCollectionReferenceFieldNames($paragraphs_type)) === 1;
  }

  /**
   * Get all content entity type names.
   *
   * @return array
   */
  protected function getContentEntityTypeNames() {
    $content_entity_types = [];
    $entity_type_definations = $this->entityTypeManager->getDefinitions();

    foreach ($entity_type_definations as $definition) {
      if ($definition instanceof ContentEntityType) {
        // @todo: Check whether the collection allows this content entity type.
        $content_entity_types[$definition->id()] = $definition->getBundleLabel();
      }
    }

    return $content_entity_types;
  }

  /**
   * Get bundles for a given entity type.
   *
   * @param string $entity_type_id
   *
   * @return array
   */
  protected function getBundlesForEntity($entity_type_id) {
    $bundles = [];

    foreach ($this->entityTypeBundleInfo->getBundleInfo($entity_type_id) as $bundle_key => $bundle_info) {
      $bundles[$bundle_key] = (string) $bundle_info['label'];
    }

    return $bundles;
  }

  /**
   * Get view_modes for a given entity type.
   *
   * @param string $entity_type_id
   *
   * @return array
   */
  protected function getViewModesForEntity($entity_type_id) {
    $view_modes = [];

    foreach ($this->entityDisplayRepository->getViewModes($entity_type_id) as $view_mode => $display_info) {
      if ($display_info['status'] === TRUE && $view_mode !== 'token') {
        $view_modes[$view_mode] = $display_info['label'];
      }
    }
    return $view_modes;
  }

}

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

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