summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/common.inc5
-rw-r--r--includes/menu.inc69
-rw-r--r--includes/theme.inc25
3 files changed, 87 insertions, 12 deletions
diff --git a/includes/common.inc b/includes/common.inc
index ce37466c4..2b98b3b7a 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -3918,7 +3918,10 @@ function _drupal_bootstrap_full() {
ini_set('log_errors', 1);
ini_set('error_log', file_directory_path() . '/error.log');
}
-
+ // Set a custom theme for the current page, if there is one. We need to run
+ // this before invoking hook_init(), since any modules which initialize the
+ // theme system will prevent a custom theme from being correctly set later.
+ menu_set_custom_theme();
// Let all modules take action before menu system handles the request
// We do not want this while running update.php.
if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
diff --git a/includes/menu.inc b/includes/menu.inc
index fe6d459d1..d967a4c13 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -359,8 +359,9 @@ function menu_set_item($path, $router_item) {
* The router item, an associate array corresponding to one row in the
* menu_router table. The value of key map holds the loaded objects. The
* value of key access is TRUE if the current user can access this page.
- * The values for key title, page_arguments, access_arguments will be
- * filled in based on the database values and the objects loaded.
+ * The values for key title, page_arguments, access_arguments, and
+ * theme_arguments will be filled in based on the database values and the
+ * objects loaded.
*/
function menu_get_item($path = NULL, $router_item = NULL) {
$router_items = &drupal_static(__FUNCTION__);
@@ -391,6 +392,7 @@ function menu_get_item($path = NULL, $router_item = NULL) {
if ($router_item['access']) {
$router_item['map'] = $map;
$router_item['page_arguments'] = array_merge(menu_unserialize($router_item['page_arguments'], $map), array_slice($map, $router_item['number_parts']));
+ $router_item['theme_arguments'] = array_merge(menu_unserialize($router_item['theme_arguments'], $map), array_slice($map, $router_item['number_parts']));
}
}
$router_items[$path] = $router_item;
@@ -936,6 +938,8 @@ function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) {
'title',
'title_callback',
'title_arguments',
+ 'theme_callback',
+ 'theme_arguments',
'type',
'description',
));
@@ -1117,6 +1121,8 @@ function menu_tree_page_data($menu_name, $max_depth = NULL) {
'title',
'title_callback',
'title_arguments',
+ 'theme_callback',
+ 'theme_arguments',
'type',
'description',
));
@@ -1390,6 +1396,38 @@ function menu_get_active_help() {
}
/**
+ * Gets the custom theme for the current page, if there is one.
+ *
+ * @param $initialize
+ * This parameter should only be used internally; it is set to TRUE in order
+ * to force the custom theme to be initialized from the menu router item for
+ * the current page.
+ * @return
+ * The machine-readable name of the custom theme, if there is one.
+ *
+ * @see menu_set_custom_theme()
+ */
+function menu_get_custom_theme($initialize = FALSE) {
+ $custom_theme = &drupal_static(__FUNCTION__);
+ // Skip this if the site is offline or being installed or updated, since the
+ // menu system may not be correctly initialized then.
+ if ($initialize && !_menu_site_is_offline(TRUE) && (!defined('MAINTENANCE_MODE') || (MAINTENANCE_MODE != 'update' && MAINTENANCE_MODE != 'install'))) {
+ $router_item = menu_get_item();
+ if (!empty($router_item['access']) && !empty($router_item['theme_callback']) && function_exists($router_item['theme_callback'])) {
+ $custom_theme = call_user_func_array($router_item['theme_callback'], $router_item['theme_arguments']);
+ }
+ }
+ return $custom_theme;
+}
+
+/**
+ * Sets a custom theme for the current page, if there is one.
+ */
+function menu_set_custom_theme() {
+ menu_get_custom_theme(TRUE);
+}
+
+/**
* Build a list of named menus.
*/
function menu_get_names() {
@@ -2728,6 +2766,13 @@ function _menu_router_build($callbacks) {
$item['file path'] = $parent['file path'];
}
}
+ // Same for theme callbacks.
+ if (!isset($item['theme callback']) && isset($parent['theme callback'])) {
+ $item['theme callback'] = $parent['theme callback'];
+ if (!isset($item['theme arguments']) && isset($parent['theme arguments'])) {
+ $item['theme arguments'] = $parent['theme arguments'];
+ }
+ }
}
}
if (!isset($item['access callback']) && isset($item['access arguments'])) {
@@ -2749,6 +2794,8 @@ function _menu_router_build($callbacks) {
'block callback' => '',
'title arguments' => array(),
'title callback' => 't',
+ 'theme arguments' => array(),
+ 'theme callback' => '',
'description' => '',
'position' => '',
'tab_parent' => '',
@@ -2798,6 +2845,8 @@ function _menu_router_save($menu, $masks) {
'title',
'title_callback',
'title_arguments',
+ 'theme_callback',
+ 'theme_arguments',
'type',
'block_callback',
'description',
@@ -2823,6 +2872,8 @@ function _menu_router_save($menu, $masks) {
'title' => $item['title'],
'title_callback' => $item['title callback'],
'title_arguments' => ($item['title arguments'] ? serialize($item['title arguments']) : ''),
+ 'theme_callback' => $item['theme callback'],
+ 'theme_arguments' => serialize($item['theme arguments']),
'type' => $item['type'],
'block_callback' => $item['block callback'],
'description' => $item['description'],
@@ -2853,20 +2904,24 @@ function menu_path_is_external($path) {
* This function will log the current user out and redirect to front page
* if the current user has no 'access site in maintenance mode' permission.
*
+ * @param $check_only
+ * If this is set to TRUE, the function will perform the access checks and
+ * return the site offline status, but not log the user out or display any
+ * messages.
* @return
* FALSE if the site is not in maintenance mode, the user login page is
* displayed, or the user has the 'access site in maintenance mode'
* permission. TRUE for anonymous users not being on the login page when the
* site is in maintenance mode.
*/
-function _menu_site_is_offline() {
+function _menu_site_is_offline($check_only = FALSE) {
// Check if site is in maintenance mode.
if (variable_get('maintenance_mode', 0)) {
if (user_access('access site in maintenance mode')) {
// Ensure that the maintenance mode message is displayed only once
// (allowing for page redirects) and specifically suppress its display on
// the maintenance mode settings page.
- if ($_GET['q'] != 'admin/config/development/maintenance') {
+ if (!$check_only && $_GET['q'] != 'admin/config/development/maintenance') {
if (user_access('administer site configuration')) {
drupal_set_message(t('Operating in maintenance mode. <a href="@url">Go online.</a>', array('@url' => url('admin/config/development/maintenance'))), 'status', FALSE);
}
@@ -2881,8 +2936,10 @@ function _menu_site_is_offline() {
return ($_GET['q'] != 'user' && $_GET['q'] != 'user/login');
}
// Logged in users are unprivileged here, so they are logged out.
- require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'user') . '/user.pages.inc';
- user_logout();
+ if (!$check_only) {
+ require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'user') . '/user.pages.inc';
+ user_logout();
+ }
}
}
return FALSE;
diff --git a/includes/theme.inc b/includes/theme.inc
index cf90b98ba..71fbf9ba7 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -38,10 +38,24 @@ define('MARK_UPDATED', 2);
*/
/**
+ * Determines if a theme is available to use.
+ *
+ * @param $theme
+ * An object representing the theme to check.
+ * @return
+ * Boolean TRUE if the theme is enabled or is the site administration theme;
+ * FALSE otherwise.
+ */
+function drupal_theme_access($theme) {
+ $admin_theme = variable_get('admin_theme');
+ return !empty($theme->status) || ($admin_theme && $theme->name == $admin_theme);
+}
+
+/**
* Initialize the theme system by loading the theme.
*/
function drupal_theme_initialize() {
- global $theme, $user, $custom_theme, $theme_key;
+ global $theme, $user, $theme_key;
// If $theme is already set, assume the others are set, too, and do nothing
if (isset($theme)) {
@@ -52,12 +66,13 @@ function drupal_theme_initialize() {
$themes = list_themes();
// Only select the user selected theme if it is available in the
- // list of enabled themes.
- $theme = !empty($user->theme) && !empty($themes[$user->theme]->status) ? $user->theme : variable_get('theme_default', 'garland');
+ // list of themes that can be accessed.
+ $theme = !empty($user->theme) && isset($themes[$user->theme]) && drupal_theme_access($themes[$user->theme]) ? $user->theme : variable_get('theme_default', 'garland');
// Allow modules to override the present theme... only select custom theme
- // if it is available in the list of installed themes.
- $theme = $custom_theme && $themes[$custom_theme] ? $custom_theme : $theme;
+ // if it is available in the list of themes that can be accessed.
+ $custom_theme = menu_get_custom_theme();
+ $theme = $custom_theme && isset($themes[$custom_theme]) && drupal_theme_access($themes[$custom_theme]) ? $custom_theme : $theme;
// Store the identifier for retrieving theme settings with.
$theme_key = $theme;