You are here

variable_realm.module in Variable 7

Same filename and directory in other branches
  1. 7.2 variable_realm/variable_realm.module

Variable API module - Realms

File

variable_realm/variable_realm.module
View source
<?php

/**
 * @file
 * Variable API module - Realms
 */

// Prefix for realm keys on query string.
define('VARIABLE_REALM_QUERY_STRING', 'variable_realm_key_');

// Prefix for realm switcher element in forms.
define('VARIABLE_REALM_FORM_SWITCHER', 'variable_realm_selector_');

/**
 * Implements hook_boot()
 *
 * We set variable realm and language code as early as possible in the page request.
 */
function variable_realm_boot() {
  variable_realm_status('global', 'default');
}

/**
 * Implements hook_init()
 *
 * Let realms be overriden by query string parameters, but only for:
 * - Admin paths (not variable admin pages)
 */
function variable_realm_init() {
  if (arg(0) == 'admin' && arg(3) != 'variable' && user_access('administer site configuration')) {
    foreach (variable_realm_params() as $realm_name => $realm_key) {
      variable_realm_switch($realm_name, $realm_key);
    }
  }
}

/**
 * Get realm parameters from query string.
 */
function variable_realm_params($realm_name = NULL) {
  $realm_params =& drupal_static(__FUNCTION__);
  if (!isset($realm_params)) {
    $realm_params = array();
    foreach (variable_realm_info() as $realm => $realm_info) {
      if (!empty($realm_info['form switcher'])) {
        $param = VARIABLE_REALM_QUERY_STRING . $realm;
        if (!empty($_GET[$param]) && array_key_exists($_GET[$param], variable_realm_keys($realm))) {
          $realm_params[$realm] = $_GET[$param];
        }
      }
    }
    drupal_alter('variable_realm_params', $realm_params);
  }
  if ($realm_name) {
    return isset($realm_params[$realm_name]) ? $realm_params[$realm_name] : FALSE;
  }
  else {
    return $realm_params;
  }
}

/**
 * Implements hook_hook_info().
 *
 * This function only specifies hooks which are NOT invoked during bootstrap.
 * See variable_realm.api.php for a complete list of hooks.
 */
function variable_realm_hook_info() {
  $hooks['variable_realm_info'] = array(
    'group' => 'variable',
  );
  $hooks['variable_realm_info_alter'] = array(
    'group' => 'variable',
  );
  return $hooks;
}

/**
 * Get information about variable realms.
 */
function variable_realm_info($realm = NULL) {
  $realm_info =& drupal_static(__FUNCTION__);
  if (!isset($realm_info)) {
    $realm_info = module_invoke_all('variable_realm_info');
    drupal_alter('variable_realm_info', $realm_info);
  }
  if ($realm) {
    return isset($realm_info[$realm]) ? $realm_info[$realm] : array();
  }
  else {
    return $realm_info;
  }
}

/**
 * Get list of all available realms ordered by default weight.
 */
function variable_realm_list() {
  $list = array();
  foreach (variable_realm_info() as $name => $info) {
    $list[$name] = $info['title'];
    uksort($list, '_variable_realm_sort');
  }
  return $list;
}

/**
 * Get keys for realm.
 */
function variable_realm_keys($realm) {
  $info = variable_realm_info($realm);
  if (!empty($info['keys callback'])) {
    $function = $info['keys callback'];
    return $function($realm, $info);
  }
  else {
    return isset($info['keys']) ? $info['keys'] : array();
  }
}

/**
 * Get options (allowed variables) for realm.
 */
function variable_realm_get_variable_options($realm_name) {
  $info = variable_realm_info($realm_name);
  return !empty($info['options']) ? $info['options'] : array_keys(variable_get_info());
}

/**
 * Get list of variable names that may be set for this realm.
 */
