';
$output .= '
' . t('List of the currently available tokens on this site') . '';
$output .= '' . theme('token_help', 'all') . '';
$output .= '';
return $output;
}
}
/**
* For a given context, builds a formatted list of tokens and descriptions
* of their replacement values.
*
* @param type
* The token types to display documentation for. Defaults to 'all'.
* @param prefix
* The prefix your module will use when parsing tokens. Defaults to '['
* @param suffix
* The suffix your module will use when parsing tokens. Defaults to ']'
* @return An HTML table containing the formatting docs.
*/
function theme_token_help($type = 'all', $prefix = '[', $suffix = ']') {
token_include();
$full_list = token_get_list($type);
$headers = array(t('Token'), t('Replacement value'));
$rows = array();
foreach ($full_list as $key => $category) {
$rows[] = array(array('data' => drupal_ucfirst($key) .' '. t('tokens'), 'class' => 'region', 'colspan' => 2));
foreach ($category as $token => $description) {
$row = array();
$row[] = $prefix . $token . $suffix;
$row[] = $description;
$rows[] = $row;
}
}
$output = theme('table', $headers, $rows, array('class' => 'description'));
return $output;
}
/**
* Sample implementation of hook_token_values().
*
* @param type
* A flag indicating the class of substitution tokens to use. If an
* object is passed in the second param, 'type' should contain the
* object's type. For example, 'node', 'comment', or 'user'. If your
* implementation of the hook inserts globally applicable tokens that
* do not depend on a particular object, it should only return values
* when $type is 'global'.
* @param object
* Optionally, the object to use for building substitution values.
* A node, comment, user, etc.
* @return
* A keyed array containing the substitution tokens and the substitution
* values for the passed-in type and object.
*/
function token_token_values($type, $object = NULL) {
global $user;
global $base_url;
$values = array();
switch ($type) {
case 'global':
$values['user-name'] = $user->uid ? $user->name : variable_get('anonymous', t('Anonymous'));
$values['user-id'] = $user->uid ? $user->uid : 0;
$values['user-mail'] = $user->uid ? $user->mail : '';
$values['site-url'] = $base_url;
$values['site-name'] = variable_get('site_name', t('Drupal'));
$values['site-slogan'] = variable_get('site_slogan', '');
$values['site-mission'] = filter_xss_admin(variable_get('site_mission', ''));
$values['site-mail'] = variable_get('site_mail', '');
$time = time(); $tz = variable_get('date_default_timezone', 0);
$values['site-date'] = format_date($time, 'small', '', $tz);
$values += token_get_date_token_values($time, 'site-date-');
// The page number may or may not be present. If it is, it may be comma separated values in which case grab the first.
$page = isset($_GET['page']) ? $_GET['page'] : '';
$values['page-number'] = 1 + (int)(($p = strpos($page, ',')) ? substr($page, 0, $p) : $page);
break;
}
return $values;
}
/**
* Sample implementation of hook_token_list(). Documents the individual
* tokens handled by your module.
*
* @param type
* A flag indicating the class of substitution tokens to return
* information on. If this is set to 'all', a complete list is being
* built and your module should return its full list, regardless of
* type. Global tokens should always be returned, regardless of the
* $type passed in.
* @return
* A keyed array listing the substitution tokens. Elements should be
* in the form of: $list[$type][$token] = $description
*/
function token_token_list($type = 'all') {
$tokens['global']['user-name'] = t('The name of the currently logged in user.');
$tokens['global']['user-id'] = t('The user ID of the currently logged in user.');
$tokens['global']['user-mail'] = t('The email address of the currently logged in user.');
$tokens['global']['site-url'] = t('The URL of the current Drupal website.');
$tokens['global']['site-name'] = t('The name of the current Drupal website.');
$tokens['global']['site-slogan'] = t('The slogan of the current Drupal website.');
$tokens['global']['site-mission'] = t('The mission of the current Drupal website.');
$tokens['global']['site-mail'] = t('The contact email address for the current Drupal website.');
$tokens['global']['site-date'] = t("The current date on the site's server.");
$tokens['global'] += token_get_date_token_info(t('The current'), 'site-date-');
return $tokens;
}
/**
* General function to include the files that token relies on for the real work.
*/
function token_include() {
static $run = FALSE;
if (!$run) {
$run = TRUE;
$path = drupal_get_path('module', 'token');
$modules_enabled = array_keys(module_list());
$modules = array('node', 'user', 'taxonomy', 'comment');
$modules = array_intersect($modules, $modules_enabled);
foreach ($modules as $module) {
if ($module == 'content') {
$module = 'cck';
}
require_once("$path/token_$module.inc");
}
}
}
/**
* Return the value of $original, with all instances of placeholder
* tokens replaced by their proper values. To replace multiple types
* at once see token_replace_multiple().
*
* @param original
* A string, or an array of strings, to perform token substitutions
* on.
* @param type
* A flag indicating the class of substitution tokens to use. If an
* object is passed in the second param, 'type' should contain the
* object's type. For example, 'node', 'comment', or 'user'. If no
* type is specified, only 'global' site-wide substitution tokens are
* built.
* @param object
* Optionally, the object to use for building substitution values.
* A node, comment, user, etc.
* @param leading
* Character(s) to prepend to the token key before searching for
* matches. Defaults to an open-bracket.
* @param trailing
* Character(s) to append to the token key before searching for
* matches. Defaults to a close-bracket.
* @param flush
* A flag indicating whether or not to flush the token cache.
* Useful for processes that need to slog through huge numbers
* of tokens in a single execution cycle. Flushing it will
* keep them from burning through memory.
* The default is FALSE.
* @return The modified version of $original, with all substitutions
* made.
*/
function token_replace($original, $type = 'global', $object = NULL, $leading = '[', $trailing = ']', $options = array(), $flush = FALSE) {
$full = token_get_values($type, $object, $flush, $options);
return _token_replace_tokens($original, $full->tokens, $full->values, $leading, $trailing);
}
/**
* Return the value of $original, with all instances of placeholder
* tokens replaced by their proper values. Contrary to token_replace(),
* this function supports replacing multiple types.
*
* @param original
* A string, or an array of strings, to perform token substitutions
* on.
* @param types
* An array of substitution classes and optional objects. The key is
* a flag indicating the class of substitution tokens to use.
* If an object is passed as value, the key should contain the
* object's type. For example, 'node', 'comment', or 'user'. The
* object will be used for building substitution values. If no type
* is specified, only 'global' site-wide substitution tokens are built.
* @param leading
* Character(s) to prepend to the token key before searching for
* matches. Defaults to an open-bracket.
* @param trailing
* Character(s) to append to the token key before searching for
* matches. Defaults to a close-bracket.
* @param flush
* A flag indicating whether or not to flush the token cache.
* Useful for processes that need to slog through huge numbers
* of tokens in a single execution cycle. Flushing it will
* keep them from burning through memory.
* The default is FALSE.
* @return The modified version of $original, with all substitutions
* made.
*/
function token_replace_multiple($original, $types = array('global' => NULL), $leading = '[', $trailing = ']', $options = array(), $flush = FALSE) {
$full = new stdClass();
$full->tokens = $full->values = array();
foreach ($types as $type => $object) {
$temp = token_get_values($type, $object, $flush, $options);
$full->tokens = array_merge($full->tokens, $temp->tokens);
$full->values = array_merge($full->values, $temp->values);
}
return _token_replace_tokens($original, $full->tokens, $full->values, $leading, $trailing);
}
// Internally used function to replace tokens.
function _token_replace_tokens($original, $tokens, $values, $leading, $trailing) {
$tokens = token_prepare_tokens($tokens, $leading, $trailing);
return str_replace($tokens, $values, $original);
}
/**
* Return a list of valid substitution tokens and their values for
* the specified type.
*
* @param type
* A flag indicating the class of substitution tokens to use. If an
* object is passed in the second param, 'type' should contain the
* object's type. For example, 'node', 'comment', or 'user'. If no
* type is specified, only 'global' site-wide substitution tokens are
* built.
* @param object
* Optionally, the object to use for building substitution values.
* A node, comment, user, etc.
* @param flush
* A flag indicating whether or not to flush the token cache.
* Useful for processes that need to slog through huge numbers
* of tokens in a single execution cycle. Flushing it will
* keep them from burning through memory.
* The default is FALSE.
* @return
* A keyed array containing the substitution tokens and the substitution
* values for the passed-in type and object.
*/
function token_get_values($type = 'global', $object = NULL, $flush = FALSE, $options = array()) {
static $tokens;
static $running;
// Flush the static token cache. Useful for processes that need to slog through
// huge numbers of tokens in a single execution cycle. Flushing it will keep
// them from burning through memory.
if ($flush || !isset($tokens)) {
$tokens = array();
}
// Since objects in PHP5 are always passed by reference, we ensure we're
// working on a copy of the object.
if (is_object($object)) {
$object = drupal_clone($object);
}
// Simple recursion check. This is to avoid content_view()'s potential
// for endless looping when a filter uses tokens, which load the content
// view, which calls the filter, which uses tokens, which...
if ($running) {
// We'll allow things to get two levels deep, but bail out after that
// without performing any substitutions.
$result = new stdClass();
$result->tokens = array();
$result->values = array();
return $result;
}
$running = TRUE;
token_include();
$id = _token_get_id($type, $object);
if ($id && isset($tokens[$type][$id])) {
$tmp_tokens = $tokens[$type][$id];
}
else {
$tmp_tokens = module_invoke_all('token_values', $type, $object, $options);
$tokens[$type][$id] = $tmp_tokens;
}
// Special-case global tokens, as we always want to be able to process
// those substitutions.
if (!isset($tokens['global']['default'])) {
$tokens['global']['default'] = module_invoke_all('token_values', 'global');
}
$all = array_merge($tokens['global']['default'], $tokens[$type][$id]);
$result = new stdClass();
$result->tokens = array_keys($all);
$result->values = array_values($all);
$running = FALSE;
return $result;
}
/**
* A helper function that retrieves all currently exposed tokens,
* and merges them recursively. This is only necessary when building
* the token listing -- during actual value replacement, only tokens
* in a particular domain are requested and a normal array_marge() is
* sufficient.
*
* @param type
* A flag indicating the class of substitution tokens to use. If an
* object is passed in the second param, 'type' should contain the
* object's type. For example, 'node', 'comment', or 'user'. If no
* type is specified, only 'global' site-wide substitution tokens are
* built.
* @return
* The array of usable tokens and their descriptions, organized by
* token type.
*/
function token_get_list($type = 'all') {
token_include();
$return = array();
foreach (module_implements('token_list') as $module) {
$function = $module .'_token_list';
$result = $function($type);
if (is_array($result)) {
foreach ($result as $category => $tokens) {
foreach ($tokens as $token => $title) {
// Automatically append a raw token warning.
if (substr($token, -4) === '-raw' && strpos($title, t('raw user input')) === FALSE && strpos($title, '1269441371') === FALSE) {
$title .= ' ' . t('Warning: Token value contains raw user input.') . '';
}
$return[$category][$token] = $title;
}
}
}
}
return $return;
}
/**
* A helper function that transforms all the elements of an
* array. Used to change the delimiter style from brackets to
* percent symbols etc.
*
* @param tokens
* The array of tokens keys with no delimiting characters
* @param leading
* Character(s) to prepend to the token key before searching for
* matches. Defaults to an open-bracket.
* @param trailing
* Character(s) to append to the token key before searching for
* matches. Defaults to a close-bracket.
* @return
* The array of token keys, each wrapped in the specified
* delimiter style.
*/
function token_prepare_tokens($tokens = array(), $leading = '[', $trailing = ']') {
foreach ($tokens as $key => $value) {
$tokens[$key] = $leading . $value . $trailing;
}
return $tokens;
}
// Internal utility function used for static caching. There are
// almost certainly better ways to do this, but for the moment it's
// sufficient.
function _token_get_id($type = 'global', $object = NULL) {
if (!isset($object)) {
return "default";
}
switch ($type) {
case 'node':
return isset($object->nid) ? $object->nid : 0;
case 'comment':
return isset($object->cid) ? $object->cid : 0;
case 'user':
return isset($object->uid) ? $object->uid : 0;
default:
return crc32(serialize($object));
}
}
/**
* Build a list of common date tokens for use in hook_token_list().
*
* @param $description
*/
function token_get_date_token_info($description, $token_prefix = '') {
$tokens[$token_prefix . 'yyyy'] = t("!description year (four digit)", array('!description' => $description));
$tokens[$token_prefix . 'yy'] = t("!description year (two digit)", array('!description' => $description));
$tokens[$token_prefix . 'month'] = t("!description month (full word)", array('!description' => $description));
$tokens[$token_prefix . 'mon'] = t("!description month (abbreviated)", array('!description' => $description));
$tokens[$token_prefix . 'mm'] = t("!description month (two digits with leading zeros)", array('!description' => $description));
$tokens[$token_prefix . 'm'] = t("!description month (one or two digits without leading zeros)", array('!description' => $description));
$tokens[$token_prefix . 'ww'] = t("!description week (two digits with leading zeros)", array('!description' => $description));
if (version_compare(PHP_VERSION, '5.1.0', '>=')) {
$tokens[$token_prefix . 'date'] = t("!description date (numeric representation of the day of the week)", array('!description' => $description));
}
$tokens[$token_prefix . 'day'] = t("!description day (full word)", array('!description' => $description));
$tokens[$token_prefix . 'ddd'] = t("!description day (abbreviation)", array('!description' => $description));
$tokens[$token_prefix . 'dd'] = t("!description day (two digits with leading zeros)", array('!description' => $description));
$tokens[$token_prefix . 'd'] = t("!description day (one or two digits without leading zeros)", array('!description' => $description));
$tokens[$token_prefix . 'raw'] = t("!description in UNIX timestamp format (1269441371)", array('!description' => $description));
return $tokens;
}
/**
* Build a list of common date tokens for use in hook_token_values().
*
* @param $description
*/
function token_get_date_token_values($timestamp, $token_prefix = '') {
$tokens = array();
$timezone = variable_get('date_default_timezone', 0);
$formats = array(
'yyyy' => 'Y',
'yy' => 'y',
'month' => 'F',
'mon' => 'M',
'mm' => 'm',
'm' => 'n',
'ww' => 'W',
//'date' => 'N', // Provided later since it is PHP 5.1 only.
'day' => 'l',
'ddd' => 'D',
'dd' => 'd',
'd' => 'j',
);
foreach ($formats as $token => $format) {
$tokens[$token_prefix . $token] = format_date($timestamp, 'custom', $format, $timezone);
}
$tokens[$token_prefix . 'raw'] = $timestamp;
$timestamp += $timezone;
if (version_compare(PHP_VERSION, '5.1.0', '>=')) {
$tokens[$token_prefix . 'date'] = gmdate('N', $timestamp);
}
return $tokens;
}