toolshed-8.x-1.x-dev/modules/toolshed_search/src/Plugin/ToolshedSearch/Autocomplete/SearchApiAutocomplete.php

modules/toolshed_search/src/Plugin/ToolshedSearch/Autocomplete/SearchApiAutocomplete.php
<?php

namespace Drupal\toolshed_search\Plugin\ToolshedSearch\Autocomplete;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\search_api\Plugin\views\filter\SearchApiFulltext;
use Drupal\search_api\Utility\Utility;
use Drupal\search_api_autocomplete\SearchInterface;
use Drupal\search_api_autocomplete\Utility\AutocompleteHelperInterface;
use Drupal\toolshed_search\Attribute\ToolshedSearchAutocomplete;
use Drupal\toolshed_search\Plugin\Block\ToolshedSearchBlock;
use Drupal\toolshed_search\Plugin\ToolshedSearchAutocompleteInterface;
use Drupal\views\ViewExecutable;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Autocomplete plugin for Search API Autocomplete provided autocomplete.
 */
#[ToolshedSearchAutocomplete(
  id: 'search_api_autocomplete',
  label: new TranslatableMarkup('Search API Autocomplete'),
)]
class SearchApiAutocomplete extends PluginBase implements ToolshedSearchAutocompleteInterface, ContainerFactoryPluginInterface {

  /**
   * The Search API Autocomplete helper.
   *
   * @var \Drupal\search_api_autocomplete\Utility\AutocompleteHelperInterface|null
   */
  protected ?AutocompleteHelperInterface $autocompleteHelper = NULL;

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

  /**
   * Creates a new instance of the SearchApiAutocomplete plugin class.
   *
   * @param array $configuration
   *   The plugin configuration values.
   * @param string $plugin_id
   *   The plugin identifier.
   * @param mixed $plugin_definition
   *   The plugin definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
    $instance = new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager')
    );

    if ($helper = $container->get('search_api_autocomplete.helper', ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
      $instance->setAutocompleteHelper($helper);
    }

    return $instance;
  }

  /**
   * Set the Search API Autocomplete helper.
   *
   * @param \Drupal\search_api_autocomplete\Utility\AutocompleteHelperInterface $autocomplete_helper
   *   The search_api_autocomplete autocomplete helper.
   */
  public function setAutocompleteHelper(AutocompleteHelperInterface $autocomplete_helper): void {
    $this->autocompleteHelper = $autocomplete_helper;
  }

  /**
   * {@inheritdoc}
   */
  public function isApplicable(ViewExecutable $view): bool {
    if ($this->autocompleteHelper) {
      $ac = $this->getAutocomplete($view);
      return $ac && $this->isAutocompleteEnabled($view, $ac);
    }

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function applyAutocomplete(array &$form, array &$filters, ToolshedSearchBlock $search_block): void {
    if (!$this->autocompleteHelper) {
      return;
    }

    $view = $search_block->getView();
    $ac = $this->getAutocomplete($view);

    if (!$ac || !$this->isAutocompleteEnabled($view, $ac)) {
      return;
    }

    foreach ($search_block->getFilters() as $filterInfo) {
      /** @var \Drupal\views\Plugin\views\filter\FilterPluginBase $filter */
      $filter = $filterInfo['filter'];
      $key = $filter->options['expose']['identifier'] ?? $filter->exposedInfo()['value'];

      if (!$filter instanceof SearchApiFulltext || empty($key)) {
        continue;
      }

      // Find a reference to the filter element.
      $element = NULL;
      if (isset($form['filters'][$key])) {
        $element = &$form['filters'][$key];
      }
      elseif (isset($form['filters'][$key . '_wrapper'][$key])) {
        $element = &$form['filters'][$key . '_wrapper'][$key];
      }
      else {
        continue;
      }

      $data = [
        'display' => $view->current_display,
        'arguments' => $view->args,
        'filter' => $key,
      ];

      // Some views filter plugins nest the value of the actual form element.
      if (!empty($element['value'])) {
        $element = &$element['value'];
        $data['field'] = $filter->realField;
      }

      // The search autocomplete helper only deals with "textfield" types.
      if ('textfield' === ($element['#type'] ?? NULL)) {
        $this->autocompleteHelper->alterElement($element, $ac, $data);
      }
    }
  }

  /**
   * Checks if the search API autocomplete is enabled for this view and display.
   *
   * @param \Drupal\views\ViewExecutable $view
   *   The view which executes the search functionality.
   * @param \Drupal\search_api_autocomplete\SearchInterface $autocomplete
   *   The Search API Autcomplete configuration entity for this view.
   *
   * @return bool
   *   TRUE if the autocomplete is enabled for this view and display.
   */
  protected function isAutocompleteEnabled(ViewExecutable $view, SearchInterface $autocomplete): bool {
    $config = $autocomplete->getSearchPlugin()->getConfiguration();

    return Utility::matches($view->current_display, $config['displays']);
  }

  /**
   * Gets the Search API Autocomplete configurations matching a view.
   *
   * @param \Drupal\views\ViewExecutable $view
   *   View to find Search API Autocomplete configurations for.
   *
   * @return \Drupal\search_api_autocomplete\SearchInterface|null
   *   The search autocomplete config entity that matches this view.
   */
  protected function getAutocomplete(ViewExecutable $view): ?SearchInterface {
    $searchId = 'views:' . $view->id();

    try {
      /** @var \Drupal\search_api_autocomplete\Entity\SearchStorage  $autocompleteStorage */
      $autocompleteStorage = $this->entityTypeManager->getStorage('search_api_autocomplete_search');

      return $autocompleteStorage->loadBySearchPlugin($searchId);
    }
    catch (InvalidPluginDefinitionException $e) {
      // Search API Autocomplete likely isn't installed, and the entity type
      // isn't available. Just exit out report no autocomplete is avaiable.
    }

    return NULL;
  }

}

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

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