function variable_realm_get_variable_list($realm_name) {
  $info = variable_realm_info($realm_name);
  if (!empty($info['list callback'])) {
    $function = $info['list callback'];
    return $function($realm_name, $info);
  }
  elseif (!empty($info['select'])) {
    return variable_get('variable_realm_list_' . $realm_name, array());
  }
  else {

    // If the variable is not set it will default to all variables
    return variable_realm_get_variable_options($realm_name);
  }
}

/**
 * Implements hook_variable_realm_controller().
 */
function variable_realm_variable_realm_controller() {
  $realm['global'] = array(
    'weight' => 0,
    'class' => 'VariableRealmGlobal',
  );
  return $realm;
}

/**
 * Get class and weight information for variable realm.
 */
function variable_realm_controller($realm = NULL) {
  $data =& drupal_static(__FUNCTION__);
  if (!isset($keys)) {
    $data = module_invoke_all('variable_realm_controller');
  }
  if ($realm) {
    return isset($data[$realm]) ? $data[$realm] : NULL;
  }
  else {
    return $data;
  }
}

/**
 * Create realm controller object.
 */
function _variable_realm_controller($realm, $key, $variables = NULL) {
  $info = variable_realm_controller($realm);
  $class = isset($info['class']) ? $info['class'] : 'VariableRealmDefaultController';

  // Set realm weight if not set before.
  variable_realm_weight($realm, NULL, _variable_realm_weight($realm));
  return new $class($realm, $key, $variables);
}

/**
 * Get default weight for realm.
 *
 * Realm weight is defined in hook_variable_realm_controller() and can be overridden
 * by a variable named 'variable_realm_weight_[realm_name]'.
 */
function _variable_realm_weight($realm_name) {
  $info = variable_realm_controller($realm_name);
  $weight = $info && isset($info['weight']) ? $info['weight'] : 0;
  return variable_get('variable_realm_weight_' . $realm_name, $weight);
}

/**
 * Order realm names by weight.
 */
function _variable_realm_sort($a, $b) {
  return _variable_realm_weight($a) - _variable_realm_weight($b);
}

/**
 * Get variable realm controller.
 *
 * The first time this function is invoked we initialize the realm system
 * and store global variables in the global/default realm.
 *
 * @param $realm
 *   Name of the realm to get / create.
 * @param $key
 *   Realm key to get / create
 *
 * @return VariableRealmControllerInterface
 */
function variable_realm($realm, $key) {
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['realm'] =& drupal_static(__FUNCTION__);
    $drupal_static_fast['realm']['global']['default'] = _variable_realm_controller('global', 'default', $GLOBALS['conf']);
  }
  $variable_realm =& $drupal_static_fast['realm'];
  if (!isset($variable_realm[$realm][$key])) {
    $variable_realm[$realm][$key] = _variable_realm_controller($realm, $key);
  }
  return $variable_realm[$realm][$key];
}

/**
 * Build current realm.
 *
 * Buids an array of variables for the current realm with higher weights overriding
 * lower weights.
 */
function variable_realm_build() {
  $variables = array();
  foreach (variable_realm_current() as $realm => $key) {
    if ($key !== FALSE && ($values = variable_realm($realm, $key)
      ->variable_list())) {
      $variables = array_merge($variables, $values);
    }
  }
  return $variables;
}

/**
 * Get value from realm
 */
function variable_realm_get($realm, $key, $name = NULL, $default = NULL) {
  return variable_realm($realm, $key)
    ->variable_get($name, $default);
}

/**
 * Set values for variable realm
 *
 * @param $realm
 *   Realm name.
 * @param $key
 *   Realm key.
 * @param $values
 *   Array of runtime variable values to add to the realm.
 * @param $weight
 *   Optional explicit weight for this realm.
 * @param $rebuild
 *   Whether to rebuild domains immediately
 */
