Esempio n. 1
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state)
 {
     $modules = array_keys($this->moduleHandler->getModuleList());
     sort($modules);
     $form['list'] = array('#type' => 'checkboxes', '#options' => array_combine($modules, $modules), '#description' => t('Uninstall and then install the selected modules. <code>hook_uninstall()</code> and <code>hook_install()</code> will be executed and the schema version number will be set to the most recent update number. You may have to manually clear out any existing tables first if the module doesn\'t implement <code>hook_uninstall()</code>.'));
     $form['submit'] = array('#value' => t('Reinstall'), '#type' => 'submit');
     return $form;
 }
Esempio n. 2
0
 /**
  * {@inheritdoc}
  */
 public function getExtensions()
 {
     foreach ($this->moduleHandler->getModuleList() as $module) {
         (yield $this->wrapCoreExtension($module));
     }
     foreach ($this->themeHandler->listInfo() as $theme) {
         (yield $this->wrapCoreExtension($theme));
     }
 }
Esempio n. 3
0
 /**
  * {@inheritdoc}
  */
 public function collect(Request $request, Response $response, \Exception $exception = NULL)
 {
     $modules = $this->moduleHandler->getModuleList();
     $themes = $this->themeHandler->listInfo();
     $this->data['drupal_extension']['count'] = count($modules) + count($themes);
     $this->data['drupal_extension']['modules'] = $modules;
     $this->data['drupal_extension']['themes'] = $themes;
     $this->data['drupal_extension']['installation_path'] = $this->root . '/';
 }
Esempio n. 4
0
 /**
  * {@inheritdoc}
  */
 public function buildOptionsForm(&$form, FormStateInterface $form_state)
 {
     parent::buildOptionsForm($form, $form_state);
     $modules = $this->moduleHandler->getModuleList();
     $names = array();
     foreach (array_keys($modules) as $name) {
         $names[$name] = $this->moduleHandler->getName($name);
     }
     $form['data_module'] = array('#title' => $this->t('Module name'), '#type' => 'select', '#description' => $this->t('The module which sets this user data.'), '#default_value' => $this->options['data_module'], '#options' => $names);
     $form['data_name'] = array('#title' => $this->t('Name'), '#type' => 'textfield', '#description' => $this->t('The name of the data key.'), '#default_value' => $this->options['data_name']);
 }
Esempio n. 5
0
 private function getAllLibraries()
 {
     $modules = $this->moduleHandler->getModuleList();
     $themes = $this->themeHandler->rebuildThemeData();
     $extensions = array_merge($modules, $themes);
     $libraries = [];
     foreach ($extensions as $extensionName => $extension) {
         $libraryFile = $extension->getPath() . '/' . $extensionName . '.libraries.yml';
         if (is_file($this->appRoot . '/' . $libraryFile)) {
             $libraries[$extensionName] = $this->libraryDiscovery->getLibrariesByExtension($extensionName);
         }
     }
     return array_keys($libraries);
 }
 /**
  * Constructs a ConfigMapperManager.
  *
  * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
  *   The cache backend.
  * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
  *   The language manager.
  * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
  *   The module handler.
  * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager
  *   The typed config manager.
  */
 public function __construct(CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, ModuleHandlerInterface $module_handler, TypedConfigManagerInterface $typed_config_manager, ThemeHandlerInterface $theme_handler)
 {
     $this->typedConfigManager = $typed_config_manager;
     // Look at all themes and modules.
     // @todo If the list of enabled modules and themes is changed, new
     //   definitions are not picked up immediately and obsolete definitions are
     //   not removed, because the list of search directories is only compiled
     //   once in this constructor. The current code only works due to
     //   coincidence: The request that enables e.g. a new theme does not
     //   instantiate this plugin manager at the beginning of the request; when
     //   routes are being rebuilt at the end of the request, this service only
     //   happens to get instantiated with the updated list of enabled themes.
     $directories = array();
     foreach ($module_handler->getModuleList() as $name => $module) {
         $directories[$name] = $module->getPath();
     }
     foreach ($theme_handler->listInfo() as $theme) {
         $directories[$theme->getName()] = $theme->getPath();
     }
     // Check for files named MODULE.config_translation.yml and
     // THEME.config_translation.yml in module/theme roots.
     $this->discovery = new YamlDiscovery('config_translation', $directories);
     $this->discovery = new InfoHookDecorator($this->discovery, 'config_translation_info');
     $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
     $this->factory = new ContainerFactory($this);
     // Let others alter definitions with hook_config_translation_info_alter().
     $this->moduleHandler = $module_handler;
     $this->themeHandler = $theme_handler;
     $this->alterInfo('config_translation_info');
     // Config translation only uses an info hook discovery, cache by language.
     $cache_key = 'config_translation_info_plugins' . ':' . $language_manager->getCurrentLanguage()->getId();
     $this->setCacheBackend($cache_backend, $cache_key, array('config_translation_info_plugins' => TRUE));
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     // Remove the key value store entry.
     $account = $this->currentUser()->id();
     $this->keyValueExpirable->delete($account);
     // Gets list of modules prior to install process.
     $before = $this->moduleHandler->getModuleList();
     // Install the given modules.
     if (!empty($this->modules['install'])) {
         // Don't catch the exception that this can throw for missing dependencies:
         // the form doesn't allow modules with unmet dependencies, so the only way
         // this can happen is if the filesystem changed between form display and
         // submit, in which case the user has bigger problems.
         try {
             $this->moduleInstaller->install(array_keys($this->modules['install']));
         } catch (PreExistingConfigException $e) {
             $config_objects = $e->flattenConfigObjects($e->getConfigObjects());
             drupal_set_message($this->formatPlural(count($config_objects), 'Unable to install @extension, %config_names already exists in active configuration.', 'Unable to install @extension, %config_names already exist in active configuration.', array('%config_names' => implode(', ', $config_objects), '@extension' => $this->modules['install'][$e->getExtension()])), 'error');
             return;
         } catch (UnmetDependenciesException $e) {
             drupal_set_message($e->getTranslatedMessage($this->getStringTranslation(), $this->modules['install'][$e->getExtension()]), 'error');
             return;
         }
     }
     // Gets module list after install process, flushes caches and displays a
     // message if there are changes.
     if ($before != $this->moduleHandler->getModuleList()) {
         drupal_set_message($this->t('The configuration options have been saved.'));
     }
     $form_state->setRedirectUrl($this->getCancelUrl());
 }
