diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc index b98d28a..994a662 100644 --- a/core/includes/theme.maintenance.inc +++ b/core/includes/theme.maintenance.inc @@ -6,6 +6,7 @@ */ use Drupal\Component\Utility\Unicode; +use Drupal\Core\Theme\MissingThemeDependencyException; use Drupal\Core\Site\Settings; /** @@ -92,9 +93,21 @@ function _drupal_maintenance_theme() { $theme_handler->addTheme($themes[$ancestor]); } } + // Ensure that at least the maintenance page has a working theme where all of + // the parent themes have been enabled. + $get_active_theme = function () use ($theme_init, $themes, $theme_handler, $custom_theme, &$get_active_theme) { + try { + return $theme_init->getActiveTheme($themes[$custom_theme]); + } + catch (MissingThemeDependencyException $e) { + $theme_handler->install([$e->theme]); + $themes = $theme_handler->rebuildThemeData(); + return $get_active_theme(); + } + }; // @todo This is just a workaround. Find a better way how to handle themes // on maintenance pages, see https://www.drupal.org/node/2322619. - \Drupal::theme()->setActiveTheme($theme_init->getActiveTheme($themes[$custom_theme], array_reverse($base_theme))); + \Drupal::theme()->setActiveTheme($get_active_theme(), array_reverse($base_theme)); // Prime the theme registry. Drupal::service('theme.registry'); } diff --git a/core/lib/Drupal/Core/Theme/MissingThemeDependencyException.php b/core/lib/Drupal/Core/Theme/MissingThemeDependencyException.php new file mode 100644 index 0000000..b28b652 --- /dev/null +++ b/core/lib/Drupal/Core/Theme/MissingThemeDependencyException.php @@ -0,0 +1,24 @@ +theme = $theme; + } + +} diff --git a/core/lib/Drupal/Core/Theme/ThemeInitialization.php b/core/lib/Drupal/Core/Theme/ThemeInitialization.php index 95f27a9..af4b2c6 100644 --- a/core/lib/Drupal/Core/Theme/ThemeInitialization.php +++ b/core/lib/Drupal/Core/Theme/ThemeInitialization.php @@ -109,6 +109,9 @@ public function getActiveThemeByName($theme_name) { $ancestor = $theme_name; while ($ancestor && isset($themes[$ancestor]->base_theme)) { $ancestor = $themes[$ancestor]->base_theme; + if (!$this->themeHandler->themeExists($ancestor)) { + throw new MissingThemeDependencyException(sprintf('Base theme %s has not been installed.', $ancestor), $ancestor); + } $base_themes[] = $themes[$ancestor]; } diff --git a/core/lib/Drupal/Core/Theme/ThemeInitializationInterface.php b/core/lib/Drupal/Core/Theme/ThemeInitializationInterface.php index f2b1547..cd5c1be 100644 --- a/core/lib/Drupal/Core/Theme/ThemeInitializationInterface.php +++ b/core/lib/Drupal/Core/Theme/ThemeInitializationInterface.php @@ -34,6 +34,9 @@ public function initTheme($theme_name); * * @return \Drupal\Core\Theme\ActiveTheme * An active theme object instance for the given theme. + * + * @throws \Drupal\Core\Theme\MissingThemeDependencyException + * Thrown when base theme for installed theme is not installed. */ public function getActiveThemeByName($theme_name); diff --git a/core/modules/config/src/Tests/ConfigImportInstallProfileTest.php b/core/modules/config/src/Tests/ConfigImportInstallProfileTest.php index 19ef2ee..e15d3ac 100644 --- a/core/modules/config/src/Tests/ConfigImportInstallProfileTest.php +++ b/core/modules/config/src/Tests/ConfigImportInstallProfileTest.php @@ -67,6 +67,7 @@ public function testInstallProfileValidation() { $core['module']['testing_config_import'] = 0; unset($core['module']['syslog']); unset($core['theme']['stark']); + $core['theme']['stable'] = 0; $core['theme']['classy'] = 0; $sync->write('core.extension', $core); $sync->deleteAll('syslog.'); diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 3d9f129..7d18d4f 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -22,6 +22,7 @@ use Drupal\Core\Extension\ModuleHandler; use Drupal\Core\Url; use Drupal\Core\Block\BlockPluginInterface; +use Drupal\Core\Theme\MissingThemeDependencyException; use Drupal\user\UserInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use GuzzleHttp\Exception\RequestException; @@ -524,8 +525,25 @@ function system_page_attachments(array &$page) { $page['#attached']['library'][] = 'system/admin'; } + // Band-aid. + /** @var \Drupal\Core\Theme\ThemeManagerInterface $theme_manager */ + $theme_manager = \Drupal::theme(); + /** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */ + $theme_handler = \Drupal::service('theme_handler'); + $get_active_theme = function () use ($theme_manager, $theme_handler, &$get_active_theme) { + try { + $active_theme = $theme_manager->getActiveTheme(); + return $active_theme; + } + catch (MissingThemeDependencyException $e) { + $theme_handler->install([$e->theme]); + $themes = $theme_handler->rebuildThemeData(); + return $get_active_theme(); + } + }; + // Attach libraries used by this theme. - $active_theme = \Drupal::theme()->getActiveTheme(); + $active_theme = $get_active_theme(); foreach ($active_theme->getLibraries() as $library) { $page['#attached']['library'][] = $library; } diff --git a/core/themes/classy/classy.info.yml b/core/themes/classy/classy.info.yml index fb5cb3e..7e74173 100644 --- a/core/themes/classy/classy.info.yml +++ b/core/themes/classy/classy.info.yml @@ -4,7 +4,6 @@ description: 'A base theme with sensible default CSS classes added. Learn how to package: Core version: VERSION core: 8.x -base theme: false libraries: - classy/base