You are here

styleswitcher.module in Style Switcher 6.2

Module's hooks implementations and helper functions.

File

styleswitcher.module
View source
<?php

/**
 * @file
 * Module's hooks implementations and helper functions.
 */

/**
 * Indicates that the cookie must live 365 days more.
 */
define('STYLESWITCHER_COOKIE_EXPIRE', 31536000);

/**
 * Implements hook_block().
 */
function styleswitcher_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      return styleswitcher_block_info();
    case 'view':
      return styleswitcher_block_view($delta);
  }
}

/**
 * Returns info about provided blocks and their initial configuration settings.
 *
 * @return array
 *   An array of block descriptions.
 *
 * @see styleswitcher_block()
 * @see styleswitcher_block_view()
 */
function styleswitcher_block_info() {
  $blocks[0] = array(
    'info' => t('Style Switcher'),
    // We cannot cache globally, because we use drupal_get_destination() with
    // links in block, which is different from page to page. And we cannot avoid
    // using destination, because in this case site users with JS-disabled
    // browsers won't go back to the same page they were at, but will go to the
    // front page each time. We also cannot rely on $_SERVER['HTTP_REFERER'],
    // because it can be empty.
    'cache' => BLOCK_CACHE_PER_PAGE,
  );
  return $blocks;
}

/**
 * Returns a renderable view of a block.
 *
 * @param string|int $delta
 *   Which block to render.
 *
 * @return array
 *   An array of block subject and content.
 *
 * @see styleswitcher_block()
 * @see styleswitcher_block_info()
 */
function styleswitcher_block_view($delta) {
  global $theme;
  switch ($delta) {

    // List of styles a user can switch between.
    case 0:
      $styles = styleswitcher_style_load_multiple($theme, array(
        'status' => TRUE,
      ));

      // Do not display block if there is only one style (no alternatives).
      if (count($styles) > 1) {
        uasort($styles, 'styleswitcher_sort');
        $links = array();
        $destination = drupal_get_destination();
        foreach ($styles as $name => $style) {
          $name_hyphenated = strtr($name, '_', '-');
          $name_parts = explode('/', $name_hyphenated);
          $class = 'style-switcher ' . $name_parts[0] . '-style style-' . $name_parts[1];
          $links[] = l($style['label'], 'styleswitcher/switch/' . $theme . '/' . $name_hyphenated, array(
            'attributes' => array(
              'class' => $class,
              'data-rel' => $name,
              'rel' => 'nofollow',
            ),
            'query' => $destination,
          ));

          // Make paths absolute for JS.
          if (isset($style['path'])) {
            $styles[$name]['path'] = _styleswitcher_file_create_url($style['path']);
          }
          else {
            $styles[$name]['path'] = url('styleswitcher/css/' . $theme, array(
              'absolute' => TRUE,
            ));
          }
        }
        $path_to_module = drupal_get_path('module', 'styleswitcher');
        $js_settings = array(
          'styleSwitcher' => array(
            'styles' => $styles,
            'default' => styleswitcher_default_style_key($theme),
            'enableOverlay' => variable_get('styleswitcher_enable_overlay', 1),
            'cookieExpire' => STYLESWITCHER_COOKIE_EXPIRE,
            'theme' => $theme,
          ),
        );
        drupal_add_css($path_to_module . '/styleswitcher.overlay.css');
        drupal_add_js($path_to_module . '/styleswitcher.js');
        drupal_add_js($js_settings, 'setting');
        $block['subject'] = t('Style Switcher');
        $block['content'] = theme('item_list', $links);
        return $block;
      }
      break;
  }
}

/**
 * Prepares variables for page templates: Adds the dynamic CSS to every page.
 *
 * Default template: page.tpl.php.
 *
 * @param array $variables
 *   An associative array with page variables, including but not limited to:
 *   - styles: A themed representation of all stylesheets that should be
 *     attached to the page as returned from drupal_get_css(). This variable is
 *     created in template_preprocess_page().
 *
 * @see drupal_get_css()
 * @see template_preprocess_page()
 */
