From e9f52b4248a5268630b51ee0746dcf8b6449d445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Hojtsy?= Date: Fri, 30 Nov 2007 12:19:10 +0000 Subject: #141727 by merlinofchaos, dvessel, sun: restore themeability support for maintenance pages (regression) --- includes/bootstrap.inc | 38 ++--- includes/common.inc | 6 +- includes/database.inc | 8 + includes/install.inc | 1 - includes/theme.inc | 223 +++++++-------------------- includes/theme.maintenance.inc | 258 ++++++++++++++++++++++++++++++++ install.php | 2 + misc/maintenance.css | 23 --- misc/maintenance.tpl.php | 62 -------- modules/system/maintenance-page.tpl.php | 98 ++++++++++++ modules/system/maintenance.css | 23 +++ modules/system/system.module | 180 +++++++++++----------- sites/default/default.settings.php | 9 ++ themes/garland/maintenance-page.tpl.php | 91 +++++++++++ update.php | 6 +- 15 files changed, 658 insertions(+), 370 deletions(-) create mode 100644 includes/theme.maintenance.inc delete mode 100644 misc/maintenance.css delete mode 100644 misc/maintenance.tpl.php create mode 100644 modules/system/maintenance-page.tpl.php create mode 100644 modules/system/maintenance.css create mode 100644 themes/garland/maintenance-page.tpl.php diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index a8da6fcb2..5345d5926 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -369,7 +369,6 @@ function conf_init() { */ function drupal_get_filename($type, $name, $filename = NULL) { static $files = array(); - global $active_db; if (!isset($files[$type])) { $files[$type] = array(); @@ -385,7 +384,7 @@ function drupal_get_filename($type, $name, $filename = NULL) { // the database. This is required because this function is called both // before we have a database connection (i.e. during installation) and // when a database connection fails. - elseif ($active_db && (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file))) { + elseif (db_is_active() && (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file))) { $files[$type][$name] = $file; } else { @@ -971,35 +970,16 @@ function _drupal_bootstrap($phase) { } /** - * Enables use of the theme system without requiring database access. Since - * there is not database access no theme will be enabled and the default - * themeable functions will be called. Some themeable functions can not be used - * without the full Drupal API loaded. For example, theme_page() is - * unavailable and theme_maintenance_page() must be used in its place. + * Enables use of the theme system without requiring database access. + * + * Loads and initializes the theme system for site installs, updates and when + * the site is in off-line mode. This also applies when the database fails. + * + * @see _drupal_maintenance_theme() */ function drupal_maintenance_theme() { - global $theme; - require_once './includes/path.inc'; - require_once './includes/theme.inc'; - require_once './includes/common.inc'; - require_once './includes/unicode.inc'; - require_once './includes/file.inc'; - require_once './modules/filter/filter.module'; - unicode_check(); - drupal_add_css(drupal_get_path('module', 'system') .'/defaults.css', 'module'); - drupal_add_css(drupal_get_path('module', 'system') .'/system.css', 'module'); - drupal_add_css(drupal_get_path('module', 'system') .'/system-menus.css', 'module'); - $theme = ''; - - // Special case registry of theme functions used by the installer - $themes = drupal_common_themes(); - foreach ($themes as $hook => $info) { - if (!isset($info['file']) && !isset($info['function'])) { - $themes[$hook]['function'] = 'theme_'. $hook; - $themes[$hook]['theme path'] = 'misc'; - } - } - _theme_set_registry($themes); + require_once './includes/theme.maintenance.inc'; + _drupal_maintenance_theme(); } /** diff --git a/includes/common.inc b/includes/common.inc index 6455bdb71..4af694080 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -2865,7 +2865,7 @@ function element_children($element) { /** * Provide theme registration for themes across .inc files. */ -function drupal_common_themes() { +function drupal_common_theme() { return array( // theme.inc 'placeholder' => array( @@ -2876,6 +2876,10 @@ function drupal_common_themes() { 'template' => 'page', ), 'maintenance_page' => array( + 'arguments' => array('content' => NULL, 'show_blocks' => TRUE, 'show_messages' => TRUE), + 'template' => 'maintenance-page', + ), + 'update_page' => array( 'arguments' => array('content' => NULL, 'show_messages' => TRUE), ), 'install_page' => array( diff --git a/includes/database.inc b/includes/database.inc index 63536e036..917fbb830 100644 --- a/includes/database.inc +++ b/includes/database.inc @@ -163,6 +163,14 @@ function db_set_active($name = 'default') { return array_search($previous_db, $db_conns); } +/** + * Returns a boolean depending on the availability of the database. + */ +function db_is_active() { + global $active_db; + return !empty($active_db); +} + /** * Helper function for db_query(). */ diff --git a/includes/install.inc b/includes/install.inc index f034dda85..04f7939b0 100644 --- a/includes/install.inc +++ b/includes/install.inc @@ -615,7 +615,6 @@ function st($string, $args = array()) { } require_once './includes/theme.inc'; - $GLOBALS['theme'] = 'theme'; // Transform arguments before inserting them foreach ($args as $key => $value) { switch ($key[0]) { diff --git a/includes/theme.inc b/includes/theme.inc index 89825dba5..e0e10cafa 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -29,7 +29,7 @@ define('MARK_UPDATED', 2); * Initialize the theme system by loading the theme. */ function init_theme() { - global $theme, $user, $custom_theme, $theme_engine, $theme_key; + global $theme, $user, $custom_theme, $theme_key; // If $theme is already set, assume the others are set, too, and do nothing if (isset($theme)) { @@ -82,8 +82,10 @@ function init_theme() { * the same information as the $theme object. It should be in * 'oldest first' order, meaning the top level of the chain will * be first. + * @param $registry_callback + * The callback to invoke to set the theme registry. */ -function _init_theme($theme, $base_theme = array()) { +function _init_theme($theme, $base_theme = array(), $registry_callback = '_theme_load_registry') { global $theme_info, $base_theme_info, $theme_engine, $theme_path; $theme_info = $theme; $base_theme_info = $base_theme; @@ -174,7 +176,8 @@ function _init_theme($theme, $base_theme = array()) { include_once './'. $theme->owner; } } - _theme_load_registry($theme, $base_theme, $theme_engine); + + $registry_callback($theme, $base_theme, $theme_engine); } /** @@ -394,6 +397,9 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) { /** * Provides a list of currently available themes. * + * If the database is active then it will be retrieved from the database. + * Otherwise it will retrieve a new list. + * * @param $refresh * Whether to reload the list of themes from the database. * @return @@ -408,59 +414,42 @@ function list_themes($refresh = FALSE) { if (empty($list)) { $list = array(); - $result = db_query("SELECT * FROM {system} WHERE type = '%s'", 'theme'); - while ($theme = db_fetch_object($result)) { - if (file_exists($theme->filename)) { - $theme->info = unserialize($theme->info); - foreach ($theme->info['stylesheets'] as $media => $stylesheets) { - foreach ($stylesheets as $stylesheet => $path) { - if (file_exists($path)) { - $theme->stylesheets[$media][$stylesheet] = $path; - } - } + $themes = array(); + // Extract from the database only when it is available. + if (db_is_active()) { + $result = db_query("SELECT * FROM {system} WHERE type = '%s'", 'theme'); + while ($theme = db_fetch_object($result)) { + if (file_exists($theme->filename)) { + $theme->info = unserialize($theme->info); + $themes[] = $theme; } - foreach ($theme->info['scripts'] as $script => $path) { + } + } + else { + // When the database is unavailable, scan the installation. + $themes = _system_theme_data(); + } + + foreach ($themes as $theme) { + foreach ($theme->info['stylesheets'] as $media => $stylesheets) { + foreach ($stylesheets as $stylesheet => $path) { if (file_exists($path)) { - $theme->scripts[$script] = $path; + $theme->stylesheets[$media][$stylesheet] = $path; } } - if (isset($theme->info['engine'])) { - $theme->engine = $theme->info['engine']; - } - if (isset($theme->info['base theme'])) { - $theme->base_theme = $theme->info['base theme']; + } + foreach ($theme->info['scripts'] as $script => $path) { + if (file_exists($path)) { + $theme->scripts[$script] = $path; } - $list[$theme->name] = $theme; } - } - } - - return $list; -} - -/** - * Provides a list of currently available theme engines - * - * @param $refresh - * Whether to reload the list of themes from the database. - * @return - * An array of the currently available theme engines. - */ -function list_theme_engines($refresh = FALSE) { - static $list; - - if ($refresh) { - unset($list); - } - - if (!$list) { - $list = array(); - $result = db_query("SELECT * FROM {system} WHERE type = '%s' AND status = %d ORDER BY name", 'theme_engine', '1'); - while ($engine = db_fetch_object($result)) { - if (file_exists($engine->filename)) { - $engine->info = unserialize($engine->info); - $list[$engine->name] = $engine; + if (isset($theme->info['engine'])) { + $theme->engine = $theme->info['engine']; } + if (isset($theme->info['base theme'])) { + $theme->base_theme = $theme->info['base theme']; + } + $list[$theme->name] = $theme; } } @@ -1028,117 +1017,6 @@ function theme_placeholder($text) { return ''. check_plain($text) .''; } -/** - * Generate a themed maintenance page. - * - * Note: this function is not themeable. - * - * @param $content - * The page content to show. - * @param $show_messages - * Whether to output status and error messages. - * FALSE can be useful to postpone the messages to a subsequent page. - */ -function theme_maintenance_page($content, $show_messages = TRUE) { - // Set required headers. - drupal_set_header('Content-Type: text/html; charset=utf-8'); - drupal_set_html_head(''); - drupal_set_html_head(''); - drupal_set_html_head(''); - drupal_set_html_head(''); - - // Prepare variables. - $variables = array( - 'head_title' => strip_tags(drupal_get_title()), - 'head' => drupal_get_html_head(), - 'styles' => '', - 'scripts' => drupal_get_js(), - 'left' => drupal_get_content('left'), - 'right' => drupal_get_content('right'), - 'base_path' => base_path(), - 'path_to_theme' => base_path() .'themes/garland/minnelli', - 'logo' => base_path() .'themes/garland/minnelli/logo.png', - 'site_title' => t('Drupal'), - 'title' => drupal_get_title(), - 'messages' => $show_messages ? theme('status_messages') : '', - 'content' => $content, - ); - - $output = theme_render_template('misc/maintenance.tpl.php', $variables); - - return $output; -} - -/** - * Generate a themed installation page. - * - * Note: this function is not themeable. - * - * @param $content - * The page content to show. - */ -function theme_install_page($content) { - drupal_set_header('Content-Type: text/html; charset=utf-8'); - drupal_add_css('misc/maintenance.css', 'module', 'all', FALSE); - drupal_set_html_head(''); - - $variables = array( - 'head_title' => strip_tags(drupal_get_title()), - 'head' => drupal_get_html_head(), - 'styles' => drupal_get_css(), - 'scripts' => drupal_get_js(), - 'left' => drupal_get_content('left'), - 'right' => drupal_get_content('right'), - 'base_path' => base_path(), - 'path_to_theme' => base_path() .'themes/garland/minnelli', - 'logo' => base_path() .'themes/garland/minnelli/logo.png', - 'site_title' => st('Drupal Installation'), - 'title' => drupal_get_title(), - 'messages' => '', - 'content' => $content, - ); - - // Special handling of error messages - $messages = drupal_set_message(); - if (isset($messages['error'])) { - $title = count($messages['error']) > 1 ? st('The following errors must be resolved before you can continue the installation process') : st('The following error must be resolved before you can continue the installation process'); - $variables['messages'] .= '