Esempio n. 8
0
 /**
  * Constructs a TwigEnvironment object and stores cache and storage
  * internally.
  */
 public function __construct(\Twig_LoaderInterface $loader = NULL, $options = array(), ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler)
 {
     // @todo Pass as arguments from the DIC.
     $this->cache_object = \Drupal::cache();
     // Ensure that twig.engine is loaded, given that it is needed to render a
     // template because functions like twig_drupal_escape_filter are called.
     require_once DRUPAL_ROOT . '/core/themes/engines/twig/twig.engine';
     // Set twig path namespace for themes and modules.
     $namespaces = array();
     foreach ($module_handler->getModuleList() as $name => $extension) {
         $namespaces[$name] = $extension->getPath();
     }
     foreach ($theme_handler->listInfo() as $name => $extension) {
         $namespaces[$name] = $extension->getPath();
     }
     foreach ($namespaces as $name => $path) {
         $templatesDirectory = $path . '/templates';
         if (file_exists($templatesDirectory)) {
             $loader->addPath($templatesDirectory, $name);
         }
     }
     $this->templateClasses = array();
     $this->stringLoader = new \Twig_Loader_String();
     parent::__construct($loader, $options);
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     // Retrieve a list of modules to install and their dependencies.
     $modules = $this->buildModuleList($form_state);
     // Check if we have to install any dependencies. If there is one or more
     // dependencies that are not installed yet, redirect to the confirmation
     // form.
     if (!empty($modules['dependencies']) || !empty($modules['missing'])) {
         // Write the list of changed module states into a key value store.
         $account = $this->currentUser()->id();
         $this->keyValueExpirable->setWithExpire($account, $modules, 60);
         // Redirect to the confirmation form.
         $form_state->setRedirect('system.modules_list_confirm');
         // We can exit here because at least one modules has dependencies
         // which we have to prompt the user for in a confirmation form.
         return;
     }
     // Gets list of modules prior to install process.
     $before = $this->moduleHandler->getModuleList();
     // There seem to be no dependencies that would need approval.
     if (!empty($modules['install'])) {
         $this->moduleHandler->install(array_keys($modules['install']));
     }
     // Gets module list after install process, flushes caches and displays a
     // message if there are changes.
     if ($before != $this->moduleHandler->getModuleList()) {
         drupal_set_message(t('The configuration options have been saved.'));
     }
 }
