diff --git a/config/schema/search_api.index.schema.yml b/config/schema/search_api.index.schema.yml index 427f03f..3af6a34 100644 --- a/config/schema/search_api.index.schema.yml +++ b/config/schema/search_api.index.schema.yml @@ -17,7 +17,7 @@ search_api.index.*: read_only: type: boolean label: 'Read-only' - fields: + field_settings: type: sequence label: 'Indexed fields' sequence: @@ -48,24 +48,18 @@ search_api.index.*: hidden: type: boolean label: 'Whether the field should appear in the UI' - processors: + processor_settings: type: sequence label: 'Processor settings' sequence: type: mapping label: 'A processor' mapping: - processor_id: + plugin_id: type: string label: 'The plugin ID of the processor' - weights: - type: sequence - label: 'The processor''s weights for the different processing stages' - sequence: - type: integer - label: 'The processor''s weight for this stage' settings: - type: plugin.plugin_configuration.search_api_processor.[%parent.processor_id] + type: plugin.plugin_configuration.search_api_processor.[%parent.plugin_id] options: type: mapping label: 'Options' @@ -76,23 +70,30 @@ search_api.index.*: index_directly: type: boolean label: 'Index items immediately' - datasources: + datasource_settings: type: sequence - label: 'Datasource plugin IDs' + label: 'Datasource settings' sequence: - type: string - datasource_configs: + type: mapping + label: 'A datasource' + mapping: + plugin_id: + type: string + label: 'The plugin ID of the datasource config' + settings: + type: plugin.plugin_configuration.search_api_datasource.[%parent.plugin_id] + tracker_settings: type: sequence - label: 'Datasource plugin configurations' + label: 'Tracker settings' sequence: - type: plugin.plugin_configuration.search_api_datasource.[%key] - label: 'Datasource plugin configuration' - tracker: - type: string - label: 'Tracker plugin ID' - tracker_config: - label: 'Tracker config plugin' - type: plugin.plugin_configuration.search_api_tracker.[%parent.tracker] + type: mapping + label: 'A tracker' + mapping: + plugin_id: + type: string + label: 'The plugin ID of the tracker config' + settings: + type: plugin.plugin_configuration.search_api_tracker.[%parent.plugin_id] server: type: string label: 'Server ID' diff --git a/config/schema/search_api.processor.schema.yml b/config/schema/search_api.processor.schema.yml index 5366cb1..1448267 100644 --- a/config/schema/search_api.processor.schema.yml +++ b/config/schema/search_api.processor.schema.yml @@ -2,6 +2,12 @@ plugin.plugin_configuration.search_api_processor.add_url: type: mapping label: 'Add URL configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -13,6 +19,12 @@ plugin.plugin_configuration.search_api_processor.aggregated_field: type: mapping label: 'Add aggregation processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The aggregated fields configured for this index' @@ -37,6 +49,12 @@ plugin.plugin_configuration.search_api_processor.highlight: type: mapping label: 'Highlight processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' prefix: type: string label: 'Text/HTML that will be prepended to all occurrences of search keywords in highlighted text' @@ -57,6 +75,12 @@ plugin.plugin_configuration.search_api_processor.html_filter: type: mapping label: 'HTML filter processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -80,6 +104,12 @@ plugin.plugin_configuration.search_api_processor.ignorecase: type: mapping label: 'Ignore case processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -91,6 +121,12 @@ plugin.plugin_configuration.search_api_processor.ignore_character: type: mapping label: 'Ignore Character processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -115,6 +151,12 @@ plugin.plugin_configuration.search_api_processor.language: type: mapping label: 'Language field processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -126,6 +168,12 @@ plugin.plugin_configuration.search_api_processor.node_status: type: mapping label: 'node status processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -137,7 +185,12 @@ plugin.plugin_configuration.search_api_processor.rendered_item: type: mapping label: 'Rendered item processor configuration' mapping: - # @todo Verify "sequence" is right here once schemas are really used. + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' view_mode: type: sequence label: 'The selected view modes for each datasource, by bundle' @@ -158,6 +211,12 @@ plugin.plugin_configuration.search_api_processor.role_filter: type: mapping label: 'Role filter processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' default: type: boolean label: 'Default' @@ -172,6 +231,12 @@ plugin.plugin_configuration.search_api_processor.stopwords: type: mapping label: 'Stopwords processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -189,6 +254,12 @@ plugin.plugin_configuration.search_api_processor.tokenizer: type: mapping label: 'Tokenizer processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -212,6 +283,12 @@ plugin.plugin_configuration.search_api_processor.transliteration: type: mapping label: 'Transliteration processor configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' @@ -223,6 +300,12 @@ plugin.plugin_configuration.search_api_processor.content_access: type: mapping label: 'Content Access configuration' mapping: + weights: + type: sequence + label: 'The processor''s weights for the different processing stages' + sequence: + type: integer + label: 'The processor''s weight for this stage' fields: type: sequence label: 'The selected fields' diff --git a/config/schema/search_api.tracker.schema.yml b/config/schema/search_api.tracker.schema.yml index 297badc..1cb3518 100644 --- a/config/schema/search_api.tracker.schema.yml +++ b/config/schema/search_api.tracker.schema.yml @@ -1,4 +1,3 @@ -# @todo Update the key when https://www.drupal.org/node/2291073 is fixed. plugin.plugin_configuration.search_api_tracker.default: type: sequence label: 'Entity tracker configuration' diff --git a/search_api.drush.inc b/search_api.drush.inc index e403668..e2460f7 100644 --- a/search_api.drush.inc +++ b/search_api.drush.inc @@ -216,7 +216,7 @@ function drush_search_api_list() { $rows[] = array( $index->id(), $index->label(), - $index->getServerId() ? $index->getServer()->label() : $none, + $index->getServerId() ? $index->getServerInstance()->label() : $none, $types ? implode(', ', $types) : $none, $index->status() ? $enabled : $disabled, (int) $index->getOption('cron_limit'), @@ -325,8 +325,8 @@ function drush_search_api_status($index_id = NULL) { ); foreach ($indexes as $index) { - $indexed = $index->getTracker()->getIndexedItemsCount(); - $total = $index->getTracker()->getTotalItemsCount(); + $indexed = $index->getTrackerInstance()->getIndexedItemsCount(); + $total = $index->getTrackerInstance()->getTotalItemsCount(); $complete = '-'; if ($total > 0) { @@ -365,7 +365,7 @@ function drush_search_api_index($index_id = NULL, $limit = NULL, $batch_size = N } foreach ($indexes as $index) { - $tracker = $index->getTracker(); + $tracker = $index->getTrackerInstance(); $remaining = $tracker->getTotalItemsCount() - $tracker->getIndexedItemsCount(); if (!$remaining) { diff --git a/search_api.theme.inc b/search_api.theme.inc index 7de7c73..bc42364 100644 --- a/search_api.theme.inc +++ b/search_api.theme.inc @@ -229,8 +229,8 @@ function theme_search_api_index($variables) { // Get the index. /** @var $index \Drupal\search_api\IndexInterface */ $index = $variables['index']; - $server = $index->hasValidServer() ? $index->getServer() : NULL; - $tracker = $index->hasValidTracker() ? $index->getTracker() : NULL; + $server = $index->hasValidServer() ? $index->getServerInstance() : NULL; + $tracker = $index->hasValidTracker() ? $index->getTrackerInstance() : NULL; $output = ''; diff --git a/search_api_db/search_api_db_defaults/config/optional/search_api.index.default_index.yml b/search_api_db/search_api_db_defaults/config/optional/search_api.index.default_index.yml index 7941caa..7539dff 100644 --- a/search_api_db/search_api_db_defaults/config/optional/search_api.index.default_index.yml +++ b/search_api_db/search_api_db_defaults/config/optional/search_api.index.default_index.yml @@ -2,7 +2,7 @@ id: default_index name: 'Default content index' description: 'Default content index created by the Database Search Defaults module' read_only: false -fields: +field_settings: search_api_language: label: 'Item language' type: string @@ -70,29 +70,29 @@ fields: type: string datasource_id: 'entity:node' property_path: type -processors: +processor_settings: content_access: - processor_id: content_access - weights: - preprocess_index: -6 - preprocess_query: -4 - settings: { } + plugin_id: content_access + settings: + weights: + preprocess_index: -6 + preprocess_query: -4 highlight: - processor_id: highlight - weights: - postprocess_query: -9 + plugin_id: highlight settings: + weights: + postprocess_query: -9 highlight: always excerpt: true excerpt_length: 256 prefix: '' suffix: '' html_filter: - processor_id: html_filter - weights: - preprocess_index: -3 - preprocess_query: -6 + plugin_id: html_filter settings: + weights: + preprocess_index: -3 + preprocess_query: -6 fields: - rendered_item title: true @@ -104,29 +104,29 @@ processors: string: 2 b: 2 ignorecase: - processor_id: ignorecase - weights: - preprocess_index: -5 - preprocess_query: -8 + plugin_id: ignorecase settings: + weights: + preprocess_index: -5 + preprocess_query: -8 fields: - rendered_item - title language: - processor_id: language - weights: - preprocess_index: -50 - settings: { } + plugin_id: language + settings: + weights: + preprocess_index: -50 node_status: - processor_id: node_status - weights: - preprocess_index: -10 - settings: { } + plugin_id: node_status + settings: + weights: + preprocess_index: -10 rendered_item: - processor_id: rendered_item - weights: - preprocess_index: -8 + plugin_id: rendered_item settings: + weights: + preprocess_index: -8 roles: anonymous: anonymous view_mode: @@ -134,11 +134,11 @@ processors: article: search_index page: search_index stopwords: - processor_id: stopwords - weights: - preprocess_query: -10 - postprocess_query: -10 + plugin_id: stopwords settings: + weights: + preprocess_query: -10 + postprocess_query: -10 fields: - rendered_item - title @@ -179,11 +179,11 @@ processors: - will - with tokenizer: - processor_id: tokenizer - weights: - preprocess_index: -2 - preprocess_query: -5 + plugin_id: tokenizer settings: + weights: + preprocess_index: -2 + preprocess_query: -5 fields: - rendered_item - title @@ -191,27 +191,29 @@ processors: overlap_cjk: 1 minimum_word_size: '3' transliteration: - processor_id: transliteration - weights: - preprocess_index: -4 - preprocess_query: -7 + plugin_id: transliteration settings: + weights: + preprocess_index: -4 + preprocess_query: -7 fields: - rendered_item - title options: index_directly: true cron_limit: 50 -datasources: - - 'entity:node' -datasource_configs: +datasource_settings: 'entity:node': - default: '1' - bundles: - article: '0' - page: '0' -tracker: default -tracker_config: { } + plugin_id: 'entity:node' + settings: + default: '1' + bundles: + article: '0' + page: '0' +tracker_settings: + 'default': + plugin_id: default + settings: { } server: default_server status: true langcode: en diff --git a/search_api_db/src/Plugin/search_api/backend/Database.php b/search_api_db/src/Plugin/search_api/backend/Database.php index ef1af4a..c5fba12 100644 --- a/search_api_db/src/Plugin/search_api/backend/Database.php +++ b/search_api_db/src/Plugin/search_api/backend/Database.php @@ -1287,7 +1287,7 @@ class Database extends BackendPluginBase { if (count($words) > 1 && max(array_map('strlen', $words)) <= 50) { // Overlong token is due to bad tokenizing. // Check for "Tokenizer" preprocessor on index. - if (empty($index->getProcessorSettings()['search_api_tokenizer']['status'])) { + if (empty($index->getProcessors()['tokenizer'])) { $this->getLogger()->warning('An overlong word (more than 50 characters) was encountered while indexing, due to bad tokenizing. It is recommended to enable the "Tokenizer" preprocessor for indexes using database servers. Otherwise, the backend class has to use its own, fixed tokenizing.'); } else { diff --git a/search_api_db/tests/src/Kernel/BackendTest.php b/search_api_db/tests/src/Kernel/BackendTest.php index 5c43111..3f5146c 100644 --- a/search_api_db/tests/src/Kernel/BackendTest.php +++ b/search_api_db/tests/src/Kernel/BackendTest.php @@ -157,8 +157,11 @@ class BackendTest extends KernelTestBase { $index = $this->getIndex(); $this->assertTrue((bool) $index, 'The index was successfully created.'); - $this->assertEquals(5, $index->getTracker()->getTotalItemsCount(), 'Correct item count.'); - $this->assertEquals(0, $index->getTracker()->getIndexedItemsCount(), 'All items still need to be indexed.'); + $this->assertEquals(array("entity:entity_test"), $index->getDatasourceIds()); + $this->assertEquals('default', $index->getTrackerId()); + + $this->assertEquals(5, $index->getTrackerInstance()->getTotalItemsCount(), 'Correct item count.'); + $this->assertEquals(0, $index->getTrackerInstance()->getIndexedItemsCount(), 'All items still need to be indexed.'); } /** @@ -200,14 +203,15 @@ class BackendTest extends KernelTestBase { $property = 'body'; $this->addField($index, $property); - $processors = $index->getProcessorSettings(); - $processors['html_filter'] = array( - 'processor_id' => 'html_filter', - 'weights' => array(), - 'settings' => array(), - ); - $index->setProcessorSettings($processors); + $processor = \Drupal::getContainer() + ->get('plugin.manager.search_api.processor') + ->createInstance('html_filter'); + + $index->addProcessor($processor); $index->save(); + + $this->assertArrayHasKey('html_filter', $index->getProcessors()); + $this->assertArrayHasKey('body', $index->getFields()); } /** @@ -216,11 +220,12 @@ class BackendTest extends KernelTestBase { protected function disableHtmlFilter() { /** @var \Drupal\search_api\IndexInterface $index */ $index = $this->getIndex(); - $processors = $index->getProcessorSettings(); - unset($processors['html_filter']); - $index->setProcessorSettings($processors); $index->removeField('body'); + $index->removeProcessor('html_filter'); $index->save(); + + $this->assertArrayNotHasKey('html_filter', $index->getProcessors()); + $this->assertArrayNotHasKey('body', $index->getFields()); } /** @@ -873,7 +878,6 @@ class BackendTest extends KernelTestBase { // Regression test for #1916474. /** @var \Drupal\search_api\IndexInterface $index */ $index = $this->getIndex(); - $index->resetCaches(); $this->addField($index, 'prices', 'decimal'); $success = $index->save(); $this->assertTrue($success, 'The index field settings were successfully changed.'); diff --git a/src/Entity/Index.php b/src/Entity/Index.php index a993e44..614e0fe 100644 --- a/src/Entity/Index.php +++ b/src/Entity/Index.php @@ -57,13 +57,11 @@ use Drupal\views\Views; * "name", * "description", * "read_only", - * "fields", - * "processors", + * "field_settings", + * "processor_settings", * "options", - * "datasources", - * "datasource_configs", - * "tracker", - * "tracker_config", + * "datasource_settings", + * "tracker_settings", * "server", * }, * links = { @@ -115,7 +113,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * * @var array */ - protected $fields = array(); + protected $field_settings = array(); /** * An array of options configuring this index. @@ -127,18 +125,11 @@ class Index extends ConfigEntityBase implements IndexInterface { protected $options = array(); /** - * The IDs of the datasources selected for this index. + * The settings of the datasources selected for this index. * * @var string[] */ - protected $datasources = array(); - - /** - * The configuration for the selected datasources. - * - * @var array - */ - protected $datasource_configs = array(); + protected $datasource_settings = array(); /** * The instantiated datasource plugins. @@ -147,30 +138,28 @@ class Index extends ConfigEntityBase implements IndexInterface { * * @see getDatasources() */ - protected $datasourcePlugins; - - /** - * The tracker plugin ID. - * - * @var string - */ - protected $tracker = 'default'; + protected $datasourceInstances; /** - * The tracker plugin configuration. + * The tracker settings * * @var array */ - protected $tracker_config = array(); + protected $tracker_settings = array( + 'default' => array( + 'plugin_id' => 'default', + 'settings' => array() + ), + ); /** * The tracker plugin instance. * * @var \Drupal\search_api\Tracker\TrackerInterface|null * - * @see getTracker() + * @see getTrackerInstance() */ - protected $trackerPlugin; + protected $trackerInstance; /** * The ID of the server on which data should be indexed. @@ -184,7 +173,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * * @var \Drupal\search_api\ServerInterface * - * @see getServer() + * @see getServerInstance() */ protected $serverInstance; @@ -201,7 +190,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * @var array * An array containing processor settings. */ - protected $processors = array(); + protected $processor_settings = array(); /** * Cached information about the processors available for this index. @@ -210,7 +199,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * * @see loadProcessors() */ - protected $processorPlugins; + protected $processorInstances = NULL; /** * Whether reindexing has been triggered for this index in this page request. @@ -301,7 +290,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getDatasourceIds() { - return $this->datasources; + return array_keys($this->datasource_settings); } /** @@ -329,20 +318,20 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getDatasources($only_enabled = TRUE) { - if (!isset($this->datasourcePlugins)) { - $this->datasourcePlugins = array(); + if (!isset($this->datasourceInstances)) { + $this->datasourceInstances = array(); /** @var $datasource_plugin_manager \Drupal\search_api\Datasource\DatasourcePluginManager */ $datasource_plugin_manager = \Drupal::service('plugin.manager.search_api.datasource'); foreach ($datasource_plugin_manager->getDefinitions() as $name => $datasource_definition) { - if (class_exists($datasource_definition['class']) && empty($this->datasourcePlugins[$name])) { + if (class_exists($datasource_definition['class']) && empty($this->datasourceInstances[$name])) { // Create our settings for this datasource. - $config = isset($this->datasource_configs[$name]) ? $this->datasource_configs[$name] : array(); + $config = isset($this->datasource_settings[$name]) ? $this->datasource_settings[$name]['settings'] : array(); $config += array('index' => $this); /** @var $datasource \Drupal\search_api\Datasource\DatasourceInterface */ $datasource = $datasource_plugin_manager->createInstance($name, $config); - $this->datasourcePlugins[$name] = $datasource; + $this->datasourceInstances[$name] = $datasource; } elseif (!class_exists($datasource_definition['class'])) { \Drupal::logger('search_api')->warning('Datasource @id specifies a non-existing @class.', array('@id' => $name, '@class' => $datasource_definition['class'])); @@ -352,9 +341,10 @@ class Index extends ConfigEntityBase implements IndexInterface { // Filter datasources by status if required. if (!$only_enabled) { - return $this->datasourcePlugins; + return $this->datasourceInstances; } - return array_intersect_key($this->datasourcePlugins, array_flip($this->datasources)); + + return array_intersect_key($this->datasourceInstances, $this->datasource_settings); } /** @@ -368,23 +358,35 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getTrackerId() { - return $this->tracker; + if (is_null($this->tracker_settings)) { + return 'default'; + } + + $plugins = array_keys($this->tracker_settings); + return $this->tracker_settings[$plugins[0]]['plugin_id']; } /** * {@inheritdoc} */ - public function getTracker() { - if (!$this->trackerPlugin) { - $tracker_plugin_configuration = array('index' => $this) + $this->tracker_config; - if (!($this->trackerPlugin = \Drupal::service('plugin.manager.search_api.tracker')->createInstance($this->getTrackerId(), $tracker_plugin_configuration))) { - $args['@tracker'] = $this->tracker; + public function getTrackerInstance() { + if (!$this->trackerInstance) { + + if (is_null($this->tracker_settings)) { + $tracker_plugin_configuration = array('index' => $this); + } else { + $plugins = array_keys($this->tracker_settings); + $tracker_plugin_configuration = array('index' => $this) + $this->tracker_settings[$plugins[0]]['settings']; + } + + if (!($this->trackerInstance = \Drupal::service('plugin.manager.search_api.tracker')->createInstance($this->getTrackerId(), $tracker_plugin_configuration))) { + $args['@tracker'] = $this->getTrackerId(); $args['%index'] = $this->label(); throw new SearchApiException(new FormattableMarkup('The tracker with ID "@tracker" could not be retrieved for index %index.', $args)); } } - return $this->trackerPlugin; + return $this->trackerInstance; } /** @@ -398,7 +400,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function isServerEnabled() { - return $this->hasValidServer() && $this->getServer()->status(); + return $this->hasValidServer() && $this->getServerInstance()->status(); } /** @@ -411,7 +413,7 @@ class Index extends ConfigEntityBase implements IndexInterface { /** * {@inheritdoc} */ - public function getServer() { + public function getServerInstance() { if (!$this->serverInstance && $this->server) { $this->serverInstance = Server::load($this->server); if (!$this->serverInstance) { @@ -441,7 +443,7 @@ class Index extends ConfigEntityBase implements IndexInterface { // Filter processors by status if required. Enabled processors are those // which have settings in the "processors" option. if ($only_enabled) { - $processors_settings = $this->getProcessorSettings(); + $processors_settings = $this->processor_settings; $processors = array_intersect_key($processors, $processors_settings); } @@ -453,15 +455,15 @@ class Index extends ConfigEntityBase implements IndexInterface { */ public function getProcessorsByStage($stage, $only_enabled = TRUE) { $processors = $this->loadProcessors(); - $processor_settings = $this->getProcessorSettings(); + $processor_settings = $this->processor_settings; $processor_weights = array(); // Get a list of all processors meeting the criteria (stage and, optionally, // enabled) along with their effective weights (user-set or default). foreach ($processors as $name => $processor) { if ($processor->supportsStage($stage) && !($only_enabled && empty($processor_settings[$name]))) { - if (!empty($processor_settings[$name]['weights'][$stage])) { - $processor_weights[$name] = $processor_settings[$name]['weights'][$stage]; + if (!empty($processor_settings[$name]['settings']['weights'][$stage])) { + $processor_weights[$name] = $processor_settings[$name]['settings']['weights'][$stage]; } else { $processor_weights[$name] = $processor->getDefaultWeight($stage); @@ -476,23 +478,51 @@ class Index extends ConfigEntityBase implements IndexInterface { foreach ($processor_weights as $name => $weight) { $return_processors[$name] = $processors[$name]; } + return $return_processors; } /** + * {@inheritdoc} + */ + public function addProcessor(ProcessorInterface $processor) { + $this->processor_settings[$processor->getPluginId()] = array( + 'plugin_id' => $processor->getPluginId(), + 'settings' => $processor->getConfiguration(), + ); + + // Reset processors canonical storage. + $this->processorInstances = NULL; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function removeProcessor($processor_id) { + unset($this->processor_settings[$processor_id]); + + // Reset processors canonical storage. + $this->processorInstances = NULL; + + return $this; + } + + /** * Retrieves all processors supported by this index. * * @return \Drupal\search_api\Processor\ProcessorInterface[] * The loaded processors, keyed by processor ID. */ protected function loadProcessors() { - if (empty($this->processorPlugins)) { + if (is_null($this->processorInstances)) { /** @var $processor_plugin_manager \Drupal\search_api\Processor\ProcessorPluginManager */ $processor_plugin_manager = \Drupal::service('plugin.manager.search_api.processor'); - $processor_settings = $this->getProcessorSettings(); + $processor_settings = $this->processor_settings; foreach ($processor_plugin_manager->getDefinitions() as $name => $processor_definition) { - if (class_exists($processor_definition['class']) && empty($this->processorPlugins[$name])) { + if (class_exists($processor_definition['class']) && empty($this->processorInstances[$name])) { // Create our settings for this processor. $settings = empty($processor_settings[$name]['settings']) ? array() : $processor_settings[$name]['settings']; $settings['index'] = $this; @@ -500,7 +530,7 @@ class Index extends ConfigEntityBase implements IndexInterface { /** @var $processor \Drupal\search_api\Processor\ProcessorInterface */ $processor = $processor_plugin_manager->createInstance($name, $settings); if ($processor->supportsIndex($this)) { - $this->processorPlugins[$name] = $processor; + $this->processorInstances[$name] = $processor; } } elseif (!class_exists($processor_definition['class'])) { @@ -509,22 +539,7 @@ class Index extends ConfigEntityBase implements IndexInterface { } } - return $this->processorPlugins; - } - - /** - * {@inheritdoc} - */ - public function getProcessorSettings() { - return $this->processors; - } - - /** - * {@inheritdoc} - */ - public function setProcessorSettings(array $processors) { - $this->processors = $processors; - return $this; + return $this->processorInstances; } /** @@ -578,9 +593,8 @@ class Index extends ConfigEntityBase implements IndexInterface { throw new SearchApiException(new FormattableMarkup('Cannot add field with machine name %field_id: machine name is already taken.', $args)); } - $this->fields[$field_id] = $field->getSettings(); + $this->field_settings[$field_id] = $field->getSettings(); - $this->resetCaches(); return $this; } @@ -588,7 +602,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function renameField($old_field_id, $new_field_id) { - if (isset($this->fields[$old_field_id])) { + if (isset($this->getFields()[$old_field_id])) { $args['%field_id'] = $old_field_id; throw new SearchApiException(new FormattableMarkup('Could not rename field with machine name %field_id: no such field.', $args)); } @@ -596,15 +610,14 @@ class Index extends ConfigEntityBase implements IndexInterface { $args['%field_id'] = $new_field_id; throw new SearchApiException(new FormattableMarkup('%field_id is a reserved value and cannot be used as the machine name of a normal field.', $args)); } - if (isset($this->fields[$new_field_id])) { + if (isset($this->getFields()[$new_field_id])) { $args['%field_id'] = $new_field_id; throw new SearchApiException(new FormattableMarkup('%field_id is a reserved value and cannot be used as the machine name of a normal field.', $args)); } - $this->fields[$new_field_id] = $this->fields[$old_field_id]; - unset($this->fields[$old_field_id]); + $this->field_settings[$new_field_id] = $this->field_settings[$old_field_id]; + unset($this->field_settings[$old_field_id]); - $this->resetCaches(); return $this; } @@ -621,9 +634,8 @@ class Index extends ConfigEntityBase implements IndexInterface { throw new SearchApiException(new FormattableMarkup('Cannot remove field with machine name %field_id: field is locked.', $args)); } - unset($this->fields[$field_id]); + unset($this->field_settings[$field_id]); - $this->resetCaches(); return $this; } @@ -631,14 +643,10 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getFields() { - $fields = $this->getCache(__FUNCTION__, FALSE); - if (!$fields) { - $fields = array(); - foreach ($this->getFieldSettings() as $key => $field_info) { - $fields[$key] = Utility::createField($this, $key, $field_info); - } + $fields = array(); + foreach ($this->field_settings as $key => $field_info) { + $fields[$key] = Utility::createField($this, $key, $field_info); } - $this->setCache(__FUNCTION__, $fields, FALSE); return $fields; } @@ -655,14 +663,10 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getFieldsByDatasource($datasource_id) { - $datasource_fields = $this->getCache(__FUNCTION__); - if (!$datasource_fields) { - $datasource_fields = array_fill_keys($this->datasources, array()); - $datasource_fields[NULL] = array(); - foreach ($this->getFields() as $field_id => $field) { - $datasource_fields[$field->getDatasourceId()][$field_id] = $field; - } - $this->setCache(__FUNCTION__, $datasource_fields); + $datasource_fields = array_fill_keys(array_keys($this->datasource_settings), array()); + $datasource_fields[NULL] = array(); + foreach ($this->getFields() as $field_id => $field) { + $datasource_fields[$field->getDatasourceId()][$field_id] = $field; } return $datasource_fields[$datasource_id]; @@ -672,15 +676,11 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getFulltextFields() { - $fulltext_fields = $this->getCache(__FUNCTION__); - if (!$fulltext_fields) { - $fulltext_fields = array(); - foreach ($this->getFieldSettings() as $key => $field_info) { - if (Utility::isTextType($field_info['type'])) { - $fulltext_fields[] = $key; - } + $fulltext_fields = array(); + foreach ($this->field_settings as $key => $field_info) { + if (Utility::isTextType($field_info['type'])) { + $fulltext_fields[] = $key; } - $this->setCache(__FUNCTION__, $fulltext_fields); } return $fulltext_fields; } @@ -688,39 +688,20 @@ class Index extends ConfigEntityBase implements IndexInterface { /** * {@inheritdoc} */ - public function getFieldSettings() { - return $this->fields; - } - - /** - * {@inheritdoc} - */ - public function setFieldSettings(array $fields = array()) { - $this->fields = $fields; - return $this; - } - - /** - * {@inheritdoc} - */ public function getPropertyDefinitions($datasource_id, $alter = TRUE) { $alter = $alter ? 1 : 0; - $properties = $this->getCache(__FUNCTION__); - if (!isset($properties[$datasource_id][$alter])) { - if (isset($datasource_id)) { - $datasource = $this->getDatasource($datasource_id); - $properties[$datasource_id][$alter] = $datasource->getPropertyDefinitions(); - } - else { - $datasource = NULL; - $properties[$datasource_id][$alter] = array(); - } - if ($alter) { - foreach ($this->getProcessors() as $processor) { - $processor->alterPropertyDefinitions($properties[$datasource_id][$alter], $datasource); - } + if (isset($datasource_id)) { + $datasource = $this->getDatasource($datasource_id); + $properties[$datasource_id][$alter] = $datasource->getPropertyDefinitions(); + } + else { + $datasource = NULL; + $properties[$datasource_id][$alter] = array(); + } + if ($alter) { + foreach ($this->getProcessors() as $processor) { + $processor->alterPropertyDefinitions($properties[$datasource_id][$alter], $datasource); } - $this->setCache(__FUNCTION__, $properties); } return $properties[$datasource_id][$alter]; } @@ -767,7 +748,7 @@ class Index extends ConfigEntityBase implements IndexInterface { */ public function indexItems($limit = '-1', $datasource_id = NULL) { if ($this->hasValidTracker() && !$this->isReadOnly()) { - $tracker = $this->getTracker(); + $tracker = $this->getTrackerInstance(); $next_set = $tracker->getRemainingItems($limit, $datasource_id); $items = $this->loadItemsMultiple($next_set); if (count($items) != count($next_set)) { @@ -799,7 +780,7 @@ class Index extends ConfigEntityBase implements IndexInterface { if (!$this->status) { throw new SearchApiException(new FormattableMarkup("Couldn't index values on index %index (index is disabled)", array('%index' => $this->label()))); } - if (empty($this->fields)) { + if (empty($this->getFields())) { throw new SearchApiException(new FormattableMarkup("Couldn't index values on index %index (no fields selected)", array('%index' => $this->label()))); } @@ -830,12 +811,12 @@ class Index extends ConfigEntityBase implements IndexInterface { // Items that are rejected should also be deleted from the server. if ($rejected_ids) { - $this->getServer()->deleteItems($this, $rejected_ids); + $this->getServerInstance()->deleteItems($this, $rejected_ids); } $indexed_ids = array(); if ($items) { - $indexed_ids = $this->getServer()->indexItems($this, $items); + $indexed_ids = $this->getServerInstance()->indexItems($this, $items); } // Return the IDs of all items that were either successfully indexed or @@ -844,7 +825,7 @@ class Index extends ConfigEntityBase implements IndexInterface { if ($processed_ids) { if ($this->hasValidTracker()) { - $this->getTracker()->trackItemsIndexed($processed_ids); + $this->getTrackerInstance()->trackItemsIndexed($processed_ids); } // Since we've indexed items now, triggering reindexing would have some // effect again. Therefore, we reset the flag. @@ -889,7 +870,7 @@ class Index extends ConfigEntityBase implements IndexInterface { foreach ($ids as $id) { $item_ids[] = Utility::createCombinedId($datasource_id, $id); } - $this->getTracker()->$tracker_method($item_ids); + $this->getTrackerInstance()->$tracker_method($item_ids); if (!$this->isReadOnly() && $this->getOption('index_directly')) { try { $items = $this->loadItemsMultiple($item_ids); @@ -913,9 +894,9 @@ class Index extends ConfigEntityBase implements IndexInterface { foreach ($ids as $id) { $item_ids[] = Utility::createCombinedId($datasource_id, $id); } - $this->getTracker()->trackItemsDeleted($item_ids); + $this->getTrackerInstance()->trackItemsDeleted($item_ids); if (!$this->isReadOnly() && $this->isServerEnabled()) { - $this->getServer()->deleteItems($this, $item_ids); + $this->getServerInstance()->deleteItems($this, $item_ids); } } } @@ -926,7 +907,7 @@ class Index extends ConfigEntityBase implements IndexInterface { public function reindex() { if ($this->status() && !$this->hasReindexed) { $this->hasReindexed = TRUE; - $this->getTracker()->trackAllItemsUpdated(); + $this->getTrackerInstance()->trackAllItemsUpdated(); \Drupal::moduleHandler()->invokeAll('search_api_index_reindex', array($this, FALSE)); } } @@ -941,11 +922,11 @@ class Index extends ConfigEntityBase implements IndexInterface { if (!$this->hasReindexed) { $invoke_hook = TRUE; $this->hasReindexed = TRUE; - $this->getTracker()->trackAllItemsUpdated(); + $this->getTrackerInstance()->trackAllItemsUpdated(); } if (!$this->isReadOnly()) { $invoke_hook = TRUE; - $this->getServer()->deleteAllIndexItems($this); + $this->getServerInstance()->deleteAllIndexItems($this); } if ($invoke_hook) { \Drupal::moduleHandler()->invokeAll('search_api_index_reindex', array($this, !$this->isReadOnly())); @@ -961,76 +942,6 @@ class Index extends ConfigEntityBase implements IndexInterface { } /** - * Retrieves data from the static and/or stored cache. - * - * @param string $method - * The name of the method for which data is requested. Used to construct the - * cache ID. - * @param bool $static_only - * (optional) If TRUE, only consult the static cache for this page request, - * don't attempt to load the value from the stored cache. - * - * @return mixed|null - * The cached data, or NULL if it could not be found. - */ - protected function getCache($method, $static_only = TRUE) { - if (isset($this->cache[$method])) { - return $this->cache[$method]; - } - - if (!$static_only) { - $cid = $this->getCacheId($method); - if ($cached = \Drupal::cache()->get($cid)) { - if (is_array($cached->data)) { - $this->updateFieldsIndex($cached->data); - } - $this->cache[$method] = $cached->data; - return $this->cache[$method]; - } - } - - return NULL; - } - - /** - * Sets data in the static and/or stored cache. - * - * @param string $method - * The name of the method for which cached data should be set. Used to - * construct the cache ID. - * @param mixed $value - * The value to set for the cache. - * @param bool $static_only - * (optional) If TRUE, only set the value in the static cache for this page - * request, not in the stored cache. - * - * @return $this - */ - protected function setCache($method, $value, $static_only = TRUE) { - $this->cache[$method] = $value; - if (!$static_only) { - $cid = $this->getCacheId($method); - \Drupal::cache() - ->set($cid, $value, Cache::PERMANENT, $this->getCacheTags()); - } - return $this; - } - - /** - * {@inheritdoc} - */ - public function resetCaches($include_stored = TRUE) { - $this->datasourcePlugins = NULL; - $this->trackerPlugin = NULL; - $this->serverInstance = NULL; - $this->processorPlugins = NULL; - $this->cache = array(); - if ($include_stored) { - Cache::invalidateTags($this->getCacheTags()); - } - } - - /** * Sets this object as the index for all fields contained in the given array. * * This is important when loading fields from the cache, because their index @@ -1075,27 +986,23 @@ class Index extends ConfigEntityBase implements IndexInterface { // Remove all "locked" and "hidden" flags from all fields of the index. If // they are still valid, they should be re-added by the processors. - foreach ($this->fields as $field_id => $field_settings) { - unset($this->fields[$field_id]['indexed_locked']); - unset($this->fields[$field_id]['type_locked']); - unset($this->fields[$field_id]['hidden']); + foreach ($this->field_settings as $field_id => $field_settings) { + unset($this->field_settings[$field_id]['indexed_locked']); + unset($this->field_settings[$field_id]['type_locked']); + unset($this->field_settings[$field_id]['hidden']); } // We first have to check for locked processors, otherwise their // preIndexSave() methods might not be called in the next step. foreach ($this->getProcessors(FALSE) as $processor_id => $processor) { - if ($processor->isLocked() && !isset($this->processors[$processor_id])) { - $this->processors[$processor_id] = array( - 'processor_id' => $processor_id, - 'weights' => array(), + if ($processor->isLocked() && !isset($this->processor_settings[$processor_id])) { + $this->processor_settings[$processor_id] = array( + 'plugin_id' => $processor_id, 'settings' => array(), ); } } - // Reset the cache so the used processors and fields will be up-to-date. - $this->resetCaches(); - // Call the preIndexSave() method of all applicable processors. foreach ($this->getProcessorsByStage(ProcessorInterface::STAGE_PRE_INDEX_SAVE) as $processor) { $processor->preIndexSave(); @@ -1107,10 +1014,10 @@ class Index extends ConfigEntityBase implements IndexInterface { */ public function postSave(EntityStorageInterface $storage, $update = TRUE) { parent::postSave($storage, $update); - $this->resetCaches(); try { // Fake an original for inserts to make code cleaner. + /** @var \Drupal\search_api\IndexInterface $original */ $original = $update ? $this->original : static::create(array('status' => FALSE)); $index_task_manager = \Drupal::getContainer() ->get('search_api.index_task_manager'); @@ -1127,11 +1034,11 @@ class Index extends ConfigEntityBase implements IndexInterface { $index_task_manager->stopTracking($this); } if ($original->isServerEnabled()) { - $original->getServer()->removeIndex($this); + $original->getServerInstance()->removeIndex($this); } } elseif ($this->status() && !$original->status()) { - $this->getServer()->addIndex($this); + $this->getServerInstance()->addIndex($this); if ($this->hasValidTracker()) { $index_task_manager->startTracking($this); } @@ -1157,7 +1064,7 @@ class Index extends ConfigEntityBase implements IndexInterface { \Drupal::cache('discovery')->delete('views:wizard'); } - $this->resetCaches(); + Cache::invalidateTags($this->getCacheTags()); } catch (SearchApiException $e) { watchdog_exception('search_api', $e); @@ -1180,17 +1087,17 @@ class Index extends ConfigEntityBase implements IndexInterface { if ($this->getServerId() != $original->getServerId()) { if ($original->isServerEnabled()) { - $original->getServer()->removeIndex($this); + $original->getServerInstance()->removeIndex($this); } if ($this->isServerEnabled()) { - $this->getServer()->addIndex($this); + $this->getServerInstance()->addIndex($this); } // When the server changes we also need to trigger a reindex. $this->reindex(); } elseif ($this->isServerEnabled()) { // Tell the server the index configuration got updated - $this->getServer()->updateIndex($this); + $this->getServerInstance()->updateIndex($this); } } @@ -1234,7 +1141,7 @@ class Index extends ConfigEntityBase implements IndexInterface { // enabled afterwards. Otherwise, this method should not be called. assert('$this->status() && $original->status()', '::reactToTrackerSwitch should only be called when the index is enabled'); - if ($this->tracker != $original->getTrackerId()) { + if ($this->getTrackerId() != $original->getTrackerId()) { $index_task_manager = \Drupal::getContainer()->get('search_api.index_task_manager'); if ($original->hasValidTracker()) { $index_task_manager->stopTracking($this); @@ -1252,21 +1159,20 @@ class Index extends ConfigEntityBase implements IndexInterface { * The previous version of the index. */ protected function reactToProcessorChanges(IndexInterface $original) { - $original_settings = $original->getProcessorSettings(); - $new_settings = $this->getProcessorSettings(); + $old_processors = $original->getProcessors(); + $new_processors = $this->getProcessors(); // Only actually do something when the processor settings are changed. - if ($original_settings != $new_settings) { + if ($old_processors != $new_processors) { $requires_reindex = FALSE; - $processors = $this->getProcessors(FALSE); // Loop over all new settings and check if the processors were already set // in the original entity. - foreach ($new_settings as $key => $setting) { + foreach ($new_processors as $key => $processor) { // The processor is new, because it wasn't configured in the original // entity. - if (!isset($original_settings[$key])) { - if ($processors[$key]->requiresReindexing(NULL, $new_settings[$key])) { + if (!isset($old_processors[$key])) { + if ($processor->requiresReindexing(NULL, $processor->getConfiguration())) { $requires_reindex = TRUE; break; } @@ -1276,17 +1182,12 @@ class Index extends ConfigEntityBase implements IndexInterface { if (!$requires_reindex) { // Loop over all original settings and check if one of them has been // removed or changed. - foreach ($original_settings as $key => $old_processor_settings) { - // If the processor isn't even available any more, we can't determine - // what it would have said about the need to reindex. Err on the side - // of caution and guess "yes". - if (empty($processors[$key])) { - $requires_reindex = TRUE; - break; - } - $new_processor_settings = isset($new_settings[$key]) ? $new_settings[$key] : NULL; - if (!isset($new_processor_settings) || $new_processor_settings != $old_processor_settings) { - if ($processors[$key]->requiresReindexing($old_processor_settings, $new_processor_settings)) { + foreach ($old_processors as $key => $old_processor) { + $new_processor = isset($new_processors[$key]) ? $new_processors[$key] : NULL; + $old_config = $old_processor->getConfiguration(); + $new_config = $new_processor ? $new_processor->getConfiguration() : NULL; + if (!$new_processor || $old_config != $new_config) { + if ($old_processor->requiresReindexing($old_config, $new_config)) { $requires_reindex = TRUE; break; } @@ -1310,10 +1211,10 @@ class Index extends ConfigEntityBase implements IndexInterface { /** @var \Drupal\search_api\IndexInterface[] $entities */ foreach ($entities as $index) { if ($index->hasValidTracker()) { - $index->getTracker()->trackAllItemsDeleted(); + $index->getTrackerInstance()->trackAllItemsDeleted(); } if ($index->hasValidServer()) { - $index->getServer()->removeIndex($index); + $index->getServerInstance()->removeIndex($index); } } } @@ -1420,7 +1321,7 @@ class Index extends ConfigEntityBase implements IndexInterface { // The server needs special treatment, since it is a dependency of the index // itself, and not one of its plugins. if ($this->hasValidServer()) { - $name = $this->getServer()->getConfigDependencyName(); + $name = $this->getServerInstance()->getConfigDependencyName(); $dependency_data['config'][$name]['optional']['index'][$this->id] = $this; } @@ -1540,18 +1441,34 @@ class Index extends ConfigEntityBase implements IndexInterface { // The handling of how we translate plugin changes back to the index varies // according to plugin type, unfortunately. // First, remove plugins that need to be removed. - $this->processors = array_intersect_key($this->processors, $all_plugins['processors']); - $this->datasources = array_keys($all_plugins['datasources']); - $this->datasource_configs = array_intersect_key($this->datasource_configs, $all_plugins['datasources']); + $this->processor_settings = array_intersect_key($this->processor_settings, $all_plugins['processors']); + $new_datasources = array(); + foreach ($all_plugins['datasources'] as $plugin_id => $settings) { + $new_datasources[$plugin_id] = array( + 'plugin_id' => $plugin_id, + 'settings' => $settings, + ); + } + $this->datasource_settings = array_intersect_key($this->datasource_settings, $new_datasources); + // There always needs to be a tracker. if (empty($all_plugins['tracker'])) { - $this->tracker = \Drupal::config('search_api.settings')->get('default_tracker'); - $this->tracker_config = array(); + $default_tracker_id = \Drupal::config('search_api.settings')->get('default_tracker'); + $this->tracker_settings = array( + $default_tracker_id = array( + 'plugin_id' => $default_tracker_id, + 'settings' => array(), + ) + ); + + // Repopulate the tracker instance with the new settings. + $this->trackerInstance = NULL; + $this->getTrackerInstance(); } // There also always needs to be a datasource, but here we have no easy way // out – if we had to remove all datasources, the operation fails. Return // FALSE to indicate this, which will cause the index to be deleted. - if (!$this->datasources) { + if (!$this->datasource_settings) { return FALSE; } @@ -1560,22 +1477,18 @@ class Index extends ConfigEntityBase implements IndexInterface { foreach ($plugin_configs as $plugin_id => $plugin_config) { switch ($plugin_type) { case 'processors': - $this->processors[$plugin_id]['settings'] = $plugin_config; + $this->processor_settings[$plugin_id]['settings'] = $plugin_config; break; case 'datasources': - $this->datasource_configs[$plugin_id] = $plugin_config; + $this->datasource_settings[$plugin_id]['settings'] = $plugin_config; break; case 'tracker': - $this->tracker_config = $plugin_config; + $this->tracker_settings[$plugin_id]['settings'] = $plugin_config; break; } } } - if ($changed) { - $this->resetCaches(); - } - return $changed; } @@ -1590,7 +1503,7 @@ class Index extends ConfigEntityBase implements IndexInterface { $plugins = array(); if ($this->hasValidTracker()) { - $plugins['tracker'][$this->getTrackerId()] = $this->getTracker(); + $plugins['tracker'][$this->getTrackerId()] = $this->getTrackerInstance(); } $plugins['processors'] = $this->getProcessors(); $plugins['datasources'] = $this->getDatasources(); @@ -1599,26 +1512,16 @@ class Index extends ConfigEntityBase implements IndexInterface { } /** - * Implements the magic __clone() method. - * - * Prevents the cached plugins and fields from being cloned, too (since they - * would then point to the wrong index object). - */ - public function __clone() { - $this->resetCaches(FALSE); - } - - /** * Implements the magic __sleep() method. * * Prevents the cached plugins and fields from being serialized. */ public function __sleep() { $properties = get_object_vars($this); - unset($properties['datasourcePlugins']); - unset($properties['trackerPlugin']); + unset($properties['datasourceInstances']); + unset($properties['trackerInstance']); unset($properties['serverInstance']); - unset($properties['processorPlugins']); + unset($properties['processorInstances']); unset($properties['cache']); return array_keys($properties); } diff --git a/src/Form/IndexFieldsForm.php b/src/Form/IndexFieldsForm.php index 4b4b2e5..a214251 100644 --- a/src/Form/IndexFieldsForm.php +++ b/src/Form/IndexFieldsForm.php @@ -213,7 +213,7 @@ class IndexFieldsForm extends EntityForm { $form['description']['#markup'] = $this->t('

