View source
<?php
namespace Drupal\search_api_autocomplete\Form;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RedirectDestinationInterface;
use Drupal\Core\Url;
use Drupal\search_api\IndexInterface;
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 Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Messenger\MessengerInterface;
class IndexOverviewForm extends FormBase {
protected $suggesterManager;
protected $searchPluginManager;
protected $pluginHelper;
protected $entityTypeManager;
protected $redirectDestination;
protected $messenger;
public function __construct(PluginManagerInterface $suggester_manager, SearchPluginManager $search_plugin_manager, PluginHelperInterface $plugin_helper, EntityTypeManagerInterface $entity_type_manager, RedirectDestinationInterface $redirect_destination, MessengerInterface $messenger) {
$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;
}
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'));
}
public function getFormId() {
return 'search_api_autocomplete_admin_overview';
}
public function buildForm(array $form, FormStateInterface $form_state, IndexInterface $search_api_index = NULL) {
$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(),
]);
$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;
}
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' => [],
]);
$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;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$messages = $this
->t('The settings have been saved.');
foreach ($form_state
->getValue('searches') as $id => $enabled) {
$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. Please 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);
}
protected function loadAutocompleteSearchByIndex($index_id) {
$searches = $this->entityTypeManager
->getStorage('search_api_autocomplete_search')
->loadByProperties([
'index_id' => $index_id,
]);
return $searches;
}
}