Esempio n. 10
0
 /**
  * {@inheritdoc}
  */
 public function assignConfigPackage($package_name, array $item_names, $force = FALSE)
 {
     $config_collection = $this->getConfigCollection();
     $module_list = $this->moduleHandler->getModuleList();
     $packages =& $this->packages;
     if (isset($packages[$package_name])) {
         $package =& $packages[$package_name];
     } else {
         throw new \Exception($this->t('Failed to package @package_name. Package not found.', ['@package_name' => $package_name]));
     }
     foreach ($item_names as $item_name) {
         if (isset($config_collection[$item_name])) {
             // Add to the package if:
             // - force is set or
             //   - the item hasn't already been assigned elsewhere, and
             //   - the package hasn't been excluded.
             // - and the item isn't already in the package.
             // Determine if the item is provided by an extension.
             $extension_provided = $config_collection[$item_name]->isExtensionProvided() === TRUE;
             $already_assigned = !empty($config_collection[$item_name]->getPackage());
             // If this is the profile package, we can reassign extension-provided configuration.
             $is_profile_package = $this->getAssigner()->getBundle($package->getBundle())->isProfilePackage($package->getMachineName());
             // An item is assignable if:
             // - it is not extension provided or this is the profile package, and
             // - it is not flagged as excluded.
             $assignable = (!$extension_provided || $is_profile_package) && !$config_collection[$item_name]->isExcluded();
             $excluded_from_package = in_array($package_name, $config_collection[$item_name]->getPackageExcluded());
             $already_in_package = in_array($item_name, $package->getConfig());
             if (($force || !$already_assigned && $assignable && !$excluded_from_package) && !$already_in_package) {
                 // Add the item to the package's config array.
                 $package->appendConfig($item_name);
                 // Mark the item as already assigned.
                 $config_collection[$item_name]->setPackage($package_name);
                 $module_dependencies = [];
                 // Add a dependency on the extension that provides this configuration
                 // type.
                 if ($config_collection[$item_name]->getType() != static::SYSTEM_SIMPLE_CONFIG) {
                     $provider = $this->entityManager->getDefinition($config_collection[$item_name]->getType())->getProvider();
                     // Ensure the provider is an installed module and not, for example,
                     // 'core'.
                     if (isset($module_list[$provider])) {
                         $module_dependencies[] = $provider;
                     }
                 }
                 // For configuration in the InstallStorage::CONFIG_INSTALL_DIRECTORY
                 // directory, set any module dependencies of the configuration item
                 // as package dependencies.
                 // As its name implies, the core-provided
                 // InstallStorage::CONFIG_OPTIONAL_DIRECTORY should not create
                 // dependencies.
                 if ($config_collection[$item_name]->getSubdirectory() === InstallStorage::CONFIG_INSTALL_DIRECTORY && isset($config_collection[$item_name]->getData()['dependencies']['module'])) {
                     $module_dependencies = array_merge($module_dependencies, $config_collection[$item_name]->getData()['dependencies']['module']);
                 }
                 $package->setDependencies($this->mergeUniqueItems($package->getDependencies(), $module_dependencies));
             }
         }
     }
     $this->setConfigCollection($config_collection);
 }
Esempio n. 11
0
 /**
  * Returns all module names.
  *
  * @return string[]
  *   Returns the human readable names of all modules keyed by machine name.
  */
 protected function getModuleNames()
 {
     $modules = array();
     foreach (array_keys($this->moduleHandler->getModuleList()) as $module) {
         $modules[$module] = $this->moduleHandler->getName($module);
     }
     asort($modules);
     return $modules;
 }
 /**
  * Returns all module names.
  *
  * @return string[]
  *   Returns the human readable names of all modules keyed by machine name.
  */
 protected function getModuleNames()
 {
     $modules = array();
     $module_info = $this->systemRebuildModuleData();
     foreach (array_keys($this->moduleHandler->getModuleList()) as $module) {
         $modules[$module] = $module_info[$module]->info['name'];
     }
     asort($modules);
     return $modules;
 }
Esempio n. 13
0
 /**
  * List of modules enabled for insertion into the script docblock.
  *
  * @return string
  *   The formatted list of enabled modules.
  */
 protected function getModulesScript()
 {
     $output = '';
     $modules = $this->moduleHandler->getModuleList();
     ksort($modules);
     foreach ($modules as $module => $filename) {
         $output .= " *  - {$module}\n";
     }
     return rtrim($output, "\n");
 }
