diff --git a/config/schema/search_api.datasource.schema.yml b/config/schema/search_api.datasource.schema.yml index e98979d..fc0f4a2 100644 --- a/config/schema/search_api.datasource.schema.yml +++ b/config/schema/search_api.datasource.schema.yml @@ -3,7 +3,7 @@ label: 'Entity datasource configuration' mapping: default: - type: string + type: integer label: 'Decides if we want to include or exclude the selected bundles.' bundles: type: sequence 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 7539dff..3cc2de8 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 @@ -206,7 +206,7 @@ datasource_settings: 'entity:node': plugin_id: 'entity:node' settings: - default: '1' + default: 1 bundles: article: '0' page: '0' diff --git a/src/Entity/Index.php b/src/Entity/Index.php index 5723e61..95078e6 100644 --- a/src/Entity/Index.php +++ b/src/Entity/Index.php @@ -162,7 +162,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * * @see getDatasources() */ - protected $datasourceInstances; + protected $datasourceInstances = NULL; /** * The tracker settings @@ -331,8 +331,15 @@ class Index extends ConfigEntityBase implements IndexInterface { /** * {@inheritdoc} */ + public function setDatasources(array $datasources = NULL) { + $this->datasourceInstances = $datasources; + } + + /** + * {@inheritdoc} + */ public function getDatasourceIds() { - return array_keys($this->datasource_settings); + return array_keys($this->getDatasources()); } /** @@ -362,33 +369,38 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getDatasources($only_enabled = TRUE) { - 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->datasourceInstances[$name])) { - // Create our settings for this datasource. - $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->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'])); - } + if ($only_enabled && !is_null($this->datasourceInstances)) { + return $this->datasourceInstances; + } + + $all_datasources = 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($all_datasources[$name])) { + // Create our settings for this datasource. + $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); + $all_datasources[$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'])); } } // Filter datasources by status if required. if (!$only_enabled) { - return $this->datasourceInstances; + return $all_datasources; } - return array_intersect_key($this->datasourceInstances, $this->datasource_settings); + $enabled_datasources = array_intersect_key($all_datasources, $this->datasource_settings); + $this->datasourceInstances = $enabled_datasources; + + return $enabled_datasources; } /** @@ -732,7 +744,7 @@ class Index extends ConfigEntityBase implements IndexInterface { * {@inheritdoc} */ public function getFieldsByDatasource($datasource_id) { - $datasource_fields = array_fill_keys(array_keys($this->datasource_settings), array()); + $datasource_fields = array_fill_keys(array_keys($this->getDatasources()), array()); $datasource_fields[NULL] = array(); foreach ($this->getFields() as $field_id => $field) { $datasource_fields[$field->getDatasourceId()][$field_id] = $field; @@ -1086,6 +1098,15 @@ class Index extends ConfigEntityBase implements IndexInterface { ) ); + // Dump the active datasources to the settings array. + $this->datasource_settings = array(); + foreach ($this->getDatasources() as $plugin_id => $datasource) { + $this->datasource_settings[$plugin_id] = array( + 'plugin_id' => $plugin_id, + 'settings' => $datasource->getConfiguration(), + ); + } + // Call the preIndexSave() method of all applicable processors. foreach ($this->getProcessorsByStage(ProcessorInterface::STAGE_PRE_INDEX_SAVE) as $processor) { $processor->preIndexSave(); @@ -1532,14 +1553,8 @@ class Index extends ConfigEntityBase implements IndexInterface { $this->processor_settings = array_intersect_key($this->processor_settings, $all_plugins['processors']); $this->processorInstances = array_intersect_key($this->processorInstances, $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); + $this->datasource_settings = array_intersect_key($this->datasource_settings, $all_plugins['datasources']); + $this->datasourceInstances = array_intersect_key($this->datasourceInstances, $all_plugins['datasources']); // There always needs to be a tracker so reset it back to the default // tracker. diff --git a/src/Form/IndexForm.php b/src/Form/IndexForm.php index a415956..47d8fec 100644 --- a/src/Form/IndexForm.php +++ b/src/Form/IndexForm.php @@ -533,10 +533,9 @@ class IndexForm extends EntityForm { $datasource_form_state = new SubFormState($form_state, array('datasource_configs', $datasource_id)); $datasource->submitConfigurationForm($datasource_form, $datasource_form_state); - $datasource_settings[$datasource_id]['plugin_id'] = $datasource_id; - $datasource_settings[$datasource_id]['settings'] = $datasource->getConfiguration(); + $datasource_settings[$datasource_id] = $datasource; } - $index->set('datasource_settings', $datasource_settings); + $index->setDatasources($datasource_settings); // Call submitConfigurationForm() for the (possibly new) tracker. // @todo It seems if we change the tracker, we would validate/submit the old diff --git a/src/IndexInterface.php b/src/IndexInterface.php index 3172607..c5195b6 100644 --- a/src/IndexInterface.php +++ b/src/IndexInterface.php @@ -128,6 +128,16 @@ interface IndexInterface extends ConfigEntityInterface { public function setOptions(array $options); /** + * Sets this index's datasource plugins. + * + * @param \Drupal\search_api\Datasource\DatasourceInterface[] $datasources + * An array of datasources + * + * @return $this + */ + public function setDatasources(array $datasources); + + /** * Retrieves the IDs of all datasources enabled for this index. * * @return string[] diff --git a/src/Tests/Processor/ContentAccessTest.php b/src/Tests/Processor/ContentAccessTest.php index b0320b9..644db5f 100644 --- a/src/Tests/Processor/ContentAccessTest.php +++ b/src/Tests/Processor/ContentAccessTest.php @@ -109,23 +109,12 @@ class ContentAccessTest extends ProcessorTestBase { $this->nodes[2]->save(); // Also index users, to verify that they are unaffected by the processor. - $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(), - ), - ) - ); + $manager = \Drupal::getContainer() + ->get('plugin.manager.search_api.datasource'); + $datasources['entity:comment'] = $manager->createInstance('entity:comment', array('index' => $this->index)); + $datasources['entity:node'] = $manager->createInstance('entity:node', array('index' => $this->index)); + $datasources['entity:user'] = $manager->createInstance('entity:user', array('index' => $this->index)); + $this->index->setDatasources($datasources); $this->index->save(); \Drupal::getContainer()->get('search_api.index_task_manager')->addItemsAll($this->index); diff --git a/tests/src/Kernel/DependencyRemovalTest.php b/tests/src/Kernel/DependencyRemovalTest.php index 1fc3c9c..e6c460c 100644 --- a/tests/src/Kernel/DependencyRemovalTest.php +++ b/tests/src/Kernel/DependencyRemovalTest.php @@ -184,22 +184,17 @@ class DependencyRemovalTest extends KernelTestBase { // server. $dependency_key = $this->dependency->getConfigDependencyKey(); $dependency_name = $this->dependency->getConfigDependencyName(); - $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, - ), - ), - ), - )); + + // Also index users, to verify that they are unaffected by the processor. + $manager = \Drupal::getContainer() + ->get('plugin.manager.search_api.datasource'); + $datasources['entity:user'] = $manager->createInstance('entity:user', array('index' => $this->index)); + $datasources['search_api_test_dependencies'] = $manager->createInstance( + 'search_api_test_dependencies', + array($dependency_key => array($dependency_name), + 'index' => $this->index)); + $this->index->setDatasources($datasources); + $this->index->save(); // Check the dependencies were calculated correctly. @@ -226,10 +221,10 @@ 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('datasource_settings'); + $datasources = $this->index->getDatasources(); if ($remove_dependency) { $this->assertArrayHasKey('search_api_test_dependencies', $datasources, 'Datasource not removed'); - $this->assertEmpty($datasources['search_api_test_dependencies']['settings'], 'Datasource settings adapted'); + $this->assertEmpty($datasources['search_api_test_dependencies']->getConfiguration(), 'Datasource settings adapted'); } else { $this->assertArrayNotHasKey('search_api_test_dependencies', $datasources, 'Datasource removed'); @@ -245,14 +240,14 @@ class DependencyRemovalTest extends KernelTestBase { // server. $dependency_key = $this->dependency->getConfigDependencyKey(); $dependency_name = $this->dependency->getConfigDependencyName(); - $this->index->set('datasource_settings', array( - 'search_api_test_dependencies' => array( - 'plugin_id' => 'search_api_test_dependencies', - 'settings' => array( - $dependency_key => array($dependency_name) - ), - ) - )); + $datasources['search_api_test_dependencies'] = \Drupal::getContainer() + ->get('plugin.manager.search_api.datasource') + ->createInstance( + 'search_api_test_dependencies', + array($dependency_key => array($dependency_name)) + ); + $this->index->setDatasources($datasources); + $this->index->save(); // Since in this test the index will be removed, we need a mock key/value @@ -406,16 +401,13 @@ class DependencyRemovalTest extends KernelTestBase { */ public function testModuleDependency() { // Test with all types of plugins at once. - $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(), - ), - )); + $datasources['search_api_test_dependencies'] = \Drupal::getContainer() + ->get('plugin.manager.search_api.datasource') + ->createInstance('search_api_test_dependencies', array('index' => $this->index)); + $datasources['entity:user'] = \Drupal::getContainer() + ->get('plugin.manager.search_api.datasource') + ->createInstance('entity:user', array('index' => $this->index)); + $this->index->setDatasources($datasources); $processor = \Drupal::getContainer() ->get('plugin.manager.search_api.processor') @@ -426,6 +418,7 @@ class DependencyRemovalTest extends KernelTestBase { ->get('plugin.manager.search_api.tracker') ->createInstance('search_api_test_dependencies'); $this->index->setTracker($tracker); + $this->index->save(); // Check the dependencies were calculated correctly.