public function Index::onDependencyRemoval in Search API 8
Informs the entity that entities it depends on will be deleted.
This method allows configuration entities to remove dependencies instead of being deleted themselves. Configuration entities can use this method to avoid being unnecessarily deleted during an extension uninstallation. For example, entity displays remove references to widgets and formatters if the plugin that supplies them depends on a module that is being uninstalled.
If this method returns TRUE then the entity needs to be re-saved by the caller for the changes to take effect. Implementations should not save the entity.
Parameters
array $dependencies: An array of dependencies that will be deleted keyed by dependency type. Dependency types are, for example, entity, module and theme.
Return value
bool TRUE if the entity has been changed as a result, FALSE if not.
Overrides ConfigEntityBase::onDependencyRemoval
See also
\Drupal\Core\Config\Entity\ConfigDependencyManager
\Drupal\Core\Config\ConfigEntityBase::preDelete()
\Drupal\Core\Config\ConfigManager::uninstall()
\Drupal\Core\Entity\EntityDisplayBase::onDependencyRemoval()
File
- src/
Entity/ Index.php, line 1797
Class
- Index
- Defines the search index configuration entity.
Namespace
Drupal\search_api\EntityCode
public function onDependencyRemoval(array $dependencies) {
$changed = parent::onDependencyRemoval($dependencies);
$all_plugins = $this
->getAllPlugins();
$dependency_data = $this
->getDependencyData();
// Make sure our dependency data has the exact same keys as $dependencies,
// to simplify the subsequent code.
$dependencies = array_filter($dependencies);
$dependency_data = array_intersect_key($dependency_data, $dependencies);
$dependency_data += array_fill_keys(array_keys($dependencies), []);
$call_on_removal = [];
foreach ($dependencies as $dependency_type => $dependency_objects) {
// Annoyingly, modules and theme dependencies come not keyed by dependency
// name here, while entities do. Flip the array for modules and themes to
// make the code simpler.
if (in_array($dependency_type, [
'module',
'theme',
])) {
$dependency_objects = array_flip($dependency_objects);
}
$dependency_data[$dependency_type] = array_intersect_key($dependency_data[$dependency_type], $dependency_objects);
foreach ($dependency_data[$dependency_type] as $name => $dependency_sources) {
// We first remove all the "hard" dependencies.
if (!empty($dependency_sources['always'])) {
foreach ($dependency_sources['always'] as $plugin_type => $plugins) {
// We can hardly remove the index itself.
if ($plugin_type == 'index') {
continue;
}
// This will definitely lead to a change.
$changed = TRUE;
if ($plugin_type == 'fields') {
// Remove a field from the index that is being removed from the
// system.
/** @var \Drupal\search_api\Item\FieldInterface $field */
foreach ($plugins as $field_id => $field) {
// In case the field is locked, unlock it before removing.
if ($field
->isIndexedLocked()) {
$field
->setIndexedLocked(FALSE);
}
$this
->removeField($field_id);
}
}
else {
// For all other types, just remove the plugin from our list.
$all_plugins[$plugin_type] = array_diff_key($all_plugins[$plugin_type], $plugins);
}
}
}
// Then, collect all the optional ones.
if (!empty($dependency_sources['optional'])) {
// However this plays out, it will lead to a change.
$changed = TRUE;
foreach ($dependency_sources['optional'] as $plugin_type => $plugins) {
// Deal with the index right away, since that dependency can only be
// the server.
if ($plugin_type == 'index') {
$this
->setServer(NULL);
continue;
}
// Fields can only have optional dependencies caused by their data
// type plugin. Reset to the fallback type.
if ($plugin_type == 'fields') {
foreach ($plugins as $field) {
$field
->setType($field
->getDataTypePlugin()
->getFallbackType());
}
continue;
}
// Only include those plugins that have not already been removed.
$plugins = array_intersect_key($plugins, $all_plugins[$plugin_type]);
foreach ($plugins as $plugin_id => $plugin) {
$call_on_removal[$plugin_type][$plugin_id][$dependency_type][$name] = $dependency_objects[$name];
}
}
}
}
}
// Now for all plugins with optional dependencies (stored in
// $call_on_removal, mapped to their removed dependencies) call their
// onDependencyRemoval() methods.
$updated_config = [];
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();
}
else {
unset($all_plugins[$plugin_type][$plugin_id]);
}
}
}
// 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->processor_settings = array_intersect_key($this->processor_settings, $all_plugins['processors']);
$this->processorInstances = array_intersect_key($this->processorInstances, $all_plugins['processors']);
$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.
if (empty($all_plugins['tracker'])) {
$default_tracker_id = \Drupal::config('search_api.settings')
->get('default_tracker');
$this->tracker_settings = [
$default_tracker_id => [],
];
// Reset $trackerInstance so it will get newly loaded from our reset
// settings when required.
$this->trackerInstance = NULL;
}
// 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->datasource_settings) {
return FALSE;
}
// Then, update configuration as necessary.
foreach ($updated_config as $plugin_type => $plugin_configs) {
foreach ($plugin_configs as $plugin_id => $plugin_config) {
switch ($plugin_type) {
case 'processors':
$this->processor_settings[$plugin_id] = $plugin_config;
break;
case 'datasources':
$this->datasource_settings[$plugin_id] = $plugin_config;
break;
case 'tracker':
$this->tracker_settings[$plugin_id] = $plugin_config;
break;
}
}
}
return $changed;
}