diff --git a/config/schema/search_api.index.schema.yml b/config/schema/search_api.index.schema.yml index 427f03f..bec9eb0 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: @@ -76,23 +76,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.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..07954f8 100644 --- a/search_api.drush.inc +++ b/search_api.drush.inc @@ -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..677cf52 100644 --- a/search_api.theme.inc +++ b/search_api.theme.inc @@ -230,7 +230,7 @@ function theme_search_api_index($variables) { /** @var $index \Drupal\search_api\IndexInterface */ $index = $variables['index']; $server = $index->hasValidServer() ? $index->getServer() : NULL; - $tracker = $index->hasValidTracker() ? $index->getTracker() : 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..4587ca0 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 @@ -202,16 +202,18 @@ processors: 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/tests/src/Kernel/BackendTest.php b/search_api_db/tests/src/Kernel/BackendTest.php index 5c43111..62b4bee 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.'); } /** diff --git a/src/Entity/Index.php b/src/Entity/Index.php index c466fc1..59a9f21 100644 --- a/src/Entity/Index.php +++ b/src/Entity/Index.php @@ -57,13 +57,11 @@ use Drupal\views\Views; * "name", * "description", * "read_only", - * "fields", + * "field_settings", * "processors", * "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. @@ -210,7 +199,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * * @see loadProcessors() */ - protected $processorPlugins; + protected $processorInstances; /** * 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, array_flip(array_keys($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; } /** @@ -486,13 +488,13 @@ class Index extends ConfigEntityBase implements IndexInterface { * The loaded processors, keyed by processor ID. */ protected function loadProcessors() { - if (empty($this->processorPlugins)) { + if (empty($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(); 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 +502,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,7 +511,7 @@ class Index extends ConfigEntityBase implements IndexInterface { } } - return $this->processorPlugins; + return $this->processorInstances; } /** @@ -578,7 +580,7 @@ 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 +590,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,13 +598,13 @@ 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,7 +623,7 @@ 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; @@ -657,7 +659,7 @@ class Index extends ConfigEntityBase implements IndexInterface { public function getFieldsByDatasource($datasource_id) { $datasource_fields = $this->getCache(__FUNCTION__); if (!$datasource_fields) { - $datasource_fields = array_fill_keys($this->datasources, array()); + $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; @@ -689,14 +691,14 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getFieldSettings() { - return $this->fields; + return $this->field_settings; } /** * {@inheritdoc} */ public function setFieldSettings(array $fields = array()) { - $this->fields = $fields; + $this->field_settings = $fields; return $this; } @@ -767,7 +769,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 ($items) { @@ -793,7 +795,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()))); } @@ -838,7 +840,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. @@ -883,7 +885,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); @@ -907,7 +909,7 @@ 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); } @@ -920,7 +922,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)); } } @@ -935,7 +937,7 @@ 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; @@ -1014,10 +1016,10 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function resetCaches($include_stored = TRUE) { - $this->datasourcePlugins = NULL; - $this->trackerPlugin = NULL; + $this->datasourceInstances = NULL; + $this->trackerInstance = NULL; $this->serverInstance = NULL; - $this->processorPlugins = NULL; + $this->processorInstances = NULL; $this->cache = array(); if ($include_stored) { Cache::invalidateTags($this->getCacheTags()); @@ -1069,10 +1071,10 @@ 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 @@ -1215,7 +1217,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * The previous version of the index. */ protected function reactToTrackerSwitch(IndexInterface $original) { - 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); @@ -1291,7 +1293,7 @@ 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); @@ -1522,17 +1524,29 @@ class Index extends ConfigEntityBase implements IndexInterface { // 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']); + $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(), + ) + ); } // 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; } @@ -1544,10 +1558,10 @@ class Index extends ConfigEntityBase implements IndexInterface { $this->processors[$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; } } @@ -1571,7 +1585,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(); @@ -1596,10 +1610,10 @@ class Index extends ConfigEntityBase implements IndexInterface { */ 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/IndexForm.php b/src/Form/IndexForm.php index 2bfca64..93d8358 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( @@ -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/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..deac9e8 100644 --- a/src/IndexInterface.php +++ b/src/IndexInterface.php @@ -200,7 +200,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. diff --git a/src/Plugin/search_api/datasource/ContentEntity.php b/src/Plugin/search_api/datasource/ContentEntity.php index 8bb2378..03d98d2 100644 --- a/src/Plugin/search_api/datasource/ContentEntity.php +++ b/src/Plugin/search_api/datasource/ContentEntity.php @@ -936,7 +936,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/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..0ef3d1b 100644 --- a/src/Tests/IntegrationTest.php +++ b/src/Tests/IntegrationTest.php @@ -97,6 +97,54 @@ class IntegrationTest extends WebTestBase { $this->deleteServer(); } + + /** + * Test what happens when an index has an integer as id/label. + * + * This needs to be in a seperate 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. */ @@ -382,7 +430,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 +440,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(); } /** @@ -723,7 +771,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 5dfec22..0dc654e 100644 --- a/src/Tests/LanguageIntegrationTest.php +++ b/src/Tests/LanguageIntegrationTest.php @@ -128,7 +128,7 @@ 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..24ea7d4 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(); } diff --git a/src/Tests/Processor/ProcessorTestBase.php b/src/Tests/Processor/ProcessorTestBase.php index 2809c31..a9ccdeb 100644 --- a/src/Tests/Processor/ProcessorTestBase.php +++ b/src/Tests/Processor/ProcessorTestBase.php @@ -87,7 +87,16 @@ 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', )); 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..ebbd30d 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(); } /** 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..04cea6b 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 @@ -54,11 +54,14 @@ processors: 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/DependencyRemovalTest.php b/tests/src/Kernel/DependencyRemovalTest.php index 9245486..717ea0d 100644 --- a/tests/src/Kernel/DependencyRemovalTest.php +++ b/tests/src/Kernel/DependencyRemovalTest.php @@ -57,9 +57,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(), + ) ), )); @@ -79,13 +87,13 @@ class DependencyRemovalTest extends KernelTestBase { * If the dependency does not get removed, proper cascading to the index is * also verified. * - * @param bool $remove_dependency + * @param bool $dependency_removal_return_value * Whether to remove the dependency from the backend when the object * depended on is deleted. * * @dataProvider dependencyTestDataProvider */ - public function testBackendDependency($remove_dependency) { + public function testBackendDependency($dependency_removal_return_value) { $dependency_key = $this->dependency->getConfigDependencyKey(); $dependency_name = $this->dependency->getConfigDependencyName(); @@ -125,7 +133,7 @@ class DependencyRemovalTest extends KernelTestBase { // dependency should be removed or not. See // \Drupal\search_api_test_backend\Plugin\search_api\backend\TestBackend::onDependencyRemoval(). $key = 'search_api_test_backend.dependencies.remove'; - \Drupal::state()->set($key, $remove_dependency); + \Drupal::state()->set($key, $dependency_removal_return_value); // Delete the backend's dependency. $this->dependency->delete(); @@ -139,7 +147,7 @@ class DependencyRemovalTest extends KernelTestBase { $storage->resetCache(); $server = $storage->load($server->id()); - if ($remove_dependency) { + if ($dependency_removal_return_value) { $this->assertInstanceOf('Drupal\search_api\ServerInterface', $server, 'Server was not removed'); $this->assertArrayNotHasKey('dependencies', $server->get('backend_config'), 'Backend config was adapted'); // @todo Logically, this should not be changed: if the server does not get @@ -161,28 +169,33 @@ class DependencyRemovalTest extends KernelTestBase { /** * Tests a datasource with a dependency that gets removed. * - * @param bool $remove_dependency + * @param bool $dependency_removal_return_value * Whether to remove the dependency from the datasource when the object * depended on is deleted. * * @dataProvider dependencyTestDataProvider */ - public function testDatasourceDependency($remove_dependency) { + public function testDatasourceDependency($dependency_removal_return_value) { // Add the datasource to the index and save it. The datasource configuration // contains the dependencies it will return – in our case, we use the test // 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(); @@ -194,7 +207,7 @@ class DependencyRemovalTest extends KernelTestBase { // dependency should be removed or not. See // \Drupal\search_api_test_dependencies\Plugin\search_api\datasource\TestDatasource::onDependencyRemoval(). $key = 'search_api_test_dependencies.datasource.remove'; - \Drupal::state()->set($key, $remove_dependency); + \Drupal::state()->set($key, $dependency_removal_return_value); // Delete the datasource's dependency. $this->dependency->delete(); @@ -210,15 +223,14 @@ 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'); - if ($remove_dependency) { - $this->assertContains('search_api_test_dependencies', $datasources, 'Datasource not removed'); - $this->assertEmpty($datasource_configs['search_api_test_dependencies'], 'Datasource settings adapted'); + $datasources = $this->index->get('datasource_settings'); + if ($dependency_removal_return_value) { + $this->assertContains('search_api_test_dependencies', array_keys($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->assertNotContains('search_api_test_dependencies', array_keys($datasources), 'Datasource removed'); + $this->assertArrayNotHasKey('search_api_test_dependencies', $datasources, 'Datasource config removed'); } } @@ -231,15 +243,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(); @@ -263,13 +273,13 @@ class DependencyRemovalTest extends KernelTestBase { /** * Tests a processor with a dependency that gets removed. * - * @param bool $remove_dependency + * @param bool $dependency_removal_return_value * Whether to remove the dependency from the processor when the object * depended on is deleted. * * @dataProvider dependencyTestDataProvider */ - public function testProcessorDependency($remove_dependency) { + public function testProcessorDependency($dependency_removal_return_value) { // Add the processor to the index and save it. The processor configuration // contains the dependencies it will return – in our case, we use the test // server. @@ -295,7 +305,7 @@ class DependencyRemovalTest extends KernelTestBase { // dependency should be removed or not. See // \Drupal\search_api_test_dependencies\Plugin\search_api\processor\TestProcessor::onDependencyRemoval(). $key = 'search_api_test_dependencies.processor.remove'; - \Drupal::state()->set($key, $remove_dependency); + \Drupal::state()->set($key, $dependency_removal_return_value); // Delete the processor's dependency. $this->dependency->delete(); @@ -312,7 +322,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'); - if ($remove_dependency) { + if ($dependency_removal_return_value) { $this->assertArrayHasKey('search_api_test_dependencies', $processors, 'Processor not removed'); $this->assertEmpty($processors['search_api_test_dependencies']['settings'], 'Processor settings adapted'); } @@ -324,23 +334,27 @@ class DependencyRemovalTest extends KernelTestBase { /** * Tests a tracker with a dependency that gets removed. * - * @param bool $remove_dependency + * @param bool $dependency_removal_return_value * Whether to remove the dependency from the tracker when the object * depended on is deleted. * * @dataProvider dependencyTestDataProvider */ - public function testTrackerDependency($remove_dependency) { + public function testTrackerDependency($dependency_removal_return_value) { // Set the tracker for the index and save it. The tracker configuration // contains the dependencies it will return – in our case, we use the test // 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(); @@ -352,10 +366,10 @@ class DependencyRemovalTest extends KernelTestBase { // dependency should be removed or not. See // \Drupal\search_api_test_dependencies\Plugin\search_api\tracker\TestTracker::onDependencyRemoval(). $key = 'search_api_test_dependencies.tracker.remove'; - \Drupal::state()->set($key, $remove_dependency); + \Drupal::state()->set($key, $dependency_removal_return_value); // If the index resets the tracker, it needs to know the ID of the default // tracker. - if (!$remove_dependency) { + if (!$dependency_removal_return_value) { \Drupal::configFactory()->getEditable('search_api.settings') ->set('default_tracker', 'default') ->save(); @@ -375,9 +389,11 @@ 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'); - if ($remove_dependency) { + $config = $this->index->get('tracker_settings'); + $plugins = array_keys($config); + $tracker = $config[$plugins[0]]['plugin_id']; + $tracker_config = $config[$plugins[0]]['settings']; + if ($dependency_removal_return_value) { $this->assertEquals('search_api_test_dependencies', $tracker, 'Tracker not reset'); $this->assertEmpty($tracker_config, 'Tracker settings adapted'); } @@ -392,9 +408,15 @@ 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( 'search_api_test_dependencies' => array( @@ -439,13 +461,24 @@ class DependencyRemovalTest extends KernelTestBase { /** * Data provider for this class's test methods. * + * If $dependency_removal_return_value 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 $dependency_removal_return_value is FALSE, Plugin::onDependencyRemoval() + * will do nothing and just return FALSE, the index says "oh, that plugin + * still has that removed depenency, 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. */ public function dependencyTestDataProvider() { return array( - 'Remove dependency' => array(TRUE), - 'Keep dependency' => array(FALSE), + 'Keep dependency' => array(TRUE), + 'Remove dependency' => array(FALSE), ); } 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..e83a87f 100644 --- a/tests/src/Kernel/ServerTaskTest.php +++ b/tests/src/Kernel/ServerTaskTest.php @@ -91,7 +91,12 @@ class ServerTaskTest extends KernelTestBase { 'name' => 'Test index', 'id' => 'test_index', 'status' => 1, - 'datasources' => array('entity:user'), + 'datasource_settings' => array( + 'entity:user' => array( + 'plugin_id' => 'entity:user', + 'settings' => array(), + ), + ), 'tracker' => 'default', 'server' => $this->server->id(), 'options' => array('index_directly' => FALSE),