localgov_services-2.1.19/modules/localgov_services_navigation/src/Plugin/EntityReferenceSelection/ServicesSelection.php

modules/localgov_services_navigation/src/Plugin/EntityReferenceSelection/ServicesSelection.php
<?php

namespace Drupal\localgov_services_navigation\Plugin\EntityReferenceSelection;

use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the 'Services' entity_reference.
 *
 * Presently hard coded to work with the hierarchy being in the field named
 * 'localgov_services_parent'.
 *
 * @EntityReferenceSelection(
 *   id = "localgov_services",
 *   label = @Translation("LocalGovDrupal: Services"),
 *   group = "localgov_services",
 *   entity_types = {"node"},
 *   weight = 0
 * )
 */
class ServicesSelection extends SelectionPluginBase implements ContainerFactoryPluginInterface {

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

  /**
   * Entity type bundle info service.
   *
   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
   */
  public $entityTypeBundleInfo;

  /**
   * The entity repository.
   *
   * @var \Drupal\Core\Entity\EntityRepositoryInterface
   */
  protected $entityRepository;

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * Constructs a new ServicesSelection object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
   *   The entity type bundle info service.
   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
   *   The entity repository.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler service.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityRepositoryInterface $entity_repository, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->entityTypeManager = $entity_type_manager;
    $this->entityTypeBundleInfo = $entity_type_bundle_info;
    $this->entityRepository = $entity_repository;
    $this->moduleHandler = $module_handler;
    $this->currentUser = $current_user;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('entity_type.bundle.info'),
      $container->get('entity.repository'),
      $container->get('module_handler'),
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'target_type' => 'node',
      'target_bundles' => [],
    ] + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);

    $configuration = $this->getConfiguration();
    $entity_type = $this->entityTypeManager->getDefinition('node');
    $bundles = $this->entityTypeBundleInfo->getBundleInfo('node');

    $bundle_options = [
      'localgov_services_landing' => $bundles['localgov_services_landing']['label'],
      'localgov_services_sublanding' => $bundles['localgov_services_sublanding']['label'],
    ];

    $form['target_bundles'] = [
      '#type' => 'checkboxes',
      '#title' => $entity_type->getBundleLabel(),
      '#options' => $bundle_options,
      '#default_value' => (array) $configuration['target_bundles'],
      '#required' => TRUE,
      '#multiple' => TRUE,
      '#element_validate' => [[get_class($this), 'elementValidateFilter']],
      '#ajax' => TRUE,
      '#limit_validation_errors' => [],
    ];

    $form['target_bundles_update'] = [
      '#type' => 'submit',
      '#value' => $this->t('Update form'),
      '#limit_validation_errors' => [],
      '#attributes' => [
        'class' => ['js-hide'],
      ],
      '#submit' => [[EntityReferenceItem::class, 'settingsAjaxSubmit']],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
    $entities = [];
    $query = $this->buildEntityQuery($match, $match_operator)
      ->accessCheck(TRUE);
    if ($limit > 0) {
      $query->range(0, $limit);
    }

    $result = $query->execute();

    if (empty($result)) {
      return [];
    }

    $options = [];
    $entities = $this->entityTypeManager->getStorage('node')->loadMultiple($result);
    foreach ($entities as $entity_id => $entity) {
      /** @var \Drupal\node\Entity\Node $entity */
      $bundle = $entity->bundle();
      if ($bundle == 'localgov_services_sublanding') {
        $parent_entity = $entity->localgov_services_parent->entity;
        if ($parent_entity) {
          $parent_label = $this->entityRepository->getTranslationFromContext($parent_entity)->label();
        }
        else {
          $parent_label = $this->t('- Missing Parent Landing Page -');
        }
        $options[$bundle][$entity_id] = Html::escape($parent_label . ' » ' . $this->entityRepository->getTranslationFromContext($entity)->label());
      }
      else {
        $options[$bundle][$entity_id] = Html::escape($this->entityRepository->getTranslationFromContext($entity)->label());
      }
    }

    return $options;
  }

  /**
   * Builds an EntityQuery to get referenceable entities.
   *
   * @param string|null $match
   *   (Optional) Text to match the label against. Defaults to NULL.
   * @param string $match_operator
   *   (Optional) The operation the matching should be done with. Defaults
   *   to "CONTAINS".
   *
   * @return \Drupal\Core\Entity\Query\QueryInterface
   *   The EntityQuery object with the basic conditions and sorting applied to
   *   it.
   */
  protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
    $configuration = $this->getConfiguration();
    $entity_type = $this->entityTypeManager->getDefinition('node');
    $query = $this->entityTypeManager->getStorage('node')->getQuery();
    $query->condition($entity_type->getKey('bundle'), $configuration['target_bundles'], 'IN');

    if (isset($match)) {
      $tokens = explode(' ', $match);
      foreach ($tokens as $token) {
        $or = $query->orConditionGroup();
        $or->condition('title', $token, $match_operator);
        $or->condition('localgov_services_parent.entity:node.title', $token, $match_operator);
        $query->condition($or);
      }
    }
    $query->sort('localgov_services_parent.entity:node.title', 'ASC');
    $query->sort('title', 'ASC');
    $query->addTag('node_access');
    // Adding the 'node_access' tag is sadly insufficient for nodes: core
    // requires us to also know about the concept of 'published' and
    // 'unpublished'. We need to do that as long as there are no access control
    // modules in use on the site. As long as one access control module is
    // there, it is supposed to handle this check.
    if (!$this->currentUser->hasPermission('bypass node access') && !$this->moduleHandler->hasImplementations('node_grants')) {
      $query->condition('status', NodeInterface::PUBLISHED);
    }
    $query->addTag('entity_reference');
    $query->addMetaData('entity_reference_selection_handler', $this);
    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function countReferenceableEntities($match = NULL, $match_operator = 'CONTAINS') {
    $query = $this->buildEntityQuery($match, $match_operator);
    return $query
      ->count()
      ->accessCheck(TRUE)
      ->execute();
  }

  /**
   * {@inheritdoc}
   */
  public function validateReferenceableEntities(array $ids) {
    $result = [];
    if ($ids) {
      $entity_type = $this->entityTypeManager->getDefinition('node');
      $query = $this->buildEntityQuery();
      $result = $query
        ->accessCheck(TRUE)
        ->condition($entity_type->getKey('id'), $ids, 'IN')
        ->execute();
    }

    return $result;
  }

  /**
   * Form element validation handler; Filters the #value property of an element.
   */
  public static function elementValidateFilter(&$element, FormStateInterface $form_state) {
    $element['#value'] = array_filter($element['#value']);
    $form_state->setValueForElement($element, $element['#value']);
  }

}

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

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