'. $title .':

'; - $variables['messages'] .= theme('status_messages', 'error'); - $variables['content'] .= '

'. st('Please check the error messages and try again.', array('!url' => request_uri())) .'

'; - } - - // Special handling of status messages - if (isset($messages['status'])) { - $warnings = count($messages['status']) > 1 ? st('The following installation warnings should be carefully reviewed, but in most cases may be safely ignored') : st('The following installation warning should be carefully reviewed, but in most cases may be safely ignored'); - $variables['messages'] .= '

'. $title .':

'; - $variables['messages'] .= theme('status_messages', 'status'); - } - - return theme_render_template('misc/maintenance.tpl.php', $variables); -} - -/** - * Return a themed list of maintenance tasks to perform. - * - * Note: this function is not themeable. - */ -function theme_task_list($items, $active = NULL) { - $done = isset($items[$active]) || $active == NULL; - $output = '
    '; - foreach ($items as $k => $item) { - if ($active == $k) { - $class = 'active'; - $done = false; - } - else { - $class = $done ? 'done' : ''; - } - $output .= '
  1. '. $item .'
  2. '; - } - $output .= '
'; - return $output; -} - /** * Return a themed set of status and/or error messages. The messages are grouped * by type. @@ -1733,11 +1611,21 @@ function template_preprocess(&$variables, $hook) { // Tell all templates where they are located. $variables['directory'] = path_to_theme(); - // Flag front page status. - $variables['is_front'] = drupal_is_front_page(); - // Tell all templates by which kind of user they're viewed. - $variables['logged_in'] = ($user->uid > 0); - $variables['is_admin'] = user_access('access administration pages'); + + // Set default variables that depend on the database. + $variables['is_admin'] = FALSE; + $variables['is_front'] = FALSE; + $variables['logged_in'] = FALSE; + if ($variables['db_is_active'] = db_is_active()) { + // Check for administrators. + if (user_access('access administration pages')) { + $variables['is_admin'] = TRUE; + } + // Flag front page status. + $variables['is_front'] = drupal_is_front_page(); + // Tell all templates by which kind of user they're viewed. + $variables['logged_in'] = ($user->uid > 0); + } } /** @@ -1750,6 +1638,9 @@ function template_preprocess(&$variables, $hook) { * Uses the arg() function to generate a series of page template suggestions * based on the current path. * + * Any changes to variables in this preprocessor should also be changed inside + * template_preprocess_maintenance_page() to keep all them consistent. + * * The $variables array contains the following arguments: * - $content * - $show_blocks @@ -1757,7 +1648,7 @@ function template_preprocess(&$variables, $hook) { * @see page.tpl.php */ function template_preprocess_page(&$variables) { - /* Add favicon */ + // Add favicon if (theme_get_setting('toggle_favicon')) { drupal_set_html_head(''); } diff --git a/includes/theme.maintenance.inc b/includes/theme.maintenance.inc new file mode 100644 index 000000000..cfc34e09b --- /dev/null +++ b/includes/theme.maintenance.inc @@ -0,0 +1,258 @@ +base_theme)) { + $base_theme[] = $new_base_theme = $themes[$themes[$ancestor]->base_theme]; + $ancestor = $themes[$ancestor]->base_theme; + } + _init_theme($themes[$theme], array_reverse($base_theme), '_theme_load_offline_registry'); + + // These are usually added from system_init() -except maintenance.css. + // When the database is inactive it's not called so we add it here. + drupal_add_css(drupal_get_path('module', 'system') .'/defaults.css', 'module'); + drupal_add_css(drupal_get_path('module', 'system') .'/system.css', 'module'); + drupal_add_css(drupal_get_path('module', 'system') .'/system-menus.css', 'module'); + drupal_add_css(drupal_get_path('module', 'system') .'/maintenance.css', 'module'); +} + +/** + * This builds the registry when the site needs to bypass any database calls. + */ +function _theme_load_offline_registry($theme, $base_theme = NULL, $theme_engine = NULL) { + $registry = _theme_build_registry($theme, $base_theme, $theme_engine); + _theme_set_registry($registry); +} + +/** + * Return a themed list of maintenance tasks to perform. + */ +function theme_task_list($items, $active = NULL) { + $done = isset($items[$active]) || $active == NULL; + $output = '
    '; + foreach ($items as $k => $item) { + if ($active == $k) { + $class = 'active'; + $done = false; + } + else { + $class = $done ? 'done' : ''; + } + $output .= '
  1. '. $item .'
  2. '; + } + $output .= '
