function ThemeInstaller::install
Same name in other branches
- 9 core/lib/Drupal/Core/Extension/ThemeInstaller.php \Drupal\Core\Extension\ThemeInstaller::install()
- 8.9.x core/lib/Drupal/Core/Extension/ThemeInstaller.php \Drupal\Core\Extension\ThemeInstaller::install()
- 10 core/lib/Drupal/Core/Extension/ThemeInstaller.php \Drupal\Core\Extension\ThemeInstaller::install()
Overrides ThemeInstallerInterface::install
File
-
core/
lib/ Drupal/ Core/ Extension/ ThemeInstaller.php, line 124
Class
- ThemeInstaller
- Manages theme installation/uninstallation.
Namespace
Drupal\Core\ExtensionCode
public function install(array $theme_list, $install_dependencies = TRUE) {
$extension_config = $this->configFactory
->getEditable('core.extension');
$theme_data = $this->themeExtensionList
->reset()
->getList();
$installed_themes = $extension_config->get('theme') ?: [];
$installed_modules = $extension_config->get('module') ?: [];
if ($install_dependencies) {
$theme_list = array_combine($theme_list, $theme_list);
if ($missing = array_diff_key($theme_list, $theme_data)) {
// One or more of the given themes doesn't exist.
throw new UnknownExtensionException('Unknown themes: ' . implode(', ', $missing) . '.');
}
// Only process themes that are not installed currently.
if (!($theme_list = array_diff_key($theme_list, $installed_themes))) {
// Nothing to do. All themes already installed.
return TRUE;
}
$module_list = $this->moduleExtensionList
->getList();
foreach ($theme_list as $theme => $value) {
$module_dependencies = $theme_data[$theme]->module_dependencies;
// $theme_data[$theme]->requires contains both theme and module
// dependencies keyed by the extension machine names.
// $theme_data[$theme]->module_dependencies contains only the module
// dependencies keyed by the module extension machine name. Therefore,
// we can find the theme dependencies by finding array keys for
// 'requires' that are not in $module_dependencies.
$theme_dependencies = array_diff_key($theme_data[$theme]->requires, $module_dependencies);
// We can find the unmet module dependencies by finding the module
// machine names keys that are not in $installed_modules keys.
$unmet_module_dependencies = array_diff_key($module_dependencies, $installed_modules);
if ($theme_data[$theme]->info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::DEPRECATED) {
// phpcs:ignore Drupal.Semantics.FunctionTriggerError
@trigger_error("The theme '{$theme}' is deprecated. See " . $theme_data[$theme]->info['lifecycle_link'], E_USER_DEPRECATED);
}
// Prevent themes with unmet module dependencies from being installed.
if (!empty($unmet_module_dependencies)) {
$unmet_module_dependencies_list = implode(', ', array_keys($unmet_module_dependencies));
throw new MissingDependencyException("Unable to install theme: '{$theme}' due to unmet module dependencies: '{$unmet_module_dependencies_list}'.");
}
foreach ($module_dependencies as $dependency => $dependency_object) {
if ($incompatible = $this->checkDependencyMessage($module_list, $dependency, $dependency_object)) {
$sanitized_message = Html::decodeEntities(strip_tags($incompatible));
throw new MissingDependencyException("Unable to install theme: {$sanitized_message}");
}
}
// Add dependencies to the list of themes to install. The new themes
// will be processed as the parent foreach loop continues.
foreach (array_keys($theme_dependencies) as $dependency) {
if (!isset($theme_data[$dependency])) {
// The dependency does not exist.
return FALSE;
}
// Skip already installed themes.
if (!isset($theme_list[$dependency]) && !isset($installed_themes[$dependency])) {
$theme_list[$dependency] = $dependency;
}
}
}
// Set the actual theme weights.
$theme_list = array_map(function ($theme) use ($theme_data) {
return $theme_data[$theme]->sort;
}, $theme_list);
// Sort the theme list by their weights (reverse).
arsort($theme_list);
$theme_list = array_keys($theme_list);
}
$themes_installed = [];
foreach ($theme_list as $key) {
// Only process themes that are not already installed.
$installed = $extension_config->get("theme.{$key}") !== NULL;
if ($installed) {
continue;
}
// Throw an exception if the theme name is too long.
if (strlen($key) > DRUPAL_EXTENSION_NAME_MAX_LENGTH) {
throw new ExtensionNameLengthException("Theme name {$key} is over the maximum allowed length of " . DRUPAL_EXTENSION_NAME_MAX_LENGTH . ' characters.');
}
// Throw an exception if a module with the same name is enabled.
$installed_modules = $extension_config->get('module') ?: [];
if (isset($installed_modules[$key])) {
throw new ExtensionNameReservedException("Theme name {$key} is already in use by an installed module.");
}
// Validate default configuration of the theme. If there is existing
// configuration then stop installing.
$this->configInstaller
->checkConfigurationToInstall('theme', $key);
// The value is not used; the weight is ignored for themes currently. Do
// not check schema when saving the configuration.
$extension_config->set("theme.{$key}", 0)
->save(TRUE);
// Reset theme settings.
$theme_settings =& drupal_static('theme_get_setting');
unset($theme_settings[$key]);
// Reset theme listing.
$this->themeHandler
->reset();
// Only install default configuration if this theme has not been installed
// already.
if (!isset($installed_themes[$key])) {
// Install default configuration of the theme.
$this->configInstaller
->installDefaultConfig('theme', $key);
}
$themes_installed[] = $key;
// Record the fact that it was installed.
$this->logger
->info('%theme theme installed.', [
'%theme' => $key,
]);
}
$this->cssCollectionOptimizer
->deleteAll();
$this->resetSystem();
// Invoke hook_themes_installed() after the themes have been installed.
$this->moduleHandler
->invokeAll('themes_installed', [
$themes_installed,
]);
return !empty($themes_installed);
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.