diff --git a/search_api.api.php b/search_api.api.php index 5ec34332..b77d344b 100644 --- a/search_api.api.php +++ b/search_api.api.php @@ -101,7 +101,7 @@ function hook_search_api_data_type_info_alter(array &$data_type_definitions) { * Alter the available parse modes. * * @param array $parse_mode_definitions - * The definitions of the data type plugins. + * The definitions of the parse mode plugins. * * @see \Drupal\search_api\ParseMode\ParseModePluginBase */ diff --git a/src/Backend/BackendPluginManager.php b/src/Backend/BackendPluginManager.php index c498cc48..1fb55e0c 100644 --- a/src/Backend/BackendPluginManager.php +++ b/src/Backend/BackendPluginManager.php @@ -5,6 +5,9 @@ namespace Drupal\search_api\Backend; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; +use Drupal\search_api\Event\BackendPluginInfoAlterAlter; +use Drupal\search_api\Annotation\SearchApiBackend; +use Drupal\search_api\SearchApiPluginManager; /** * Manages search backend plugins. @@ -14,7 +17,7 @@ use Drupal\Core\Plugin\DefaultPluginManager; * @see \Drupal\search_api\Backend\BackendPluginBase * @see plugin_api */ -class BackendPluginManager extends DefaultPluginManager { +class BackendPluginManager extends SearchApiPluginManager { /** * Constructs a BackendPluginManager object. @@ -28,9 +31,10 @@ class BackendPluginManager extends DefaultPluginManager { * The module handler. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/search_api/backend', $namespaces, $module_handler, 'Drupal\search_api\Backend\BackendInterface', 'Drupal\search_api\Annotation\SearchApiBackend'); - $this->setCacheBackend($cache_backend, 'search_api_backends'); + parent::__construct('Plugin/search_api/backend', $namespaces, $module_handler, BackendInterface::class, SearchApiBackend::class); $this->alterInfo('search_api_backend_info'); + $this->alterEvent(BackendPluginInfoAlterAlter::class); + $this->setCacheBackend($cache_backend, 'search_api_backends'); } } diff --git a/src/DataType/DataTypePluginManager.php b/src/DataType/DataTypePluginManager.php index 770dbb9e..29362f3c 100644 --- a/src/DataType/DataTypePluginManager.php +++ b/src/DataType/DataTypePluginManager.php @@ -4,7 +4,8 @@ namespace Drupal\search_api\DataType; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Plugin\DefaultPluginManager; +use Drupal\search_api\Event\DataTypePluginInfoAlterAlter; +use Drupal\search_api\SearchApiPluginManager; /** * Manages data type plugins. @@ -14,7 +15,7 @@ use Drupal\Core\Plugin\DefaultPluginManager; * @see \Drupal\search_api\DataType\DataTypePluginBase * @see plugin_api */ -class DataTypePluginManager extends DefaultPluginManager { +class DataTypePluginManager extends SearchApiPluginManager { /** * Static cache for the data type definitions. @@ -51,6 +52,7 @@ class DataTypePluginManager extends DefaultPluginManager { $this->setCacheBackend($cache_backend, 'search_api_data_type'); $this->alterInfo('search_api_data_type_info'); + $this->alterEvent(DataTypePluginInfoAlterAlter::class); } /** diff --git a/src/Datasource/DatasourcePluginManager.php b/src/Datasource/DatasourcePluginManager.php index be9e684c..5fb8696c 100644 --- a/src/Datasource/DatasourcePluginManager.php +++ b/src/Datasource/DatasourcePluginManager.php @@ -4,7 +4,8 @@ namespace Drupal\search_api\Datasource; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Plugin\DefaultPluginManager; +use Drupal\search_api\Event\DataSourcePluginInfoAlterAlter; +use Drupal\search_api\SearchApiPluginManager; /** * Manages datasource plugins. @@ -14,7 +15,7 @@ use Drupal\Core\Plugin\DefaultPluginManager; * @see \Drupal\search_api\Datasource\DatasourcePluginBase * @see plugin_api */ -class DatasourcePluginManager extends DefaultPluginManager { +class DatasourcePluginManager extends SearchApiPluginManager { /** * Constructs a DatasourcePluginManager object. @@ -29,8 +30,9 @@ class DatasourcePluginManager extends DefaultPluginManager { */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { parent::__construct('Plugin/search_api/datasource', $namespaces, $module_handler, 'Drupal\search_api\Datasource\DatasourceInterface', 'Drupal\search_api\Annotation\SearchApiDatasource'); - $this->setCacheBackend($cache_backend, 'search_api_datasources'); $this->alterInfo('search_api_datasource_info'); + $this->alterEvent(DataSourcePluginInfoAlterAlter::class); + $this->setCacheBackend($cache_backend, 'search_api_datasources'); } } diff --git a/src/Entity/Index.php b/src/Entity/Index.php index 7765e079..fb3f186a 100644 --- a/src/Entity/Index.php +++ b/src/Entity/Index.php @@ -8,6 +8,8 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\search_api\Datasource\DatasourceInterface; +use Drupal\search_api\Event\ItemsIndexed; +use Drupal\search_api\Event\Reindex; use Drupal\search_api\IndexInterface; use Drupal\search_api\Item\FieldInterface; use Drupal\search_api\LoggerTrait; @@ -20,6 +22,7 @@ use Drupal\search_api\Tracker\TrackerInterface; use Drupal\search_api\Utility\Utility; use Drupal\Core\TempStore\TempStoreException; use Drupal\views\Views; +use Symfony\Component\EventDispatcher\Event; /** * Defines the search index configuration entity. @@ -996,7 +999,13 @@ class Index extends ConfigEntityBase implements IndexInterface { // Since we've indexed items now, triggering reindexing would have some // effect again. Therefore, we reset the flag. $this->setHasReindexed(FALSE); - \Drupal::moduleHandler()->invokeAll('search_api_items_indexed', [$this, $processed_ids]); + + $warning = 'Use the ItemsIndexed event instead'; + \Drupal::moduleHandler()->invokeAllDeprecated($warning, 'search_api_items_indexed', [$this, $processed_ids]); + + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ + $dispatcher = \Drupal::getContainer()->get('event_dispatcher'); + $dispatcher->dispatch(ItemsIndexed::NAME, new ItemsIndexed($this, $processed_ids)); // Clear search api list caches. Cache::invalidateTags(['search_api_list:' . $this->id]); @@ -1100,7 +1109,10 @@ class Index extends ConfigEntityBase implements IndexInterface { if ($this->status() && !$this->isReindexing()) { $this->setHasReindexed(); $this->getTrackerInstance()->trackAllItemsUpdated(); - \Drupal::moduleHandler()->invokeAll('search_api_index_reindex', [$this, FALSE]); + \Drupal::moduleHandler()->invokeAllDeprecated('Use the Reindex event instead.','search_api_index_reindex', [$this, FALSE]); + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ + $dispatcher = \Drupal::getContainer()->get('event_dispatcher'); + $dispatcher->dispatch(Reindex::NAME, new Reindex($this, FALSE)); } } @@ -1125,7 +1137,11 @@ class Index extends ConfigEntityBase implements IndexInterface { } if ($invoke_hook) { \Drupal::moduleHandler() - ->invokeAll('search_api_index_reindex', [$this, !$this->isReadOnly()]); + ->invokeAllDeprecated('Use the Reindex event instead.', 'search_api_index_reindex', [$this, !$this->isReadOnly()]); + + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ + $dispatcher = \Drupal::getContainer()->get('event_dispatcher'); + $dispatcher->dispatch(Reindex::NAME, new Reindex($this, !$this->isReadOnly())); } } @@ -1143,7 +1159,10 @@ class Index extends ConfigEntityBase implements IndexInterface { $index_task_manager->startTracking($this); $this->setHasReindexed(); \Drupal::moduleHandler() - ->invokeAll('search_api_index_reindex', [$this, FALSE]); + ->invokeAllDeprecated('Use the Reindex event instead.', 'search_api_index_reindex', [$this, FALSE]); + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ + $dispatcher = \Drupal::getContainer()->get('event_dispatcher'); + $dispatcher->dispatch(Reindex::NAME, new Reindex($this, FALSE)); $index_task_manager->addItemsBatch($this); } diff --git a/src/Event/BackendPluginInfoAlterAlter.php b/src/Event/BackendPluginInfoAlterAlter.php new file mode 100644 index 00000000..c0f5d5ed --- /dev/null +++ b/src/Event/BackendPluginInfoAlterAlter.php @@ -0,0 +1,22 @@ +getDefinitions(); + } + +} diff --git a/src/Event/DataSourcePluginInfoAlterAlter.php b/src/Event/DataSourcePluginInfoAlterAlter.php new file mode 100644 index 00000000..ab2617b5 --- /dev/null +++ b/src/Event/DataSourcePluginInfoAlterAlter.php @@ -0,0 +1,22 @@ +getDefinitions(); + } + +} \ No newline at end of file diff --git a/src/Event/DataTypePluginInfoAlterAlter.php b/src/Event/DataTypePluginInfoAlterAlter.php new file mode 100644 index 00000000..4ae2dcc1 --- /dev/null +++ b/src/Event/DataTypePluginInfoAlterAlter.php @@ -0,0 +1,23 @@ +getDefinitions(); + } + +} diff --git a/src/Event/FieldTypeMappingAlter.php b/src/Event/FieldTypeMappingAlter.php new file mode 100644 index 00000000..3fca5602 --- /dev/null +++ b/src/Event/FieldTypeMappingAlter.php @@ -0,0 +1,40 @@ +fieldTypeMapping = &$fieldTypeMapping; + } + + /** + * Get a reference to the field type mapping. + * + * @return array + * An array mapping all known (and supported) Drupal data types to their + * corresponding Search API data types. A value of FALSE means that fields of + * that type should be ignored by the Search API. + */ + public function &getFieldTypeMapping() { + return $this->fieldTypeMapping; + } + +} diff --git a/src/Event/ItemsIndexed.php b/src/Event/ItemsIndexed.php new file mode 100644 index 00000000..ec0df72c --- /dev/null +++ b/src/Event/ItemsIndexed.php @@ -0,0 +1,62 @@ +index = $index; + $this->processedIds = $processedIds; + } + + /** + * Get the index that indexed the items. + * + * @return \Drupal\search_api\IndexInterface + * The used index. + */ + public function getIndex() { + return $this->index; + } + + /** + * Get the processed ids. + * + * @return int[] + * An array containing the successfully indexed items' IDs. + */ + public function getProcessedIds() { + return $this->processedIds; + } + +} diff --git a/src/Event/ParseModePluginInfoAlterAlter.php b/src/Event/ParseModePluginInfoAlterAlter.php new file mode 100644 index 00000000..5c6c0691 --- /dev/null +++ b/src/Event/ParseModePluginInfoAlterAlter.php @@ -0,0 +1,22 @@ +getDefinitions(); + } + +} diff --git a/src/Event/PluginInfoAlterEvent.php b/src/Event/PluginInfoAlterEvent.php new file mode 100644 index 00000000..12e6e5a4 --- /dev/null +++ b/src/Event/PluginInfoAlterEvent.php @@ -0,0 +1,38 @@ +definitions = &$definitions; + } + + /** + * Get a reference to the definitions. + * + * @return array + */ + public function &getDefinitions() { + return $this->definitions; + } + +} diff --git a/src/Event/ProcessorPluginInfoAlterAlter.php b/src/Event/ProcessorPluginInfoAlterAlter.php new file mode 100644 index 00000000..ec7daa60 --- /dev/null +++ b/src/Event/ProcessorPluginInfoAlterAlter.php @@ -0,0 +1,22 @@ +getDefinitions(); + } + +} diff --git a/src/Event/Reindex.php b/src/Event/Reindex.php new file mode 100644 index 00000000..8d497889 --- /dev/null +++ b/src/Event/Reindex.php @@ -0,0 +1,62 @@ +index = $index; + $this->clear = $clear; + } + + /** + * Get the index scheduled for reindexing. + * + * @return \Drupal\search_api\IndexInterface + * The index scheduled for reindexing. + */ + public function getIndex() { + return $this->index; + } + + /** + * Get the boolean indicating whether the index was also cleared. + * + * @return bool + * Boolean indicating whether the index was also cleared. + */ + public function isClear() { + return $this->clear; + } + +} \ No newline at end of file diff --git a/src/Event/TrackerPluginInfoAlterAlter.php b/src/Event/TrackerPluginInfoAlterAlter.php new file mode 100644 index 00000000..a7b97ba8 --- /dev/null +++ b/src/Event/TrackerPluginInfoAlterAlter.php @@ -0,0 +1,22 @@ +getDefinitions(); + } + +} diff --git a/src/ParseMode/ParseModePluginManager.php b/src/ParseMode/ParseModePluginManager.php index d913d9a2..deee1985 100644 --- a/src/ParseMode/ParseModePluginManager.php +++ b/src/ParseMode/ParseModePluginManager.php @@ -4,7 +4,8 @@ namespace Drupal\search_api\ParseMode; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Plugin\DefaultPluginManager; +use Drupal\search_api\Event\ParseModePluginInfoAlterAlter; +use Drupal\search_api\SearchApiPluginManager; /** * Manages parse mode plugins. @@ -14,7 +15,7 @@ use Drupal\Core\Plugin\DefaultPluginManager; * @see \Drupal\search_api\ParseMode\ParseModePluginBase * @see plugin_api */ -class ParseModePluginManager extends DefaultPluginManager { +class ParseModePluginManager extends SearchApiPluginManager { /** * Constructs a ParseModePluginManager object. @@ -29,9 +30,9 @@ class ParseModePluginManager extends DefaultPluginManager { */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { parent::__construct('Plugin/search_api/parse_mode', $namespaces, $module_handler, 'Drupal\search_api\ParseMode\ParseModeInterface', 'Drupal\search_api\Annotation\SearchApiParseMode'); - - $this->setCacheBackend($cache_backend, 'search_api_parse_mode'); $this->alterInfo('search_api_parse_mode_info'); + $this->alterEvent(ParseModePluginInfoAlterAlter::class); + $this->setCacheBackend($cache_backend, 'search_api_parse_mode'); } /** diff --git a/src/Processor/ProcessorPluginManager.php b/src/Processor/ProcessorPluginManager.php index e665310a..39126f83 100644 --- a/src/Processor/ProcessorPluginManager.php +++ b/src/Processor/ProcessorPluginManager.php @@ -4,9 +4,10 @@ namespace Drupal\search_api\Processor; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Plugin\DefaultPluginManager; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; +use Drupal\search_api\Event\ProcessorPluginInfoAlterAlter; +use Drupal\search_api\SearchApiPluginManager; /** * Manages processor plugins. @@ -16,7 +17,7 @@ use Drupal\Core\StringTranslation\TranslationInterface; * @see \Drupal\search_api\Processor\ProcessorPluginBase * @see plugin_api */ -class ProcessorPluginManager extends DefaultPluginManager { +class ProcessorPluginManager extends SearchApiPluginManager { use StringTranslationTrait; @@ -37,6 +38,7 @@ class ProcessorPluginManager extends DefaultPluginManager { parent::__construct('Plugin/search_api/processor', $namespaces, $module_handler, 'Drupal\search_api\Processor\ProcessorInterface', 'Drupal\search_api\Annotation\SearchApiProcessor'); $this->setCacheBackend($cache_backend, 'search_api_processors'); $this->alterInfo('search_api_processor_info'); + $this->alterEvent(ProcessorPluginInfoAlterAlter::class); $this->setStringTranslation($translation); } diff --git a/src/SearchApiPluginManager.php b/src/SearchApiPluginManager.php new file mode 100644 index 00000000..ff4e5885 --- /dev/null +++ b/src/SearchApiPluginManager.php @@ -0,0 +1,46 @@ +alterEvent = $alterEvent; + } + + /** + * {@inheritdoc} + */ + protected function alterDefinitions(&$definitions) { + if ($this->alterHook && !$this->alterEvent) { + $this->moduleHandler->alter($this->alterHook, $definitions); + return; + } + + if ($this->alterHook) { + $alternative = sprintf('Use the %s event instead.', $this->alterEvent); + $this->moduleHandler->alterDeprecated($alternative, $this->alterHook, $definitions); + } + + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ + $dispatcher = \Drupal::getContainer()->get('event_dispatcher'); + $event = new $this->alterEvent($definitions); + $dispatcher->dispatch($event::NAME, $event); + } + +} diff --git a/src/Tracker/TrackerPluginManager.php b/src/Tracker/TrackerPluginManager.php index 7221979e..28731935 100644 --- a/src/Tracker/TrackerPluginManager.php +++ b/src/Tracker/TrackerPluginManager.php @@ -5,6 +5,8 @@ namespace Drupal\search_api\Tracker; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; +use Drupal\search_api\Event\TrackerPluginInfoAlterAlter; +use Drupal\search_api\SearchApiPluginManager; use Drupal\search_api\Utility\Utility; /** @@ -16,7 +18,7 @@ use Drupal\search_api\Utility\Utility; * @see \Drupal\search_api\Tracker\TrackerPluginBase * @see plugin_api */ -class TrackerPluginManager extends DefaultPluginManager { +class TrackerPluginManager extends SearchApiPluginManager { /** * Constructs a TrackerPluginManager object. @@ -33,6 +35,7 @@ class TrackerPluginManager extends DefaultPluginManager { parent::__construct('Plugin/search_api/tracker', $namespaces, $module_handler, 'Drupal\search_api\Tracker\TrackerInterface', 'Drupal\search_api\Annotation\SearchApiTracker'); $this->setCacheBackend($cache_backend, 'search_api_trackers'); $this->alterInfo('search_api_tracker_info'); + $this->alterEvent(TrackerPluginInfoAlterAlter::class); } /** diff --git a/src/Utility/CommandHelper.php b/src/Utility/CommandHelper.php index 86b68f14..e53818b7 100644 --- a/src/Utility/CommandHelper.php +++ b/src/Utility/CommandHelper.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityStorageException; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\search_api\ConsoleException; +use Drupal\search_api\Event\Reindex; use Drupal\search_api\IndexBatchHelper; use Drupal\search_api\IndexInterface; use Drupal\search_api\SearchApiException; @@ -354,7 +355,10 @@ class CommandHelper implements LoggerAwareInterface { $reindexed_datasources[] = $datasource->label(); } } - $this->moduleHandler->invokeAll('search_api_index_reindex', [$index, FALSE]); + $this->moduleHandler->invokeAllDeprecated('Use the Reindex event instead.', 'search_api_index_reindex', [$index, FALSE]); + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ + $dispatcher = \Drupal::getContainer()->get('event_dispatcher'); + $dispatcher->dispatch(Reindex::NAME, new Reindex($index, FALSE)); $arguments = [ '!index' => $index->label(), '!datasources' => implode(', ', $reindexed_datasources), diff --git a/src/Utility/DataTypeHelper.php b/src/Utility/DataTypeHelper.php index e535cf3f..6e24cf00 100644 --- a/src/Utility/DataTypeHelper.php +++ b/src/Utility/DataTypeHelper.php @@ -4,6 +4,7 @@ namespace Drupal\search_api\Utility; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\search_api\DataType\DataTypePluginManager; +use Drupal\search_api\Event\FieldTypeMappingAlter; use Drupal\search_api\IndexInterface; use Drupal\search_api\SearchApiException; @@ -125,7 +126,11 @@ class DataTypeHelper implements DataTypeHelperInterface { // Allow other modules to intercept and define what default type they want // to use for their data type. - $this->moduleHandler->alter('search_api_field_type_mapping', $mapping); + $warning = sprintf('Use %s instead.', FieldTypeMappingAlter::class); + $this->moduleHandler->alterDeprecated($warning, 'search_api_field_type_mapping', $mapping); + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher */ + $eventDispatcher = \Drupal::getContainer()->get('event_dispatcher'); + $eventDispatcher->dispatch(FieldTypeMappingAlter::NAME, new FieldTypeMappingAlter($mapping)); $this->fieldTypeMapping = $mapping; } diff --git a/tests/search_api_test_events/search_api_test_events.info.yml b/tests/search_api_test_events/search_api_test_events.info.yml new file mode 100644 index 00000000..2bf1bcc3 --- /dev/null +++ b/tests/search_api_test_events/search_api_test_events.info.yml @@ -0,0 +1,8 @@ +name: 'Search API Events Test' +type: module +description: 'Support module for Search API tests, tests all the events.' +package: Testing +dependencies: + - search_api:search_api +core: 8.x +hidden: true diff --git a/tests/search_api_test_events/search_api_test_events.services.yml b/tests/search_api_test_events/search_api_test_events.services.yml new file mode 100644 index 00000000..9ac7d9ba --- /dev/null +++ b/tests/search_api_test_events/search_api_test_events.services.yml @@ -0,0 +1,7 @@ +services: + + search_api_test_events.event_listener: + class: \Drupal\search_api_test_events\EventListener + arguments: ['@messenger'] + tags: + - { name: event_subscriber } diff --git a/tests/search_api_test_events/src/EventListener.php b/tests/search_api_test_events/src/EventListener.php new file mode 100644 index 00000000..468a7e85 --- /dev/null +++ b/tests/search_api_test_events/src/EventListener.php @@ -0,0 +1,162 @@ +messenger = $messenger; + } + + /** + * {@inheritDoc} + */ + public static function getSubscribedEvents() { + return [ + BackendPluginInfoAlterAlter::NAME => 'backendInfoAlter', + DataSourcePluginInfoAlterAlter::NAME => 'dataSourceInfoAlter', + DataTypePluginInfoAlterAlter::NAME => 'dataTypeInfoAlter', + FieldTypeMappingAlter::NAME => 'fieldTypeMappingAlter', + ItemsIndexed::NAME => 'itemsIndexed', + ParseModePluginInfoAlterAlter::NAME => 'parseModeInfoAlter', + ProcessorPluginInfoAlterAlter::NAME => 'processorInfoAlter', + Reindex::NAME => 'reindex', + TrackerPluginInfoAlterAlter::NAME => 'trackerInfoAlter', + ]; + } + + /** + * Event handler for the backend info alter event. + * + * @param \Drupal\search_api\Event\BackendPluginInfoAlterAlter $event + * The backend info alter event. + */ + public function backendInfoAlter(BackendPluginInfoAlterAlter $event) { + $backend_info = &$event->getBackendInfo(); + $backend_info['search_api_test']['label'] = 'Slims return'; + } + + /** + * Event handler for the data type info alter event. + * + * @param \Drupal\search_api\Event\DataTypePluginInfoAlterAlter $event + * The data type info alter event. + */ + public function dataTypeInfoAlter(DataTypePluginInfoAlterAlter $event) { + $dataTypePluginInfo = &$event->getDataTypePluginInfo(); + if (isset($dataTypePluginInfo['text'])) { + $dataTypePluginInfo['text']['label'] = 'Peace/Dolphin dance'; + } + } + + /** + * Event handler for the data source info alter event. + * + * @param \Drupal\search_api\Event\DataSourcePluginInfoAlterAlter $event + * The data source info alter event. + */ + public function dataSourceInfoAlter(DataSourcePluginInfoAlterAlter $event) { + $infos = &$event->getDataSourceInfo(); + if (isset($infos['entity:node'])) { + $infos['entity:node']['label'] = 'Distant land'; + } + } + + /** + * Event handler for the field type mapping alter event. + * + * @param \Drupal\search_api\Event\FieldTypeMappingAlter $event + * The field type mapping alter event. + */ + public function fieldTypeMappingAlter(FieldTypeMappingAlter $event) { + $mapping = &$event->getFieldTypeMapping(); + $mapping['datetime_iso8601'] = FALSE; + $mapping['timestamp'] = FALSE; + } + + /** + * Event handler for the items indexed event. + * + * @param \Drupal\search_api\Event\ItemsIndexed $event + * The items indexed event. + */ + public function itemsIndexed(ItemsIndexed $event) { + $this->messenger->addStatus('Please set me at ease'); + } + + /** + * Event handler for the parse mode info alter event. + * + * @param \Drupal\search_api\Event\ParseModePluginInfoAlterAlter $event + * The parse mode plugin info alter event. + */ + public function parseModeInfoAlter(ParseModePluginInfoAlterAlter $event) { + $parseModeInfo = &$event->getParseModeInfo(); + if (isset($parseModeInfo['direct'])) { + $parseModeInfo['direct']['label'] = 'Song for My Father'; + } + } + + /** + * Event handler for the processor info alter event. + * + * @param \Drupal\search_api\Event\ProcessorPluginInfoAlterAlter $event + * The processor plugin info alter event. + */ + public function processorInfoAlter(ProcessorPluginInfoAlterAlter $event) { + $processorInfo = &$event->getProcessorInfo(); + $processorInfo['content_access']['label'] = 'Mystic bounce'; + } + + /** + * Event handler for the reindex event. + * + * @param \Drupal\search_api\Event\Reindex $event + * The reindex index event. + */ + public function reindex(Reindex $event) { + $this->messenger->addStatus('Montara'); + } + + /**® + * Event handler for the tracker info alter event. + * + * @param \Drupal\search_api\Event\TrackerPluginInfoAlterAlter $event + * The tracker plugin info alter event. + */ + public function trackerInfoAlter(TrackerPluginInfoAlterAlter $event) { + $trackerInfo = &$event->getTrackerInfo(); + $trackerInfo['search_api_test']['label'] = 'Good luck'; + } + +} diff --git a/tests/src/Functional/EventsTest.php b/tests/src/Functional/EventsTest.php new file mode 100644 index 00000000..ac1bcb48 --- /dev/null +++ b/tests/src/Functional/EventsTest.php @@ -0,0 +1,165 @@ +drupalCreateNode(['type' => 'page', 'title' => 'node - 1']); + $this->drupalCreateNode(['type' => 'page', 'title' => 'node - 2']); + $this->drupalCreateNode(['type' => 'page', 'title' => 'node - 3']); + $this->drupalCreateNode(['type' => 'page', 'title' => 'node - 4']); + + // Create an index and server to work with. + $this->server = $this->getTestServer(); + $index = $this->getTestIndex(); + + // Add the test processor to the index so we can make sure that all expected + // processor methods are called, too. + /** @var \Drupal\search_api\Processor\ProcessorInterface $processor */ + $processor = \Drupal::getContainer() + ->get('search_api.plugin_helper') + ->createProcessorPlugin($index, 'search_api_test'); + $index->addProcessor($processor)->save(); + + // Parts of this test actually use the "database_search_index" from the + // search_api_test_db module (via the test view). Set the processor there, + // too. + $index = Index::load('database_search_index'); + $processor = \Drupal::getContainer() + ->get('search_api.plugin_helper') + ->createProcessorPlugin($index, 'search_api_test'); + $index->addProcessor($processor)->save(); + + // Reset the called methods on the processor. + $this->getCalledMethods('processor'); + + // Log in, so we can test all the things. + $this->drupalLogin($this->adminUser); + } + + /** + * Tests various operations via the Search API's admin UI. + */ + public function testEvents() { + // The BackendInfo event was invoked. + $this->drupalGet('admin/config/search/search-api/add-server'); + $this->assertSession()->pageTextContains('Slims return'); + + // The DatasourceInfo event was invoked. + $this->drupalGet('admin/config/search/search-api/add-index'); + $this->assertSession()->pageTextContains('Distant land'); + // The TrackerInfo event was invoked. + $this->assertSession()->pageTextContains('Good luck'); + + // The ProcessorInfo event was invoked. + $this->drupalGet($this->getIndexPath('processors')); + $this->assertSession()->pageTextContains('Mystic bounce'); + + // The ParseModeInfo event was invoked. + $definition = \Drupal::getContainer() + ->get('plugin.manager.search_api.parse_mode') + ->getDefinition('direct'); + $this->assertEquals('Song for My Father', $definition['label']); + + // Saving the index should trigger the processor's preIndexSave() method. + $this->submitForm([], 'Save'); + $processor_methods = $this->getCalledMethods('processor'); + $this->assertEquals(['preIndexSave'], $processor_methods); + + $this->drupalGet($this->getIndexPath()); + // Duplication on value 'Index now' with summary. + $this->submitForm([], 'Index now'); + $this->checkForMetaRefresh(); + $this->assertSession()->pageTextContains('Successfully indexed 4 items.'); + + // During indexing, alterIndexedItems() and preprocessIndexItems() should be + // called on the processor. + $processor_methods = $this->getCalledMethods('processor'); + $expected = ['alterIndexedItems', 'preprocessIndexItems']; + $this->assertEquals($expected, $processor_methods); + + // hook_search_api_index_items_alter() was invoked, this removed node:1. + // hook_search_api_query_TAG_alter() was invoked, this removed node:3. +// $this->assertSession()->pageTextContains('There are 2 items indexed on the server for this index.'); +// $this->assertSession()->pageTextContains('Stormy'); + + // The ItemsIndexed event was invoked. + $this->assertSession()->pageTextContains('Please set me at ease'); + + // The Reindex event was invoked. + $this->drupalGet($this->getIndexPath('reindex')); + $this->submitForm([], 'Confirm'); + $this->assertSession()->pageTextContains('Montara'); + + // The DataTypePluginInfo event was invoked. + $this->drupalGet($this->getIndexPath('fields')); + $this->assertSession()->pageTextContains('Peace/Dolphin dance'); + // The implementation of hook_search_api_field_type_mapping_alter() has + // removed all dates, so we can't see any timestamp anymore in the page. + $url_options['query']['datasource'] = 'entity:node'; + $this->drupalGet($this->getIndexPath('fields/add/nojs'), $url_options); + $this->assertSession()->pageTextContains('Add fields to index'); + $this->assertSession()->pageTextNotContains('timestamp'); + return; // @todo implement other events + + $this->drupalGet('search-api-test'); + $this->assertSession()->pageTextContains('Search id: views_page:search_api_test_view__page_1'); + // hook_search_api_query_alter() was invoked. + $this->assertSession()->pageTextContains('Funky blue note'); + // hook_search_api_results_alter() was invoked. + $this->assertSession()->pageTextContains('Stepping into tomorrow'); + // hook_search_api_results_TAG_alter() was invoked. + $this->assertSession()->pageTextContains('Llama'); + + // The query alter methods of the processor were called. + $processor_methods = $this->getCalledMethods('processor'); + $expected = ['preprocessSearchQuery', 'postprocessSearchResults']; + $this->assertEquals($expected, $processor_methods); + + // hook_search_api_server_features_alter() is triggered. + $this->assertTrue($this->server->supportsFeature('welcome_to_the_jungle')); + + $displays = \Drupal::getContainer()->get('plugin.manager.search_api.display') + ->getInstances(); + // hook_search_api_displays_alter was invoked. + $display_label = $displays['views_page:search_api_test_view__page_1']->label(); + $this->assertEquals('Some funny label for testing', $display_label); + } + +}