'; + return $output; +} + +/** + * Generate a themed installation page. + * + * Note: this function is not themeable. + * + * @param $content + * The page content to show. + */ +function theme_install_page($content) { + drupal_set_header('Content-Type: text/html; charset=utf-8'); + + // Assign content. + $variables['content'] = $content; + // Delay setting the message variable so it can be processed below. + $variables['show_messages'] = FALSE; + // The maintenance preprocess function is recycled here. + template_preprocess_maintenance_page($variables); + + // Special handling of error messages + $messages = drupal_set_message(); + if (isset($messages['error'])) { + $title = count($messages['error']) > 1 ? st('The following errors must be resolved before you can continue the installation process') : st('The following error must be resolved before you can continue the installation process'); + $variables['messages'] .= '

'. $title .':

'; + $variables['messages'] .= theme('status_messages', 'error'); + $variables['content'] .= '

'. st('Please check the error messages and try again.', array('!url' => request_uri())) .'

'; + } + + // Special handling of status messages + if (isset($messages['status'])) { + $warnings = count($messages['status']) > 1 ? st('The following installation warnings should be carefully reviewed, but in most cases may be safely ignored') : st('The following installation warning should be carefully reviewed, but in most cases may be safely ignored'); + $variables['messages'] .= '

'. $title .':

