diff --git a/core/includes/common.inc b/core/includes/common.inc index d18c0c1..a002e45 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3635,11 +3635,19 @@ function drupal_prepare_page($page) { drupal_set_page_content($page); $page = element_info('page'); } + // Special front controllers (like install.php and update.php) are returning a + // proper #type 'page' render array (in order to set a custom #theme template), + // so just ensure that #type 'page' is complete. + elseif (isset($page['#type']) && $page['#type'] === 'page') { + $page += element_info('page'); + } // Modules can add elements to $page as needed in hook_page_build(). - foreach (\Drupal::moduleHandler()->getImplementations('page_build') as $module) { - $function = $module . '_page_build'; - $function($page); + if (!defined('MAINTENANCE_MODE')) { + foreach (\Drupal::moduleHandler()->getImplementations('page_build') as $module) { + $function = $module . '_page_build'; + $function($page); + } } // Modules alter the $page as needed. Blocks are populated into regions like // 'sidebar_first', 'footer', etc. @@ -3662,7 +3670,7 @@ function drupal_prepare_page($page) { // If no module has taken care of the main content, add it to the page now. // This allows the site to still be usable even if no modules that // control page regions (for example, the Block module) are enabled. - if (!$main_content_display) { + if (!$main_content_display && !isset($page['content']['system_main'])) { $page['content']['system_main'] = drupal_set_page_content(); } diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 8d27e08..de4069e 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -9,11 +9,13 @@ use Drupal\Core\Database\Database; use Drupal\Core\Database\DatabaseExceptionWrapper; use Drupal\Core\Database\Install\TaskException; +use Drupal\Core\Extension\InfoParser; use Drupal\Core\Installer\Exception\AlreadyInstalledException; use Drupal\Core\Installer\Exception\InstallerException; use Drupal\Core\Installer\Exception\NoProfilesException; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManager; +use Drupal\Core\Page\HtmlPage; use Drupal\Core\StringTranslation\Translator\FileTranslation; use Drupal\Core\Extension\ExtensionDiscovery; use Drupal\Core\DependencyInjection\ContainerBuilder; @@ -299,6 +301,7 @@ function install_begin_request(&$install_state) { require_once __DIR__ . '/form.inc'; require_once __DIR__ . '/batch.inc'; require_once __DIR__ . '/ajax.inc'; + require_once __DIR__ . '/menu.inc'; // Load module basics (needed for hook invokes). include_once __DIR__ . '/module.inc'; @@ -344,19 +347,47 @@ function install_begin_request(&$install_state) { } } + // Add list of all available profiles to the installation state. + $listing = new ExtensionDiscovery(); + $listing->setProfileDirectories(array()); + $install_state['profiles'] += $listing->scan('profile'); + + // Prime drupal_get_filename()'s static cache. + foreach ($install_state['profiles'] as $name => $profile) { + drupal_get_filename('profile', $name, $profile->uri); + } + + $container->set('info_parser', new InfoParser()); + if ($profile = _install_select_profile($install_state)) { + $install_state['parameters']['profile'] = $profile; + install_load_profile($install_state); + if (isset($install_state['profile_info']['distribution']['install']['theme'])) { + $install_state['theme'] = $install_state['profile_info']['distribution']['install']['theme']; + } + } + // Replace services with in-memory and null implementations. This kernel is // replaced with a regular one in drupal_install_system(). if (!$install_state['base_system_verified']) { - $environment = 'install'; $GLOBALS['conf']['container_service_providers']['InstallerServiceProvider'] = 'Drupal\Core\Installer\InstallerServiceProvider'; + $kernel = new DrupalKernel('install', drupal_classloader(), FALSE); + $module_list['system'] = 'core/modules/system/system.module'; + $kernel->updateModules($module_list, $module_list); } else { - $environment = 'prod'; + $kernel = new DrupalKernel('prod', drupal_classloader(), FALSE); } - - $kernel = new DrupalKernel($environment, drupal_classloader(), FALSE); $kernel->boot(); + // Override the module list with a minimal set of modules. + $module_handler = \Drupal::moduleHandler(); + if ($profile && !$module_handler->moduleExists($profile)) { + $module_list = $module_handler->getModuleList(); + $module_list[$profile] = $install_state['profiles'][$profile]->uri; + $module_handler->setModuleList($module_list); + $kernel->updateModules($module_list, $module_list); + } + // Enter the request scope and add the Request. // @todo Remove this after converting all installer screens into controllers. $container = $kernel->getContainer(); @@ -379,38 +410,7 @@ function install_begin_request(&$install_state) { \Drupal::translation()->setDefaultLangcode($install_state['parameters']['langcode']); } - // Add list of all available profiles to the installation state. - $listing = new ExtensionDiscovery(); - $listing->setProfileDirectories(array()); - $install_state['profiles'] += $listing->scan('profile'); - - // Prime drupal_get_filename()'s static cache. - foreach ($install_state['profiles'] as $name => $profile) { - drupal_get_filename('profile', $name, $profile->uri); - } - - if ($profile = _install_select_profile($install_state)) { - $install_state['parameters']['profile'] = $profile; - install_load_profile($install_state); - if (isset($install_state['profile_info']['distribution']['install']['theme'])) { - $install_state['theme'] = $install_state['profile_info']['distribution']['install']['theme']; - } - } - - // Override the module list with a minimal set of modules. - $module_handler = \Drupal::moduleHandler(); - $module_list = $module_handler->getModuleList(); - if (!$module_handler->moduleExists('system')) { - $module_list['system'] = 'core/modules/system/system.module'; - } - if ($profile && !$module_handler->moduleExists($profile)) { - $module_list[$profile] = $install_state['profiles'][$profile]->uri; - } - $module_handler->setModuleList($module_list); - // After setting up a custom and finite module list in a custom low-level - // bootstrap like here, ensure to use ModuleHandler::loadAll() so that - // ModuleHandler::isLoaded() returns TRUE, since that is a condition being - // checked by other subsystems (e.g., the theme system). + // _theme() requires all modules to be loaded. $module_handler->loadAll(); // Prepare for themed output. We need to run this at the beginning of the @@ -900,6 +900,15 @@ function install_display_output($output, $install_state) { ); drupal_add_html_head($noindex_meta_tag, 'install_meta_robots'); + $install_page = array( + '#type' => 'page', + '#theme' => 'install_page', + '#title' => $output['#title'], + 'content' => array( + 'system_main' => $output, + ), + ); + // Only show the task list if there is an active task; otherwise, the page // request has ended before tasks have even been started, so there is nothing // meaningful to show. @@ -913,20 +922,20 @@ function install_display_output($output, $install_state) { '#active' => $active_task, '#variant' => 'install', ); - drupal_add_region_content('sidebar_first', drupal_render($task_list)); + $install_page['sidebar_first'] = $task_list; } - $install_page = array( - '#theme' => 'install_page', - // $output has to be rendered here, because the install page template is not - // wrapped into the html template, which means that any #attached libraries - // in $output will not be loaded, because the wrapping HTML has been printed - // already. - '#content' => drupal_render($output), - ); - if (isset($output['#title'])) { - $install_page['#page']['#title'] = $output['#title']; - } - print drupal_render($install_page); + + // @see \Drupal\Core\Page\DefaultHtmlFragmentRenderer::render() + // @see \Drupal\system\Controller\BatchController::render() + $page = new HtmlPage('', array(), $output['#title']); + $page_array = drupal_prepare_page($install_page); + + $page = \Drupal::service('html_fragment_renderer')->preparePage($page, $page_array); + $page->setBodyTop(drupal_render($page_array['page_top'])); + $page->setBodyBottom(drupal_render($page_array['page_bottom'])); + $page->setContent(drupal_render($page_array)); + + print \Drupal::service('html_page_renderer')->render($page); exit; } diff --git a/core/includes/theme.inc b/core/includes/theme.inc index cfd8427..d1c13f9 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1967,9 +1967,6 @@ function template_preprocess_html(&$variables) { } } - // Initializes attributes which are specific to the html and body elements. - $variables['html_attributes'] = new Attribute; - // HTML element attributes. $language_interface = \Drupal::service('language_manager')->getCurrentLanguage(); $variables['html_attributes']['lang'] = $language_interface->id; @@ -2088,10 +2085,12 @@ function template_preprocess_page(&$variables) { $variables['logo'] = theme_get_setting('logo.url'); $variables['main_menu'] = theme_get_setting('features.main_menu') ? menu_main_menu() : array(); $variables['secondary_menu'] = theme_get_setting('features.secondary_menu') ? menu_secondary_menu() : array(); - $variables['action_links'] = menu_get_local_actions(); $variables['site_name'] = (theme_get_setting('features.name') ? String::checkPlain($site_config->get('name')) : ''); $variables['site_slogan'] = (theme_get_setting('features.slogan') ? filter_xss_admin($site_config->get('slogan')) : ''); - $variables['tabs'] = menu_local_tabs(); + if (!defined('MAINTENANCE_MODE')) { + $variables['tabs'] = menu_local_tabs(); + $variables['action_links'] = menu_get_local_actions(); + } // Pass the main menu and secondary menu to the template as render arrays. if (!empty($variables['main_menu'])) { @@ -2132,10 +2131,12 @@ function template_preprocess_page(&$variables) { // re-use the cache of an already retrieved menu containing the active link // for the current page. // @see menu_tree_page_data() - $variables['breadcrumb'] = array( - '#theme' => 'breadcrumb', - '#breadcrumb' => \Drupal::service('breadcrumb')->build(\Drupal::request()->attributes->all()), - ); + if (!defined('MAINTENANCE_MODE')) { + $variables['breadcrumb'] = array( + '#theme' => 'breadcrumb', + '#breadcrumb' => \Drupal::service('breadcrumb')->build(\Drupal::request()->attributes->all()), + ); + } } /** @@ -2213,12 +2214,6 @@ function theme_get_suggestions($args, $base, $delimiter = '__') { * * Default template: maintenance-page.html.twig. * - * The variables array generated here is a mirror of - * template_preprocess_page(). This preprocessor will run its course when - * theme_maintenance_page() is invoked. An alternate template file of - * maintenance-page--offline.html.twig can be used when the database is offline - * to hide errors and completely replace the content. - * * @param array $variables * An associative array containing: * - content - An array of page content. @@ -2226,117 +2221,29 @@ function theme_get_suggestions($args, $base, $delimiter = '__') { * @see system_page_build() */ function template_preprocess_maintenance_page(&$variables) { - $language_interface = \Drupal::languageManager()->getCurrentLanguage(); - - // Initializes attributes which are specific to the html element. - $variables['html_attributes'] = new Attribute; - - // HTML element attributes. - $variables['html_attributes']['lang'] = $language_interface->id; - $variables['html_attributes']['dir'] = $language_interface->direction ? 'rtl' : 'ltr'; - - // Add favicon - if (theme_get_setting('features.favicon')) { - $favicon = theme_get_setting('favicon.url'); - $type = theme_get_setting('favicon.mimetype'); - $build['#attached']['drupal_add_html_head_link'][][] = array( - 'rel' => 'shortcut icon', - 'href' => UrlHelper::stripDangerousProtocols($favicon), - 'type' => $type, - ); - drupal_render($build); - } - - foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) { - if (!isset($variables[$region_key])) { - $variables[$region_key] = array(); - } - // Append region content set with drupal_add_region_content() as markup. - if ($region_content = drupal_get_region_content($region_key)) { - $variables[$region_key][]['#markup'] = $region_content; - } - } - - // Setup layout variable. - $variables['layout'] = 'none'; - if (!empty($variables['sidebar_first'])) { - $variables['layout'] = 'first'; - } - if (!empty($variables['sidebar_second'])) { - $variables['layout'] = ($variables['layout'] == 'first') ? 'both' : 'second'; - } - - $site_config = \Drupal::config('system.site'); - $site_name = $site_config->get('name'); - $site_slogan = $site_config->get('slogan'); - - // Construct the page title. - if (isset($variables['page']['#title'])) { - $head_title = array( - 'title' => strip_tags($variables['page']['#title']), - 'name' => String::checkPlain($site_config->get('name')), - ); - } - else { - $head_title = array('name' => String::checkPlain($site_name)); - if ($site_slogan) { - $head_title['slogan'] = strip_tags(filter_xss_admin($site_slogan)); - } - } - - // These are usually added from system_page_build() except maintenance.css. - // When the database is inactive it's not called so we add it here. - $default_css['library'][] = 'core/normalize'; - $default_css['library'][] = 'system/maintenance'; - $attached = array('#attached' => $default_css); - drupal_render($attached); - $variables['messages'] = array( - '#theme' => 'status_messages', - '#access' => $variables['show_messages'], - ); - - $variables['head_title_array'] = $head_title; - $variables['head_title'] = implode(' | ', $head_title); - $variables['front_page'] = url(); - $variables['help'] = ''; - $variables['language'] = $language_interface; - $variables['logo'] = theme_get_setting('logo.url'); - $variables['site_name'] = (theme_get_setting('features.name') ? String::checkPlain($site_name) : ''); - $variables['site_slogan'] = (theme_get_setting('features.slogan') ? filter_xss_admin($site_slogan) : ''); - - // Compile a list of classes that are going to be applied to the body element. - $variables['attributes']['class'][] = 'maintenance-page'; - $variables['attributes']['class'][] = 'in-maintenance'; + // @todo Rename the templates to page--maintenance + page--install. + template_preprocess_page($variables); + + $page_object = $variables['page']['#page']; + $attributes = $page_object->getBodyAttributes(); + $classes = $attributes['class']; + $classes[] = 'maintenance-page'; + $classes[] = 'in-maintenance'; if (isset($variables['db_is_active']) && !$variables['db_is_active']) { - $variables['attributes']['class'][] = 'db-offline'; + $classes[] = 'db-offline'; } - if ($variables['layout'] == 'both') { - $variables['attributes']['class'][] = 'two-sidebars'; - } - elseif ($variables['layout'] == 'none') { - $variables['attributes']['class'][] = 'no-sidebars'; - } - else { - $variables['attributes']['class'][] = 'one-sidebar'; - $variables['attributes']['class'][] = 'sidebar-' . $variables['layout']; - } - - $variables['head'] = drupal_get_html_head(); + $attributes['class'] = $classes; - // While this code is used in the installer, the language module may not be - // enabled yet (even maybe no database set up yet), but an RTL language - // selected should result in RTL stylesheets loaded properly already. - $css = _drupal_add_css(); - include_once DRUPAL_ROOT . '/core/modules/language/language.module'; - // Wrapping drupal_get_css() and drupal_get_js() in an object so they can - // be called when printed. - $variables['styles'] = new RenderWrapper('drupal_get_css', array($css)); - $variables['scripts'] = new RenderWrapper('drupal_get_js'); - - // Allow the page to define a title. - if (isset($variables['page']['#title'])) { - $variables['title'] = $variables['page']['#title']; - } + // @see system_page_build() + $attached = array( + '#attached' => array( + 'library' => array( + 'core/normalize', + 'system/maintenance', + ), + ), + ); + drupal_render($attached); } /** @@ -2344,20 +2251,21 @@ function template_preprocess_maintenance_page(&$variables) { * * Default template: install-page.html.twig. * - * The variables array generated here is a mirror of - * template_preprocess_page(). This preprocessor will run its course when - * theme_install_page() is invoked. - * * @param array $variables * An associative array containing: * - content - An array of page content. * * @see template_preprocess_maintenance_page() - * */ function template_preprocess_install_page(&$variables) { template_preprocess_maintenance_page($variables); - $variables['attributes']['class'][] = 'install-page'; + + $page_object = $variables['page']['#page']; + $attributes = $page_object->getBodyAttributes(); + $classes = $attributes['class']; + $classes[] = 'install-page'; + $attributes['class'] = $classes; + // Override the site name that is displayed on the page, since Drupal is // still in the process of being installed. $distribution_name = String::checkPlain(drupal_install_profile_distribution_name()); @@ -2472,11 +2380,11 @@ function drupal_common_theme() { ), // From theme.maintenance.inc. 'maintenance_page' => array( - 'variables' => array('content' => NULL, 'show_messages' => TRUE, 'page' => array()), + 'render element' => 'page', 'template' => 'maintenance-page', ), 'install_page' => array( - 'variables' => array('content' => NULL, 'show_messages' => TRUE, 'page' => array()), + 'render element' => 'page', 'template' => 'install-page', ), 'task_list' => array( diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc index 429b932..903c63f 100644 --- a/core/includes/theme.maintenance.inc +++ b/core/includes/theme.maintenance.inc @@ -30,6 +30,7 @@ function _drupal_maintenance_theme() { require_once __DIR__ . '/unicode.inc'; require_once __DIR__ . '/file.inc'; require_once __DIR__ . '/module.inc'; + require_once __DIR__ . '/database.inc'; Unicode::check(); // Install and update pages are treated differently to prevent theming overrides. @@ -42,13 +43,6 @@ function _drupal_maintenance_theme() { } } else { - // The bootstrap was not complete. So we are operating in a crippled - // environment, we need to bootstrap just enough to allow hook invocations - // to work. See _drupal_log_error(). - if (!class_exists('Drupal\Core\Database\Database', FALSE)) { - require_once __DIR__ . '/database.inc'; - } - // Use the maintenance theme if specified, otherwise attempt to use the // default site theme. try { diff --git a/core/modules/system/templates/install-page.html.twig b/core/modules/system/templates/install-page.html.twig index 031013e..ad1c04c 100644 --- a/core/modules/system/templates/install-page.html.twig +++ b/core/modules/system/templates/install-page.html.twig @@ -3,24 +3,14 @@ * @file * Default theme implementation to display a Drupal installation page. * - * All the available variables are mirrored in html.html.twig and - * page.html.twig. Some may be blank but they are provided for consistency. + * All available variables are mirrored in page.html.twig. + * Some may be blank but they are provided for consistency. * * @see template_preprocess_install_page() * * @ingroup themeable */ #} - - -
- {{ head }} -