function styleswitcher_preprocess_page(array &$variables) {
  global $theme;

  // Construct absolute URL explicitly to work out disabled clean URLs.
  $url = url('styleswitcher/css/' . $theme, array(
    'absolute' => TRUE,
  ));

  // Function drupal_get_css() processes only really existing CSS files and not
  // dynamic links so it can't be used. Add link tag directly to the end of all
  // styles - they are already rendered to corresponding variable.
  $variables['styles'] .= '<link type="text/css" rel="stylesheet" media="all" href="' . $url . '" id="styleswitcher-css" />' . "\n";
}

/**
 * Implements hook_perm().
 */
function styleswitcher_perm() {
  return array(
    'administer styleswitcher',
  );
}

/**
 * Implements hook_menu().
 */
function styleswitcher_menu() {
  $items['admin/settings/styleswitcher'] = array(
    'title' => 'Styleswitcher',
    'description' => 'Configure Styleswitcher module.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'styleswitcher_admin',
    ),
    'access arguments' => array(
      'administer styleswitcher',
    ),
    'file' => 'styleswitcher.admin.inc',
  );
  $items['admin/settings/styleswitcher/global'] = array(
    'title' => 'Global settings',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -1,
  );
  foreach (list_themes() as $theme) {
    $items['admin/settings/styleswitcher/settings/' . $theme->name] = array(
      'title' => $theme->info['name'],
      'description' => 'Configure theme-specific styles settings.',
      'page callback' => 'drupal_get_form',
      'page arguments' => array(
        'styleswitcher_config_theme',
        4,
      ),
      'access callback' => '_styleswitcher_config_theme_access',
      'access arguments' => array(
        $theme,
      ),
      'type' => MENU_LOCAL_TASK,
      'file' => 'styleswitcher.admin.inc',
    );
  }
  $items['admin/settings/styleswitcher/add'] = array(
    'title' => 'Add style',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'styleswitcher_style_form',
    ),
    'access arguments' => array(
      'administer styleswitcher',
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'styleswitcher.admin.inc',
  );
  $items['admin/settings/styleswitcher/custom/%styleswitcher_style'] = array(
    'title' => 'Edit',
    'title callback' => 'styleswitcher_style_title',
    'title arguments' => array(
      4,
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'styleswitcher_style_form',
      4,
    ),
    'load arguments' => array(
      '',
      'custom',
    ),
    'access arguments' => array(
      'administer styleswitcher',
    ),
    'file' => 'styleswitcher.admin.inc',
  );
  $items['admin/settings/styleswitcher/custom/%styleswitcher_style/edit'] = array(
    'title' => 'Edit',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    // D6 needs load arguments here too.
    'load arguments' => array(
      '',
      'custom',
    ),
  );
  $items['admin/settings/styleswitcher/custom/%styleswitcher_style/delete'] = array(
    'title' => 'Delete',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'styleswitcher_style_delete_form',
      4,
    ),
    'load arguments' => array(
      '',
      'custom',
    ),
    'access arguments' => array(
      'administer styleswitcher',
    ),
    'file' => 'styleswitcher.admin.inc',
  );

  // The theme argument must be set for next routes to know what the page user
  // came from and what theme was used there.
  $items['styleswitcher/switch/%/%/%styleswitcher_style'] = array(
    'title' => 'Styleswitcher',
    'page callback' => 'styleswitcher_switch',
    'page arguments' => array(
      4,
    ),
    'load arguments' => array(
      2,
      3,
    ),
    'access callback' => '_styleswitcher_theme_access',
    'access arguments' => array(
      2,
    ),
    'type' => MENU_CALLBACK,
  );
  $items['styleswitcher/css/%'] = array(
    'title' => 'Styleswitcher',
    'page callback' => 'styleswitcher_css',
    'page arguments' => array(
      2,
    ),
    'access callback' => '_styleswitcher_theme_access',
    'access arguments' => array(
      2,
    ),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Access callback: Allows only for enabled themes.
 *
 * @param string|object $theme
 *   Either the name of a theme or a full theme object.
 *
 * @see styleswitcher_menu()
 */
function _styleswitcher_theme_access($theme) {
  if (is_string($theme)) {
    $themes = list_themes();
    if (!isset($themes[$theme])) {
      return FALSE;
    }
    $theme = $themes[$theme];
  }
  return $theme->status || $theme->name == variable_get('admin_theme', '0');
}

/**
 * Access callback: Allows only admin and only for enabled themes.
 *
 * @param string|object $theme
 *   Either the name of a theme or a full theme object.
 *
 * @see styleswitcher_menu()
 */
function _styleswitcher_config_theme_access($theme) {
  return user_access('administer styleswitcher') && _styleswitcher_theme_access($theme);
}

/**
 * Page callback: Switches style when JS is disabled.
 *
 * @param array $style
 *   New active style. The structure of an array is the same as returned from
 *   styleswitcher_style_load().
 *
 * @see styleswitcher_style_load()
 * @see styleswitcher_menu()
 */
function styleswitcher_switch(array $style) {
  if ($style['status']) {
    styleswitcher_save_user_preference($style['theme'], $style['name']);
  }
  drupal_goto();
}

/**
 * Page callback: Redirects to CSS file of currently active style.
 *
 * @param string $theme
 *   Name of the theme to find the active style for.
 *
 * @see styleswitcher_menu()
 */
function styleswitcher_css($theme) {

  // Prevent resource incorrect interpretation.
  drupal_set_header('Content-Type: text/css');

  // Prevent browser caching of the final style and always show the right one.
  // This is D6 only, D7 already sets ETag in core.
  drupal_set_header('ETag: "' . time() . '"');
  $path = styleswitcher_active_style_path($theme);
  if (isset($path)) {
    drupal_goto(_styleswitcher_file_create_url($path));
  }
}

/**
 * Loads a style array by its machine name and a theme name.
 *
 * @param string $name
 *   Machine name of the style to load.
 * @param string $theme
 *   Machine name of the theme to get the style for.
 * @param string $type
 *   (optional) Style type: 'theme' or 'custom'. If the type is specified then
 *   it will be prefixed with a slash to the $name argument.
 *
 * @return array|false
 *   Style array on success or FALSE otherwise. Style is an associative array
 *   containing:
 *   - name: Machine name.
 *   - label: Human-readable label.
 *   - path: System or external path to the CSS file.
 *   - weight: Weight of style link in the switch list.
 *   - status: Indicates whether the style is enabled or not.
 *   - is_default: Indicates that this style is the default one. This element
 *     may not always show the truth. It is recommended to use
 *     styleswitcher_default_style_key() to get the default style key.
 *   - _i: Index number of the style. It is used for sorting of styles with
 *     equal weights.
 *   - theme: Name of the theme the style is loaded for.
 *
 * @see styleswitcher_default_style_key()
 */
function styleswitcher_style_load($name, $theme, $type = '') {
  if ($type) {
    $name = $type . '/' . $name;

    // The next conversion is only rationale for auto-loader wildcards in paths
    // and there are $type arguments always set in menu items so if this
    // function is called with only one argument this conversion is redundant.
    $name = strtr($name, '-', '_');
  }
  $styles = styleswitcher_style_load_multiple($theme, array(
    'name' => $name,
  ));
  return reset($styles);
}

/**
 * Returns style's label.
 *
 * This function is assigned as a title callback in styleswitcher_menu().
 *
 * @param array $style
 *   Style array as returned from styleswitcher_style_load().
 *
 * @return string
 *   Label of the style.
 *
 * @see styleswitcher_style_load()
 */
function styleswitcher_style_title(array $style) {
  return $style['label'];
}

/**
 * Returns a list of styles.
 *
 * @param string $theme
 *   Name of the theme to get styles for.
 * @param array $filter
 *   Style properties to filter by. Each key is a property name, and value is
 *   a corresponding filter value.
 *
 * @return array
 *   Array of styles - all or just filtered by conditions from the $filter
 *   argument. Keys are machine names and each element is a corresponding style
 *   array, which structure is the same as returned from
 *   styleswitcher_style_load().
 *
 * @see styleswitcher_style_load()
 */
function styleswitcher_style_load_multiple($theme, array $filter = array()) {
  static $styles = array();
  if (!isset($styles[$theme])) {
    $theme_styles = styleswitcher_custom_styles() + styleswitcher_theme_styles($theme);
    $settings = styleswitcher_styles_settings($theme);
    foreach (array_keys($theme_styles) as $i => $key) {
      if (isset($settings[$key])) {
        $theme_styles[$key] += $settings[$key];
      }

      // Default settings.
      $theme_styles[$key] += array(
        'is_default' => FALSE,
        'status' => TRUE,
        'weight' => 0,
        '_i' => $i,
        'theme' => $theme,
      );
    }
    $styles[$theme] = $theme_styles;
  }
  if (empty($filter)) {
    return $styles[$theme];
  }
  $return = array();
  foreach ($styles[$theme] as $key => $style) {

    // Check the requested conditions.
    foreach ($filter as $property => $value) {
      if ($style[$property] != $value) {
        continue 2;
      }
    }
    $return[$key] = $style;
  }
  return $return;
}

/**
 * Returns a list of styles with theme-specific settings.
 *
 * @param string $theme
 *   Name of the theme to get styles settings for.
 *
 * @return array
 *   Array which keys are styles machine names and each element is a
 *   corresponding array with settings: weight, status and is_default. All
 *   settings are optional. See styleswitcher_style_load() for their
 *   descriptions.
 *
 * @see styleswitcher_style_load()
 */
function styleswitcher_styles_settings($theme) {
  $settings = variable_get('styleswitcher_styles_settings', array());
  if (empty($settings[$theme])) {
    $settings[$theme] = array();
    styleswitcher_theme_styles($theme);

    // Disable the blank style if theme has its own default one.
    if (styleswitcher_theme_default_style_key($theme)) {
      $settings[$theme]['custom/default']['status'] = FALSE;
    }
  }
  return $settings[$theme];
}

/**
 * Returns a list of custom styles.
 *
 * @return array
 *   Array which keys are styles machine names and each element is a
 *   corresponding array with properties: name, label and path. All properties
 *   are mandatory. See styleswitcher_style_load() for their descriptions.
 *
 * @see styleswitcher_style_load()
 */
function styleswitcher_custom_styles() {
  $defaults['custom/default'] = array(
    'name' => 'custom/default',
    'label' => 'Default',
    'path' => NULL,
  );
  return variable_get('styleswitcher_custom_styles', $defaults);
}

/**
 * Returns a list of styles provided by a theme.
 *
 * @param string $theme
 *   Name of the theme to retrieve styles of.
 * @param string|null $original_theme
 *   (optional) Name of the theme which the function was originally called with.
 *   While iterating over base themes the $theme argument changes but
 *   $original_theme keeps the same value.
 *
 * @return array
 *   Array of styles. Keys are machine names and each element is a corresponding
 *   array of style properties: name, label and path. All properties are
 *   mandatory. See styleswitcher_style_load() for their descriptions.
 *
 * @see styleswitcher_style_load()
 */
function styleswitcher_theme_styles($theme, $original_theme = NULL) {
  static $styles = array();

  // Theme can be an empty string if custom style is loading.
  if (!$theme) {
    return array();
  }
  if (isset($styles[$theme])) {
    return $styles[$theme];
  }
  $theme_styles = array();
  $theme_path = drupal_get_path('theme', $theme);

  // Do not use system_get_info() because it skips disabled base themes.
  $themes = list_themes();
  $theme_info = $themes[$theme]->info;
  if (!isset($original_theme)) {
    $original_theme = $theme;
  }

  // Search base themes for styleswitcher info.
  if (isset($theme_info['base theme'])) {
    $theme_styles = styleswitcher_theme_styles($theme_info['base theme'], $original_theme);
  }
  if (!empty($theme_info['styleswitcher'])) {
    $info = $theme_info['styleswitcher'];

    // Array of alternatives.
    if (!empty($info['css'])) {
      foreach ($info['css'] as $label => $path) {
        $name = 'theme/' . _styleswitcher_style_name($label);
        $theme_styles[$name] = array(
          'name' => $name,
          'label' => $label,
          'path' => menu_path_is_external($path) ? $path : $theme_path . '/' . $path,
        );
      }
    }

    // Default style.
    if (isset($info['default'])) {
      $default = $info['default'];
    }
    elseif (isset($info['css']['default'])) {
      $default = $info['css']['default'];
      unset($theme_styles['theme/default']);
    }
    if (isset($default)) {
      $default_in_existing = FALSE;

      // Check if Default points to one of existing alternatives.
      foreach ($theme_styles as $name => $style) {
        if ($default == $style['label'] || $default == $style['path'] || $theme_path . '/' . $default == $style['path']) {
          styleswitcher_theme_default_style_key($original_theme, $name);
          $default_in_existing = TRUE;
          break;
        }
      }

      // Default is a path not mentioned in css array.
      if (!$default_in_existing) {
        $defaults['theme/default'] = array(
          'name' => 'theme/default',
          'label' => 'Default',
          'path' => menu_path_is_external($default) ? $default : $theme_path . '/' . $default,
        );

        // Place default style above others.
        $theme_styles = $defaults + $theme_styles;
        styleswitcher_theme_default_style_key($original_theme, 'theme/default');
      }
    }
  }

  // Do not inflate the memory.
  if ($theme == $original_theme) {
    $styles[$theme] = $theme_styles;
  }
  return $theme_styles;
}

/**
 * Transliterates a human-readable name to a machine name.
 *
 * @param string $display_name
 *   Style label.
 *
 * @return string
 *   Transliterated name.
 */
function _styleswitcher_style_name($display_name) {
  $name = drupal_strtolower($display_name);
  $name = strtr($name, array(
    ' ' => '_',
    '-' => '_',
  ));
  $name = preg_replace('/[^a-z0-9_]/', '', $name);
  return $name;
}

/**
 * Saves/returns the key of default style provided by a theme.
 *
 * When theme's .info file is scanned for styles to switch this function is
 * called with argument to statically save a style key for further use. And
 * after, when this function is called it returns the key saved earlier.
 *
 * @param string $theme
 *   Name of the theme which default style is being saved/requested.
 * @param string|null $key
 *   The key of theme's default style.
 *
 * @return string|null
 *   The key of theme's default style.
 */
function styleswitcher_theme_default_style_key($theme, $key = NULL) {
  static $default_key = array();
  if (isset($key)) {
    $default_key[$theme] = $key;
  }
  return isset($default_key[$theme]) ? $default_key[$theme] : NULL;
}

/**
 * Finds the default style and returns its key.
 *
 * @param string $theme
 *   Name of the theme to find the default style for.
 *
 * @return string
 *   The key of the default style.
 */
function styleswitcher_default_style_key($theme) {
  static $default_key = array();

  // Search the default style explicitly set by admin.
  if (!isset($default_key[$theme])) {
    $styles = styleswitcher_style_load_multiple($theme, array(
      'is_default' => TRUE,
    ));
    $default_key[$theme] = key($styles);
  }

  // Plan B. If default style is not set in styles configuration form by admin
  // then find out initial default style defined by theme.
  if (!isset($default_key[$theme])) {
    styleswitcher_theme_styles($theme);
    $default_key[$theme] = styleswitcher_theme_default_style_key($theme);
  }

  // Fallback to the blank style.
  if (!isset($default_key[$theme])) {
    $styles = styleswitcher_style_load_multiple($theme, array(
      'path' => NULL,
    ));
    $default_key[$theme] = key($styles);
  }
  return $default_key[$theme];
}

/**
 * Finds the style active for current user and returns its path.
 *
 * This function is called at every page request before styleswitcher_switch()
 * or JS' Drupal.styleSwitcher.switchStyle() so we can update old user cookies
 * here once and not bother about it in other places.
 *
 * @param string $theme
 *   Name of the theme to find the active style for.
 *
 * @return string|null
 *   The path property of active style. It can be NULL if active style is the
 *   blank one.
 *
 * @see styleswitcher_switch()
 * @see Drupal.styleSwitcher.switchStyle()
 */
function styleswitcher_active_style_path($theme) {
  if (isset($_COOKIE['styleswitcher'])) {
    $cookie = $_COOKIE['styleswitcher'];
    if (isset($cookie[$theme])) {
      $active = styleswitcher_style_load($cookie[$theme], $theme);
    }
  }
  elseif (isset($_COOKIE['styleSwitcher'])) {
    $name = 'theme/' . _styleswitcher_style_name($_COOKIE['styleSwitcher']);

    // Remove this old cookie.
    setcookie('styleSwitcher', '', 0, base_path());

    // We actually do not know what theme was used (it was a global $theme) when
    // user switched to this style. So let us just set this style as active for
    // every theme which has a style with this name.
    foreach (array_keys(list_themes()) as $style_theme) {
      if ($style = styleswitcher_style_load($name, $style_theme)) {
        styleswitcher_save_user_preference($style_theme, $name);
        if ($theme == $style_theme) {
          $active = $style;
        }
      }
    }
  }
  if (empty($active)) {
    $active = styleswitcher_style_load(styleswitcher_default_style_key($theme), $theme);
  }
  return $active['path'];
}

/**
 * Implements hook_theme().
 */
function styleswitcher_theme() {
  return array(
    'styleswitcher_admin_styles_table' => array(
      'arguments' => array(
        'form' => array(),
      ),
      'file' => 'styleswitcher.admin.inc',
    ),
    'styleswitcher_admin_style_overview' => array(
      'arguments' => array(
        'style' => array(),
      ),
      'file' => 'styleswitcher.admin.inc',
    ),
  );
}

/**
 * Sorts styles by weight and index.
 *
 * This function first compares style weights, and then - if weights are equal -
 * style index numbers.
 *
 * The compared items (function parameters) should be associative arrays that
 * include a 'weight' and an '_i' elements.
 *
 * Callback for uasort() within styleswitcher_block_view() and
 * styleswitcher_admin().
 *
 * @see styleswitcher_admin()
 * @see styleswitcher_block_view()
 */
function styleswitcher_sort(array $a, array $b) {
  $property = $a['weight'] != $b['weight'] ? 'weight' : '_i';
  return $a[$property] - $b[$property];
}

/**
 * Saves the style key to the cookie.
 *
 * @param string $theme_key
 *   Name of the theme to save the style for.
 * @param string $style_key
 *   Style key to save.
 */
function styleswitcher_save_user_preference($theme_key, $style_key) {
  setcookie('styleswitcher[' . $theme_key . ']', $style_key, time() + STYLESWITCHER_COOKIE_EXPIRE, base_path());
}

/**
 * Creates a web-accessible URL for a "shipped" file.
 *
 * This function imitates D7's file_create_url() because D6's one does not work
 * with files, which ship as part of modules or themes. Also this is needed to
 * avoid breaking path in url() when clean urls are turned off.
 *
 * @param string $path
 *   The path to a shipped file or an external URL.
 *
 * @return string
 *   A string containing a URL that may be used to access the file. If the
 *   provided string is already an external path, nothing is done and the same
 *   string is returned.
 */
function _styleswitcher_file_create_url($path) {
  if (!menu_path_is_external($path)) {
    $path = $GLOBALS['base_url'] . '/' . drupal_urlencode($path);
  }
  return $path;
}

Functions

Namesort descending Description
styleswitcher_active_style_path Finds the style active for current user and returns its path.
styleswitcher_block Implements hook_block().
styleswitcher_block_info Returns info about provided blocks and their initial configuration settings.
styleswitcher_block_view Returns a renderable view of a block.
styleswitcher_css Page callback: Redirects to CSS file of currently active style.
styleswitcher_custom_styles Returns a list of custom styles.
styleswitcher_default_style_key Finds the default style and returns its key.
styleswitcher_menu Implements hook_menu().
styleswitcher_perm Implements hook_perm().
styleswitcher_preprocess_page Prepares variables for page templates: Adds the dynamic CSS to every page.
styleswitcher_save_user_preference Saves the style key to the cookie.
styleswitcher_sort Sorts styles by weight and index.
styleswitcher_styles_settings Returns a list of styles with theme-specific settings.
styleswitcher_style_load Loads a style array by its machine name and a theme name.
styleswitcher_style_load_multiple Returns a list of styles.
styleswitcher_style_title Returns style's label.
styleswitcher_switch Page callback: Switches style when JS is disabled.
styleswitcher_theme Implements hook_theme().
styleswitcher_theme_default_style_key Saves/returns the key of default style provided by a theme.
styleswitcher_theme_styles Returns a list of styles provided by a theme.
_styleswitcher_config_theme_access Access callback: Allows only admin and only for enabled themes.
_styleswitcher_file_create_url Creates a web-accessible URL for a "shipped" file.
_styleswitcher_style_name Transliterates a human-readable name to a machine name.
_styleswitcher_theme_access Access callback: Allows only for enabled themes.

Constants

Namesort descending Description
STYLESWITCHER_COOKIE_EXPIRE Indicates that the cookie must live 365 days more.