'; + $variables['messages'] .= theme('status_messages', 'status'); + } + + return theme_render_template('themes/garland/maintenance-page.tpl.php', $variables); +} + +/** + * Generate a themed update page. + * + * Note: this function is not themeable. + * + * @param $content + * The page content to show. + * @param $show_messages + * Whether to output status and error messages. + * FALSE can be useful to postpone the messages to a subsequent page. + */ +function theme_update_page($content, $show_messages = TRUE) { + // Set required headers. + drupal_set_header('Content-Type: text/html; charset=utf-8'); + + // Assign content and show message flag. + $variables['content'] = $content; + $variables['show_messages'] = $show_messages; + // The maintenance preprocess function is recycled here. + template_preprocess_maintenance_page($variables); + + return theme_render_template('themes/garland/maintenance-page.tpl.php', $variables); +} + +/** + * The variables generated here is a mirror of template_preprocess_page(). + * This preprocessor will run it's course when theme_maintenance_page() is + * invoked. It is also used in theme_install_page() and theme_update_page() to + * keep all the variables consistent. + * + * An alternate template file of "maintenance-page-offline.tpl.php" can be + * used when the database is offline to hide errors and completely replace the + * content. + * + * The $variables array contains the following arguments: + * - $content + * - $show_blocks + * + * @see maintenance-page.tpl.php + */ +function template_preprocess_maintenance_page(&$variables) { + // Add favicon + if (theme_get_setting('toggle_favicon')) { + drupal_set_html_head(''); + } + + global $theme; + // Retrieve the theme data to list all available regions. + $theme_data = _system_theme_data(); + $regions = $theme_data[$theme]->info['regions']; + + // Get all region content set with drupal_set_content(). + foreach (array_keys($regions) as $region) { + // Assign region to a region variable. + $region_content = drupal_get_content($region); + isset($variables[$region]) ? $variables[$region] .= $region_content : $variables[$region] = $region_content; + } + + // Setup layout variable. + $variables['layout'] = 'none'; + if (!empty($variables['left'])) { + $variables['layout'] = 'left'; + } + if (!empty($variables['right'])) { + $variables['layout'] = ($variables['layout'] == 'left') ? 'both' : 'right'; + } + + // Construct page title + if (drupal_get_title()) { + $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal')); + } + else { + $head_title = array(variable_get('site_name', 'Drupal')); + if (variable_get('site_slogan', '')) { + $head_title[] = variable_get('site_slogan', ''); + } + } + $variables['head_title'] = implode(' | ', $head_title); + $variables['base_path'] = base_path(); + $variables['breadcrumb'] = ''; + $variables['feed_icons'] = ''; + $variables['footer_message'] = filter_xss_admin(variable_get('site_footer', FALSE)); + $variables['head'] = drupal_get_html_head(); + $variables['help'] = ''; + $variables['language'] = $GLOBALS['language']; + $variables['logo'] = theme_get_setting('logo'); + $variables['messages'] = $variables['show_messages'] ? theme('status_messages') : ''; + $variables['mission'] = ''; + $variables['primary_links'] = array(); + $variables['secondary_links'] = array(); + $variables['search_box'] = ''; + $variables['site_name'] = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : ''); + $variables['site_slogan'] = (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : ''); + $variables['css'] = drupal_add_css(); + $variables['styles'] = drupal_get_css(); + $variables['scripts'] = drupal_get_js(); + $variables['tabs'] = ''; + $variables['title'] = drupal_get_title(); + $variables['closure'] = ''; + + // Compile a list of classes that are going to be applied to the body element. + $body_classes = array(); + $body_classes[] = 'in-maintenance'; + if (isset($variables['db_is_active']) && !$variables['db_is_active']) { + $body_classes[] = 'db-offline'; + } + if ($variables['layout'] == 'both') { + $body_classes[] = 'two-sidebars'; + } + elseif ($variables['layout'] == 'none') { + $body_classes[] = 'no-sidebars'; + } + else { + $body_classes[] = 'one-sidebar sidebar-'. $variables['layout']; + } + $variables['body_classes'] = implode(' ', $body_classes); + + // Dead databases will show error messages so supplying this template will + // allow themers to override the page and the content completely. + if (isset($variables['db_is_active']) && !$variables['db_is_active']) { + $variables['template_file'] = 'maintenance-page-offline'; + } +} diff --git a/install.php b/install.php index 1716ffed9..4125b29af 100644 --- a/install.php +++ b/install.php @@ -3,6 +3,8 @@ require_once './includes/install.inc'; +define('MAINTENANCE_MODE', 'install'); + /** * The Drupal installation happens in a series of steps. We begin by verifying * that the current environment meets our minimum requirements. We then go diff --git a/misc/maintenance.css b/misc/maintenance.css deleted file mode 100644 index a18f10c1a..000000000 --- a/misc/maintenance.css +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id$ */ - -/* Update styles */ -#update-results { - margin-top: 3em; - padding: 0.25em; - border: 1px solid #ccc; - background: #eee; - font-size: smaller; -} -#update-results h2 { - margin-top: 0.25em; -} -#update-results h4 { - margin-bottom: 0.25em; -} -#update-results li.none { - color: #888; - font-style: italic; -} -#update-results li.failure strong { - color: #b63300; -} diff --git a/misc/maintenance.tpl.php b/misc/maintenance.tpl.php deleted file mode 100644 index 24d554f4a..000000000 --- a/misc/maintenance.tpl.php +++ /dev/null @@ -1,62 +0,0 @@ - - - - <?php print $head_title ?> - - - - - - - - - -
- -
-
- - - - - - - -
- '. $title .''; endif; ?> - - -
- -
- - - -
- - - - - -
-
- - - - diff --git a/modules/system/maintenance-page.tpl.php b/modules/system/maintenance-page.tpl.php new file mode 100644 index 000000000..12037ab93 --- /dev/null +++ b/modules/system/maintenance-page.tpl.php @@ -0,0 +1,98 @@ + + + + + + <?php print $head_title; ?> + + + + + + +
+ + +
+ + + + + +
+ +
+

+ +
+ +
+
+ +
+ + + + + +
+ + + +
+ + + diff --git a/modules/system/maintenance.css b/modules/system/maintenance.css new file mode 100644 index 000000000..a18f10c1a --- /dev/null +++ b/modules/system/maintenance.css @@ -0,0 +1,23 @@ +/* $Id$ */ + +/* Update styles */ +#update-results { + margin-top: 3em; + padding: 0.25em; + border: 1px solid #ccc; + background: #eee; + font-size: smaller; +} +#update-results h2 { + margin-top: 0.25em; +} +#update-results h4 { + margin-bottom: 0.25em; +} +#update-results li.none { + color: #888; + font-style: italic; +} +#update-results li.failure strong { + color: #b63300; +} diff --git a/modules/system/system.module b/modules/system/system.module index d6997c2f1..ca8e54703 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -77,7 +77,7 @@ function system_help($path, $arg) { } function system_theme() { - return array_merge(drupal_common_themes(), array( + return array_merge(drupal_common_theme(), array( 'system_theme_select_form' => array( 'arguments' => array('form' => NULL), 'file' => 'system.admin.inc', @@ -711,111 +711,119 @@ function system_theme_default() { } /** - * Collect data about all currently available themes + * Collect data about all currently available themes. + * + * @return + * Array of all available themes and their data. */ function system_theme_data() { - // Find themes - $themes = drupal_system_listing('\.info$', 'themes'); + // Scan the installation theme .info files and their engines. + $themes = _system_theme_data(); - // Find theme engines - $engines = drupal_system_listing('\.engine$', 'themes/engines'); - - // Remove all theme engines from the system table - db_query("DELETE FROM {system} WHERE type = '%s'", 'theme_engine'); + // Extract current files from database. + system_get_files_database($themes, 'theme'); - foreach ($engines as $engine) { - // Insert theme engine into system table - drupal_get_filename('theme_engine', $engine->name, $engine->filename); - drupal_load('theme_engine', $engine->name); - db_query("INSERT INTO {system} (name, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', %d, %d, %d)", $engine->name, 'theme_engine', $engine->filename, 1, 0, 0); - } + db_query("DELETE FROM {system} WHERE type = 'theme'"); - $defaults = system_theme_default(); + foreach ($themes as $theme) { + if (!isset($theme->owner)) { + $theme->owner = ''; + } - $sub_themes = array(); - // Read info files for each theme - foreach ($themes as $key => $theme) { - $themes[$key]->info = drupal_parse_info_file($theme->filename) + $defaults; + db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0); + } - // Invoke hook_system_info_alter() to give installed modules a chance to - // modify the data in the .info files if necessary. - drupal_alter('system_info', $themes[$key]->info, $themes[$key]); + return $themes; +} - if (!empty($themes[$key]->info['base theme'])) { - $sub_themes[] = $key; - } - if (empty($themes[$key]->info['engine'])) { - $filename = dirname($themes[$key]->filename) .'/'. $themes[$key]->name .'.theme'; - if (file_exists($filename)) { - $themes[$key]->owner = $filename; - $themes[$key]->prefix = $key; +/** + * Helper function to scan and collect theme .info data and their engines. + */ +function _system_theme_data() { + static $themes_info = array(); + + if (empty($theme_info)) { + // Find themes + $themes = drupal_system_listing('\.info$', 'themes'); + // Find theme engines + $engines = drupal_system_listing('\.engine$', 'themes/engines'); + + $defaults = system_theme_default(); + + $sub_themes = array(); + // Read info files for each theme + foreach ($themes as $key => $theme) { + $themes[$key]->info = drupal_parse_info_file($theme->filename) + $defaults; + + // Invoke hook_system_info_alter() to give installed modules a chance to + // modify the data in the .info files if necessary. + drupal_alter('system_info', $themes[$key]->info, $themes[$key]); + + if (!empty($themes[$key]->info['base theme'])) { + $sub_themes[] = $key; } - } - else { - $engine = $themes[$key]->info['engine']; - if (isset($engines[$engine])) { - $themes[$key]->owner = $engines[$engine]->filename; - $themes[$key]->prefix = $engines[$engine]->name; - $themes[$key]->template = TRUE; + if (empty($themes[$key]->info['engine'])) { + $filename = dirname($themes[$key]->filename) .'/'. $themes[$key]->name .'.theme'; + if (file_exists($filename)) { + $themes[$key]->owner = $filename; + $themes[$key]->prefix = $key; + } } - } - - // Give the stylesheets proper path information. - $pathed_stylesheets = array(); - foreach ($themes[$key]->info['stylesheets'] as $media => $stylesheets) { - foreach ($stylesheets as $stylesheet) { - $pathed_stylesheets[$media][$stylesheet] = dirname($themes[$key]->filename) .'/'. $stylesheet; + else { + $engine = $themes[$key]->info['engine']; + if (isset($engines[$engine])) { + $themes[$key]->owner = $engines[$engine]->filename; + $themes[$key]->prefix = $engines[$engine]->name; + $themes[$key]->template = TRUE; + } } - } - $themes[$key]->info['stylesheets'] = $pathed_stylesheets; - // Give the scripts proper path information. - $scripts = array(); - foreach ($themes[$key]->info['scripts'] as $script) { - $scripts[$script] = dirname($themes[$key]->filename) .'/'. $script; - } - $themes[$key]->info['scripts'] = $scripts; - // Give the screenshot proper path information. - if (!empty($themes[$key]->info['screenshot'])) { - $themes[$key]->info['screenshot'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['screenshot']; - } - } + // Give the stylesheets proper path information. + $pathed_stylesheets = array(); + foreach ($themes[$key]->info['stylesheets'] as $media => $stylesheets) { + foreach ($stylesheets as $stylesheet) { + $pathed_stylesheets[$media][$stylesheet] = dirname($themes[$key]->filename) .'/'. $stylesheet; + } + } + $themes[$key]->info['stylesheets'] = $pathed_stylesheets; - // Now that we've established all our master themes, go back and fill in - // data for subthemes. - foreach ($sub_themes as $key) { - $base_key = system_find_base_theme($themes, $key); - if (!$base_key) { - continue; - } - // Copy the 'owner' and 'engine' over if the top level theme uses a - // theme engine. - if (isset($themes[$base_key]->owner)) { - if (isset($themes[$base_key]->info['engine'])) { - $themes[$key]->info['engine'] = $themes[$base_key]->info['engine']; - $themes[$key]->owner = $themes[$base_key]->owner; - $themes[$key]->prefix = $themes[$base_key]->prefix; + // Give the scripts proper path information. + $scripts = array(); + foreach ($themes[$key]->info['scripts'] as $script) { + $scripts[$script] = dirname($themes[$key]->filename) .'/'. $script; } - else { - $themes[$key]->prefix = $key; + $themes[$key]->info['scripts'] = $scripts; + // Give the screenshot proper path information. + if (!empty($themes[$key]->info['screenshot'])) { + $themes[$key]->info['screenshot'] = dirname($themes[$key]->filename) .'/'. $themes[$key]->info['screenshot']; } } - } - - // Extract current files from database. - system_get_files_database($themes, 'theme'); - db_query("DELETE FROM {system} WHERE type = 'theme'"); - - foreach ($themes as $theme) { - if (!isset($theme->owner)) { - $theme->owner = ''; + // Now that we've established all our master themes, go back and fill in + // data for subthemes. + foreach ($sub_themes as $key) { + $base_key = system_find_base_theme($themes, $key); + if (!$base_key) { + continue; + } + // Copy the 'owner' and 'engine' over if the top level theme uses a + // theme engine. + if (isset($themes[$base_key]->owner)) { + if (isset($themes[$base_key]->info['engine'])) { + $themes[$key]->info['engine'] = $themes[$base_key]->info['engine']; + $themes[$key]->owner = $themes[$base_key]->owner; + $themes[$key]->prefix = $themes[$base_key]->prefix; + } + else { + $themes[$key]->prefix = $key; + } + } } - - db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0); + + $themes_info = $themes; } - return $themes; + return $themes_info; } /** diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 4fc53c365..69205fb30 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -172,6 +172,15 @@ ini_set('url_rewriter.tags', ''); # 'site_name' => 'My Drupal site', # 'theme_default' => 'minnelli', # 'anonymous' => 'Visitor', +/** + * A custom theme can be set for the off-line page. This applies when the site + * is explicitly set to off-line mode through the administration page or when + * the database is inactive due to an error. It can be set through the + * 'maintenance_theme' key. The template file should also be copied into the + * theme. It is located inside 'modules/system/maintenance-page.tpl.php'. + * Note: This setting does not apply to installation and update pages. + */ +# 'maintenance_theme' => 'minnelli', /** * reverse_proxy accepts a boolean value. * diff --git a/themes/garland/maintenance-page.tpl.php b/themes/garland/maintenance-page.tpl.php new file mode 100644 index 000000000..6087b354c --- /dev/null +++ b/themes/garland/maintenance-page.tpl.php @@ -0,0 +1,91 @@ + + + + <?php print $head_title ?> + + + + + + > + + +
+ +
+
+ + + + + + + +
+ '. $title .''; endif; ?> + + +
+ +
+ +
+ + + + + +
+
+ + + + diff --git a/update.php b/update.php index 890d4c0ad..38738dee9 100644 --- a/update.php +++ b/update.php @@ -13,6 +13,8 @@ * be sure to open settings.php again, and change it back to its original state! */ +define('MAINTENANCE_MODE', 'update'); + /** * Add a column to a database using syntax appropriate for PostgreSQL. * Save result of SQL commands in $ret array. @@ -803,7 +805,7 @@ function update_task_list($active = NULL) { 'finished' => 'Review log', ); - drupal_set_content('left', theme_task_list($tasks, $active)); + drupal_set_content('left', theme('task_list', $tasks, $active)); } // Some unavoidable errors happen because the database is not yet up-to-date. @@ -875,5 +877,5 @@ else { $output = update_access_denied_page(); } if (isset($output) && $output) { - print theme('maintenance_page', $output); + print theme('update_page', $output); } -- cgit v1.2.3