search_api_autocomplete-8.x-1.x-dev/src/Form/IndexOverviewForm.php

src/Form/IndexOverviewForm.php
<?php

namespace Drupal\search_api_autocomplete\Form;

use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RedirectDestinationInterface;
use Drupal\Core\Url;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\SearchApiException;
use Drupal\search_api_autocomplete\Entity\Search;
use Drupal\search_api_autocomplete\Search\SearchPluginInterface;
use Drupal\search_api_autocomplete\Search\SearchPluginManager;
use Drupal\search_api_autocomplete\Utility\PluginHelperInterface;
use Drupal\search_api_solr\SolrBackendInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines the overview of all search autocompletion configurations.
 */
class IndexOverviewForm extends FormBase {

  /**
   * The autocomplete suggester manager.
   *
   * @var \Drupal\Component\Plugin\PluginManagerInterface
   */
  protected $suggesterManager;

  /**
   * The search plugin manager.
   *
   * @var \Drupal\search_api_autocomplete\Search\SearchPluginManager
   */
  protected $searchPluginManager;

  /**
   * The plugin helper.
   *
   * @var \Drupal\search_api_autocomplete\Utility\PluginHelperInterface
   */
  protected $pluginHelper;

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

  /**
   * The redirect destination.
   *
   * @var \Drupal\Core\Routing\RedirectDestinationInterface
   */
  protected $redirectDestination;

