vars.module in Variable API 7
Same filename and directory in other branches
Implement an API to handle persistent variables.
File
vars.moduleView source
<?php
/**
* @file
* Implement an API to handle persistent variables.
*/
class Vars implements ArrayAccess {
/**
* The constants for the type of variable saved in the database.
*/
const VARS_DYNAMIC = 1;
const VARS_NODE_TYPE = 3;
protected $module;
protected $sysVars = array();
/**
* Constructs a Vars object.
*
* @param $module
* The name of the module that implements the class.
* @param $options
* An array of options. The currently defined option is 'sysVars', used to
* define the default values for variables defined from modules not using
* Variable API.
*/
public function __construct($module = '', array $options = array()) {
$this->module = $module;
if (!empty($options['sysVars'])) {
$this->sysVars = $options['sysVars'];
}
}
/**
* Returns the default values for the variable passed as argument.
*
* Returns the default values for the variable passed as argument. It is used
* to get the default value for variables defined in a module that doesn't
* use the Variable API module.
*
* @param $name
* The name of the variable.
* @return
* The default value for the variable, or NULL if it is not found.
*/
protected function defaultValue($name) {
return isset($this->sysVars[$name]) ? $this->sysVars[$name] : NULL;
}
/**
* Deletes the specified persistent variables.
*
* Deletes the specified persistent variables from memory, and from the
* database.
*
* @param $names
* An array of persistent variable names.
*
* @see Vars::renameVariables()
*/
public static function deleteVariables(array $names) {
global $conf;
$count = 0;
foreach ($names as $name) {
unset($conf[$name]);
$count++;
}
if ($count) {
db_delete('variable')
->condition('name', $names, 'IN')
->execute();
cache_clear_all('variables', 'cache_bootstrap');
}
}
/**
* Returns the default value for the variables used by the module.
*
* A module using Variable API should normally implement a class derived
* from Vars, and overwrite this method.
*
* @return
* An array containing information about the implemented persistent
* variables.
*
* @see Vars::saveDefaults()
*/
protected function getDefaults() {
return array();
}
/**
* Loads the default value for all the variables respecting some conditions.
*
* This function is used to load the default value for all the variables
* respecting some conditions. The function should not be called from
* modules; it's thought to be used only from the Variable API module.
*
* @param $cid
* The cache ID of the data to retrieve.
* @param $conditions
* A DatabaseCondition object for the conditions the persistent variables
* must respect.
* @return
* An array containing information about the default value for the
* persistent variables.
*
* @see vars_node_type()
*/
public static function loadDefaults($cid, DatabaseCondition $conditions = NULL) {
if ($cache = cache_get($cid, 'cache_vars')) {
return $cache->data;
}
if ($cid == 'node_type') {
$conditions = db_and()
->condition('vd.flags', Vars::VARS_NODE_TYPE);
}
$defaults = array();
$query = db_select('variable_default', 'vd')
->fields('vd', array(
'name',
'value',
'flags',
));
if (isset($conditions)) {
$query
->condition($conditions);
}
foreach ($query
->execute() as $var) {
$index = $var->flags ? 'dynamic' : 'static';
$defaults[$index][$var->name] = unserialize($var->value);
}
drupal_alter('vars_default_values', $defaults, $cid);
cache_set($cid, $defaults, 'cache_vars');
return $defaults;
}
/**
* Implements ArrayAccess::offsetExists().
*/
public function offsetExists($offset) {
$value = $this
->offsetGet($offset);
return isset($value);
}
/**
* Implements ArrayAccess::offsetGet().
*/
public function offsetGet($offset) {
global $conf;
if (isset($conf[$offset])) {
return $conf[$offset];
}
$value = $this
->defaultValue($offset);
if (isset($value)) {
return $value;
}
$defaults =& drupal_static('vars_default_values', array());
if (isset($defaults['static'][$offset])) {
return $defaults['static'][$offset];
}
if (!empty($defaults['dynamic'])) {
foreach ($defaults['dynamic'] as $var => $value) {
if (strpos($offset, $var . '_') === 0) {
$defaults['static'][$offset] = $value;
return $value;
}
}
}
$module = db_query_range("SELECT module FROM {variable_default} WHERE name = :name OR (:name LIKE CONCAT(name, '\\_%') AND flags > 0)", 0, 1, array(
':name' => $offset,
))
->fetchField();
if (!$module) {
return NULL;
}
$vars = self::loadDefaults('module:' . $this->module, db_and()
->condition('vd.module', $this->module));
if (!empty($vars)) {
$defaults['static'] = array_merge(empty($defaults['static']) ? array() : $defaults['static'], empty($vars['static']) ? array() : $vars['static']);
$defaults['dynamic'] = array_merge(empty($defaults['dynamic']) ? array() : $defaults['dynamic'], empty($vars['dynamic']) ? array() : $vars['dynamic']);
if (isset($defaults['static'][$offset])) {
return $defaults['static'][$offset];
}
if (!empty($defaults['dynamic'])) {
foreach ($defaults['dynamic'] as $var => $value) {
if (strpos($offset, $var) === 0) {
$defaults['static'][$offset] = $value;
return $value;
}
}
}
}
}
/**
* Implements ArrayAccess::offsetSet().
*/
public function offsetSet($offset, $value) {
if (!empty($offset)) {
variable_set($offset, $value);
}
}
/**
* Implements ArrayAccess::offsetUnset().
*/
public function offsetUnset($offset) {
$this
->deleteVariables(array(
$offset,
));
}
/**
* Removes the default values contained in the table variable_default.
*
* Remove the default values that are contained in the database table
* created by the Variables API module. The function should be called from
* the implementations of hook_uninstall(), or hook_update_N().
*
* This function is deprecated. Variable API will automatically remove the default
* values from its database table, once the modules are uninstalled.
*
* @param $set
* An optional array of variables to remove. If the parameter is not
* passed, the function will remove all the variables defined from the
* module.
* The variables are also removed from memory, and from the table of
* persistent variables used by Drupal core.
*
* @see Vars::saveDefaults()
*/
public function removeDefaults(array $set = array()) {
}
/**
* Renames persistent variables.
*
* Renames the persistent variables whose name matched the passed argument.
* The variables are renamed in memory, and in the database table used by
* Drupal core code.
*
* @param $names
* A array whose keys are the names of the variables to rename, and the
* values are the new names to give to the persistent variables.
*
* @see Vars::deleteVariables()
*/
public static function renameVariables(array $names) {
global $conf;
$count = 0;
foreach ($names as $old_name => $new_name) {
if (isset($conf[$old_name])) {
$conf[$new_name] = $conf[$old_name];
db_merge('variable')
->key(array(
'name' => $new_name,
))
->fields(array(
'value' => serialize($conf[$old_name]),
))
->execute();
unset($conf[$old_name]);
$count++;
}
}
if ($count) {
db_delete('variable')
->condition('name', array_keys($names), 'IN')
->execute();
cache_clear_all('variables', 'cache_bootstrap');
}
}
/**
* Saves the default value for the variables defined from the module.
*
* Saves the default values for the variables defined from the module
* implementing a subclass of Vars.
* The function should be called from the implementations of hook_install(),
* or hook_update_N().
*/
public function saveDefaults() {
$vars = $this
->getDefaults();
if (!empty($vars) && is_array($vars)) {
foreach ($vars as $name => $info) {
if (!is_array($info)) {
$info = array(
'value' => $info,
);
}
$info += array(
'value' => '',
'flags' => 0,
);
try {
db_merge('variable_default')
->key(array(
'module' => $this->module,
'name' => $name,
))
->fields(array(
'value' => serialize($info['value']),
'flags' => $info['flags'],
))
->execute();
} catch (Exception $e) {
}
$clear_cache = TRUE;
}
if (isset($clear_cache)) {
cache_clear_all('variables', 'cache_bootstrap');
cache_clear_all('module:' . $this->module, 'cache_vars');
drupal_static_reset('vars_default_values');
}
}
}
/**
* Resets one or all centrally stored static variable(s).
*
* This static method is provided for compatibility with code using Drupal 6;
* code for Drupal 7 should use the function provided by Drupal.
*
* @param $name
* Name of the static variable to reset. Omit to reset all variables.
*/
public static function staticReset($name = NULL) {
drupal_static($name, NULL, TRUE);
}
/**
* Central static variable storage.
*
* This static method is provided for compatibility with code using Drupal 6;
* code for Drupal 7 should use the function provided by Drupal.
*
* @param $name
* Globally unique name for the variable. For a function with only one
* static variable, the function name (e.g. via the PHP magic
* __FUNCTION__ constant) is recommended. For a function with multiple
* static variables add a distinguishing suffix to the function name for
* each one.
*
* @param $default_value
* Optional default value.
*
* @param $reset
* TRUE to reset a specific named variable, or all variables if $name is
* NULL.
* Resetting every variable should only be used, for example, for running
* unit tests with a clean environment. Should be used only though via
* function vars_static_reset() and the return value should not be used in
* this case.
*
* @return
* Returns a variable by reference.
*/
public static function &staticValue($name, $default_value = NULL, $reset = FALSE) {
return drupal_static($name, $default_value, $reset);
}
}
/**
* Implements hook_boot().
*
* The hook is intentionally empty, as it is used only to assure the module is
* loaded on early bootstrap time.
*/
function vars_boot() {
}
/**
* Implements hook_flush_caches().
*/
function vars_flush_caches() {
return array(
'cache_vars',
);
}
/**
* Implements hook_modules_uninstalled().
*/
function vars_modules_uninstalled($modules) {
global $conf;
$defaults = db_select('variable_default', 'vd')
->condition('vd.module', $modules, 'IN')
->fields('vd', array(
'name',
'value',
'flags',
))
->execute();
$variables = array();
foreach ($defaults as $default) {
$name = $default->name;
if ($default->flags & self::VARS_DYNAMIC) {
$name_like = db_like($name . '_') . '%';
$vars = db_select('variable', 'v')
->condition(db_or()
->condition('v.name', $name_like, 'LIKE')
->condition('v.name', $name))
->fields('v', array(
'name',
))
->execute();
foreach ($vars as $var) {
unset($conf[$var->name]);
$variables[] = $var->name;
}
}
else {
$variables[] = $name;
unset($conf[$name]);
}
}
if (!empty($variables)) {
db_delete('variable')
->condition('name', $variables, 'IN')
->execute();
db_delete('variable_default')
->condition('module', $modules, 'IN')
->execute();
foreach ($modules as $module) {
cache_clear_all('module:' . $module, 'cache_vars');
}
cache_clear_all('variables', 'cache_bootstrap');
Vars::staticReset('vars_default_values');
}
}
/**
* Implements hook_node_type_delete().
*/
function vars_node_type_delete($info) {
global $conf;
$names = array();
$variables = Vars::loadDefaults('node_type');
if (array_key_exists('dynamic', $variables)) {
foreach (array_keys($variables['dynamic']) as $var) {
$names[] = $var->name . '_' . $info->type;
unset($conf[$var->name . '_' . $info->type]);
}
}
if (!empty($names)) {
db_delete('variable')
->condition('name', $names, 'IN')
->execute();
cache_clear_all('variables', 'cache_bootstrap');
}
}
Functions
Name | Description |
---|---|
vars_boot | Implements hook_boot(). |
vars_flush_caches | Implements hook_flush_caches(). |
vars_modules_uninstalled | Implements hook_modules_uninstalled(). |
vars_node_type_delete | Implements hook_node_type_delete(). |