Esempio n. 14
0
 /**
  * Constructs a new FilesystemLoader object.
  *
  * @param string|array $paths
  *   A path or an array of paths to check for templates.
  * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
  *   The module handler service.
  * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
  *   The theme handler service.
  */
 public function __construct($paths = array(), ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler)
 {
     parent::__construct($paths);
     // Add namespaced paths for modules and themes.
     $namespaces = array();
     foreach ($module_handler->getModuleList() as $name => $extension) {
         $namespaces[$name] = $extension->getPath();
     }
     foreach ($theme_handler->listInfo() as $name => $extension) {
         $namespaces[$name] = $extension->getPath();
     }
     foreach ($namespaces as $name => $path) {
         $this->addPath($path . '/templates', $name);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     // Remove the key value store entry.
     $account = $this->currentUser()->id();
     $this->keyValueExpirable->delete($account);
     // Gets list of modules prior to install process.
     $before = $this->moduleHandler->getModuleList();
     // Install the given modules.
     if (!empty($this->modules['install'])) {
         $this->moduleHandler->install(array_keys($this->modules['install']));
     }
     // Gets module list after install process, flushes caches and displays a
     // message if there are changes.
     if ($before != $this->moduleHandler->getModuleList()) {
         drupal_set_message($this->t('The configuration options have been saved.'));
     }
     $form_state->setRedirectUrl($this->getCancelUrl());
 }
Esempio n. 16
0
 /**
  * {@inheritdoc}
  */
 public function assignPackageDependencies(Package $package = NULL)
 {
     if (is_null($package)) {
         $packages = $this->getPackages();
     } else {
         $packages = array($package);
     }
     $module_list = $this->moduleHandler->getModuleList();
     $config_collection = $this->getConfigCollection();
     foreach ($packages as $package) {
         $module_dependencies = [];
         foreach ($package->getConfig() as $item_name) {
             if (isset($config_collection[$item_name])) {
                 $dependencies = $this->getConfigDependency($config_collection[$item_name], $module_list);
                 $module_dependencies = array_merge($module_dependencies, $dependencies);
             }
         }
         $package->setDependencies($this->mergeUniqueItems($package->getDependencies(), $module_dependencies));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function getExistingPackages($enabled = FALSE)
 {
     $result = array();
     if ($enabled) {
         $modules = $this->moduleHandler->getModuleList();
     } else {
         // ModuleHandler::getModuleList() returns data only for installed
         // modules. We want to search all possible exports for Features that
         // might be disabled.
         $listing = new ExtensionDiscovery(\Drupal::root());
         $modules = $listing->scan('module');
     }
     foreach ($modules as $name => $module) {
         if ($this->isFeatureModule($module)) {
             $result[$name] = $this->getExtensionInfo($module);
             $result[$name]['status'] = $this->moduleHandler->moduleExists($name) ? FeaturesManagerInterface::STATUS_ENABLED : FeaturesManagerInterface::STATUS_DISABLED;
         }
     }
     return $result;
 }
Esempio n. 18
0
 /**
  * Constructs a TwigEnvironment object and stores cache and storage
  * internally.
  */
 public function __construct(\Twig_LoaderInterface $loader = NULL, $options = array(), ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler)
 {
     // @todo Pass as arguments from the DIC.
     $this->cache_object = \Drupal::cache();
     // Set twig path namespace for themes and modules.
     $namespaces = array();
     foreach ($module_handler->getModuleList() as $name => $extension) {
         $namespaces[$name] = $extension->getPath();
     }
     foreach ($theme_handler->listInfo() as $name => $extension) {
         $namespaces[$name] = $extension->getPath();
     }
     foreach ($namespaces as $name => $path) {
         $templatesDirectory = $path . '/templates';
         if (file_exists($templatesDirectory)) {
             $loader->addPath($templatesDirectory, $name);
         }
     }
     $this->templateClasses = array();
     parent::__construct($loader, $options);
 }
Esempio n. 19
0
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     // Retrieve a list of modules to install and their dependencies.
     $modules = $this->buildModuleList($form_state);
     // Check if we have to install any dependencies. If there is one or more
     // dependencies that are not installed yet, redirect to the confirmation
     // form.
     if (!empty($modules['dependencies']) || !empty($modules['missing'])) {
         // Write the list of changed module states into a key value store.
         $account = $this->currentUser()->id();
         $this->keyValueExpirable->setWithExpire($account, $modules, 60);
         // Redirect to the confirmation form.
         $form_state->setRedirect('system.modules_list_confirm');
         // We can exit here because at least one modules has dependencies
         // which we have to prompt the user for in a confirmation form.
         return;
     }
     // Gets list of modules prior to install process.
     $before = $this->moduleHandler->getModuleList();
     // There seem to be no dependencies that would need approval.
     if (!empty($modules['install'])) {
         try {
             $this->moduleInstaller->install(array_keys($modules['install']));
         } catch (PreExistingConfigException $e) {
             $config_objects = $e->flattenConfigObjects($e->getConfigObjects());
             drupal_set_message($this->formatPlural(count($config_objects), 'Unable to install @extension, %config_names already exists in active configuration.', 'Unable to install @extension, %config_names already exist in active configuration.', array('%config_names' => implode(', ', $config_objects), '@extension' => $modules['install'][$e->getExtension()])), 'error');
             return;
         } catch (UnmetDependenciesException $e) {
             drupal_set_message($e->getTranslatedMessage($this->getStringTranslation(), $modules['install'][$e->getExtension()]), 'error');
             return;
         }
     }
     // Gets module list after install process, flushes caches and displays a
     // message if there are changes.
     if ($before != $this->moduleHandler->getModuleList()) {
         drupal_set_message(t('The configuration options have been saved.'));
     }
 }
Esempio n. 20
0
 /**
  * Completes the theme registry adding discovered functions and hooks.
  *
  * @param array $cache
  *   The theme registry as documented in
  *   \Drupal\Core\Theme\Registry::processExtension().
  * @param \Drupal\Core\Theme\ActiveTheme $theme
  *   Current active theme.
  *
  * @see ::processExtension()
  */
 protected function postProcessExtension(array &$cache, ActiveTheme $theme)
 {
     $grouped_functions = $this->getPrefixGroupedUserFunctions();
     // Gather prefixes. This will be used to limit the found functions to the
     // expected naming conventions.
     $prefixes = array_keys((array) $this->moduleHandler->getModuleList());
     foreach (array_reverse($theme->getBaseThemes()) as $base) {
         $prefixes[] = $base->getName();
     }
     if ($theme->getEngine()) {
         $prefixes[] = $theme->getEngine() . '_engine';
     }
     $prefixes[] = $theme->getName();
     // Collect all variable preprocess functions in the correct order.
     $suggestion_level = [];
     $matches = [];
     // Look for functions named according to the pattern and add them if they
     // have matching hooks in the registry.
     foreach ($prefixes as $prefix) {
         // Grep only the functions which are within the prefix group.
         list($first_prefix, ) = explode('_', $prefix, 2);
         if (!isset($grouped_functions[$first_prefix])) {
             continue;
         }
         // Add the function and the name of the associated theme hook to the list
         // of preprocess functions grouped by suggestion specificity if a matching
         // base hook is found.
         foreach ($grouped_functions[$first_prefix] as $candidate) {
             if (preg_match("/^{$prefix}_preprocess_(((?:[^_]++|_(?!_))+)__.*)/", $candidate, $matches)) {
                 if (isset($cache[$matches[2]])) {
                     $level = substr_count($matches[1], '__');
                     $suggestion_level[$level][$candidate] = $matches[1];
                 }
             }
         }
     }
     // Add missing variable preprocessors. This is needed for modules that do
     // not explicitly register the hook. For example, when a theme contains a
     // variable preprocess function but it does not implement a template, it
     // will go missing. This will add the expected function. It also allows
     // modules or themes to have a variable process function based on a pattern
     // even if the hook does not exist.
     ksort($suggestion_level);
     foreach ($suggestion_level as $level => $item) {
         foreach ($item as $preprocessor => $hook) {
             if (isset($cache[$hook]['preprocess functions']) && !in_array($hook, $cache[$hook]['preprocess functions'])) {
                 // Add missing preprocessor to existing hook.
                 $cache[$hook]['preprocess functions'][] = $preprocessor;
             } elseif (!isset($cache[$hook]) && strpos($hook, '__')) {
                 // Process non-existing hook and register it.
                 // Look for a previously defined hook that is either a less specific
                 // suggestion hook or the base hook.
                 $this->completeSuggestion($hook, $cache);
                 $cache[$hook]['preprocess functions'][] = $preprocessor;
             }
         }
     }
     // Inherit all base hook variable preprocess functions into suggestion
     // hooks. This ensures that derivative hooks have a complete set of variable
     // preprocess functions.
     foreach ($cache as $hook => $info) {
         // The 'base hook' is only applied to derivative hooks already registered
         // from a pattern. This is typically set from
         // drupal_find_theme_functions() and drupal_find_theme_templates().
         if (isset($info['incomplete preprocess functions'])) {
             $this->completeSuggestion($hook, $cache);
             unset($cache[$hook]['incomplete preprocess functions']);
         }
         // Optimize the registry.
         if (isset($cache[$hook]['preprocess functions']) && empty($cache[$hook]['preprocess functions'])) {
             unset($cache[$hook]['preprocess functions']);
         }
         // Ensure uniqueness.
         if (isset($cache[$hook]['preprocess functions'])) {
             $cache[$hook]['preprocess functions'] = array_unique($cache[$hook]['preprocess functions']);
         }
     }
 }
Esempio n. 21
0
 /**
  * Generates a report about config updates.
  *
  * @param string $report_type
  *   Type of report to generate: 'type', 'module', 'theme', or 'profile'.
  * @param string $value
  *   Machine name of a configuration type, module, or theme to generate the
  *   report for. Ignored for profile, since that uses the active profile.
  *
  * @return array
  *   Render array for the updates report. Empty if invalid or missing
  *   report type or value.
  */
 protected function generateReport($report_type, $value)
 {
     // Figure out what to name the report, and incidentally, validate that
     // $value exists for this type of report.
     switch ($report_type) {
         case 'type':
             if ($value == 'system.all') {
                 $label = $this->t('All configuration');
             } elseif ($value == 'system.simple') {
                 $label = $this->t('Simple configuration');
             } else {
                 $definition = $this->configList->getType($value);
                 if (!$definition) {
                     return NULL;
                 }
                 $label = $this->t('@name configuration', array('@name' => $definition->getLabel()));
             }
             break;
         case 'module':
             $list = $this->moduleHandler->getModuleList();
             if (!isset($list[$value])) {
                 return NULL;
             }
             $label = $this->t('@name module', array('@name' => $this->moduleHandler->getName($value)));
             break;
         case 'theme':
             $list = $this->themeHandler->listInfo();
             if (!isset($list[$value])) {
                 return NULL;
             }
             $label = $this->t('@name theme', array('@name' => $this->themeHandler->getName($value)));
             break;
         case 'profile':
             $profile = Settings::get('install_profile');
             $label = $this->t('@name profile', array('@name' => $this->moduleHandler->getName($profile)));
             break;
         default:
             return NULL;
     }
     // List the active and extension-provided config.
     list($active_list, $install_list, $optional_list) = $this->configList->listConfig($report_type, $value);
     // Build the report.
     $build = array();
     $build['#title'] = $this->t('Configuration updates report for @label', array('@label' => $label));
     $build['report_header'] = array('#markup' => '<h3>' . $this->t('Updates report') . '</h3>');
     // List items missing from site.
     $removed = array_diff($install_list, $active_list);
     $build['removed'] = array('#caption' => $this->t('Missing configuration items'), '#empty' => $this->t('None: all provided configuration items are in your active configuration.')) + $this->makeReportTable($removed, 'extension', array('import'));
     // List optional items that are not installed.
     $inactive = array_diff($optional_list, $active_list);
     $build['inactive'] = array('#caption' => $this->t('Inactive optional items'), '#empty' => $this->t('None: all optional configuration items are in your active configuration.')) + $this->makeReportTable($inactive, 'extension', array('import'));
     // List items added to site, which only makes sense in the report for a
     // config type.
     $added = array_diff($active_list, $install_list, $optional_list);
     if ($report_type == 'type') {
         $build['added'] = array('#caption' => $this->t('Added configuration items'), '#empty' => $this->t('None: all active configuration items of this type were provided by modules, themes, or install profile.')) + $this->makeReportTable($added, 'active', array('export', 'delete'));
     }
     // For differences, we need to go through the array of config in both
     // and see if each config item is the same or not.
     $both = array_diff($active_list, $added);
     $different = array();
     foreach ($both as $name) {
         if (!$this->configDiff->same($this->configRevert->getFromExtension('', $name), $this->configRevert->getFromActive('', $name))) {
             $different[] = $name;
         }
     }
     $build['different'] = array('#caption' => $this->t('Changed configuration items'), '#empty' => $this->t('None: no active configuration items differ from their current provided versions.')) + $this->makeReportTable($different, 'active', array('diff', 'export', 'revert'));
     return $build;
 }
Esempio n. 22
0
 /**
  * {@inheritdoc}
  */
 public function uninstall(array $module_list, $uninstall_dependents = TRUE)
 {
     // Get all module data so we can find dependencies and sort.
     $module_data = system_rebuild_module_data();
     $module_list = $module_list ? array_combine($module_list, $module_list) : array();
     if (array_diff_key($module_list, $module_data)) {
         // One or more of the given modules doesn't exist.
         return FALSE;
     }
     $extension_config = \Drupal::configFactory()->getEditable('core.extension');
     $installed_modules = $extension_config->get('module') ?: array();
     if (!($module_list = array_intersect_key($module_list, $installed_modules))) {
         // Nothing to do. All modules already uninstalled.
         return TRUE;
     }
     if ($uninstall_dependents) {
         // Add dependent modules to the list. The new modules will be processed as
         // the while loop continues.
         $profile = drupal_get_profile();
         while (list($module) = each($module_list)) {
             foreach (array_keys($module_data[$module]->required_by) as $dependent) {
                 if (!isset($module_data[$dependent])) {
                     // The dependent module does not exist.
                     return FALSE;
                 }
                 // Skip already uninstalled modules.
                 if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent]) && $dependent != $profile) {
                     $module_list[$dependent] = $dependent;
                 }
             }
         }
     }
     // Use the validators and throw an exception with the reasons.
     if ($reasons = $this->validateUninstall($module_list)) {
         foreach ($reasons as $reason) {
             $reason_message[] = implode(', ', $reason);
         }
         throw new ModuleUninstallValidatorException(format_string('The following reasons prevents the modules from being uninstalled: @reasons', array('@reasons' => implode(', ', $reason_message))));
     }
     // Set the actual module weights.
     $module_list = array_map(function ($module) use($module_data) {
         return $module_data[$module]->sort;
     }, $module_list);
     // Sort the module list by their weights.
     asort($module_list);
     $module_list = array_keys($module_list);
     // Only process modules that are enabled. A module is only enabled if it is
     // configured as enabled. Custom or overridden module handlers might contain
     // the module already, which means that it might be loaded, but not
     // necessarily installed.
     foreach ($module_list as $module) {
         // Clean up all entity bundles (including fields) of every entity type
         // provided by the module that is being uninstalled.
         // @todo Clean this up in https://www.drupal.org/node/2350111.
         $entity_manager = \Drupal::entityManager();
         foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) {
             if ($entity_type->getProvider() == $module) {
                 foreach (array_keys($entity_manager->getBundleInfo($entity_type_id)) as $bundle) {
                     $entity_manager->onBundleDelete($bundle, $entity_type_id);
                 }
             }
         }
         // Allow modules to react prior to the uninstallation of a module.
         $this->moduleHandler->invokeAll('module_preuninstall', array($module));
         // Uninstall the module.
         module_load_install($module);
         $this->moduleHandler->invoke($module, 'uninstall');
         // Remove all configuration belonging to the module.
         \Drupal::service('config.manager')->uninstall('module', $module);
         // Notify interested components that this module's entity types are being
         // deleted. For example, a SQL-based storage handler can use this as an
         // opportunity to drop the corresponding database tables.
         // @todo Clean this up in https://www.drupal.org/node/2350111.
         foreach ($entity_manager->getDefinitions() as $entity_type) {
             if ($entity_type->getProvider() == $module) {
                 $entity_manager->onEntityTypeDelete($entity_type);
             }
         }
         // Remove the schema.
         drupal_uninstall_schema($module);
         // Remove the module's entry from the config.
         \Drupal::configFactory()->getEditable('core.extension')->clear("module.{$module}")->save();
         // Update the module handler to remove the module.
         // The current ModuleHandler instance is obsolete with the kernel rebuild
         // below.
         $module_filenames = $this->moduleHandler->getModuleList();
         unset($module_filenames[$module]);
         $this->moduleHandler->setModuleList($module_filenames);
         // Remove any potential cache bins provided by the module.
         $this->removeCacheBins($module);
         // Clear the static cache of system_rebuild_module_data() to pick up the
         // new module, since it merges the installation status of modules into
         // its statically cached list.
         drupal_static_reset('system_rebuild_module_data');
         // Clear plugin manager caches.
         \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
         // Update the kernel to exclude the uninstalled modules.
         $this->updateKernel($module_filenames);
         // Update the theme registry to remove the newly uninstalled module.
         drupal_theme_rebuild();
         // Modules can alter theme info, so refresh theme data.
         // @todo ThemeHandler cannot be injected into ModuleHandler, since that
         //   causes a circular service dependency.
         // @see https://drupal.org/node/2208429
         \Drupal::service('theme_handler')->refreshInfo();
         \Drupal::logger('system')->info('%module module uninstalled.', array('%module' => $module));
         $schema_store = \Drupal::keyValue('system.schema');
         $schema_store->delete($module);
     }
     \Drupal::service('router.builder')->setRebuildNeeded();
     drupal_get_installed_schema_version(NULL, TRUE);
     // Let other modules react.
     $this->moduleHandler->invokeAll('modules_uninstalled', array($module_list));
     // Flush all persistent caches.
     // Any cache entry might implicitly depend on the uninstalled modules,
     // so clear all of them explicitly.
     $this->moduleHandler->invokeAll('cache_flush');
     foreach (Cache::getBins() as $service_id => $cache_backend) {
         $cache_backend->deleteAll();
     }
     return TRUE;
 }