function variable_realm_add($realm, $key, $values = array(), $weight = NULL, $rebuild = TRUE) {
  $variable_realm = variable_realm($realm, $key);
  foreach ($values as $name => $value) {
    $variable_realm
      ->variable_add($name, $value);
  }
  if (isset($weight)) {
    variable_realm_weight($realm, $weight);
  }

  // Rebuild only if this is the current realm
  if ($rebuild) {
    variable_realm_rebuild($realm, $key);
  }
}

/**
 * Set variable value for realm, for page request only
 */
function variable_realm_set($realm, $key, $name, $value, $rebuild = TRUE) {
  variable_realm($realm, $key)
    ->variable_set($name, $value);
  if ($rebuild) {
    variable_realm_rebuild($realm, $key);
  }
}

/**
 * Delete variable from realm
 */
function variable_realm_del($realm, $key, $name, $rebuild = TRUE) {
  variable_realm($realm, $key)
    ->variable_del($name);
  if ($rebuild) {
    variable_realm_rebuild($realm, $key);
  }
}

/**
 * Delete variable for all keys on realm.
 *
 * @param $realm_name
 *   Realm name to delete.
 * @param $variable_name
 *   Variable name to delete.
 */
function variable_realm_delete_variable($realm_name, $variable_name, $rebuild = TRUE) {
  foreach (array_keys(variable_realm_keys($realm_name)) as $key) {
    variable_realm_del($realm_name, $key, $variable_name, FALSE);
  }
  if ($rebuild) {
    variable_realm_rebuild();
  }
}

/**
 * Get current realm values ordered by weights.
 *
 * @return array
 *   Ordered array of name => value pairs, only realms that are set.
 */
function variable_realm_current() {
  $realms = variable_realm_weight();
  $current = array_combine($realms, $realms);

  // Filter the result so we don't return unset realms
  return array_filter(array_map('variable_realm_status', $current));
}

/**
 * Get original global variable
 */
function variable_realm_global_get($name, $default = NULL) {
  return variable_realm_get('global', 'default', $name, $default);
}

/**
 * Switch global variable
 *
 * @param $name
 *   Optional global variable name. If not set, it will reset all global variables to its original value.
 * @param $value
 *   Optional new value for global variable. If not set, it will reset the variable to its original value.
 * @param $rebuild
 *   Whether to rebuild the current global $conf
 */
function variable_realm_global_set($name, $value = NULL, $rebuild = TRUE) {
  variable_realm_set('global', 'default', $name, $value, $rebuild);
}

/**
 * Set / get current realm values.
 *
 * @param $realm
 *   Optional realm name
 * @param $key
 *   Optional realm value to set a status for this realm.
 *   FALSE to disable this realm.
 */
function variable_realm_status($realm = NULL, $key = NULL) {
  $status =& drupal_static(__FUNCTION__, array());
  if ($realm && isset($key)) {

    // Make sure the realm is created.
    variable_realm($realm, $key);

    // Set current realm key.
    $status[$realm] = $key;
  }
  if ($realm) {
    return isset($status[$realm]) ? $status[$realm] : NULL;
  }
  else {
    return $status;
  }
}

/**
 * Switch current variable realms.
 *
 * @see variable_realm_weight()
 *
 * @param $realm
 *   Realm name. Example 'language'.
 * @param $key
 *   Realm key. Example, for language will be a language code, 'en
 *   FALSE to unset the realm.
 */
function variable_realm_switch($realm, $key) {

  // Check previous status, if not changed no need to rebuild.
  $current = variable_realm_status($realm);
  if (!isset($current) || $current !== $key) {
    variable_realm_status($realm, $key);
    module_invoke_all('variable_realm_switch', $realm, $key);
    variable_realm_rebuild();
  }
}

/**
 * Get / set realm weights.
 *
 * The default realm will have a weight of 0. Realms with higher weights will override
 * global variables.
 *
 * @param $realm
 *   Optional realm name
 * @param $weight
 *   Optional numeric value for realm weight.
 * @param $default
 *   Default weight to set if no $weight is set.
 * @return array()
 *   Ordered realm names.
 */