The data type of a field determines how it can be used for searching and filtering. The boost is used to give additional weight to certain fields, e.g. titles or tags.

Whether detailed field types are supported depends on the type of server this index resides on. In any case, fields of type "Fulltext" will always be fulltext-searchable.

'); if ($index->hasValidServer()) { $form['description']['#markup'] .= '

' . $this->t('Check the ' . "server's backend class description for details.", - array(':server-url' => $index->getServer()->toUrl('canonical')->toString())) . '

'; + array(':server-url' => $index->getServerInstance()->toUrl('canonical')->toString())) . '

'; } if ($fields = $index->getFieldsByDatasource(NULL)) { diff --git a/src/Form/IndexForm.php b/src/Form/IndexForm.php index 2bfca64..1db8781 100644 --- a/src/Form/IndexForm.php +++ b/src/Form/IndexForm.php @@ -262,7 +262,7 @@ class IndexForm extends EntityForm { '#title' => $this->t('Tracker'), '#description' => $this->t('Select the type of tracker which should be used for keeping track of item changes.'), '#options' => $this->getTrackerPluginManager()->getOptionsList(), - '#default_value' => $index->hasValidTracker() ? $index->getTracker()->getPluginId() : key($tracker_options), + '#default_value' => $index->hasValidTracker() ? $index->getTrackerInstance()->getPluginId() : key($tracker_options), '#required' => TRUE, '#disabled' => !$index->isNew(), '#ajax' => array( @@ -313,7 +313,7 @@ class IndexForm extends EntityForm { '#description' => $this->t('Only enabled indexes can be used for indexing and searching. This setting will only take effect if the selected server is also enabled.'), '#default_value' => $index->status(), // Can't enable an index lying on a disabled server or no server at all. - '#disabled' => !$index->status() && (!$index->hasValidServer() || !$index->getServer()->status()), + '#disabled' => !$index->status() && (!$index->hasValidServer() || !$index->getServerInstance()->status()), // @todo This doesn't seem to work and should also hide for disabled // servers. If that works, we can probably remove the last sentence of // the description. @@ -392,7 +392,7 @@ class IndexForm extends EntityForm { */ public function buildTrackerConfigForm(array &$form, FormStateInterface $form_state, IndexInterface $index) { if ($index->hasValidTracker()) { - $tracker = $index->getTracker(); + $tracker = $index->getTrackerInstance(); // @todo Create, use and save SubFormState already here, not only in // validate(). Also, use proper subset of $form for first parameter? if ($config_form = $tracker->buildConfigurationForm(array(), $form_state)) { @@ -484,7 +484,7 @@ class IndexForm extends EntityForm { // form structure). $tracker_id = $form_state->getValue('tracker', NULL); if ($this->originalEntity->getTrackerId() == $tracker_id) { - $tracker = $this->originalEntity->getTracker(); + $tracker = $this->originalEntity->getTrackerInstance(); } else { $tracker = $this->trackerPluginManager->createInstance($tracker_id, array('index' => $this->originalEntity)); @@ -526,15 +526,17 @@ class IndexForm extends EntityForm { $datasources = $form_state->getValue('datasources', array()); /** @var \Drupal\search_api\Datasource\DatasourceInterface[] $datasource_plugins */ $datasource_plugins = $this->originalEntity->getDatasources(FALSE); - $datasource_configuration = array(); + $datasource_settings = array(); foreach ($datasources as $datasource_id) { $datasource = $datasource_plugins[$datasource_id]; $datasource_form = (!empty($form['datasource_configs'][$datasource_id])) ? $form['datasource_configs'][$datasource_id] : array(); $datasource_form_state = new SubFormState($form_state, array('datasource_configs', $datasource_id)); $datasource->submitConfigurationForm($datasource_form, $datasource_form_state); - $datasource_configuration[$datasource_id] = $datasource->getConfiguration(); + + $datasource_settings[$datasource_id]['plugin_id'] = $datasource_id; + $datasource_settings[$datasource_id]['settings'] = $datasource->getConfiguration(); } - $index->set('datasource_configs', $datasource_configuration); + $index->set('datasource_settings', $datasource_settings); // Call submitConfigurationForm() for the (possibly new) tracker. // @todo It seems if we change the tracker, we would validate/submit the old @@ -544,7 +546,7 @@ class IndexForm extends EntityForm { // form structure). $tracker_id = $form_state->getValue('tracker', NULL); if ($this->originalEntity->getTrackerId() == $tracker_id) { - $tracker = $this->originalEntity->getTracker(); + $tracker = $this->originalEntity->getTrackerInstance(); } else { $tracker = $this->trackerPluginManager->createInstance($tracker_id, array('index' => $this->originalEntity)); @@ -552,7 +554,12 @@ class IndexForm extends EntityForm { $tracker_form_state = new SubFormState($form_state, array('tracker_config')); $tracker->submitConfigurationForm($form['tracker_config'], $tracker_form_state); - $index->set('tracker_config', $tracker->getConfiguration()); + $index->set('tracker_settings', array( + $tracker_id => array( + 'plugin_id' => $tracker_id, + 'settings' => $tracker->getConfiguration(), + ) + )); } /** diff --git a/src/Form/IndexProcessorsForm.php b/src/Form/IndexProcessorsForm.php index d32e5ac..30caed6 100644 --- a/src/Form/IndexProcessorsForm.php +++ b/src/Form/IndexProcessorsForm.php @@ -96,8 +96,8 @@ class IndexProcessorsForm extends EntityForm { $processors_by_stage[$stage] = $this->entity->getProcessorsByStage($stage, FALSE); } - if ($this->entity->getServer()) { - $backend_discouraged_processors = $this->entity->getServer() + if ($this->entity->getServerInstance()) { + $backend_discouraged_processors = $this->entity->getServerInstance() ->getBackend() ->getDiscouragedProcessors(); @@ -112,7 +112,7 @@ class IndexProcessorsForm extends EntityForm { } } - $processor_settings = $this->entity->getProcessorSettings(); + $enabled_processors = $this->entity->getProcessors(); $form['#tree'] = TRUE; $form['#attached']['library'][] = 'search_api/drupal.search_api.index-active-formatters'; @@ -132,7 +132,7 @@ class IndexProcessorsForm extends EntityForm { $form['status'][$processor_id] = array( '#type' => 'checkbox', '#title' => $processor->label(), - '#default_value' => $processor->isLocked() || !empty($processor_settings[$processor_id]), + '#default_value' => $processor->isLocked() || !empty($enabled_processors[$processor_id]), '#description' => $processor->getDescription(), '#attributes' => array( 'class' => array( @@ -171,9 +171,7 @@ class IndexProcessorsForm extends EntityForm { foreach ($processors_by_stage as $stage => $processors) { /** @var \Drupal\search_api\Processor\ProcessorInterface $processor */ foreach ($processors as $processor_id => $processor) { - $weight = isset($processor_settings[$processor_id]['weights'][$stage]) - ? $processor_settings[$processor_id]['weights'][$stage] - : $processor->getDefaultWeight($stage); + $weight = $processor->getDefaultWeight($stage); if ($processor->isHidden()) { $form['processors'][$processor_id]['weights'][$stage] = array( '#type' => 'value', @@ -252,9 +250,13 @@ class IndexProcessorsForm extends EntityForm { $values = $form_state->getValues(); $new_settings = array(); + $old_processors = $this->entity->getProcessors(); + $old_configurations = array(); + foreach ($old_processors as $id => $processor) { + $old_configurations[$id] = $processor->getConfiguration(); + } + // Store processor settings. - // @todo Go through all available processors, enable/disable with method on - // processor plugin to allow reaction. /** @var \Drupal\search_api\Processor\ProcessorInterface $processor */ $processors = $this->entity->getProcessors(FALSE); foreach ($processors as $processor_id => $processor) { @@ -262,27 +264,33 @@ class IndexProcessorsForm extends EntityForm { continue; } $new_settings[$processor_id] = array( - 'processor_id' => $processor_id, - 'weights' => array(), + 'plugin_id' => $processor_id, 'settings' => array(), ); $processor_values = $values['processors'][$processor_id]; - if (!empty($processor_values['weights'])) { - $new_settings[$processor_id]['weights'] = $processor_values['weights']; - } if (isset($form['settings'][$processor_id])) { $processor_form_state = new SubFormState($form_state, array('processors', $processor_id, 'settings')); $processor->submitConfigurationForm($form['settings'][$processor_id], $processor_form_state); $new_settings[$processor_id]['settings'] = $processor->getConfiguration(); } + if (!empty($processor_values['weights'])) { + $new_settings[$processor_id]['settings']['weights'] = $processor_values['weights']; + } + } + + $new_configurations = array(); + foreach ($new_settings as $plugin_id => $new_processor_settings) { + /** @var \Drupal\search_api\Processor\ProcessorInterface $new_processor */ + $new_processor = $this->processorPluginManager->createInstance($plugin_id, $new_processor_settings['settings']); + if (isset($old_processors[$plugin_id])) { + $this->entity->removeProcessor($plugin_id); + } + $this->entity->addProcessor($new_processor); + $new_configurations[$plugin_id] = $new_processor->getConfiguration(); } - // Sort the processors so we won't have unnecessary changes. - ksort($new_settings); - $settings_changed = $new_settings != $this->entity->getProcessorSettings(); - $form_state->set('processors_changed', $settings_changed); - if ($settings_changed) { - $this->entity->setProcessorSettings($new_settings); + if ($old_configurations != $new_configurations) { + $form_state->set('processors_changed', TRUE); } } diff --git a/src/Form/IndexStatusForm.php b/src/Form/IndexStatusForm.php index 640e795..ad42155 100644 --- a/src/Form/IndexStatusForm.php +++ b/src/Form/IndexStatusForm.php @@ -65,7 +65,7 @@ class IndexStatusForm extends FormBase { 'class' => array('container-inline'), ), ); - $has_remaining_items = ($index->getTracker()->getRemainingItemsCount() > 0); + $has_remaining_items = ($index->getTrackerInstance()->getRemainingItemsCount() > 0); $all_value = $this->t('all', array(), array('context' => 'items to index')); $limit = array( '#type' => 'textfield', diff --git a/src/IndexBatchHelper.php b/src/IndexBatchHelper.php index 56c4d3b..144817d 100644 --- a/src/IndexBatchHelper.php +++ b/src/IndexBatchHelper.php @@ -137,7 +137,7 @@ class IndexBatchHelper { // Get the remaining item count. When no valid tracker is available then // the value will be set to zero which will cause the batch process to // stop. - $remaining_item_count = ($index->hasValidTracker() ? $index->getTracker()->getRemainingItemsCount() : 0); + $remaining_item_count = ($index->hasValidTracker() ? $index->getTrackerInstance()->getRemainingItemsCount() : 0); // Check if an explicit limit needs to be used. if ($context['sandbox']['limit'] > -1) { diff --git a/src/IndexInterface.php b/src/IndexInterface.php index a435f35..85570ae 100644 --- a/src/IndexInterface.php +++ b/src/IndexInterface.php @@ -9,6 +9,7 @@ namespace Drupal\search_api; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\search_api\Item\FieldInterface; +use Drupal\search_api\Processor\ProcessorInterface; use Drupal\search_api\Query\QueryInterface; use Drupal\search_api\Query\ResultSetInterface; @@ -200,7 +201,7 @@ interface IndexInterface extends ConfigEntityInterface { * @throws \Drupal\search_api\SearchApiException * Thrown if the tracker couldn't be instantiated. */ - public function getTracker(); + public function getTrackerInstance(); /** * Determines whether this index is lying on a valid server. @@ -236,7 +237,7 @@ interface IndexInterface extends ConfigEntityInterface { * @throws \Drupal\search_api\SearchApiException * Thrown if the server couldn't be loaded. */ - public function getServer(); + public function getServerInstance(); /** * Sets the server the index is attached to @@ -277,22 +278,24 @@ interface IndexInterface extends ConfigEntityInterface { public function getProcessorsByStage($stage, $only_enabled = TRUE); /** - * Retrieves this index's processor settings. + * Adds a processor to this index. * - * @return array - * An array of processors and their settings. + * @param \Drupal\search_api\Processor\ProcessorInterface $processor + * The processor to be added. + * + * @return $this */ - public function getProcessorSettings(); + public function addProcessor(ProcessorInterface $processor); /** - * Sets this index's processor settings. + * Removes a processor from this index. * - * @param array $processors - * An array of processors and their settings. + * @param string $processor_id + * The ID of the processor to remove. * * @return $this */ - public function setProcessorSettings(array $processors); + public function removeProcessor($processor_id); /** * Preprocesses data items for indexing. @@ -420,24 +423,6 @@ interface IndexInterface extends ConfigEntityInterface { public function getFulltextFields(); /** - * Retrieves this index's field settings. - * - * @return array - * An array of field settings. - */ - public function getFieldSettings(); - - /** - * Sets this index's field settings. - * - * @param array $fields - * An array of field settings. - * - * @return $this - */ - public function setFieldSettings(array $fields); - - /** * Retrieves the properties of one of this index's datasources. * * @param string|null $datasource_id @@ -591,15 +576,6 @@ interface IndexInterface extends ConfigEntityInterface { public function isReindexing(); /** - * Resets the static and stored caches associated with this index. - * - * @param bool $include_stored - * (optional) If set to FALSE, only the static caches will be cleared, the - * stored cache will remain untouched. - */ - public function resetCaches($include_stored = TRUE); - - /** * Creates a query object for this index. * * @param array $options diff --git a/src/Item/Field.php b/src/Item/Field.php index 8580c59..2d14eb4 100644 --- a/src/Item/Field.php +++ b/src/Item/Field.php @@ -167,7 +167,7 @@ class Field implements \IteratorAggregate, FieldInterface { * {@inheritdoc} */ public function setIndex(IndexInterface $index) { - if ($this->index->id() != $index->id()) { + if ($this->index instanceof IndexInterface && $this->index->id() != $index->id()) { throw new \InvalidArgumentException('Attempted to change the index of a field object.'); } $this->index = $index; diff --git a/src/Plugin/search_api/datasource/ContentEntity.php b/src/Plugin/search_api/datasource/ContentEntity.php index 570085c..8116722 100644 --- a/src/Plugin/search_api/datasource/ContentEntity.php +++ b/src/Plugin/search_api/datasource/ContentEntity.php @@ -940,7 +940,7 @@ class ContentEntity extends DatasourcePluginBase { $entity_bundle = $entity->bundle(); $index_names = \Drupal::entityQuery('search_api_index') - ->condition('datasources.*', $datasource_id) + ->condition('datasource_settings.*.plugin_id', $datasource_id) ->execute(); if (!$index_names) { diff --git a/src/Plugin/views/argument/SearchApiMoreLikeThis.php b/src/Plugin/views/argument/SearchApiMoreLikeThis.php index f39c8b0..bfe03e3 100644 --- a/src/Plugin/views/argument/SearchApiMoreLikeThis.php +++ b/src/Plugin/views/argument/SearchApiMoreLikeThis.php @@ -69,7 +69,7 @@ class SearchApiMoreLikeThis extends SearchApiArgument { */ public function query($group_by = FALSE) { try { - $server = $this->query->getIndex()->getServer(); + $server = $this->query->getIndex()->getServerInstance(); if (!$server->supportsFeature('search_api_mlt')) { $backend_id = $server->getBackendId(); \Drupal::logger('search_api')->error('The search backend "@backend_id" does not offer "More like this" functionality.', diff --git a/src/Query/Query.php b/src/Query/Query.php index eb22371..53bbe60 100644 --- a/src/Query/Query.php +++ b/src/Query/Query.php @@ -318,7 +318,7 @@ class Query implements QueryInterface { $this->preExecute(); // Execute query. - $response = $this->index->getServer()->search($this); + $response = $this->index->getServerInstance()->search($this); // Postprocess the search results. $this->postExecute($response); diff --git a/src/Task/IndexTaskManager.php b/src/Task/IndexTaskManager.php index db1b5b8..4cfafcb 100644 --- a/src/Task/IndexTaskManager.php +++ b/src/Task/IndexTaskManager.php @@ -99,7 +99,7 @@ class IndexTaskManager implements IndexTaskManagerInterface { $item_ids[] = Utility::createCombinedId($datasource_id, $raw_id); } $added = count($item_ids); - $index->getTracker()->trackItemsInserted($item_ids); + $index->getTrackerInstance()->trackItemsInserted($item_ids); } } } @@ -195,7 +195,7 @@ class IndexTaskManager implements IndexTaskManagerInterface { if (!isset($datasource_ids)) { $this->state->delete($this->getIndexStateKey($index)); if ($valid_tracker) { - $index->getTracker()->trackAllItemsDeleted(); + $index->getTrackerInstance()->trackAllItemsDeleted(); } return; } @@ -211,7 +211,7 @@ class IndexTaskManager implements IndexTaskManagerInterface { foreach ($datasource_ids as $datasource_id) { unset($index_state['pages'][$datasource_id]); if ($valid_tracker) { - $index->getTracker()->trackAllItemsDeleted($datasource_id); + $index->getTrackerInstance()->trackAllItemsDeleted($datasource_id); } } diff --git a/src/Tests/IntegrationTest.php b/src/Tests/IntegrationTest.php index a14f24d..9ea4230 100644 --- a/src/Tests/IntegrationTest.php +++ b/src/Tests/IntegrationTest.php @@ -98,6 +98,53 @@ class IntegrationTest extends WebTestBase { } /** + * Tests what happens when an index has an integer as id/label. + * + * This needs to be in a separate index because we also want to see what + * happens with the content and we don't want to mess with the content entity + * tracking of the other index. + */ + public function testIntegerIndex() { + $this->drupalLogin($this->adminUser); + $this->getTestServer(); + + $this->drupalCreateNode(array('type' => 'article')); + $this->drupalCreateNode(array('type' => 'article')); + + $this->drupalGet('admin/config/search/search-api/add-index'); + + $this->indexId = 123; + $edit = array( + 'name' => $this->indexId, + 'id' => $this->indexId, + 'status' => 1, + 'description' => 'test Index:: 123~', + 'server' => 'webtest_server', + 'datasources[]' => array('entity:node'), + ); + $this->drupalPostForm(NULL, $edit, $this->t('Save')); + $this->assertText($this->t('The index was successfully saved.')); + $this->assertText($this->t('Successfully tracked @count items for this index.', array('@count' => 2))); + $this->assertEqual(2, $this->countTrackedItems()); + + $this->enableAllProcessors(); + $this->checkFieldLabels(); + + $this->addFieldsToIndex(); + $this->removeFieldsFromIndex(); + + $this->configureFilter(); + $this->configureFilterPage(); + $this->checkProcessorChanges(); + $this->changeProcessorFieldBoost(); + + $this->setReadOnly(); + $this->disableEnableIndex(); + $this->changeIndexDatasource(); + $this->changeIndexServer(); + } + + /** * Tests creating a search server via the UI. */ protected function createServer($server_id = '_test_server') { @@ -382,7 +429,7 @@ class IntegrationTest extends WebTestBase { * The number of tracked items in the test index. */ protected function countTrackedItems() { - return $this->getIndex()->getTracker()->getTotalItemsCount(); + return $this->getIndex()->getTrackerInstance()->getTotalItemsCount(); } /** @@ -392,7 +439,7 @@ class IntegrationTest extends WebTestBase { * The number of unindexed items in the test index. */ protected function countRemainingItems() { - return $this->getIndex()->getTracker()->getRemainingItemsCount(); + return $this->getIndex()->getTrackerInstance()->getRemainingItemsCount(); } /** @@ -454,10 +501,6 @@ class IntegrationTest extends WebTestBase { $this->drupalPostForm(NULL, $edit, $this->t('Save and continue')); $this->drupalPostForm(NULL, array(), $this->t('Save field settings')); - // @todo This should not be necessary, the field cache should be invalidated - // automatically when available fields change. See #2637032. - $this->getIndex()->resetCaches(); - $url_options['query']['datasource'] = 'entity:node'; $this->drupalGet($this->getIndexPath('fields/add'), $url_options); $this->assertHtmlEscaped($field_name); @@ -723,7 +766,7 @@ class IntegrationTest extends WebTestBase { $this->drupalPostForm($index_path, array(), $this->t('Index now')); - $remaining_after = $index->getTracker()->getRemainingItemsCount(); + $remaining_after = $index->getTrackerInstance()->getRemainingItemsCount(); $this->assertEqual(0, $remaining_after, 'Items were indexed after removing the "read only" flag.'); } diff --git a/src/Tests/LanguageIntegrationTest.php b/src/Tests/LanguageIntegrationTest.php index 92c88df..5a4a428 100644 --- a/src/Tests/LanguageIntegrationTest.php +++ b/src/Tests/LanguageIntegrationTest.php @@ -120,6 +120,6 @@ class LanguageIntegrationTest extends WebTestBase { protected function countTrackedItems() { /** @var \Drupal\search_api\IndexInterface $index */ $index = Index::load($this->indexId); - return $index->getTracker()->getTotalItemsCount(); + return $index->getTrackerInstance()->getTotalItemsCount(); } } diff --git a/src/Tests/Processor/ContentAccessTest.php b/src/Tests/Processor/ContentAccessTest.php index b301cd4..b0320b9 100644 --- a/src/Tests/Processor/ContentAccessTest.php +++ b/src/Tests/Processor/ContentAccessTest.php @@ -109,7 +109,23 @@ class ContentAccessTest extends ProcessorTestBase { $this->nodes[2]->save(); // Also index users, to verify that they are unaffected by the processor. - $this->index->set('datasources', array('entity:comment', 'entity:node', 'entity:user')); + $this->index->set( + 'datasource_settings', + array( + 'entity:comment' => array( + 'plugin_id' => 'entity:comment', + 'settings' => array(), + ), + 'entity:node' => array( + 'plugin_id' => 'entity:node', + 'settings' => array(), + ), + 'entity:user' => array( + 'plugin_id' => 'entity:user', + 'settings' => array(), + ), + ) + ); $this->index->save(); \Drupal::getContainer()->get('search_api.index_task_manager')->addItemsAll($this->index); @@ -125,6 +141,8 @@ class ContentAccessTest extends ProcessorTestBase { user_role_grant_permissions('anonymous', array('access content', 'access comments')); $this->index->reindex(); $this->index->indexItems(); + $this->assertEqual(5, $this->index->getTrackerInstance()->getIndexedItemsCount(), '5 items indexed, as expected.'); + $query = Utility::createQuery($this->index); $result = $query->execute(); @@ -138,6 +156,8 @@ class ContentAccessTest extends ProcessorTestBase { user_role_grant_permissions('anonymous', array('access comments')); $this->index->reindex(); $this->index->indexItems(); + $this->assertEqual(5, $this->index->getTrackerInstance()->getIndexedItemsCount(), '5 items indexed, as expected.'); + $query = Utility::createQuery($this->index); $result = $query->execute(); @@ -154,6 +174,7 @@ class ContentAccessTest extends ProcessorTestBase { $this->nodes[3] = Node::create(array('status' => NODE_NOT_PUBLISHED, 'type' => 'page', 'title' => 'foo', 'uid' => 2)); $this->nodes[3]->save(); $this->index->indexItems(); + $this->assertEqual(7, $this->index->getTrackerInstance()->getIndexedItemsCount(), '7 items indexed, as expected.'); $query = Utility::createQuery($this->index); $query->setOption('search_api_access_account', $authenticated_user); diff --git a/src/Tests/Processor/ProcessorIntegrationTest.php b/src/Tests/Processor/ProcessorIntegrationTest.php index ad617c8..b2ab842 100644 --- a/src/Tests/Processor/ProcessorIntegrationTest.php +++ b/src/Tests/Processor/ProcessorIntegrationTest.php @@ -32,7 +32,12 @@ class ProcessorIntegrationTest extends WebTestBase { 'name' => 'Test index', 'id' => $this->indexId, 'status' => 1, - 'datasources' => array('entity:node'), + 'datasource_settings' => array( + 'entity:node' => array( + 'plugin_id' => 'entity:user', + 'settings' => array(), + ), + ), ))->save(); } @@ -43,18 +48,91 @@ class ProcessorIntegrationTest extends WebTestBase { * avoid the overhead of having one test per processor. */ public function testProcessorIntegration() { + // By default, the add_url and language processors are already enabled. + $enabled = array('language', 'add_url'); + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkContentAccessIntegration(); + $enabled[] = 'content_access'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkHighlightIntegration(); + $enabled[] = 'highlight'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkHtmlFilterIntegration(); + $enabled[] = 'html_filter'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkIgnoreCaseIntegration(); + $enabled[] = 'ignorecase'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkIgnoreCharactersIntegration(); - $this->checkLanguageIntegration(); + $enabled[] = 'ignore_character'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkNodeStatusIntegration(); + $enabled[] = 'node_status'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkRenderedItemIntegration(); + $enabled[] = 'rendered_item'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkStopWordsIntegration(); + $enabled[] = 'stopwords'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkTokenizerIntegration(); + $enabled[] = 'tokenizer'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkTransliterationIntegration(); + $enabled[] = 'transliteration'; + sort($enabled); + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + + // The 'language' and 'add_url' processors are are not available to be removed + $actual_processors = array_keys($this->loadIndex()->getProcessors()); + sort($actual_processors); + $this->assertEqual($enabled, $actual_processors); + $this->checkLanguageIntegration(); + $this->assertEqual($enabled, $actual_processors); $this->checkUrlFieldIntegration(); + $this->assertEqual($enabled, $actual_processors); } /** @@ -168,10 +246,11 @@ class ProcessorIntegrationTest extends WebTestBase { */ public function checkLanguageIntegration() { $index = $this->loadIndex(); - $processors = $index->getProcessorSettings(); + $processors = $index->getProcessors(); $this->assertTrue(!empty($processors['language']), 'The "language" processor is enabled by default.'); - unset($processors['language']); - $index->setProcessorSettings($processors)->save(); + $index->removeProcessor('language'); + $index->save(); + $processors = $this->loadIndex()->getProcessors(); $this->assertTrue(!empty($processors['language']), 'The "language" processor cannot be disabled.'); } @@ -240,10 +319,11 @@ class ProcessorIntegrationTest extends WebTestBase { */ public function checkUrlFieldIntegration() { $index = $this->loadIndex(); - $processors = $index->getProcessorSettings(); + $processors = $index->getProcessors(); $this->assertTrue(!empty($processors['add_url']), 'The "Add URL" processor is enabled by default.'); - unset($processors['add_url']); - $index->setProcessorSettings($processors)->save(); + $index->removeProcessor('add_url'); + $index->save(); + $processors = $this->loadIndex()->getProcessors(); $this->assertTrue(!empty($processors['add_url']), 'The "Add URL" processor cannot be disabled.'); } diff --git a/src/Tests/Processor/ProcessorTestBase.php b/src/Tests/Processor/ProcessorTestBase.php index 2809c31..17d4932 100644 --- a/src/Tests/Processor/ProcessorTestBase.php +++ b/src/Tests/Processor/ProcessorTestBase.php @@ -9,6 +9,7 @@ namespace Drupal\search_api\Tests\Processor; use Drupal\search_api\Entity\Index; use Drupal\search_api\Entity\Server; +use Drupal\search_api\Item\Field; use Drupal\search_api\Utility; use Drupal\system\Tests\Entity\EntityUnitTestBase; @@ -87,37 +88,41 @@ abstract class ProcessorTestBase extends EntityUnitTestBase { 'id' => 'index', 'name' => 'Index name', 'status' => TRUE, - 'datasources' => array('entity:comment', 'entity:node'), + 'datasource_settings' => array( + 'entity:comment' => array( + 'plugin_id' => 'entity:comment', + 'settings' => array(), + ), + 'entity:node' => array( + 'plugin_id' => 'entity:node', + 'settings' => array(), + ), + ), 'server' => 'server', 'tracker' => 'default', )); $this->index->setServer($this->server); - $this->index->setFieldSettings(array( - 'subject' => array( - 'label' => 'Subject', - 'type' => 'text', - 'datasource_id' => 'entity:comment', - 'property_path' => 'subject', - ), - 'title' => array( - 'label' => 'Title', - 'type' => 'text', - 'datasource_id' => 'entity:node', - 'property_path' => 'title', - ), - )); - if ($processor) { - $this->index->setProcessorSettings(array( - $processor => array( - 'processor_id' => $processor, - 'weights' => array(), - 'settings' => array(), - ), - )); + $field_subject = new Field($this->index, 'subject'); + $field_subject->setType('text'); + $field_subject->setPropertyPath('subject'); + $field_subject->setDatasourceId('entity:comment'); + $field_subject->setLabel('Subject'); + + $field_title = new Field($this->index, 'title'); + $field_title->setType('text'); + $field_title->setPropertyPath('title'); + $field_title->setDatasourceId('entity:node'); + $field_title->setLabel('Title'); + + $this->index->addField($field_subject); + $this->index->addField($field_title); + + if ($processor) { /** @var \Drupal\search_api\Processor\ProcessorPluginManager $plugin_manager */ $plugin_manager = \Drupal::service('plugin.manager.search_api.processor'); $this->processor = $plugin_manager->createInstance($processor, array('index' => $this->index)); + $this->index->addProcessor($this->processor); } $this->index->save(); } diff --git a/src/Tests/Processor/RenderedItemTest.php b/src/Tests/Processor/RenderedItemTest.php index 8a920e4..4b561fc 100644 --- a/src/Tests/Processor/RenderedItemTest.php +++ b/src/Tests/Processor/RenderedItemTest.php @@ -115,6 +115,35 @@ class RenderedItemTest extends ProcessorTestBase { } /** + * Tests that the processor is added correctly. + */ + public function testAddProcessor() { + $processors = $this->index->getProcessors(); + $this->assertTrue( + array_key_exists('rendered_item', $processors), + 'Processor successfully added.' + ); + + $items = array(); + foreach ($this->nodes as $node) { + $items[] = array( + 'datasource' => 'entity:node', + 'item' => $node->getTypedData(), + 'item_id' => $node->id(), + 'text' => 'node text' . $node->id(), + ); + } + $items = $this->generateItems($items); + + foreach ($items as $item) { + $this->assertTrue( + array_key_exists('rendered_item', $item->getFields()), + 'Field successfully added.' + ); + } + } + + /** * Tests whether the rendered_item field is correctly filled by the processor. */ public function testPreprocessIndexItems() { diff --git a/src/Tests/WebTestBase.php b/src/Tests/WebTestBase.php index 8b85ea6..4dd9113 100644 --- a/src/Tests/WebTestBase.php +++ b/src/Tests/WebTestBase.php @@ -169,7 +169,12 @@ abstract class WebTestBase extends SimpletestWebTestBase { 'name' => $name, 'description' => $name . ' description', 'server' => $server_id, - 'datasources' => array($datasource_id), + 'datasource_settings' => array( + $datasource_id => array( + 'plugin_id' => $datasource_id, + 'settings' => array() + ) + ), )); $index->save(); $this->indexId = $index->id(); diff --git a/src/UnsavedIndexConfiguration.php b/src/UnsavedIndexConfiguration.php index 8fe07be..1f1045e 100644 --- a/src/UnsavedIndexConfiguration.php +++ b/src/UnsavedIndexConfiguration.php @@ -249,8 +249,8 @@ class UnsavedIndexConfiguration implements IndexInterface, UnsavedConfigurationI /** * {@inheritdoc} */ - public function getTracker() { - return $this->entity->getTracker(); + public function getTrackerInstance() { + return $this->entity->getTrackerInstance(); } /** @@ -277,8 +277,8 @@ class UnsavedIndexConfiguration implements IndexInterface, UnsavedConfigurationI /** * {@inheritdoc} */ - public function getServer() { - return $this->entity->getServer(); + public function getServerInstance() { + return $this->entity->getServerInstance(); } /** @@ -431,13 +431,6 @@ class UnsavedIndexConfiguration implements IndexInterface, UnsavedConfigurationI /** * {@inheritdoc} */ - public function resetCaches($include_stored = TRUE) { - return $this->entity->resetCaches($include_stored); - } - - /** - * {@inheritdoc} - */ public function query(array $options = array()) { return $this->entity->query($options); } diff --git a/src/Utility.php b/src/Utility.php index aed1a96..3674331 100644 --- a/src/Utility.php +++ b/src/Utility.php @@ -154,7 +154,7 @@ class Utility { if (empty(static::$dataTypeFallbackMapping[$index_id])) { $server = NULL; try { - $server = $index->getServer(); + $server = $index->getServerInstance(); } catch (SearchApiException $e) { // If the server isn't available, just ignore it here and return all diff --git a/tests/search_api_test_db/config/install/search_api.index.database_search_index.yml b/tests/search_api_test_db/config/install/search_api.index.database_search_index.yml index 4f42d29..e6c886a 100644 --- a/tests/search_api_test_db/config/install/search_api.index.database_search_index.yml +++ b/tests/search_api_test_db/config/install/search_api.index.database_search_index.yml @@ -2,7 +2,7 @@ id: database_search_index name: 'Test index' description: 'An index used for testing' read_only: false -fields: +field_settings: id: label: ID type: integer @@ -40,25 +40,28 @@ fields: property_path: search_api_language index_locked: true type_locked: true -processors: +processor_settings: add_url: - processor_id: add_url - weights: - preprocess_index: -30 - settings: { } + plugin_id: add_url + settings: + weights: + preprocess_index: -30 language: - processor_id: language - weights: - preprocess_index: -50 - settings: { } + plugin_id: language + settings: + weights: + preprocess_index: -50 options: cron_limit: -1 index_directly: false -datasources: - - 'entity:entity_test' -datasource_configs: { } -tracker: default -tracker_config: { } +datasource_settings: + 'entity:entity_test': + plugin_id: 'entity:entity_test' + settings: { } +tracker_settings: + 'default': + plugin_id: default + settings: { } server: database_search_server status: true langcode: en diff --git a/tests/src/Kernel/CliTest.php b/tests/src/Kernel/CliTest.php index 70fd5cc..95c3395 100644 --- a/tests/src/Kernel/CliTest.php +++ b/tests/src/Kernel/CliTest.php @@ -94,15 +94,20 @@ class CliTest extends KernelTestBase { 'name' => 'Test index', 'id' => 'index', 'status' => 1, - 'datasources' => array('entity:entity_test'), + 'datasource_settings' => array( + 'entity:entity_test' => array( + 'plugin_id' => 'entity:entity_test', + 'settings' => array(), + ), + ), 'tracker' => 'default', 'server' => $this->server->id(), 'options' => array('index_directly' => TRUE), )); $index->save(); - $total_items = $index->getTracker()->getTotalItemsCount(); - $indexed_items = $index->getTracker()->getIndexedItemsCount(); + $total_items = $index->getTrackerInstance()->getTotalItemsCount(); + $indexed_items = $index->getTrackerInstance()->getIndexedItemsCount(); $this->assertEquals($total_items, 2, 'The 2 items are tracked.'); $this->assertEquals($indexed_items, 0, 'No items are indexed'); @@ -122,8 +127,8 @@ class CliTest extends KernelTestBase { 'category' => 'item_category' ))->save(); - $total_items = $index->getTracker()->getTotalItemsCount(); - $indexed_items = $index->getTracker()->getIndexedItemsCount(); + $total_items = $index->getTrackerInstance()->getTotalItemsCount(); + $indexed_items = $index->getTrackerInstance()->getIndexedItemsCount(); $this->assertEquals($total_items, 4, 'All 4 items are tracked.'); $this->assertEquals($indexed_items, 2, '2 items are indexed'); diff --git a/tests/src/Kernel/CustomDataTypesTest.php b/tests/src/Kernel/CustomDataTypesTest.php index 56b9647..97dca85 100644 --- a/tests/src/Kernel/CustomDataTypesTest.php +++ b/tests/src/Kernel/CustomDataTypesTest.php @@ -116,25 +116,30 @@ class CustomDataTypesTest extends KernelTestBase { $item = $this->index->loadItem('entity:entity_test/1:en'); $item = Utility::createItemFromObject($this->index, $item, 'entity:entity_test/1:en'); - $name_field = $item->getField('name'); + $name_field = $item->getField('name'); $processed_value = $name_field->getValues()[0]; $processed_type = $name_field->getType(); + $label = $name_field->getLabel(); $this->assertEquals($original_value, $processed_value, 'The processed value matches the original value'); $this->assertEquals($original_type, $processed_type, 'The processed type matches the original type.'); + $this->assertEquals('Name', $label, 'The label is correctly set.'); // Reset the fields on the item and change to the supported data type. $item->setFieldsExtracted(FALSE); $item->setFields(array()); - $this->index->getField('name')->setType('search_api_test_data_type'); - $name_field = $item->getField('name'); + $this->index->getField('name') + ->setType('search_api_test_data_type') + ->setLabel("Test"); + $name_field = $item->getField('name'); $processed_value = $name_field->getValues()[0]; $processed_type = $name_field->getType(); $this->assertEquals($original_value, $processed_value, 'The processed value matches the original value'); $this->assertEquals('search_api_test_data_type', $processed_type, 'The processed type matches the new type.'); + $this->assertEquals('Test', $name_field->getLabel(), 'The label is correctly set.'); // Reset the fields on the item and change to the non-supported data type. $item->setFieldsExtracted(FALSE); diff --git a/tests/src/Kernel/DependencyRemovalTest.php b/tests/src/Kernel/DependencyRemovalTest.php index 9245486..08a16e7 100644 --- a/tests/src/Kernel/DependencyRemovalTest.php +++ b/tests/src/Kernel/DependencyRemovalTest.php @@ -37,6 +37,7 @@ class DependencyRemovalTest extends KernelTestBase { */ public static $modules = array( 'user', + 'system', 'search_api', 'search_api_test_backend', 'search_api_test_dependencies', @@ -48,6 +49,8 @@ class DependencyRemovalTest extends KernelTestBase { public function setUp() { parent::setUp(); + $this->installSchema('system', 'key_value_expire'); + // The server tasks manager is needed when removing a server. $mock = $this->getMock('Drupal\search_api\Task\ServerTaskManagerInterface'); $this->container->set('search_api.server_task_manager', $mock); @@ -57,9 +60,17 @@ class DependencyRemovalTest extends KernelTestBase { $this->index = Index::create(array( 'id' => 'test_index', 'name' => 'Test index', - 'tracker' => 'default', - 'datasources' => array( - 'entity:user', + 'tracker_settings' => array( + 'default' => array( + 'plugin_id' => 'default', + 'settings' => array() + ) + ), + 'datasource_settings' => array( + 'entity:user' => array( + 'plugin_id' => 'entity:user', + 'settings' => array(), + ) ), )); @@ -173,16 +184,21 @@ class DependencyRemovalTest extends KernelTestBase { // server. $dependency_key = $this->dependency->getConfigDependencyKey(); $dependency_name = $this->dependency->getConfigDependencyName(); - $this->index->set('datasources', array( - 'entity:user', - 'search_api_test_dependencies', - )); - $this->index->set('datasource_configs', array( - 'search_api_test_dependencies' => array( - $dependency_key => array( - $dependency_name, + $this->index->set( + 'datasource_settings', + array( + 'entity:user' => array( + 'plugin_id' => 'entity:user', + 'settings' => array(), + ), + 'search_api_test_dependencies' => array( + 'plugin_id' => 'search_api_test_dependencies', + 'settings' => array( + $dependency_key => array( + $dependency_name, + ), + ), ), - ), )); $this->index->save(); @@ -210,15 +226,13 @@ class DependencyRemovalTest extends KernelTestBase { // Depending on whether the plugin should have removed the dependency or // not, make sure the right action was taken. - $datasources = $this->index->get('datasources'); - $datasource_configs = $this->index->get('datasource_configs'); + $datasources = $this->index->get('datasource_settings'); if ($remove_dependency) { - $this->assertContains('search_api_test_dependencies', $datasources, 'Datasource not removed'); - $this->assertEmpty($datasource_configs['search_api_test_dependencies'], 'Datasource settings adapted'); + $this->assertArrayHasKey('search_api_test_dependencies', $datasources, 'Datasource not removed'); + $this->assertEmpty($datasources['search_api_test_dependencies']['settings'], 'Datasource settings adapted'); } else { - $this->assertNotContains('search_api_test_dependencies', $datasources, 'Datasource removed'); - $this->assertArrayNotHasKey('search_api_test_dependencies', $datasource_configs, 'Datasource config removed'); + $this->assertArrayNotHasKey('search_api_test_dependencies', $datasources, 'Datasource removed'); } } @@ -231,15 +245,13 @@ class DependencyRemovalTest extends KernelTestBase { // server. $dependency_key = $this->dependency->getConfigDependencyKey(); $dependency_name = $this->dependency->getConfigDependencyName(); - $this->index->set('datasources', array( - 'search_api_test_dependencies', - )); - $this->index->set('datasource_configs', array( + $this->index->set('datasource_settings', array( 'search_api_test_dependencies' => array( - $dependency_key => array( - $dependency_name, + 'plugin_id' => 'search_api_test_dependencies', + 'settings' => array( + $dependency_key => array($dependency_name) ), - ), + ) )); $this->index->save(); @@ -275,9 +287,9 @@ class DependencyRemovalTest extends KernelTestBase { // server. $dependency_key = $this->dependency->getConfigDependencyKey(); $dependency_name = $this->dependency->getConfigDependencyName(); - $this->index->set('processors', array( + $this->index->set('processor_settings', array( 'search_api_test_dependencies' => array( - 'processor_id' => 'search_api_test_dependencies', + 'plugin_id' => 'search_api_test_dependencies', 'settings' => array( $dependency_key => array( $dependency_name, @@ -311,7 +323,7 @@ class DependencyRemovalTest extends KernelTestBase { // Depending on whether the plugin should have removed the dependency or // not, make sure the right action was taken. - $processors = $this->index->get('processors'); + $processors = $this->index->get('processor_settings'); if ($remove_dependency) { $this->assertArrayHasKey('search_api_test_dependencies', $processors, 'Processor not removed'); $this->assertEmpty($processors['search_api_test_dependencies']['settings'], 'Processor settings adapted'); @@ -336,11 +348,15 @@ class DependencyRemovalTest extends KernelTestBase { // server. $dependency_key = $this->dependency->getConfigDependencyKey(); $dependency_name = $this->dependency->getConfigDependencyName(); - $this->index->set('tracker', 'search_api_test_dependencies'); - $this->index->set('tracker_config', array( - $dependency_key => array( - $dependency_name, - ), + $this->index->set('tracker_settings', array( + 'search_api_test_dependencies' => array( + 'plugin_id' => 'search_api_test_dependencies', + 'settings' => array( + $dependency_key => array( + $dependency_name, + ), + ) + ) )); $this->index->save(); @@ -375,8 +391,10 @@ class DependencyRemovalTest extends KernelTestBase { // Depending on whether the plugin should have removed the dependency or // not, make sure the right action was taken. - $tracker = $this->index->get('tracker'); - $tracker_config = $this->index->get('tracker_config'); + $config = $this->index->get('tracker_settings'); + $plugins = array_keys($config); + $tracker = $config[$plugins[0]]['plugin_id']; + $tracker_config = $config[$plugins[0]]['settings']; if ($remove_dependency) { $this->assertEquals('search_api_test_dependencies', $tracker, 'Tracker not reset'); $this->assertEmpty($tracker_config, 'Tracker settings adapted'); @@ -392,13 +410,19 @@ class DependencyRemovalTest extends KernelTestBase { */ public function testModuleDependency() { // Test with all types of plugins at once. - $this->index->set('datasources', array( - 'entity:user', - 'search_api_test_dependencies', + $this->index->set('datasource_settings', array( + 'entity:user' => array( + 'plugin_id' => 'entity:user', + 'settings' => array(), + ), + 'search_api_test_dependencies' => array( + 'plugin_id' => 'search_api_test_dependencies', + 'settings' => array(), + ), )); - $this->index->set('processors', array( + $this->index->set('processor_settings', array( 'search_api_test_dependencies' => array( - 'processor_id' => 'search_api_test_dependencies', + 'plugin_id' => 'search_api_test_dependencies', 'settings' => array(), ), )); @@ -439,6 +463,16 @@ class DependencyRemovalTest extends KernelTestBase { /** * Data provider for this class's test methods. * + * If $remove_dependency is TRUE, in Plugin::onDependencyRemoval() it clears + * its configuration (and thus its dependency, in those test plugins) and + * returns TRUE, which the index will take as "all OK, dependency removed" and + * leave the plugin where it is, only with updated configuration. + * + * If $remove_dependency is FALSE, Plugin::onDependencyRemoval() will do + * nothing and just return FALSE, the index says "oh, that plugin still has + * that removed dependency, so I should better remove the plugin" and the + * plugin gets removed. + * * @return array * An array of argument arrays for this class's test methods. */ diff --git a/tests/src/Kernel/IndexStorageTest.php b/tests/src/Kernel/IndexStorageTest.php index 0e89a46..bab7e78 100644 --- a/tests/src/Kernel/IndexStorageTest.php +++ b/tests/src/Kernel/IndexStorageTest.php @@ -64,7 +64,12 @@ class IndexStorageTest extends KernelTestBase { $indexData = array( 'id' => 'test', 'name' => 'Index test name', - 'tracker' => 'default', + 'tracker' => array( + 'default' => array( + 'plugin_id' => 'default', + 'settings' => array(), + ) + ), ); $index = $this->storage->create($indexData); diff --git a/tests/src/Kernel/LanguageKernelTest.php b/tests/src/Kernel/LanguageKernelTest.php index 671a957..75c8bc6 100644 --- a/tests/src/Kernel/LanguageKernelTest.php +++ b/tests/src/Kernel/LanguageKernelTest.php @@ -108,8 +108,18 @@ class LanguageKernelTest extends KernelTestBase { 'name' => 'Test Index', 'id' => 'test_index', 'status' => 1, - 'datasources' => array('entity:' . $this->testEntityTypeId), - 'tracker' => 'default', + 'datasource_settings' => array( + 'entity:' . $this->testEntityTypeId => array( + 'plugin_id' => 'entity:' . $this->testEntityTypeId, + 'settings' => array(), + ), + ), + 'tracker_settings' => array( + 'default' => array( + 'plugin_id' => 'default', + 'settings' => array(), + ) + ), 'server' => $this->server->id(), 'options' => array('index_directly' => FALSE), )); @@ -153,10 +163,10 @@ class LanguageKernelTest extends KernelTestBase { $this->assertEquals($expected, $datasource_item_ids, 'Datasource returns correct item ids.'); // Test indexing the new entity. - $this->assertEquals(0, $this->index->getTracker()->getIndexedItemsCount(), 'The index is empty.'); - $this->assertEquals(2, $this->index->getTracker()->getTotalItemsCount(), 'There are two items to be indexed.'); + $this->assertEquals(0, $this->index->getTrackerInstance()->getIndexedItemsCount(), 'The index is empty.'); + $this->assertEquals(2, $this->index->getTrackerInstance()->getTotalItemsCount(), 'There are two items to be indexed.'); $this->index->indexItems(); - $this->assertEquals(2, $this->index->getTracker()->getIndexedItemsCount(), 'Two items have been indexed.'); + $this->assertEquals(2, $this->index->getTrackerInstance()->getIndexedItemsCount(), 'Two items have been indexed.'); // Now, make the first entity language-specific by assigning a language. $default_langcode = $this->langcodes[0]; @@ -175,8 +185,8 @@ class LanguageKernelTest extends KernelTestBase { $this->assertEquals($expected, $datasource_item_ids, 'Datasource returns correct item ids.'); // Test that the index needs to be updated. - $this->assertEquals(1, $this->index->getTracker()->getIndexedItemsCount(), 'The updated item needs to be reindexed.'); - $this->assertEquals(2, $this->index->getTracker()->getTotalItemsCount(), 'There are two items in total.'); + $this->assertEquals(1, $this->index->getTrackerInstance()->getIndexedItemsCount(), 'The updated item needs to be reindexed.'); + $this->assertEquals(2, $this->index->getTrackerInstance()->getTotalItemsCount(), 'There are two items in total.'); // Set two translations for the first entity and test that the datasource // returns three separate item IDs, one for each translation. @@ -197,8 +207,8 @@ class LanguageKernelTest extends KernelTestBase { $this->assertEquals($expected, $datasource_item_ids, 'Datasource returns correct item ids for a translated entity.'); // Test that the index needs to be updated. - $this->assertEquals(1, $this->index->getTracker()->getIndexedItemsCount(), 'The updated items needs to be reindexed.'); - $this->assertEquals(4, $this->index->getTracker()->getTotalItemsCount(), 'There are four items in total.'); + $this->assertEquals(1, $this->index->getTrackerInstance()->getIndexedItemsCount(), 'The updated items needs to be reindexed.'); + $this->assertEquals(4, $this->index->getTrackerInstance()->getTotalItemsCount(), 'There are four items in total.'); // Delete one translation and test that the datasource returns only three // items. @@ -215,10 +225,10 @@ class LanguageKernelTest extends KernelTestBase { $this->assertEquals($expected, $datasource_item_ids, 'Datasource returns correct item ids for a translated entity.'); // Test reindexing. - $this->assertEquals(3, $this->index->getTracker()->getTotalItemsCount(), 'There are three items in total.'); - $this->assertEquals(1, $this->index->getTracker()->getIndexedItemsCount(), 'The updated items needs to be reindexed.'); + $this->assertEquals(3, $this->index->getTrackerInstance()->getTotalItemsCount(), 'There are three items in total.'); + $this->assertEquals(1, $this->index->getTrackerInstance()->getIndexedItemsCount(), 'The updated items needs to be reindexed.'); $this->index->indexItems(); - $this->assertEquals(3, $this->index->getTracker()->getIndexedItemsCount(), 'Three items are indexed.'); + $this->assertEquals(3, $this->index->getTrackerInstance()->getIndexedItemsCount(), 'Three items are indexed.'); } } diff --git a/tests/src/Kernel/ServerTaskTest.php b/tests/src/Kernel/ServerTaskTest.php index a31595d..a3faf29 100644 --- a/tests/src/Kernel/ServerTaskTest.php +++ b/tests/src/Kernel/ServerTaskTest.php @@ -91,8 +91,18 @@ class ServerTaskTest extends KernelTestBase { 'name' => 'Test index', 'id' => 'test_index', 'status' => 1, - 'datasources' => array('entity:user'), - 'tracker' => 'default', + 'datasource_settings' => array( + 'entity:user' => array( + 'plugin_id' => 'entity:user', + 'settings' => array(), + ), + ), + 'tracker' => array( + 'default' => array( + 'plugin_id' => 'default', + 'settings' => array(), + ) + ), 'server' => $this->server->id(), 'options' => array('index_directly' => FALSE), ));