public function ModuleHandler::uninstall

Uninstalls a given list of disabled modules.

Parameters

array $module_list: The modules to uninstall. It is the caller's responsibility to ensure that all modules in this list have already been disabled before this function is called.

bool $uninstall_dependents: (optional) If TRUE, the function will check that all modules which depend on the passed-in module list either are already uninstalled or contained in the list, and it will ensure that the modules are uninstalled in the correct order. This incurs a significant performance cost, so use FALSE if you know $module_list is already complete and in the correct order. Defaults to TRUE.

Return value

bool Returns TRUE if the operation succeeds or FALSE if it aborts due to an unsafe condition, namely, $uninstall_dependents is TRUE and a module in $module_list has dependents which are not already uninstalled and not also included in $module_list).

Overrides ModuleHandlerInterface::uninstall

1 method overrides ModuleHandler::uninstall()
UpdateModuleHandler::uninstall in drupal/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
Uninstalls a given list of disabled modules.

File

drupal/core/lib/Drupal/Core/Extension/ModuleHandler.php, line 803
Contains Drupal\Core\Extension\ModuleHandler.

Class

ModuleHandler
Class that manages enabled modules in a Drupal installation.

Namespace

Drupal\Core\Extension

Code

public function uninstall($module_list = array(), $uninstall_dependents = TRUE) {
  if ($uninstall_dependents) {

    // Get all module data so we can find dependents and sort.
    $module_data = system_rebuild_module_data();

    // Create an associative array with weights as values.
    $module_list = array_flip(array_values($module_list));
    $profile = drupal_get_profile();
    while (list($module) = each($module_list)) {
      if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) {

        // This module doesn't exist or is already uninstalled. Skip it.
        unset($module_list[$module]);
        continue;
      }
      $module_list[$module] = $module_data[$module]->sort;

      // If the module has any dependents which are not already uninstalled and
      // not included in the passed-in list, abort. It is not safe to uninstall
      // them automatically because uninstalling a module is a destructive
      // operation.
      foreach (array_keys($module_data[$module]->required_by) as $dependent) {
        if (!isset($module_list[$dependent]) && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED && $dependent != $profile) {
          return FALSE;
        }
      }
    }

    // Sort the module list by pre-calculated weights.
    asort($module_list);
    $module_list = array_keys($module_list);
  }
  $schema_store = \Drupal::keyValue('system.schema');
  $disabled_config = config('system.module.disabled');
  foreach ($module_list as $module) {

    // Uninstall the module.
    module_load_install($module);
    $this
      ->invoke($module, 'uninstall');
    drupal_uninstall_schema($module);

    // Remove all configuration belonging to the module.
    config_uninstall_default_config('module', $module);

    // Remove any cache bins defined by the module.
    $service_yaml_file = drupal_get_path('module', $module) . "/{$module}.services.yml";
    if (file_exists($service_yaml_file)) {
      $parser = new Parser();
      $definitions = $parser
        ->parse(file_get_contents($service_yaml_file));
      if (isset($definitions['services'])) {
        foreach ($definitions['services'] as $id => $definition) {
          if (isset($definition['tags'])) {
            foreach ($definition['tags'] as $tag) {

              // This works for the default cache registration and even in some
              // cases when a non-default "super" factory is used. That should
              // be extremely rare.
              if ($tag['name'] == 'cache.bin' && isset($definition['factory_service']) && isset($definition['factory_method']) && !empty($definition['arguments'])) {
                try {
                  $factory = \Drupal::service($definition['factory_service']);
                  if (method_exists($factory, $definition['factory_method'])) {
                    $backend = call_user_func_array(array(
                      $factory,
                      $definition['factory_method'],
                    ), $definition['arguments']);
                    if ($backend instanceof CacheBackendInterface) {
                      $backend
                        ->removeBin();
                    }
                  }
                } catch (\Exception $e) {
                  watchdog_exception('system', $e, 'Failed to remove cache bin defined by the service %id.', array(
                    '%id' => $id,
                  ));
                }
              }
            }
          }
        }
      }
    }
    watchdog('system', '%module module uninstalled.', array(
      '%module' => $module,
    ), WATCHDOG_INFO);
    $schema_store
      ->delete($module);
    $disabled_config
      ->clear($module);
  }
  $disabled_config
    ->save();
  drupal_get_installed_schema_version(NULL, TRUE);
  if (!empty($module_list)) {

    // Let other modules react.
    $this
      ->invokeAll('modules_uninstalled', array(
      $module_list,
    ));
  }
  return TRUE;
}