themekey_debug.module in ThemeKey 7.3
Same filename and directory in other branches
Provides a debug mode for module ThemeKey.
@author Markus Kalkbrenner | bio.logis GmbH
File
themekey_debug.moduleView source
<?php
/**
* @file
* Provides a debug mode for module ThemeKey.
* @see themekey.module
*
* @author Markus Kalkbrenner | bio.logis GmbH
* @see http://drupal.org/user/124705
*/
/**
* Implements hook_permission().
*/
function themekey_debug_permission() {
return array(
'themekey_debug_see_messages' => array(
'title' => t('See ThemeKey debug messages'),
'description' => t('Using this permission debug messages will be displayed to users in that role.'),
),
);
}
/**
* Iterates over all ThemeKey Properties and prints
* out their current values.
*/
function themekey_debug_properties() {
global $user;
if (1 == $user->uid || user_access('themekey_debug_see_messages', $user) || variable_get('themekey_debug_non_admin_users', FALSE)) {
module_load_include('inc', 'themekey', 'themekey_base');
$properties = variable_get('themekey_properties', array());
$message = t('These are the current values of all available ThemeKey Properties. By clicking the value you can start creating a corresponding Theme Switching Rule.') . '<ul>';
$parameters = themekey_get_global_parameters();
foreach ($properties as $property) {
if (!isset($parameters[$property])) {
themekey_property_value($parameters, $property);
}
$value = '';
if (is_null($parameters[$property])) {
if ('drupal:path' == $property) {
$value = '<em>no debug information</em>';
}
else {
$value = '<em>empty</em>';
}
}
else {
$values = is_array($parameters[$property]) ? $parameters[$property] : array(
$parameters[$property],
);
$links = array();
foreach ($values as $single_value) {
// Don't use the l() function at this early stage of bootstrapping because it will initialize the theme engine. Use url() instead.
$links[] = '<a href="' . url('admin/config/user-interface/themekey', array(
'fragment' => 'themekey_new_rule',
'query' => array(
'property' => $property,
'value' => $single_value,
),
)) . '">' . $single_value . '</a>';
}
$value = implode('<br />', $links);
}
$message .= '<li>' . $property . '<br />' . $value . '</li><br />';
}
$message .= '</ul>';
themekey_set_debug_message($message, array(), FALSE);
}
}
/**
* Implements hook_menu().
*/
function themekey_debug_menu() {
$items = array();
$items['admin/config/user-interface/themekey/settings/debug'] = array(
'title' => 'Debug',
'access callback' => 'user_access',
'access arguments' => array(
'administer themekey settings',
),
'file' => 'themekey_debug_admin.inc',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'themekey_debug_settings_form',
),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
);
return $items;
}
/**
* Implements hook_theme().
*/
function themekey_debug_theme() {
$items = array(
'themekey_debug_messages' => array(
'template' => 'themekey-debug-messages',
'variables' => array(
'messages' => array(),
),
),
);
return $items;
}
/**
* Implements hook_init().
*
* Detects if hook_custom_theme() has been skipped because
* a different module already initialized the theme engine.
*/
function themekey_debug_init() {
if (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
if (!in_array('system', variable_get('themekey_compat_modules_enabled', array())) && path_is_admin($_GET['q']) && variable_get('admin_theme', '0')) {
themekey_set_debug_message('"%admin_theme" is configured as administration theme at !link. This setting is more powerful than a corresponding ThemeKey rule.', array(
'%admin_theme' => variable_get('admin_theme', '0'),
'!link' => l(t('!path', array(
'!path' => 'admin/appearance',
)), 'admin/appearance'),
), TRUE, TRUE);
}
$custom_theme_called =& drupal_static('themekey_custom_theme_called', FALSE);
if (!$custom_theme_called) {
themekey_set_debug_message("Consider to activate the module ThemeKey Compatibility to integrate a different theme switching module into ThemeKey's theme switching rule chain", array(), TRUE, TRUE);
themekey_set_debug_message('Skipped rule checking because another module already initialized the theme engine.', array(), TRUE, TRUE);
}
else {
global $theme;
$themekey_custom_theme =& drupal_static('themekey_custom_theme', '');
if (!empty($themekey_custom_theme) && 'default' != $themekey_custom_theme) {
if ($theme != $themekey_custom_theme) {
themekey_set_debug_message('Theme switching to custom theme "%custom_theme" did not work because theme has been set to "%theme" by another module.', array(
'%custom_theme' => $themekey_custom_theme,
'%theme' => $theme,
), TRUE, TRUE);
}
}
else {
if (variable_get('theme_default', 'bartik') != $theme) {
themekey_set_debug_message('ThemeKey did not switch the theme because no rule matched. But something else set the theme to "%theme".', array(
'%theme' => $theme,
), TRUE, TRUE);
}
}
}
}
}
/**
* Implements hook_form_node_form_alter().
*
* Detects if custom theme has been skipped because
* the adminstration theme is used for node editing.
*/
function themekey_debug_form_node_form_alter() {
if (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
if (variable_get('node_admin_theme', '0')) {
themekey_set_debug_message('As configured at !link adding or editing a node will use the administration theme %admin_theme.', array(
'%admin_theme' => variable_get('admin_theme', '0'),
'!link' => l(t('!path', array(
'!path' => 'admin/appearance',
)), 'admin/appearance'),
), TRUE, TRUE);
}
}
}
/**
* Implements hook_page_alter().
*
* Prints out debug messages at the end of the page.
*
* @return string
*/
function themekey_debug_page_alter(&$page) {
if (variable_get('themekey_debug_show_property_values', FALSE)) {
// add the properties to the end of debug messages
themekey_debug_properties();
}
if (variable_get('themekey_css_debug_css_files', FALSE)) {
// add the list of css files to the end of debug messages.
$list['title'] = t('Css files on a page');
$list['items'] = array_filter(explode("\n", drupal_get_css()), 'themekey_debug_filter_css_array');
themekey_set_debug_message(theme('item_list', $list));
}
if ($messages = themekey_set_debug_message('flush')) {
$page['page_bottom']['themekey'] = array(
'#type' => 'markup',
'#markup' => $messages,
);
// Avoid caching of pages containing debug info in internal page cache
drupal_page_is_cacheable(FALSE);
// ... and external caches like varnish, boost, ...
drupal_add_http_header('Status', '503 Service unavailable');
}
}
/**
* Function for filtering array elements.
*
* Filters elements with empty strings and elements with strings
* that contains '<style>' tag from array generated by
* explode("\n", drupal_get_css()). drupal_get_css() returns
* html markup with "@import" statements combined in <style> tags.
* themekey_set_debug_message() use filter_xss() to filtering html
* from string, but filter_xss() leaves empty string where was html markup.
*
* @param string $element
* Array element.
*
* @return bool
* TRUE if element is not an empty string or string without <style> tag.
*/
function themekey_debug_filter_css_array($element) {
if (strlen(trim($element)) > 0 && strpos($element, '<style') === FALSE && strpos($element, '</style>') === FALSE) {
return TRUE;
}
else {
return FALSE;
}
}
/**
* Replacement for drupal_set_message() during ThemeKey's initialization.
* drupal_set_message() might inititialize the theme engine too early,
* which causes ThemeKey to not switch the theme.
*
* themekey_debug_set_debug_message() put the untranslated messages on a
* stack and hand them over to drupal_set_message() on demand.
*
* @param $msg
* the message as string. If the message is 'flush'
* all messages stored on the stack will be printed using
* drupal_set_message()
*
* @param $placeholder
* associative array of string replacments for $msg
* @see t()
*
* @param $translate
* boolean, if set to TRUE $msg will be handled by t()
* when handed over to drupal_set_message()
*/
function themekey_debug_set_debug_message($msg, $placeholder = array(), $translate = TRUE, $unshift = FALSE) {
static $msg_stack = array();
global $user, $theme;
if (1 == $user->uid || user_access('themekey_debug_see_messages', $user) || variable_get('themekey_debug_non_admin_users', FALSE)) {
if ('flush' == $msg) {
$messages = array();
if (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
$messages[] = t('Current theme: %theme', array(
'%theme' => $theme,
));
}
foreach ($msg_stack as $key => $msg) {
$messages[] = filter_xss($msg['translate'] ? t($msg['msg'], $msg['placeholder']) : $msg['msg'], array(
'a',
'b',
'br',
'li',
'ul',
));
unset($msg_stack[$key]);
}
if (!empty($messages)) {
return theme('themekey_debug_messages', array(
'messages' => $messages,
));
}
}
else {
$tmp = array(
'msg' => $msg,
'placeholder' => $placeholder,
'translate' => $translate,
);
if ($unshift) {
$tmp['msg'] = '<b>' . $tmp['msg'] . '</b>';
array_unshift($msg_stack, $tmp);
}
else {
$msg_stack[] = $tmp;
}
}
}
}
Functions
Name | Description |
---|---|
themekey_debug_filter_css_array | Function for filtering array elements. |
themekey_debug_form_node_form_alter | Implements hook_form_node_form_alter(). |
themekey_debug_init | Implements hook_init(). |
themekey_debug_menu | Implements hook_menu(). |
themekey_debug_page_alter | Implements hook_page_alter(). |
themekey_debug_permission | Implements hook_permission(). |
themekey_debug_properties | Iterates over all ThemeKey Properties and prints out their current values. |
themekey_debug_set_debug_message | Replacement for drupal_set_message() during ThemeKey's initialization. drupal_set_message() might inititialize the theme engine too early, which causes ThemeKey to not switch the theme. |
themekey_debug_theme | Implements hook_theme(). |