function variable_realm_weight($realm = NULL, $weight = NULL, $default = 10) {
  $current =& drupal_static(__FUNCTION__, array());
  if ($realm && !isset($current[$realm]) || isset($weight)) {
    $current[$realm] = isset($weight) ? $weight : $default;
    asort($current);
  }

  // This will always return ordered keys
  return array_keys($current);
}

/**
 * Rebuild current variable realm
 *
 * If there are $realm and $key parameters, the rebuild will happen only if this is the current realm key
 *
 * @param $realm
 *   Optional realm name that has been set
 * @param $key
 *   Optional realm value that has been set
 */
function variable_realm_rebuild($realm = NULL, $key = NULL) {
  if (!$realm || !$key || variable_realm_status($realm) == $key) {
    $GLOBALS['conf'] = variable_realm_build();
  }
}

/**
 * Reset realms, deleting currently set ones
 *
 * If no parameters passed, it will reset global variables to original values
 */
function variable_realm_reset($realms = array()) {
  $status =& drupal_static('variable_realm_status');

  // We need at least some value for the global realm
  $status = $realms + array(
    'global',
    'default',
  );
  variable_realm_rebuild();
}

/**
 * Implements hook_variable_delete().
 */
function variable_realm_variable_delete($variable, $options) {

  // If there's a realm option, we are already deleting variable for a realm only.
  if (empty($options['realm'])) {

    // Delete each variable for each current and existing realm/key
    foreach (variable_children($variable['name']) as $variable_name) {
      foreach (variable_realm_list() as $realm_name => $realm_title) {
        variable_realm_delete_variable($realm_name, $variable_name, FALSE);
      }
    }
    variable_realm_rebuild();
  }
}

/**
 * Implements hook_features_api().
 */
function variable_realm_features_api() {
  $components = array(
    'variable_realm' => array(
      'name' => t('Realm variables'),
      'default_hook' => 'variable_realm_default_variables',
      'default_file' => FEATURES_DEFAULTS_CUSTOM,
      'default_filename' => 'variable',
      'features_source' => TRUE,
      'file' => drupal_get_path('module', 'variable_realm') . '/variable_realm.features.inc',
    ),
  );
  return $components;
}

Functions

Namesort descending Description
variable_realm Get variable realm controller.
variable_realm_add Set values for variable realm
variable_realm_boot Implements hook_boot()
variable_realm_build Build current realm.
variable_realm_controller Get class and weight information for variable realm.
variable_realm_current Get current realm values ordered by weights.
variable_realm_del Delete variable from realm
variable_realm_delete_variable Delete variable for all keys on realm.
variable_realm_features_api Implements hook_features_api().
variable_realm_get Get value from realm
variable_realm_get_variable_list Get list of variable names that may be set for this realm.
variable_realm_get_variable_options Get options (allowed variables) for realm.
variable_realm_global_get Get original global variable
variable_realm_global_set Switch global variable
variable_realm_hook_info Implements hook_hook_info().
variable_realm_info Get information about variable realms.
variable_realm_init Implements hook_init()
variable_realm_keys Get keys for realm.
variable_realm_list Get list of all available realms ordered by default weight.
variable_realm_params Get realm parameters from query string.
variable_realm_rebuild Rebuild current variable realm
variable_realm_reset Reset realms, deleting currently set ones
variable_realm_set Set variable value for realm, for page request only
variable_realm_status Set / get current realm values.
variable_realm_switch Switch current variable realms.
variable_realm_variable_delete Implements hook_variable_delete().
variable_realm_variable_realm_controller Implements hook_variable_realm_controller().
variable_realm_weight Get / set realm weights.
_variable_realm_controller Create realm controller object.
_variable_realm_sort Order realm names by weight.
_variable_realm_weight Get default weight for realm.

Constants