diff --git a/src/Datasource/DatasourcePluginBase.php b/src/Datasource/DatasourcePluginBase.php index 3a91803..0734447 100644 --- a/src/Datasource/DatasourcePluginBase.php +++ b/src/Datasource/DatasourcePluginBase.php @@ -92,7 +92,9 @@ abstract class DatasourcePluginBase extends IndexPluginBase implements Datasourc * {@inheritdoc} */ public function getBundles() { - return array(); + return array( + $this->getPluginId() => $this->label(), + ); } /** diff --git a/src/Entity/Index.php b/src/Entity/Index.php index 14191af..a3c7465 100644 --- a/src/Entity/Index.php +++ b/src/Entity/Index.php @@ -1503,10 +1503,16 @@ class Index extends ConfigEntityBase implements IndexInterface { } } + // Now for all plugins with optional dependencies (stored in + // $call_on_removal, mapped to their removed dependencies) call their + // onDependencyRemoval() methods. $updated_config = array(); foreach ($call_on_removal as $plugin_type => $plugins) { foreach ($plugins as $plugin_id => $plugin_dependencies) { $removal_successful = $all_plugins[$plugin_type][$plugin_id]->onDependencyRemoval($plugin_dependencies); + // If the plugin was successfully changed to remove the dependency, + // remember the new configuration to later set it. Otherwise, remove the + // plugin from the index so the dependency still gets removed. if ($removal_successful) { $updated_config[$plugin_type][$plugin_id] = $all_plugins[$plugin_type][$plugin_id]->getConfiguration(); } @@ -1529,7 +1535,7 @@ class Index extends ConfigEntityBase implements IndexInterface { } // 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 (and hope this means the right thing). + // FALSE to indicate this, which will cause the index to be deleted. if (!$this->datasources) { return FALSE; } diff --git a/src/Plugin/search_api/processor/RenderedItem.php b/src/Plugin/search_api/processor/RenderedItem.php index b817e34..a277fc3 100644 --- a/src/Plugin/search_api/processor/RenderedItem.php +++ b/src/Plugin/search_api/processor/RenderedItem.php @@ -319,11 +319,12 @@ class RenderedItem extends ProcessorPluginBase { * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { - // Make arrays of dependencies associative to simplify the code. - foreach (array_keys($dependencies) as $dependency_type) { - $dependencies[$dependency_type] = array_combine($dependencies[$dependency_type], $dependencies[$dependency_type]); - } - + // All dependencies of this processor are entity view modes, so we go + // through our configuration and remove the settings for all datasources or + // bundles which were set to one of the removed view modes. This will always + // result in the removal of all those dependencies. + // The code is highly similar to calculateDependencies(), only that we + // remove the setting (if necessary) instead of adding a dependency. $view_modes = $this->configuration['view_mode']; foreach ($this->index->getDatasources() as $datasource_id => $datasource) { if ($entity_type_id = $datasource->getEntityTypeId() && !empty($view_modes[$datasource_id])) { @@ -336,7 +337,6 @@ class RenderedItem extends ProcessorPluginBase { $dependency_name = $view_mode->getConfigDependencyName(); if (!empty($dependencies[$dependency_key][$dependency_name])) { unset($this->configuration['view_mode'][$datasource_id][$bundle]); - unset($dependencies[$dependency_key][$dependency_name]); } } } @@ -344,7 +344,7 @@ class RenderedItem extends ProcessorPluginBase { } } - return empty($dependencies); + return TRUE; } } diff --git a/tests/src/Kernel/DependencyRemovalTest.php b/tests/src/Kernel/DependencyRemovalTest.php index 7aa0cc3..61a7da3 100644 --- a/tests/src/Kernel/DependencyRemovalTest.php +++ b/tests/src/Kernel/DependencyRemovalTest.php @@ -115,7 +115,7 @@ class DependencyRemovalTest extends KernelTestBase { $this->index->disable(); $this->index->save(); - // Check the dependencies were calculated correctly. + // Check that the dependencies were calculated correctly. $server_dependencies = $server->getDependencies(); $this->assertContains($dependency_name, $server_dependencies[$dependency_key], 'Backend dependency correctly inserted'); $index_dependencies = $this->index->getDependencies(); @@ -132,7 +132,7 @@ class DependencyRemovalTest extends KernelTestBase { // Reload the index and check it's still there. $this->reloadIndex(); - $this->assertNotNull($this->index, 'Index not removed'); + $this->assertInstanceOf('Drupal\search_api\IndexInterface', $this->index, 'Index not removed'); // Reload the server. $storage = \Drupal::entityTypeManager()->getStorage('search_api_server'); @@ -140,7 +140,7 @@ class DependencyRemovalTest extends KernelTestBase { $server = $storage->load($server->id()); if ($remove_dependency) { - $this->assertNotNull($server, 'Server was not removed'); + $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 // removed, there is no need to adapt the index's configuration. @@ -201,7 +201,7 @@ class DependencyRemovalTest extends KernelTestBase { // Reload the index and check it's still there. $this->reloadIndex(); - $this->assertNotNull($this->index, 'Index not removed'); + $this->assertInstanceOf('Drupal\search_api\IndexInterface', $this->index, 'Index not removed'); // Make sure the dependency has been removed, one way or the other. $dependencies = $this->index->getDependencies(); @@ -243,7 +243,10 @@ class DependencyRemovalTest extends KernelTestBase { )); $this->index->save(); - // Since in this test the index will be removed, we need a mock + // Since in this test the index will be removed, we need a mock key/value + // store (the index will purge any unsaved configuration of it upon + // deletion, which uses a "user-shared temp store", which in turn uses a + // key/value store). $mock = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface'); $mock_factory = $this->getMock('Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface'); $mock_factory->method('get')->willReturn($mock); @@ -299,7 +302,7 @@ class DependencyRemovalTest extends KernelTestBase { // Reload the index and check it's still there. $this->reloadIndex(); - $this->assertNotNull($this->index, 'Index not removed'); + $this->assertInstanceOf('Drupal\search_api\IndexInterface', $this->index, 'Index not removed'); // Make sure the dependency has been removed, one way or the other. $dependencies = $this->index->getDependencies(); @@ -350,8 +353,8 @@ class DependencyRemovalTest extends KernelTestBase { // \Drupal\search_api_test_dependencies\Plugin\search_api\tracker\TestTracker::onDependencyRemoval(). $key = 'search_api_test_dependencies.tracker.remove'; \Drupal::state()->set($key, $remove_dependency); - // If the index resets the tracker, it needs to have the config setting to - // work correctly. + // If the index resets the tracker, it needs to know the ID of the default + // tracker. if (!$remove_dependency) { \Drupal::configFactory()->getEditable('search_api.settings') ->set('default_tracker', 'default') @@ -363,7 +366,7 @@ class DependencyRemovalTest extends KernelTestBase { // Reload the index and check it's still there. $this->reloadIndex(); - $this->assertNotNull($this->index, 'Index not removed'); + $this->assertInstanceOf('Drupal\search_api\IndexInterface', $this->index, 'Index not removed'); // Make sure the dependency has been removed, one way or the other. $dependencies = $this->index->getDependencies(); @@ -392,8 +395,8 @@ class DependencyRemovalTest extends KernelTestBase { */ public function dependencyTestDataProvider() { return array( - array(TRUE), - array(FALSE), + 'Remove dependency' => array(TRUE), + 'Keep dependency' => array(FALSE), ); }