You are here

public function SavedSearchType::onDependencyRemoval in Search API Saved Searches 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/SavedSearchType.php, line 490

Class

SavedSearchType
Provides an entity type for configuring how searches can be saved.

Namespace

Drupal\search_api_saved_searches\Entity

Code

public function onDependencyRemoval(array $dependencies) {
  $changed = parent::onDependencyRemoval($dependencies);
  $all_plugins = $this
    ->getNotificationPlugins();
  $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'])) {

        // This will definitely lead to a change (or to us returning FALSE
        // directly).
        $changed = TRUE;
        foreach ($dependency_sources['always'] as $plugin_type => $plugins) {

          // We can hardly remove the entity itself, so just give up.
          if ($plugin_type === 'entity') {
            return FALSE;
          }

          // Otherwise, the dependency has to come from one or more
          // notification plugins. So, remove them.
          $all_plugins = array_diff_key($all_plugins, $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) {

          // Type entities currently have no soft dependencies, so this has to
          // be a plugin dependency. We want to call onDependencyRemoval() on
          // that plugin.
          // Only include those plugins that have not already been removed.
          $plugins = array_intersect_key($plugins, $all_plugins);
          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_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_id]
          ->getConfiguration();
      }
      else {
        unset($all_plugins[$plugin_id]);
      }
    }
  }

  // Finally, apply the changes by removing all plugins that have been unset
  // from $all_plugins.
  $this->notificationPluginInstances = array_intersect_key($this->notificationPluginInstances, $all_plugins);
  return $changed;
}