  /**
   * The messenger.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

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

  /**
   * Creates a new AutocompleteSearchAdminOverview instance.
   *
   * @param \Drupal\Component\Plugin\PluginManagerInterface $suggester_manager
   *   The suggester manager.
   * @param \Drupal\search_api_autocomplete\Search\SearchPluginManager $search_plugin_manager
   *   The search plugin manager.
   * @param \Drupal\search_api_autocomplete\Utility\PluginHelperInterface $plugin_helper
   *   The plugin helper.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination
   *   The redirect destination.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   */
  public function __construct(PluginManagerInterface $suggester_manager, SearchPluginManager $search_plugin_manager, PluginHelperInterface $plugin_helper, EntityTypeManagerInterface $entity_type_manager, RedirectDestinationInterface $redirect_destination, MessengerInterface $messenger, ModuleHandlerInterface $module_handler) {
    $this->suggesterManager = $suggester_manager;
    $this->searchPluginManager = $search_plugin_manager;
    $this->pluginHelper = $plugin_helper;
    $this->entityTypeManager = $entity_type_manager;
    $this->redirectDestination = $redirect_destination;
    $this->messenger = $messenger;
    $this->moduleHandler = $module_handler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('plugin.manager.search_api_autocomplete.suggester'),
      $container->get('plugin.manager.search_api_autocomplete.search'),
      $container->get('search_api_autocomplete.plugin_helper'),
      $container->get('entity_type.manager'),
      $container->get('redirect.destination'),
      $container->get('messenger'),
      $container->get('module_handler'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'search_api_autocomplete_admin_overview';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, IndexInterface $search_api_index = NULL) {
    try {
      // Display hint about using the new Search API Solr Autocomplete module.
      // See search_api_autocomplete_requirements().
      if (interface_exists(SolrBackendInterface::class)
          && $search_api_index->hasValidServer()
          && $search_api_index->getServerInstance()->getBackend() instanceof SolrBackendInterface
          && !$this->moduleHandler->moduleExists('search_api_solr_autocomplete')
          && (method_exists(SolrBackendInterface::class, 'getPreferredSchemaVersion')
              || version_compare(SolrBackendInterface::SEARCH_API_SOLR_SCHEMA_VERSION, '4.2.5', '>='))
      ) {
        $this->messenger->addWarning($this->t('When using a Solr server as the search backend, it is recommended to enable the "Search API Solr Autocomplete" module for improved autocomplete functionality.'));
      }
    }
    catch (SearchApiException $e) {
      // Ignore here, will cause enough problems elsewhere.
    }

    $form_state->set('index', $search_api_index);
    $index_id = $search_api_index->id();

    $form['#tree'] = TRUE;
    $form['#title'] = $this->t('Manage autocomplete for search index %label', ['%label' => $search_api_index->label()]);

    /** @var \Drupal\search_api_autocomplete\SearchInterface[] $searches_by_plugin */
    $searches_by_plugin = [];
    foreach ($this->loadAutocompleteSearchByIndex($index_id) as $search) {
      $searches_by_plugin[$search->getSearchPluginId()] = $search;
    }
    $used_ids = [];

    $plugins = $this->pluginHelper->createSearchPluginsForIndex($index_id);
    foreach ($plugins as $plugin_id => $plugin) {
      $group_label = (string) $plugin->getGroupLabel();
      if (empty($form[$group_label])) {
        $form[$group_label] = [
          '#type' => 'details',
          '#open' => TRUE,
          '#title' => $plugin->getGroupLabel(),
        ];
        if ($description = $plugin->getGroupDescription()) {
          $form[$group_label]['#description'] = '<p>' . $description . '</p>';
        }
        $form[$group_label]['searches']['#type'] = 'tableselect';
        $form[$group_label]['searches']['#header'] = [
          'label' => $this->t('Label'),
          'operations' => $this->t('Operations'),
        ];
        $form[$group_label]['searches']['#empty'] = '';
        $form[$group_label]['searches']['#js_select'] = TRUE;
      }

      if (isset($searches_by_plugin[$plugin_id])) {
        $search = $searches_by_plugin[$plugin_id];
      }
      else {
        $search = $this->createSearchForPlugin($plugin, $used_ids);
        $used_ids[$search->id()] = TRUE;
      }

      $id = $search->id();
      $form_state->set(['searches', $id], $search);
      $form[$group_label]['searches'][$id] = [
        '#type' => 'checkbox',
        '#default_value' => $search->status(),
        '#parents' => ['searches', $id],
      ];

      $options = &$form[$group_label]['searches']['#options'][$id];
      $options['label'] = $search->label();
      $items = [];
      if ($search->status()) {
        $items[] = [
          'title' => $this->t('Edit'),
          'url' => $search->toUrl('edit-form'),
        ];
      }
      if (!$search->isNew()) {
        $items[] = [
          'title' => $this->t('Delete'),
          'url' => $search->toUrl('delete-form'),
        ];
      }

      if ($items) {
        $options['operations'] = [
          'data' => [
            '#type' => 'operations',
            '#links' => $items,
          ],
        ];
      }
      else {
        $options['operations'] = '';
      }
      unset($options);
    }

    if (!Element::children($form)) {
      $form['message']['#markup'] = '<p>' . $this->t('There are currently no searches known for this index. You need to create at least one search view.') . '</p>';
    }
    else {
      $form['actions'] = ['#type' => 'actions'];
      $form['actions']['submit'] = [
        '#type' => 'submit',
        '#button_type' => 'primary',
        '#value' => $this->t('Save'),
      ];
    }

    return $form;
  }

  /**
   * Creates a new search entity for the given search plugin.
   *
   * @param \Drupal\search_api_autocomplete\Search\SearchPluginInterface $plugin
   *   The search plugin for which to create a search entity.
   * @param true[] $used_ids
   *   The IDs of the searches created so far for this form (to avoid
   *   duplicates). IDs are used as array keys, mapping to TRUE.
   *
   * @return \Drupal\search_api_autocomplete\SearchInterface
   *   The new search entity.
   */
  protected function createSearchForPlugin(SearchPluginInterface $plugin, array $used_ids) {
    $plugin_id = $plugin->getPluginId();
    $index_id = $plugin->getIndexId();

    $id = $base_id = $plugin->getDerivativeId() ?: $plugin_id;
    $search_storage = $this->entityTypeManager
      ->getStorage('search_api_autocomplete_search');
    $i = 0;
    while (!empty($used_ids[$id]) || $search_storage->load($id)) {
      $id = $base_id . '_' . ++$i;
    }

    $search = Search::create([
      'id' => $id,
      'status' => FALSE,
      'label' => $plugin->label(),
      'index_id' => $index_id,
      'search_settings' => [
        $plugin_id => [],
      ],
      'options' => [],
    ]);

    // Find a supported suggester and set it as the default for the search.
    $suggesters = array_map(function ($suggester_info) {
      return $suggester_info['class'];
    }, $this->suggesterManager->getDefinitions());
    $filter_suggesters = function ($suggester_class) use ($search) {
      return $suggester_class::supportsSearch($search);
    };
    $available_suggesters = array_filter($suggesters, $filter_suggesters);
    if ($available_suggesters) {
      reset($available_suggesters);
      $suggester_id = key($available_suggesters);
      $suggester = $this->pluginHelper
        ->createSuggesterPlugin($search, $suggester_id);
      $search->setSuggesters([
        $suggester_id => $suggester,
      ]);
    }

    return $search;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $messages = $this->t('The settings have been saved.');
    foreach ($form_state->getValue('searches') as $id => $enabled) {
      /** @var \Drupal\search_api_autocomplete\SearchInterface $search */
      $search = $form_state->get(['searches', $id]);
      if ($search && $search->status() != $enabled) {
        $change = TRUE;
        if ($search->isNew()) {
          $options['query'] = $this->redirectDestination->getAsArray();
          $options['fragment'] = 'module-search_api_autocomplete';
          $url = Url::fromRoute('user.admin_permissions', [], $options);
          if ($url->access()) {
            $vars[':perm_url'] = $url->toString();
            $messages = $this->t('The settings have been saved. Remember to set the <a href=":perm_url">permissions</a> for the newly enabled searches.', $vars);
          }
        }
        $search->setStatus($enabled);
        $search->save();
      }
    }
    $this->messenger->addStatus(empty($change) ? $this->t('No values were changed.') : $messages);
  }

  /**
   * Load the autocomplete plugins for an index.
   *
   * @param string $index_id
   *   The index ID.
   *
   * @return \Drupal\search_api_autocomplete\SearchInterface[]
   *   An array of autocomplete plugins.
   */
  protected function loadAutocompleteSearchByIndex($index_id) {
    /** @var \Drupal\search_api_autocomplete\SearchInterface[] $searches */
    $searches = $this->entityTypeManager
      ->getStorage('search_api_autocomplete_search')
      ->loadByProperties([
        'index_id' => $index_id,
      ]);
    return $searches;
  }

}

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

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