';
$output .= '
' . t('List of the currently available tokens on this site') . '';
$output .= '' . theme('token_tree', array('token_types' => 'all', 'click_insert' => FALSE)) . '';
$output .= '';
return $output;
}
}
/**
* Implements hook_menu().
*/
function token_menu() {
$items['token/autocomplete'] = array(
'page callback' => 'token_autocomplete',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => 'token.pages.inc',
);
return $items;
}
/**
* Implements hook_theme().
*/
function token_theme() {
return array(
'token_tree' => array(
'variables' => array('token_types' => array(), 'global_types' => TRUE, 'click_insert' => TRUE, 'recursion_limit' => 4),
'file' => 'token.pages.inc',
),
);
}
/**
* Implements hook_library().
*/
function token_library() {
// jQuery treeTable plugin.
$libraries['treeTable'] = array(
'title' => 'jQuery treeTable',
'website' => 'http://plugins.jquery.com/project/treetable',
'version' => '2.3.0',
'js' => array(
drupal_get_path('module', 'token') . '/jquery.treeTable.js' => array(),
),
'css' => array(
drupal_get_path('module', 'token') . '/jquery.treeTable.css' => array(),
),
);
return $libraries;
}
/**
* Implements hook_entity_info_alter().
*
* Since some token types to do not match their entity type names, we have to
* map them to the proper type. This is purely for other modules' benefit.
*/
function token_entity_info_alter(&$info) {
$token_mappings = array(
'comment' => 'comment',
'node' => 'node',
'file' => 'file',
'taxonomy_term' => 'term',
'taxonomy_vocabulary' => 'vocabulary',
'user' => 'user',
);
foreach ($token_mappings as $entity_type => $token_type) {
if (isset($info[$entity_type])) {
$info[$entity_type]['token type'] = $token_type;
}
}
}
/**
* Retrieve and store token info from the cache.
*/
function token_get_info() {
global $language;
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['token_info'] = &drupal_static(__FUNCTION__);
}
$token_info = &$drupal_static_fast['token_info'];
if (empty($token_info)) {
$langcode = $language->language;
if ($cache = cache_get("token_info:$langcode")) {
$token_info = $cache->data;
}
else {
$token_info = token_info();
cache_set("token_info:$langcode", $token_info);
}
}
return $token_info;
}
/**
* Get a list of token types that can be used without any context (global).
*
* @return
* An array of global token types.
*/
function token_get_global_token_types() {
$global_types = &drupal_static(__FUNCTION__, array());
if (empty($global_types)) {
$token_info = token_get_info();
foreach ($token_info['types'] as $type => $type_info) {
// If the token types has not specified that 'needs-data' => TRUE, then
// it is a global token type that will always be replaced in any context.
if (empty($type_info['needs-data'])) {
$global_types[] = $type;
}
}
}
return $global_types;
}
/**
* Validate an tokens in raw text based on possible contexts.
*
* @param $text
* A string with the raw text containing the raw tokens.
* @param $tokens
* An array of token types that will be used when token replacement is
* performed.
* @return
* An array with the invalid tokens in their original raw forms.
*/
function token_get_invalid_tokens_by_context($text, $valid_types = array()) {
// Add the token types that are always valid in global context.
$valid_types = array_merge($valid_types, token_get_global_token_types());
$invalid_tokens = array();
foreach (token_scan($text) as $type => $tokens) {
if (!in_array($type, $valid_types)) {
// If the token type is not a valid context, its tokens are invalid.
$invalid_tokens = array_merge($invalid_tokens, array_values($tokens));
}
else {
// Check each individual token for validity.
$invalid_tokens = array_merge($invalid_tokens, token_get_invalid_tokens($type, $tokens));
}
}
array_unique($invalid_tokens);
return $invalid_tokens;
}
/**
* Validate an array of tokens based on their token type.
*
* @param $type
* The type of tokens to validate (e.g. 'node', etc.)
* @param $tokens
* A keyed array of tokens, and their original raw form in the source text.
* @return
* An array with the invalid tokens in their original raw forms.
*/
function token_get_invalid_tokens($type, $tokens) {
$token_info = token_get_info();
$invalid_tokens = array();
foreach ($tokens as $token => $full_token) {
// Split token up if it has chains.
$parts = explode(':', $token, 2);
if (!isset($token_info['tokens'][$type][$parts[0]])) {
// This is an invalid token (not defined).
$invalid_tokens[] = $full_token;
}
elseif (count($parts) == 2) {
$sub_token_info = $token_info['tokens'][$type][$parts[0]];
if (!empty($sub_token_info['dynamic'])) {
// If this token has been flagged as a dynamic token, skip it.
continue;
}
elseif (empty($sub_token_info['type'])) {
// If the token has chains, but does not support it, it is invalid.
$invalid_tokens[] = $full_token;
}
else {
// Resursively check the chained tokens.
$sub_tokens = token_find_with_prefix(array($token => $full_token), $parts[0]);
$invalid_tokens = array_merge($invalid_tokens, token_get_invalid_tokens($sub_token_info['type'], $sub_tokens));
}
}
}
return $invalid_tokens;
}