Esempio n. 23
0
 /**
  * Process a single implementation of hook_theme().
  *
  * @param $cache
  *   The theme registry that will eventually be cached; It is an associative
  *   array keyed by theme hooks, whose values are associative arrays
  *   describing the hook:
  *   - 'type': The passed-in $type.
  *   - 'theme path': The passed-in $path.
  *   - 'function': The name of the function generating output for this theme
  *     hook. Either defined explicitly in hook_theme() or, if neither
  *     'function' nor 'template' is defined, then the default theme function
  *     name is used. The default theme function name is the theme hook
  *     prefixed by either 'theme_' for modules or '$name_' for everything
  *     else. If 'function' is defined, 'template' is not used.
  *   - 'template': The filename of the template generating output for this
  *     theme hook. The template is in the directory defined by the 'path' key
  *     of hook_theme() or defaults to "$path/templates".
  *   - 'variables': The variables for this theme hook as defined in
  *     hook_theme(). If there is more than one implementation and 'variables'
  *     is not specified in a later one, then the previous definition is kept.
  *   - 'render element': The renderable element for this theme hook as defined
  *     in hook_theme(). If there is more than one implementation and
  *     'render element' is not specified in a later one, then the previous
  *     definition is kept.
  *   - 'preprocess functions': See _theme() for detailed documentation.
  * @param string $name
  *   The name of the module, theme engine, base theme engine, theme or base
  *   theme implementing hook_theme().
  * @param string $type
  *   One of 'module', 'theme_engine', 'base_theme_engine', 'theme', or
  *   'base_theme'. Unlike regular hooks that can only be implemented by
  *   modules, each of these can implement hook_theme(). This function is
  *   called in aforementioned order and new entries override older ones. For
  *   example, if a theme hook is both defined by a module and a theme, then
  *   the definition in the theme will be used.
  * @param \stdClass $theme
  *   The loaded $theme object as returned from list_themes().
  * @param string $path
  *   The directory where $name is. For example, modules/system or
  *   themes/bartik.
  *
  * @see _theme()
  * @see hook_theme()
  * @see list_themes()
  */
 protected function processExtension(&$cache, $name, $type, $theme, $path)
 {
     $result = array();
     $hook_defaults = array('variables' => TRUE, 'render element' => TRUE, 'pattern' => TRUE, 'base hook' => TRUE);
     $module_list = array_keys((array) $this->moduleHandler->getModuleList());
     // Invoke the hook_theme() implementation, preprocess what is returned, and
     // merge it into $cache.
     $function = $name . '_theme';
     if (function_exists($function)) {
         $result = $function($cache, $type, $theme, $path);
         foreach ($result as $hook => $info) {
             // When a theme or engine overrides a module's theme function
             // $result[$hook] will only contain key/value pairs for information being
             // overridden.  Pull the rest of the information from what was defined by
             // an earlier hook.
             // Fill in the type and path of the module, theme, or engine that
             // implements this theme function.
             $result[$hook]['type'] = $type;
             $result[$hook]['theme path'] = $path;
             // If function and file are omitted, default to standard naming
             // conventions.
             if (!isset($info['template']) && !isset($info['function'])) {
                 $result[$hook]['function'] = ($type == 'module' ? 'theme_' : $name . '_') . $hook;
             }
             if (isset($cache[$hook]['includes'])) {
                 $result[$hook]['includes'] = $cache[$hook]['includes'];
             }
             // If the theme implementation defines a file, then also use the path
             // that it defined. Otherwise use the default path. This allows
             // system.module to declare theme functions on behalf of core .include
             // files.
             if (isset($info['file'])) {
                 $include_file = isset($info['path']) ? $info['path'] : $path;
                 $include_file .= '/' . $info['file'];
                 include_once DRUPAL_ROOT . '/' . $include_file;
                 $result[$hook]['includes'][] = $include_file;
             }
             // If the default keys are not set, use the default values registered
             // by the module.
             if (isset($cache[$hook])) {
                 $result[$hook] += array_intersect_key($cache[$hook], $hook_defaults);
             }
             // The following apply only to theming hooks implemented as templates.
             if (isset($info['template'])) {
                 // Prepend the current theming path when none is set.
                 if (!isset($info['path'])) {
                     $result[$hook]['template'] = $path . '/templates/' . $info['template'];
                 }
             }
             // Preprocess variables for all theming hooks, whether the hook is
             // implemented as a template or as a function. Ensure they are arrays.
             if (!isset($info['preprocess functions']) || !is_array($info['preprocess functions'])) {
                 $info['preprocess functions'] = array();
                 $prefixes = array();
                 if ($type == 'module') {
                     // Default variable preprocessor prefix.
                     $prefixes[] = 'template';
                     // Add all modules so they can intervene with their own variable
                     // preprocessors. This allows them to provide variable preprocessors
                     // even if they are not the owner of the current hook.
                     $prefixes = array_merge($prefixes, $module_list);
                 } elseif ($type == 'theme_engine' || $type == 'base_theme_engine') {
                     // Theme engines get an extra set that come before the normally
                     // named variable preprocessors.
                     $prefixes[] = $name . '_engine';
                     // The theme engine registers on behalf of the theme using the
                     // theme's name.
                     $prefixes[] = $theme;
                 } else {
                     // This applies when the theme manually registers their own variable
                     // preprocessors.
                     $prefixes[] = $name;
                 }
                 foreach ($prefixes as $prefix) {
                     // Only use non-hook-specific variable preprocessors for theming
                     // hooks implemented as templates. See _theme().
                     if (isset($info['template']) && function_exists($prefix . '_preprocess')) {
                         $info['preprocess functions'][] = $prefix . '_preprocess';
                     }
                     if (function_exists($prefix . '_preprocess_' . $hook)) {
                         $info['preprocess functions'][] = $prefix . '_preprocess_' . $hook;
                     }
                 }
             }
             // Check for the override flag and prevent the cached variable
             // preprocessors from being used. This allows themes or theme engines
             // to remove variable preprocessors set earlier in the registry build.
             if (!empty($info['override preprocess functions'])) {
                 // Flag not needed inside the registry.
                 unset($result[$hook]['override preprocess functions']);
             } elseif (isset($cache[$hook]['preprocess functions']) && is_array($cache[$hook]['preprocess functions'])) {
                 $info['preprocess functions'] = array_merge($cache[$hook]['preprocess functions'], $info['preprocess functions']);
             }
             $result[$hook]['preprocess functions'] = $info['preprocess functions'];
         }
         // Merge the newly created theme hooks into the existing cache.
         $cache = $result + $cache;
     }
     // Let themes have variable preprocessors even if they didn't register a
     // template.
     if ($type == 'theme' || $type == 'base_theme') {
         foreach ($cache as $hook => $info) {
             // Check only if not registered by the theme or engine.
             if (empty($result[$hook])) {
                 if (!isset($info['preprocess functions'])) {
                     $cache[$hook]['preprocess functions'] = array();
                 }
                 // Only use non-hook-specific variable preprocessors for theme hooks
                 // implemented as templates. See _theme().
                 if (isset($info['template']) && function_exists($name . '_preprocess')) {
                     $cache[$hook]['preprocess functions'][] = $name . '_preprocess';
                 }
                 if (function_exists($name . '_preprocess_' . $hook)) {
                     $cache[$hook]['preprocess functions'][] = $name . '_preprocess_' . $hook;
                     $cache[$hook]['theme path'] = $path;
                 }
                 // Ensure uniqueness.
                 $cache[$hook]['preprocess functions'] = array_unique($cache[$hook]['preprocess functions']);
             }
         }
     }
 }