annotate sites/all/modules/token/token.module @ 11:b0ee71395280

deleted .DS_Store files
author danieleb <danielebarchiesi@me.com>
date Mon, 28 Oct 2013 16:12:13 +0000
parents ff03f76ab3fe
children
rev   line source
danielebarchiesi@0 1 <?php
danielebarchiesi@0 2
danielebarchiesi@0 3 /**
danielebarchiesi@0 4 * @file
danielebarchiesi@0 5 * Enhances the token API in core: adds a browseable UI, missing tokens, etc.
danielebarchiesi@0 6 */
danielebarchiesi@0 7
danielebarchiesi@0 8 /**
danielebarchiesi@0 9 * The maximum depth for token tree recursion.
danielebarchiesi@0 10 */
danielebarchiesi@0 11 define('TOKEN_MAX_DEPTH', 9);
danielebarchiesi@0 12
danielebarchiesi@0 13 /**
danielebarchiesi@0 14 * Implements hook_help().
danielebarchiesi@0 15 */
danielebarchiesi@0 16 function token_help($path, $arg) {
danielebarchiesi@0 17 if ($path == 'admin/help#token') {
danielebarchiesi@0 18 if (current_path() != 'admin/help/token') {
danielebarchiesi@0 19 // Because system_modules() executes hook_help() for each module to 'test'
danielebarchiesi@0 20 // if they will return anything, but not actually display it, we want to
danielebarchiesi@0 21 // return a TRUE value if this is not actually the help page.
danielebarchiesi@0 22 return TRUE;
danielebarchiesi@0 23 }
danielebarchiesi@0 24 $output = '<dl>';
danielebarchiesi@0 25 $output .= '<dt>' . t('List of the currently available tokens on this site') . '</dt>';
danielebarchiesi@0 26 $output .= '<dd>' . theme('token_tree', array('token_types' => 'all', 'click_insert' => FALSE, 'show_restricted' => TRUE)) . '</dd>';
danielebarchiesi@0 27 $output .= '</dl>';
danielebarchiesi@0 28 return $output;
danielebarchiesi@0 29 }
danielebarchiesi@0 30 }
danielebarchiesi@0 31
danielebarchiesi@0 32 /**
danielebarchiesi@0 33 * Implements hook_system_info_alter().
danielebarchiesi@0 34 *
danielebarchiesi@0 35 * Prevent the token_actions module from being enabled since updates may have
danielebarchiesi@0 36 * left the old module files still in the directory.
danielebarchiesi@0 37 */
danielebarchiesi@0 38 function token_system_info_alter(&$info, $file, $type) {
danielebarchiesi@0 39 if ($type == 'module' && $file->name == 'token_actions') {
danielebarchiesi@0 40 $info['hidden'] = TRUE;
danielebarchiesi@0 41 }
danielebarchiesi@0 42 }
danielebarchiesi@0 43
danielebarchiesi@0 44 /**
danielebarchiesi@0 45 * Return an array of the core modules supported by token.module.
danielebarchiesi@0 46 */
danielebarchiesi@0 47 function _token_core_supported_modules() {
danielebarchiesi@0 48 return array('book', 'field', 'menu', 'profile');
danielebarchiesi@0 49 }
danielebarchiesi@0 50
danielebarchiesi@0 51 /**
danielebarchiesi@0 52 * Implements hook_menu().
danielebarchiesi@0 53 */
danielebarchiesi@0 54 function token_menu() {
danielebarchiesi@0 55 /*$items['token/autocomplete/all/%menu_tail'] = array(
danielebarchiesi@0 56 'page callback' => 'token_autocomplete',
danielebarchiesi@0 57 'access callback' => TRUE,
danielebarchiesi@0 58 'type' => MENU_CALLBACK,
danielebarchiesi@0 59 'file' => 'token.pages.inc',
danielebarchiesi@0 60 );*/
danielebarchiesi@0 61 $items['token/autocomplete/%token_type'] = array(
danielebarchiesi@0 62 'page callback' => 'token_autocomplete_token',
danielebarchiesi@0 63 'page arguments' => array(2),
danielebarchiesi@0 64 'access callback' => TRUE,
danielebarchiesi@0 65 'type' => MENU_CALLBACK,
danielebarchiesi@0 66 'file' => 'token.pages.inc',
danielebarchiesi@0 67 );
danielebarchiesi@0 68 /*$items['token/autocomplete/%token_type/%menu_tail'] = array(
danielebarchiesi@0 69 'page callback' => 'token_autocomplete_token',
danielebarchiesi@0 70 'page arguments' => array(2, 3),
danielebarchiesi@0 71 'access callback' => TRUE,
danielebarchiesi@0 72 'type' => MENU_CALLBACK,
danielebarchiesi@0 73 'file' => 'token.pages.inc',
danielebarchiesi@0 74 );*/
danielebarchiesi@0 75
danielebarchiesi@0 76 $items['token/tree'] = array(
danielebarchiesi@0 77 'page callback' => 'token_page_output_tree',
danielebarchiesi@0 78 'access callback' => TRUE,
danielebarchiesi@0 79 'type' => MENU_CALLBACK,
danielebarchiesi@0 80 'file' => 'token.pages.inc',
danielebarchiesi@0 81 'theme callback' => 'ajax_base_page_theme',
danielebarchiesi@0 82 );
danielebarchiesi@0 83
danielebarchiesi@0 84 // Devel token pages.
danielebarchiesi@0 85 if (module_exists('devel')) {
danielebarchiesi@0 86 $items['node/%node/devel/token'] = array(
danielebarchiesi@0 87 'title' => 'Tokens',
danielebarchiesi@0 88 'page callback' => 'token_devel_token_object',
danielebarchiesi@0 89 'page arguments' => array('node', 1),
danielebarchiesi@0 90 'access arguments' => array('access devel information'),
danielebarchiesi@0 91 'type' => MENU_LOCAL_TASK,
danielebarchiesi@0 92 'file' => 'token.pages.inc',
danielebarchiesi@0 93 'weight' => 5,
danielebarchiesi@0 94 );
danielebarchiesi@0 95 $items['comment/%comment/devel/token'] = array(
danielebarchiesi@0 96 'title' => 'Tokens',
danielebarchiesi@0 97 'page callback' => 'token_devel_token_object',
danielebarchiesi@0 98 'page arguments' => array('comment', 1),
danielebarchiesi@0 99 'access arguments' => array('access devel information'),
danielebarchiesi@0 100 'type' => MENU_LOCAL_TASK,
danielebarchiesi@0 101 'file' => 'token.pages.inc',
danielebarchiesi@0 102 'weight' => 5,
danielebarchiesi@0 103 );
danielebarchiesi@0 104 $items['taxonomy/term/%taxonomy_term/devel/token'] = array(
danielebarchiesi@0 105 'title' => 'Tokens',
danielebarchiesi@0 106 'page callback' => 'token_devel_token_object',
danielebarchiesi@0 107 'page arguments' => array('taxonomy_term', 2),
danielebarchiesi@0 108 'access arguments' => array('access devel information'),
danielebarchiesi@0 109 'type' => MENU_LOCAL_TASK,
danielebarchiesi@0 110 'file' => 'token.pages.inc',
danielebarchiesi@0 111 'weight' => 5,
danielebarchiesi@0 112 );
danielebarchiesi@0 113 $items['user/%user/devel/token'] = array(
danielebarchiesi@0 114 'title' => 'Tokens',
danielebarchiesi@0 115 'page callback' => 'token_devel_token_object',
danielebarchiesi@0 116 'page arguments' => array('user', 1),
danielebarchiesi@0 117 'access arguments' => array('access devel information'),
danielebarchiesi@0 118 'type' => MENU_LOCAL_TASK,
danielebarchiesi@0 119 'file' => 'token.pages.inc',
danielebarchiesi@0 120 'weight' => 5,
danielebarchiesi@0 121 );
danielebarchiesi@0 122 }
danielebarchiesi@0 123
danielebarchiesi@0 124 // Admin menu callback to clear token caches.
danielebarchiesi@0 125 $items['token/flush-cache'] = array(
danielebarchiesi@0 126 'page callback' => 'token_flush_cache_callback',
danielebarchiesi@0 127 'access arguments' => array('flush caches'),
danielebarchiesi@0 128 'type' => MENU_CALLBACK,
danielebarchiesi@0 129 'file' => 'token.pages.inc',
danielebarchiesi@0 130 );
danielebarchiesi@0 131
danielebarchiesi@0 132 return $items;
danielebarchiesi@0 133 }
danielebarchiesi@0 134
danielebarchiesi@0 135 /**
danielebarchiesi@0 136 * Implements hook_admin_menu_output_alter().
danielebarchiesi@0 137 */
danielebarchiesi@0 138 function token_admin_menu_output_alter(&$content) {
danielebarchiesi@0 139 $content['icon']['icon']['flush-cache']['token'] = array(
danielebarchiesi@0 140 '#title' => t('Token registry'),
danielebarchiesi@0 141 '#href' => 'token/flush-cache',
danielebarchiesi@0 142 '#options' => array(
danielebarchiesi@0 143 'query' => drupal_get_destination() + array('token' => drupal_get_token('token/flush-cache')),
danielebarchiesi@0 144 ),
danielebarchiesi@0 145 );
danielebarchiesi@0 146 }
danielebarchiesi@0 147
danielebarchiesi@0 148 function token_type_load($token_type) {
danielebarchiesi@0 149 $info = token_get_info();
danielebarchiesi@0 150 return isset($info['types'][$token_type]) ? $info['types'][$token_type] : FALSE;
danielebarchiesi@0 151 }
danielebarchiesi@0 152
danielebarchiesi@0 153 /**
danielebarchiesi@0 154 * Implements hook_theme().
danielebarchiesi@0 155 */
danielebarchiesi@0 156 function token_theme() {
danielebarchiesi@0 157 $info['tree_table'] = array(
danielebarchiesi@0 158 'variables' => array(
danielebarchiesi@0 159 'header' => array(),
danielebarchiesi@0 160 'rows' => array(),
danielebarchiesi@0 161 'attributes' => array(),
danielebarchiesi@0 162 'empty' => '',
danielebarchiesi@0 163 'caption' => '',
danielebarchiesi@0 164 ),
danielebarchiesi@0 165 'file' => 'token.pages.inc',
danielebarchiesi@0 166 );
danielebarchiesi@0 167 $info['token_tree'] = array(
danielebarchiesi@0 168 'variables' => array(
danielebarchiesi@0 169 'token_types' => array(),
danielebarchiesi@0 170 'global_types' => TRUE,
danielebarchiesi@0 171 'click_insert' => TRUE,
danielebarchiesi@0 172 'show_restricted' => FALSE,
danielebarchiesi@0 173 'recursion_limit' => 3,
danielebarchiesi@0 174 'dialog' => FALSE,
danielebarchiesi@0 175 ),
danielebarchiesi@0 176 'file' => 'token.pages.inc',
danielebarchiesi@0 177 );
danielebarchiesi@0 178 $info['token_tree_link'] = array(
danielebarchiesi@0 179 'variables' => array(
danielebarchiesi@0 180 'text' => NULL,
danielebarchiesi@0 181 'options' => array(),
danielebarchiesi@0 182 'dialog' => TRUE,
danielebarchiesi@0 183 ),
danielebarchiesi@0 184 'file' => 'token.pages.inc',
danielebarchiesi@0 185 );
danielebarchiesi@0 186
danielebarchiesi@0 187 return $info;
danielebarchiesi@0 188 }
danielebarchiesi@0 189
danielebarchiesi@0 190 /**
danielebarchiesi@0 191 * Implements hook_library().
danielebarchiesi@0 192 */
danielebarchiesi@0 193 function token_library() {
danielebarchiesi@0 194 // jQuery treeTable plugin.
danielebarchiesi@0 195 $libraries['treeTable'] = array(
danielebarchiesi@0 196 'title' => 'jQuery treeTable',
danielebarchiesi@0 197 'website' => 'http://plugins.jquery.com/project/treetable',
danielebarchiesi@0 198 'version' => '2.3.0',
danielebarchiesi@0 199 'js' => array(
danielebarchiesi@0 200 drupal_get_path('module', 'token') . '/jquery.treeTable.js' => array(),
danielebarchiesi@0 201 ),
danielebarchiesi@0 202 'css' => array(
danielebarchiesi@0 203 drupal_get_path('module', 'token') . '/jquery.treeTable.css' => array(),
danielebarchiesi@0 204 ),
danielebarchiesi@0 205 );
danielebarchiesi@0 206
danielebarchiesi@0 207 $libraries['dialog'] = array(
danielebarchiesi@0 208 'title' => 'Token dialog',
danielebarchiesi@0 209 'version' => '1.0',
danielebarchiesi@0 210 'js' => array(
danielebarchiesi@0 211 drupal_get_path('module', 'token') . '/token.js' => array(),
danielebarchiesi@0 212 ),
danielebarchiesi@0 213 'dependencies' => array(
danielebarchiesi@0 214 array('system', 'ui.dialog'),
danielebarchiesi@0 215 ),
danielebarchiesi@0 216 );
danielebarchiesi@0 217
danielebarchiesi@0 218 return $libraries;
danielebarchiesi@0 219 }
danielebarchiesi@0 220
danielebarchiesi@0 221 /**
danielebarchiesi@0 222 * Implements hook_form_alter().
danielebarchiesi@0 223 *
danielebarchiesi@0 224 * Adds a submit handler to forms which could affect the tokens available on
danielebarchiesi@0 225 * the site.
danielebarchiesi@0 226 */
danielebarchiesi@0 227 function token_form_alter(&$form, $form_state, $form_id) {
danielebarchiesi@0 228 switch ($form_id) {
danielebarchiesi@0 229 // Profile field forms.
danielebarchiesi@0 230 case 'profile_field_form':
danielebarchiesi@0 231 case 'profile_field_delete':
danielebarchiesi@0 232 // User picture form.
danielebarchiesi@0 233 case 'user_admin_settings':
danielebarchiesi@0 234 // System date type form.
danielebarchiesi@0 235 // @todo Remove when http://drupal.org/node/1173706 is fixed.
danielebarchiesi@0 236 case 'system_add_date_format_type_form':
danielebarchiesi@0 237 case 'system_delete_date_format_type_form':
danielebarchiesi@0 238 $form += array('#submit' => array());
danielebarchiesi@0 239 array_unshift($form['#submit'], 'token_clear_cache');
danielebarchiesi@0 240 break;
danielebarchiesi@0 241 }
danielebarchiesi@0 242 }
danielebarchiesi@0 243
danielebarchiesi@0 244 /**
danielebarchiesi@0 245 * Implements hook_block_view_alter().
danielebarchiesi@0 246 */
danielebarchiesi@0 247 function token_block_view_alter(&$data, $block) {
danielebarchiesi@0 248 if (!empty($block->title) && $block->title != '<none>') {
danielebarchiesi@0 249 // Perform unsanitized token replacement since _block_render_blocks() will
danielebarchiesi@0 250 // call check_plain() on $block->title.
danielebarchiesi@0 251 $block->title = token_replace($block->title, array(), array('sanitize' => FALSE));
danielebarchiesi@0 252 }
danielebarchiesi@0 253 }
danielebarchiesi@0 254
danielebarchiesi@0 255 /**
danielebarchiesi@0 256 * Implements hook_form_FORM_ID_alter().
danielebarchiesi@0 257 */
danielebarchiesi@0 258 function token_form_block_add_block_form_alter(&$form, $form_state) {
danielebarchiesi@0 259 token_form_block_admin_configure_alter($form, $form_state);
danielebarchiesi@0 260 }
danielebarchiesi@0 261
danielebarchiesi@0 262 /**
danielebarchiesi@0 263 * Implements hook_form_FORM_ID_alter().
danielebarchiesi@0 264 */
danielebarchiesi@0 265 function token_form_block_admin_configure_alter(&$form, $form_state) {
danielebarchiesi@0 266 $form['settings']['title']['#description'] .= ' ' . t('This field supports tokens.');
danielebarchiesi@0 267 // @todo Figure out why this token validation does not seem to be working here.
danielebarchiesi@0 268 $form['settings']['title']['#element_validate'][] = 'token_element_validate';
danielebarchiesi@0 269 $form['settings']['title'] += array('#token_types' => array());
danielebarchiesi@0 270 }
danielebarchiesi@0 271
danielebarchiesi@0 272 /**
danielebarchiesi@0 273 * Implements hook_widget_form_alter().
danielebarchiesi@0 274 */
danielebarchiesi@0 275 function token_field_widget_form_alter(&$element, &$form_state, $context) {
danielebarchiesi@0 276 if (!empty($element['#description']) && is_string($element['#description'])) {
danielebarchiesi@0 277 $element['#description'] = filter_xss_admin(token_replace($element['#description']));
danielebarchiesi@0 278 }
danielebarchiesi@0 279 }
danielebarchiesi@0 280
danielebarchiesi@0 281 /**
danielebarchiesi@0 282 * Implements hook_field_info_alter().
danielebarchiesi@0 283 */
danielebarchiesi@0 284 function token_field_info_alter(&$info) {
danielebarchiesi@0 285 $defaults = array(
danielebarchiesi@0 286 'taxonomy_term_reference' => 'taxonomy_term_reference_plain',
danielebarchiesi@0 287 'number_integer' => 'number_unformatted',
danielebarchiesi@0 288 'number_decimal' => 'number_unformatted',
danielebarchiesi@0 289 'number_float' => 'number_unformatted',
danielebarchiesi@0 290 'file' => 'file_url_plain',
danielebarchiesi@0 291 'image' => 'file_url_plain',
danielebarchiesi@0 292 'text' => 'text_default',
danielebarchiesi@0 293 'text_long' => 'text_default',
danielebarchiesi@0 294 'text_with_summary' => 'text_default',
danielebarchiesi@0 295 'list_integer' => 'list_default',
danielebarchiesi@0 296 'list_float' => 'list_default',
danielebarchiesi@0 297 'list_text' => 'list_default',
danielebarchiesi@0 298 'list_boolean' => 'list_default',
danielebarchiesi@0 299 );
danielebarchiesi@0 300 foreach ($defaults as $field_type => $default_token_formatter) {
danielebarchiesi@0 301 if (isset($info[$field_type])) {
danielebarchiesi@0 302 $info[$field_type] += array('default_token_formatter' => $default_token_formatter);
danielebarchiesi@0 303 }
danielebarchiesi@0 304 }
danielebarchiesi@0 305 }
danielebarchiesi@0 306
danielebarchiesi@0 307 /**
danielebarchiesi@0 308 * Implements hook_field_display_alter().
danielebarchiesi@0 309 */
danielebarchiesi@0 310 function token_field_display_alter(&$display, $context) {
danielebarchiesi@0 311 if ($context['view_mode'] == 'token') {
danielebarchiesi@0 312 $view_mode_settings = field_view_mode_settings($context['instance']['entity_type'], $context['instance']['bundle']);
danielebarchiesi@0 313 // If the token view mode fell back to the 'default' view mode, then
danielebarchiesi@0 314 // use the default token formatter.
danielebarchiesi@0 315 if (empty($view_mode_settings[$context['view_mode']]['custom_settings'])) {
danielebarchiesi@0 316 $field_type_info = field_info_field_types($context['field']['type']);
danielebarchiesi@0 317
danielebarchiesi@0 318 // If the field has specified a specific formatter to be used by default
danielebarchiesi@0 319 // with tokens, use that, otherwise use the default formatter.
danielebarchiesi@0 320 $formatter = !empty($field_type_info['default_token_formatter']) ? $field_type_info['default_token_formatter'] : $field_type_info['default_formatter'];
danielebarchiesi@0 321
danielebarchiesi@0 322 // Now that we have a formatter, fill in all the settings.
danielebarchiesi@0 323 $display['type'] = $formatter;
danielebarchiesi@0 324 $formatter_info = field_info_formatter_types($formatter);
danielebarchiesi@0 325 $display['settings'] = isset($formatter_info['settings']) ? $formatter_info['settings'] : array();
danielebarchiesi@0 326 $display['settings']['label'] = 'hidden';
danielebarchiesi@0 327 $display['module'] = $formatter_info['module'];
danielebarchiesi@0 328 }
danielebarchiesi@0 329 }
danielebarchiesi@0 330 }
danielebarchiesi@0 331
danielebarchiesi@0 332 /**
danielebarchiesi@0 333 * Implements hook_field_create_instance().
danielebarchiesi@0 334 */
danielebarchiesi@0 335 function token_field_create_instance($instance) {
danielebarchiesi@0 336 token_clear_cache();
danielebarchiesi@0 337 }
danielebarchiesi@0 338
danielebarchiesi@0 339 /**
danielebarchiesi@0 340 * Implements hook_field_update_instance().
danielebarchiesi@0 341 */
danielebarchiesi@0 342 function token_field_update_instance($instance) {
danielebarchiesi@0 343 token_clear_cache();
danielebarchiesi@0 344 }
danielebarchiesi@0 345
danielebarchiesi@0 346 /**
danielebarchiesi@0 347 * Implements hook_field_delete_instance().
danielebarchiesi@0 348 */
danielebarchiesi@0 349 function token_field_delete_instance($instance) {
danielebarchiesi@0 350 token_clear_cache();
danielebarchiesi@0 351 }
danielebarchiesi@0 352
danielebarchiesi@0 353 /**
danielebarchiesi@0 354 * Clear token caches and static variables.
danielebarchiesi@0 355 */
danielebarchiesi@0 356 function token_clear_cache() {
danielebarchiesi@0 357 if (db_table_exists('cache_token')) {
danielebarchiesi@0 358 cache_clear_all('*', 'cache_token', TRUE);
danielebarchiesi@0 359 }
danielebarchiesi@0 360 drupal_static_reset('token_get_info');
danielebarchiesi@0 361 drupal_static_reset('token_get_global_token_types');
danielebarchiesi@0 362 drupal_static_reset('token_get_entity_mapping');
danielebarchiesi@0 363 drupal_static_reset('token_build_tree');
danielebarchiesi@0 364 drupal_static_reset('_token_profile_fields');
danielebarchiesi@0 365 drupal_static_reset('token_menu_link_load');
danielebarchiesi@0 366 drupal_static_reset('token_book_link_load');
danielebarchiesi@0 367 drupal_static_reset('token_node_menu_link_load');
danielebarchiesi@0 368 drupal_static_reset('_token_field_info');
danielebarchiesi@0 369 }
danielebarchiesi@0 370
danielebarchiesi@0 371 /**
danielebarchiesi@0 372 * Return an array of entity type to token type mappings.
danielebarchiesi@0 373 *
danielebarchiesi@0 374 * Why do we need this? Because when the token API was moved to core we did not
danielebarchiesi@0 375 * re-use the entity type as the base name for taxonomy terms and vocabulary
danielebarchiesi@0 376 * tokens.
danielebarchiesi@0 377 *
danielebarchiesi@0 378 * @see token_entity_info_alter()
danielebarchiesi@0 379 * @see http://drupal.org/node/737726
danielebarchiesi@0 380 */
danielebarchiesi@0 381 function token_get_entity_mapping($value_type = 'token', $value = NULL, $fallback = FALSE) {
danielebarchiesi@0 382 $mapping = &drupal_static(__FUNCTION__, array());
danielebarchiesi@0 383
danielebarchiesi@0 384 if (empty($mapping)) {
danielebarchiesi@0 385 foreach (entity_get_info() as $entity_type => $info) {
danielebarchiesi@0 386 $mapping[$entity_type] = !empty($info['token type']) ? $info['token type'] : $entity_type;
danielebarchiesi@0 387 }
danielebarchiesi@0 388 // Allow modules to alter the mapping array.
danielebarchiesi@0 389 drupal_alter('token_entity_mapping', $mapping);
danielebarchiesi@0 390 }
danielebarchiesi@0 391
danielebarchiesi@0 392 if (!isset($value)) {
danielebarchiesi@0 393 return $value_type == 'token' ? array_flip($mapping) : $mapping;
danielebarchiesi@0 394 }
danielebarchiesi@0 395 elseif ($value_type == 'token') {
danielebarchiesi@0 396 $return = array_search($value, $mapping);
danielebarchiesi@0 397 return $return !== FALSE ? $return : ($fallback ? $value : FALSE);
danielebarchiesi@0 398 }
danielebarchiesi@0 399 elseif ($value_type == 'entity') {
danielebarchiesi@0 400 return isset($mapping[$value]) ? $mapping[$value] : ($fallback ? $value : FALSE);
danielebarchiesi@0 401 }
danielebarchiesi@0 402 }
danielebarchiesi@0 403
danielebarchiesi@0 404 /**
danielebarchiesi@0 405 * Implements hook_entity_info_alter().
danielebarchiesi@0 406 *
danielebarchiesi@0 407 * Because some token types to do not match their entity type names, we have to
danielebarchiesi@0 408 * map them to the proper type. This is purely for other modules' benefit.
danielebarchiesi@0 409 *
danielebarchiesi@0 410 * @see token_get_entity_mapping()
danielebarchiesi@0 411 * @see http://drupal.org/node/737726
danielebarchiesi@0 412 */
danielebarchiesi@0 413 function token_entity_info_alter(&$info) {
danielebarchiesi@0 414 foreach (array_keys($info) as $entity_type) {
danielebarchiesi@0 415 // Add a token view mode if it does not already exist.
danielebarchiesi@0 416 if (!empty($info[$entity_type]['view modes']) && !isset($info[$entity_type]['view modes']['token'])) {
danielebarchiesi@0 417 $info[$entity_type]['view modes']['token'] = array(
danielebarchiesi@0 418 'label' => t('Tokens'),
danielebarchiesi@0 419 'custom settings' => FALSE,
danielebarchiesi@0 420 );
danielebarchiesi@0 421 }
danielebarchiesi@0 422
danielebarchiesi@0 423 if (!empty($info[$entity_type]['token type'])) {
danielebarchiesi@0 424 // If the entity's token type is already defined, great!
danielebarchiesi@0 425 continue;
danielebarchiesi@0 426 }
danielebarchiesi@0 427
danielebarchiesi@0 428 // Fill in default token types for entities.
danielebarchiesi@0 429 switch ($entity_type) {
danielebarchiesi@0 430 case 'taxonomy_term':
danielebarchiesi@0 431 case 'taxonomy_vocabulary':
danielebarchiesi@0 432 // Stupid taxonomy token types...
danielebarchiesi@0 433 $info[$entity_type]['token type'] = str_replace('taxonomy_', '', $entity_type);
danielebarchiesi@0 434 break;
danielebarchiesi@0 435 default:
danielebarchiesi@0 436 // By default the token type is the same as the entity type.
danielebarchiesi@0 437 $info[$entity_type]['token type'] = $entity_type;
danielebarchiesi@0 438 break;
danielebarchiesi@0 439 }
danielebarchiesi@0 440 }
danielebarchiesi@0 441 }
danielebarchiesi@0 442
danielebarchiesi@0 443 /**
danielebarchiesi@0 444 * Implements hook_module_implements_alter().
danielebarchiesi@0 445 *
danielebarchiesi@0 446 * Adds missing token support for core modules.
danielebarchiesi@0 447 */
danielebarchiesi@0 448 function token_module_implements_alter(&$implementations, $hook) {
danielebarchiesi@0 449 module_load_include('inc', 'token', 'token.tokens');
danielebarchiesi@0 450
danielebarchiesi@0 451 if ($hook == 'tokens' || $hook == 'token_info' || $hook == 'token_info_alter' || $hook == 'tokens_alter') {
danielebarchiesi@0 452 foreach (_token_core_supported_modules() as $module) {
danielebarchiesi@0 453 if (module_exists($module) && function_exists($module . '_' . $hook)) {
danielebarchiesi@0 454 $implementations[$module] = FALSE;
danielebarchiesi@0 455 }
danielebarchiesi@0 456 }
danielebarchiesi@0 457 // Move token.module to get included first since it is responsible for
danielebarchiesi@0 458 // other modules.
danielebarchiesi@0 459 unset($implementations['token']);
danielebarchiesi@0 460 $implementations = array_merge(array('token' => 'tokens'), $implementations);
danielebarchiesi@0 461 }
danielebarchiesi@0 462 }
danielebarchiesi@0 463
danielebarchiesi@0 464 /**
danielebarchiesi@0 465 * Implements hook_flush_caches().
danielebarchiesi@0 466 */
danielebarchiesi@0 467 function token_flush_caches() {
danielebarchiesi@0 468 if (db_table_exists('cache_token')) {
danielebarchiesi@0 469 return array('cache_token');
danielebarchiesi@0 470 }
danielebarchiesi@0 471 }
danielebarchiesi@0 472
danielebarchiesi@0 473 /**
danielebarchiesi@0 474 * Retrieve, sort, store token info from the cache.
danielebarchiesi@0 475 *
danielebarchiesi@0 476 * @param $token_type
danielebarchiesi@0 477 * The optional token type that if specified will return
danielebarchiesi@0 478 * $info['types'][$token_type].
danielebarchiesi@0 479 * @param $token
danielebarchiesi@0 480 * The optional token name if specified will return
danielebarchiesi@0 481 * $info['tokens'][$token_type][$token].
danielebarchiesi@0 482 *
danielebarchiesi@0 483 * @return
danielebarchiesi@0 484 * An array of all token information from hook_token_info(), or the array
danielebarchiesi@0 485 * of a token type or specific token.
danielebarchiesi@0 486 *
danielebarchiesi@0 487 * @see hook_token_info()
danielebarchiesi@0 488 * @see hook_token_info_alter()
danielebarchiesi@0 489 */
danielebarchiesi@0 490 function token_get_info($token_type = NULL, $token = NULL) {
danielebarchiesi@0 491 global $language;
danielebarchiesi@0 492
danielebarchiesi@0 493 // Use the advanced drupal_static() pattern, since this is called very often.
danielebarchiesi@0 494 static $drupal_static_fast;
danielebarchiesi@0 495 if (!isset($drupal_static_fast)) {
danielebarchiesi@0 496 $drupal_static_fast['token_info'] = &drupal_static(__FUNCTION__);
danielebarchiesi@0 497 }
danielebarchiesi@0 498 $token_info = &$drupal_static_fast['token_info'];
danielebarchiesi@0 499
danielebarchiesi@0 500 if (empty($token_info)) {
danielebarchiesi@0 501 $cid = "info:{$language->language}";
danielebarchiesi@0 502
danielebarchiesi@0 503 if ($cache = cache_get($cid, 'cache_token')) {
danielebarchiesi@0 504 $token_info = $cache->data;
danielebarchiesi@0 505 }
danielebarchiesi@0 506 else {
danielebarchiesi@0 507 $token_info = token_info();
danielebarchiesi@0 508
danielebarchiesi@0 509 foreach (array_keys($token_info['types']) as $type_key) {
danielebarchiesi@0 510 if (isset($token_info['types'][$type_key]['type'])) {
danielebarchiesi@0 511 $base_type = $token_info['types'][$type_key]['type'];
danielebarchiesi@0 512 // If this token type extends another token type, then merge in
danielebarchiesi@0 513 // the base token type's tokens.
danielebarchiesi@0 514 if (isset($token_info['tokens'][$base_type])) {
danielebarchiesi@0 515 $token_info['tokens'] += array($type_key => array());
danielebarchiesi@0 516 $token_info['tokens'][$type_key] += $token_info['tokens'][$base_type];
danielebarchiesi@0 517 }
danielebarchiesi@0 518 }
danielebarchiesi@0 519 else {
danielebarchiesi@0 520 // Add a 'type' value to each token type so we can properly use
danielebarchiesi@0 521 // token_type_load().
danielebarchiesi@0 522 $token_info['types'][$type_key]['type'] = $type_key;
danielebarchiesi@0 523 }
danielebarchiesi@0 524 }
danielebarchiesi@0 525
danielebarchiesi@0 526 // Pre-sort tokens.
danielebarchiesi@0 527 uasort($token_info['types'], 'token_asort_tokens');
danielebarchiesi@0 528 foreach (array_keys($token_info['tokens']) as $type) {
danielebarchiesi@0 529 uasort($token_info['tokens'][$type], 'token_asort_tokens');
danielebarchiesi@0 530 }
danielebarchiesi@0 531
danielebarchiesi@0 532 // Store info in cache for future use.
danielebarchiesi@0 533 cache_set($cid, $token_info, 'cache_token');
danielebarchiesi@0 534 }
danielebarchiesi@0 535 }
danielebarchiesi@0 536
danielebarchiesi@0 537 if (isset($token_type) && isset($token)) {
danielebarchiesi@0 538 return isset($token_info['tokens'][$token_type][$token]) ? $token_info['tokens'][$token_type][$token] : NULL;
danielebarchiesi@0 539 }
danielebarchiesi@0 540 elseif (isset($token_type)) {
danielebarchiesi@0 541 return isset($token_info['types'][$token_type]) ? $token_info['types'][$token_type] : NULL;
danielebarchiesi@0 542 }
danielebarchiesi@0 543 else {
danielebarchiesi@0 544 return $token_info;
danielebarchiesi@0 545 }
danielebarchiesi@0 546 }
danielebarchiesi@0 547
danielebarchiesi@0 548 /**
danielebarchiesi@0 549 * Return the module responsible for a token.
danielebarchiesi@0 550 *
danielebarchiesi@0 551 * @param string $type
danielebarchiesi@0 552 * The token type.
danielebarchiesi@0 553 * @param string $name
danielebarchiesi@0 554 * The token name.
danielebarchiesi@0 555 *
danielebarchiesi@0 556 * @return mixed
danielebarchiesi@0 557 * The value of $info['tokens'][$type][$name]['module'] from token_get_info(),
danielebarchiesi@0 558 * or NULL if the value does not exist.
danielebarchiesi@0 559 */
danielebarchiesi@0 560 function _token_module($type, $name) {
danielebarchiesi@0 561 $token_info = token_get_info($type, $name);
danielebarchiesi@0 562 return isset($token_info['module']) ? $token_info['module'] : NULL;
danielebarchiesi@0 563 }
danielebarchiesi@0 564
danielebarchiesi@0 565 /**
danielebarchiesi@0 566 * uasort() callback to sort tokens by the 'name' property.
danielebarchiesi@0 567 */
danielebarchiesi@0 568 function token_asort_tokens($token_a, $token_b) {
danielebarchiesi@0 569 return strnatcmp($token_a['name'], $token_b['name']);
danielebarchiesi@0 570 }
danielebarchiesi@0 571
danielebarchiesi@0 572 /**
danielebarchiesi@0 573 * Get a list of token types that can be used without any context (global).
danielebarchiesi@0 574 *
danielebarchiesi@0 575 * @return
danielebarchiesi@0 576 * An array of global token types.
danielebarchiesi@0 577 */
danielebarchiesi@0 578 function token_get_global_token_types() {
danielebarchiesi@0 579 $global_types = &drupal_static(__FUNCTION__, array());
danielebarchiesi@0 580
danielebarchiesi@0 581 if (empty($global_types)) {
danielebarchiesi@0 582 $token_info = token_get_info();
danielebarchiesi@0 583 foreach ($token_info['types'] as $type => $type_info) {
danielebarchiesi@0 584 // If the token types has not specified that 'needs-data' => TRUE, then
danielebarchiesi@0 585 // it is a global token type that will always be replaced in any context.
danielebarchiesi@0 586 if (empty($type_info['needs-data'])) {
danielebarchiesi@0 587 $global_types[] = $type;
danielebarchiesi@0 588 }
danielebarchiesi@0 589 }
danielebarchiesi@0 590 }
danielebarchiesi@0 591
danielebarchiesi@0 592 return $global_types;
danielebarchiesi@0 593 }
danielebarchiesi@0 594
danielebarchiesi@0 595 /**
danielebarchiesi@0 596 * Validate an tokens in raw text based on possible contexts.
danielebarchiesi@0 597 *
danielebarchiesi@0 598 * @param $value
danielebarchiesi@0 599 * A string with the raw text containing the raw tokens, or an array of
danielebarchiesi@0 600 * tokens from token_scan().
danielebarchiesi@0 601 * @param $tokens
danielebarchiesi@0 602 * An array of token types that will be used when token replacement is
danielebarchiesi@0 603 * performed.
danielebarchiesi@0 604 * @return
danielebarchiesi@0 605 * An array with the invalid tokens in their original raw forms.
danielebarchiesi@0 606 */
danielebarchiesi@0 607 function token_get_invalid_tokens_by_context($value, $valid_types = array()) {
danielebarchiesi@0 608 if (in_array('all', $valid_types)) {
danielebarchiesi@0 609 $info = token_get_info();
danielebarchiesi@0 610 $valid_types = array_keys($info['types']);
danielebarchiesi@0 611 }
danielebarchiesi@0 612 else {
danielebarchiesi@0 613 // Add the token types that are always valid in global context.
danielebarchiesi@0 614 $valid_types = array_merge($valid_types, token_get_global_token_types());
danielebarchiesi@0 615 }
danielebarchiesi@0 616
danielebarchiesi@0 617 $invalid_tokens = array();
danielebarchiesi@0 618 $value_tokens = is_string($value) ? token_scan($value) : $value;
danielebarchiesi@0 619
danielebarchiesi@0 620 foreach ($value_tokens as $type => $tokens) {
danielebarchiesi@0 621 if (!in_array($type, $valid_types)) {
danielebarchiesi@0 622 // If the token type is not a valid context, its tokens are invalid.
danielebarchiesi@0 623 $invalid_tokens = array_merge($invalid_tokens, array_values($tokens));
danielebarchiesi@0 624 }
danielebarchiesi@0 625 else {
danielebarchiesi@0 626 // Check each individual token for validity.
danielebarchiesi@0 627 $invalid_tokens = array_merge($invalid_tokens, token_get_invalid_tokens($type, $tokens));
danielebarchiesi@0 628 }
danielebarchiesi@0 629 }
danielebarchiesi@0 630
danielebarchiesi@0 631 array_unique($invalid_tokens);
danielebarchiesi@0 632 return $invalid_tokens;
danielebarchiesi@0 633 }
danielebarchiesi@0 634
danielebarchiesi@0 635 /**
danielebarchiesi@0 636 * Validate an array of tokens based on their token type.
danielebarchiesi@0 637 *
danielebarchiesi@0 638 * @param $type
danielebarchiesi@0 639 * The type of tokens to validate (e.g. 'node', etc.)
danielebarchiesi@0 640 * @param $tokens
danielebarchiesi@0 641 * A keyed array of tokens, and their original raw form in the source text.
danielebarchiesi@0 642 * @return
danielebarchiesi@0 643 * An array with the invalid tokens in their original raw forms.
danielebarchiesi@0 644 */
danielebarchiesi@0 645 function token_get_invalid_tokens($type, $tokens) {
danielebarchiesi@0 646 $token_info = token_get_info();
danielebarchiesi@0 647 $invalid_tokens = array();
danielebarchiesi@0 648
danielebarchiesi@0 649 foreach ($tokens as $token => $full_token) {
danielebarchiesi@0 650 // Split token up if it has chains.
danielebarchiesi@0 651 $parts = explode(':', $token, 2);
danielebarchiesi@0 652
danielebarchiesi@0 653 if (!isset($token_info['tokens'][$type][$parts[0]])) {
danielebarchiesi@0 654 // This is an invalid token (not defined).
danielebarchiesi@0 655 $invalid_tokens[] = $full_token;
danielebarchiesi@0 656 }
danielebarchiesi@0 657 elseif (count($parts) == 2) {
danielebarchiesi@0 658 $sub_token_info = $token_info['tokens'][$type][$parts[0]];
danielebarchiesi@0 659 if (!empty($sub_token_info['dynamic'])) {
danielebarchiesi@0 660 // If this token has been flagged as a dynamic token, skip it.
danielebarchiesi@0 661 continue;
danielebarchiesi@0 662 }
danielebarchiesi@0 663 elseif (empty($sub_token_info['type'])) {
danielebarchiesi@0 664 // If the token has chains, but does not support it, it is invalid.
danielebarchiesi@0 665 $invalid_tokens[] = $full_token;
danielebarchiesi@0 666 }
danielebarchiesi@0 667 else {
danielebarchiesi@0 668 // Resursively check the chained tokens.
danielebarchiesi@0 669 $sub_tokens = token_find_with_prefix(array($token => $full_token), $parts[0]);
danielebarchiesi@0 670 $invalid_tokens = array_merge($invalid_tokens, token_get_invalid_tokens($sub_token_info['type'], $sub_tokens));
danielebarchiesi@0 671 }
danielebarchiesi@0 672 }
danielebarchiesi@0 673 }
danielebarchiesi@0 674
danielebarchiesi@0 675 return $invalid_tokens;
danielebarchiesi@0 676 }
danielebarchiesi@0 677
danielebarchiesi@0 678 /**
danielebarchiesi@0 679 * Validate a form element that should have tokens in it.
danielebarchiesi@0 680 *
danielebarchiesi@0 681 * Form elements that want to add this validation should have the #token_types
danielebarchiesi@0 682 * parameter defined.
danielebarchiesi@0 683 *
danielebarchiesi@0 684 * For example:
danielebarchiesi@0 685 * @code
danielebarchiesi@0 686 * $form['my_node_text_element'] = array(
danielebarchiesi@0 687 * '#type' => 'textfield',
danielebarchiesi@0 688 * '#title' => t('Some text to token-ize that has a node context.'),
danielebarchiesi@0 689 * '#default_value' => 'The title of this node is [node:title].',
danielebarchiesi@0 690 * '#element_validate' => array('token_element_validate'),
danielebarchiesi@0 691 * '#token_types' => array('node'),
danielebarchiesi@0 692 * '#min_tokens' => 1,
danielebarchiesi@0 693 * '#max_tokens' => 10,
danielebarchiesi@0 694 * );
danielebarchiesi@0 695 * @endcode
danielebarchiesi@0 696 */
danielebarchiesi@0 697 function token_element_validate(&$element, &$form_state) {
danielebarchiesi@0 698 $value = isset($element['#value']) ? $element['#value'] : $element['#default_value'];
danielebarchiesi@0 699
danielebarchiesi@0 700 if (!drupal_strlen($value)) {
danielebarchiesi@0 701 // Empty value needs no further validation since the element should depend
danielebarchiesi@0 702 // on using the '#required' FAPI property.
danielebarchiesi@0 703 return $element;
danielebarchiesi@0 704 }
danielebarchiesi@0 705
danielebarchiesi@0 706 $tokens = token_scan($value);
danielebarchiesi@0 707 $title = empty($element['#title']) ? $element['#parents'][0] : $element['#title'];
danielebarchiesi@0 708 // @todo Find old Drupal 6 style tokens and add them to invalid tokens.
danielebarchiesi@0 709
danielebarchiesi@0 710 // Validate if an element must have a minimum number of tokens.
danielebarchiesi@0 711 if (isset($element['#min_tokens']) && count($tokens) < $element['#min_tokens']) {
danielebarchiesi@0 712 // @todo Change this error message to include the minimum number.
danielebarchiesi@0 713 $error = format_plural($element['#min_tokens'], 'The %element-title cannot contain fewer than one token.', 'The %element-title must contain at least @count tokens.', array('%element-title' => $title));
danielebarchiesi@0 714 form_error($element, $error);
danielebarchiesi@0 715 }
danielebarchiesi@0 716
danielebarchiesi@0 717 // Validate if an element must have a maximum number of tokens.
danielebarchiesi@0 718 if (isset($element['#max_tokens']) && count($tokens) > $element['#max_tokens']) {
danielebarchiesi@0 719 // @todo Change this error message to include the maximum number.
danielebarchiesi@0 720 $error = format_plural($element['#max_tokens'], 'The %element-title must contain as most one token.', 'The %element-title must contain at most @count tokens.', array('%element-title' => $title));
danielebarchiesi@0 721 form_error($element, $error);
danielebarchiesi@0 722 }
danielebarchiesi@0 723
danielebarchiesi@0 724 // Check if the field defines specific token types.
danielebarchiesi@0 725 if (isset($element['#token_types'])) {
danielebarchiesi@0 726 $invalid_tokens = token_get_invalid_tokens_by_context($tokens, $element['#token_types']);
danielebarchiesi@0 727 if ($invalid_tokens) {
danielebarchiesi@0 728 form_error($element, t('The %element-title is using the following invalid tokens: @invalid-tokens.', array('%element-title' => $title, '@invalid-tokens' => implode(', ', $invalid_tokens))));
danielebarchiesi@0 729 }
danielebarchiesi@0 730 }
danielebarchiesi@0 731
danielebarchiesi@0 732 return $element;
danielebarchiesi@0 733 }
danielebarchiesi@0 734
danielebarchiesi@0 735 /**
danielebarchiesi@0 736 * Deprecated. Use token_element_validate() instead.
danielebarchiesi@0 737 */
danielebarchiesi@0 738 function token_element_validate_token_context(&$element, &$form_state) {
danielebarchiesi@0 739 return token_element_validate($element, $form_state);
danielebarchiesi@0 740 }
danielebarchiesi@0 741
danielebarchiesi@0 742 /**
danielebarchiesi@0 743 * Implements hook_form_FORM_ID_alter().
danielebarchiesi@0 744 */
danielebarchiesi@0 745 function token_form_field_ui_field_edit_form_alter(&$form, $form_state) {
danielebarchiesi@0 746 if (!isset($form['instance']) || !empty($form['#field']['locked'])) {
danielebarchiesi@0 747 return;
danielebarchiesi@0 748 }
danielebarchiesi@0 749
danielebarchiesi@0 750 if (($form['#field']['type'] == 'file' || $form['#field']['type'] == 'image') && isset($form['instance']['settings']['file_directory']) && !module_exists('filefield_paths')) {
danielebarchiesi@0 751 // GAH! We can only support global tokens in the upload file directory path.
danielebarchiesi@0 752 $form['instance']['settings']['file_directory']['#element_validate'][] = 'token_element_validate';
danielebarchiesi@0 753 $form['instance']['settings']['file_directory'] += array('#token_types' => array());
danielebarchiesi@0 754 $form['instance']['settings']['file_directory']['#description'] .= ' ' . t('This field supports tokens.');
danielebarchiesi@0 755 }
danielebarchiesi@0 756
danielebarchiesi@0 757 // Note that the description is tokenized via token_field_widget_form_alter().
danielebarchiesi@0 758 $form['instance']['description']['#description'] .= '<br />' . t('This field supports tokens.');
danielebarchiesi@0 759 $form['instance']['description']['#element_validate'][] = 'token_element_validate';
danielebarchiesi@0 760 $form['instance']['description'] += array('#token_types' => array());
danielebarchiesi@0 761
danielebarchiesi@0 762 $form['instance']['settings']['token_tree'] = array(
danielebarchiesi@0 763 '#theme' => 'token_tree',
danielebarchiesi@0 764 '#token_types' => array(),
danielebarchiesi@0 765 '#dialog' => TRUE,
danielebarchiesi@0 766 '#weight' => $form['instance']['description']['#weight'] + 0.5,
danielebarchiesi@0 767 );
danielebarchiesi@0 768 }
danielebarchiesi@0 769
danielebarchiesi@0 770 /**
danielebarchiesi@0 771 * Implements hook_form_FORM_ID_alter().
danielebarchiesi@0 772 *
danielebarchiesi@0 773 * Alters the configure action form to add token context validation and
danielebarchiesi@0 774 * adds the token tree for a better token UI and selection.
danielebarchiesi@0 775 */
danielebarchiesi@0 776 function token_form_system_actions_configure_alter(&$form, $form_state) {
danielebarchiesi@0 777 $action = actions_function_lookup($form['actions_action']['#value']);
danielebarchiesi@0 778
danielebarchiesi@0 779 switch ($action) {
danielebarchiesi@0 780 case 'system_message_action':
danielebarchiesi@0 781 case 'system_send_email_action':
danielebarchiesi@0 782 case 'system_goto_action':
danielebarchiesi@0 783 $form['token_tree'] = array(
danielebarchiesi@0 784 '#theme' => 'token_tree',
danielebarchiesi@0 785 '#token_types' => 'all',
danielebarchiesi@0 786 '#dialog' => TRUE,
danielebarchiesi@0 787 '#weight' => 100,
danielebarchiesi@0 788 );
danielebarchiesi@0 789 // @todo Add token validation to the action fields that can use tokens.
danielebarchiesi@0 790 break;
danielebarchiesi@0 791 }
danielebarchiesi@0 792 }
danielebarchiesi@0 793
danielebarchiesi@0 794 /**
danielebarchiesi@0 795 * Implements hook_form_FORM_ID_alter().
danielebarchiesi@0 796 *
danielebarchiesi@0 797 * Alters the user e-mail fields to add token context validation and
danielebarchiesi@0 798 * adds the token tree for a better token UI and selection.
danielebarchiesi@0 799 */
danielebarchiesi@0 800 function token_form_user_admin_settings_alter(&$form, &$form_state) {
danielebarchiesi@0 801 $email_token_help = t('Available variables are: [site:name], [site:url], [user:name], [user:mail], [site:login-url], [site:url-brief], [user:edit-url], [user:one-time-login-url], [user:cancel-url].');
danielebarchiesi@0 802
danielebarchiesi@0 803 foreach (element_children($form) as $key) {
danielebarchiesi@0 804 $element = &$form[$key];
danielebarchiesi@0 805
danielebarchiesi@0 806 // Remove the crummy default token help text.
danielebarchiesi@0 807 if (!empty($element['#description'])) {
danielebarchiesi@0 808 $element['#description'] = trim(str_replace($email_token_help, t('The list of available tokens that can be used in e-mails is provided below.'), $element['#description']));
danielebarchiesi@0 809 }
danielebarchiesi@0 810
danielebarchiesi@0 811 switch ($key) {
danielebarchiesi@0 812 case 'email_admin_created':
danielebarchiesi@0 813 case 'email_pending_approval':
danielebarchiesi@0 814 case 'email_no_approval_required':
danielebarchiesi@0 815 case 'email_password_reset':
danielebarchiesi@0 816 case 'email_cancel_confirm':
danielebarchiesi@0 817 // Do nothing, but allow execution to continue.
danielebarchiesi@0 818 break;
danielebarchiesi@0 819 case 'email_activated':
danielebarchiesi@0 820 case 'email_blocked':
danielebarchiesi@0 821 case 'email_canceled':
danielebarchiesi@0 822 // These fieldsets have their e-mail elements inside a 'settings'
danielebarchiesi@0 823 // sub-element, so switch to that element instead.
danielebarchiesi@0 824 $element = &$form[$key]['settings'];
danielebarchiesi@0 825 break;
danielebarchiesi@0 826 default:
danielebarchiesi@0 827 continue 2;
danielebarchiesi@0 828 }
danielebarchiesi@0 829
danielebarchiesi@0 830 foreach (element_children($element) as $sub_key) {
danielebarchiesi@0 831 if (!isset($element[$sub_key]['#type'])) {
danielebarchiesi@0 832 continue;
danielebarchiesi@0 833 }
danielebarchiesi@0 834 elseif ($element[$sub_key]['#type'] == 'textfield' && substr($sub_key, -8) === '_subject') {
danielebarchiesi@0 835 // Add validation to subject textfields.
danielebarchiesi@0 836 $element[$sub_key]['#element_validate'][] = 'token_element_validate';
danielebarchiesi@0 837 $element[$sub_key] += array('#token_types' => array('user'));
danielebarchiesi@0 838 }
danielebarchiesi@0 839 elseif ($element[$sub_key]['#type'] == 'textarea' && substr($sub_key, -5) === '_body') {
danielebarchiesi@0 840 // Add validation to body textareas.
danielebarchiesi@0 841 $element[$sub_key]['#element_validate'][] = 'token_element_validate';
danielebarchiesi@0 842 $element[$sub_key] += array('#token_types' => array('user'));
danielebarchiesi@0 843 }
danielebarchiesi@0 844 }
danielebarchiesi@0 845 }
danielebarchiesi@0 846
danielebarchiesi@0 847 // Add the token tree UI.
danielebarchiesi@0 848 $form['email']['token_tree'] = array(
danielebarchiesi@0 849 '#theme' => 'token_tree',
danielebarchiesi@0 850 '#token_types' => array('user'),
danielebarchiesi@0 851 '#show_restricted' => TRUE,
danielebarchiesi@0 852 '#dialog' => TRUE,
danielebarchiesi@0 853 '#weight' => 90,
danielebarchiesi@0 854 );
danielebarchiesi@0 855 }
danielebarchiesi@0 856
danielebarchiesi@0 857 /**
danielebarchiesi@0 858 * Build a tree array of tokens used for themeing or information.
danielebarchiesi@0 859 *
danielebarchiesi@0 860 * @param $token_type
danielebarchiesi@0 861 * The token type.
danielebarchiesi@0 862 * @param $flat_tree
danielebarchiesi@0 863 * A boolean if TRUE will only make a flat array of tokens, otherwise
danielebarchiesi@0 864 * child tokens will be inside the 'children' parameter of a token.
danielebarchiesi@0 865 * @param $show_restricted
danielebarchiesi@0 866 * A boolean if TRUE will show restricted tokens. Otherwise they will be
danielebarchiesi@0 867 * hidden. Default is FALSE.
danielebarchiesi@0 868 * @param $recursion_limit
danielebarchiesi@0 869 * An integer with the maximum number of token levels to recurse.
danielebarchiesi@0 870 * @param $parents
danielebarchiesi@0 871 * An optional array with the current parents of the tokens.
danielebarchiesi@0 872 */
danielebarchiesi@0 873 function token_build_tree($token_type, array $options = array()) {
danielebarchiesi@0 874 global $language;
danielebarchiesi@0 875
danielebarchiesi@0 876 // Static cache of already built token trees.
danielebarchiesi@0 877 $trees = &drupal_static(__FUNCTION__, array());
danielebarchiesi@0 878
danielebarchiesi@0 879 $options += array(
danielebarchiesi@0 880 'restricted' => FALSE,
danielebarchiesi@0 881 'depth' => 4,
danielebarchiesi@0 882 'data' => array(),
danielebarchiesi@0 883 'values' => FALSE,
danielebarchiesi@0 884 'flat' => FALSE,
danielebarchiesi@0 885 );
danielebarchiesi@0 886
danielebarchiesi@0 887 // Do not allow past the maximum token information depth.
danielebarchiesi@0 888 $options['depth'] = min($options['depth'], TOKEN_MAX_DEPTH);
danielebarchiesi@0 889
danielebarchiesi@0 890 // If $token_type is an entity, make sure we are using the actual token type.
danielebarchiesi@0 891 if ($entity_token_type = token_get_entity_mapping('entity', $token_type)) {
danielebarchiesi@0 892 $token_type = $entity_token_type;
danielebarchiesi@0 893 }
danielebarchiesi@0 894
danielebarchiesi@0 895 $tree_cid = "tree:{$token_type}:{$language->language}:{$options['depth']}";
danielebarchiesi@0 896
danielebarchiesi@0 897 // If we do not have this base tree in the static cache, check {cache_token}
danielebarchiesi@0 898 // otherwise generate and store it in the cache.
danielebarchiesi@0 899 if (!isset($trees[$tree_cid])) {
danielebarchiesi@0 900 if ($cache = cache_get($tree_cid, 'cache_token')) {
danielebarchiesi@0 901 $trees[$tree_cid] = $cache->data;
danielebarchiesi@0 902 }
danielebarchiesi@0 903 else {
danielebarchiesi@0 904 $options['parents'] = array();
danielebarchiesi@0 905 $trees[$tree_cid] = _token_build_tree($token_type, $options);
danielebarchiesi@0 906 cache_set($tree_cid, $trees[$tree_cid], 'cache_token');
danielebarchiesi@0 907 }
danielebarchiesi@0 908 }
danielebarchiesi@0 909
danielebarchiesi@0 910 $tree = $trees[$tree_cid];
danielebarchiesi@0 911
danielebarchiesi@0 912 // If the user has requested a flat tree, convert it.
danielebarchiesi@0 913 if (!empty($options['flat'])) {
danielebarchiesi@0 914 $tree = token_flatten_tree($tree);
danielebarchiesi@0 915 }
danielebarchiesi@0 916
danielebarchiesi@0 917 // Fill in token values.
danielebarchiesi@0 918 if (!empty($options['values'])) {
danielebarchiesi@0 919 $token_values = array();
danielebarchiesi@0 920 foreach ($tree as $token => $token_info) {
danielebarchiesi@0 921 if (!empty($token_info['dynamic']) || !empty($token_info['restricted'])) {
danielebarchiesi@0 922 continue;
danielebarchiesi@0 923 }
danielebarchiesi@0 924 elseif (!isset($token_info['value'])) {
danielebarchiesi@0 925 $token_values[$token_info['token']] = $token;
danielebarchiesi@0 926 }
danielebarchiesi@0 927 }
danielebarchiesi@0 928 if (!empty($token_values)) {
danielebarchiesi@0 929 $token_values = token_generate($token_type, $token_values, $options['data']);
danielebarchiesi@0 930 foreach ($token_values as $token => $replacement) {
danielebarchiesi@0 931 $tree[$token]['value'] = $replacement;
danielebarchiesi@0 932 }
danielebarchiesi@0 933 }
danielebarchiesi@0 934 }
danielebarchiesi@0 935
danielebarchiesi@0 936 return $tree;
danielebarchiesi@0 937 }
danielebarchiesi@0 938
danielebarchiesi@0 939 /**
danielebarchiesi@0 940 * Flatten a token tree.
danielebarchiesi@0 941 */
danielebarchiesi@0 942 function token_flatten_tree($tree) {
danielebarchiesi@0 943 $result = array();
danielebarchiesi@0 944 foreach ($tree as $token => $token_info) {
danielebarchiesi@0 945 $result[$token] = $token_info;
danielebarchiesi@0 946 if (isset($token_info['children']) && is_array($token_info['children'])) {
danielebarchiesi@0 947 $result += token_flatten_tree($token_info['children']);
danielebarchiesi@0 948 // unset($result[$token]['children']);
danielebarchiesi@0 949 }
danielebarchiesi@0 950 }
danielebarchiesi@0 951 return $result;
danielebarchiesi@0 952 }
danielebarchiesi@0 953
danielebarchiesi@0 954 /**
danielebarchiesi@0 955 * Generate a token tree.
danielebarchiesi@0 956 */
danielebarchiesi@0 957 function _token_build_tree($token_type, array $options) {
danielebarchiesi@0 958 $options += array(
danielebarchiesi@0 959 'parents' => array(),
danielebarchiesi@0 960 );
danielebarchiesi@0 961
danielebarchiesi@0 962 $info = token_get_info();
danielebarchiesi@0 963 if ($options['depth'] <= 0 || !isset($info['types'][$token_type]) || !isset($info['tokens'][$token_type])) {
danielebarchiesi@0 964 return array();
danielebarchiesi@0 965 }
danielebarchiesi@0 966
danielebarchiesi@0 967 $tree = array();
danielebarchiesi@0 968 foreach ($info['tokens'][$token_type] as $token => $token_info) {
danielebarchiesi@0 969 // Build the raw token string.
danielebarchiesi@0 970 $token_parents = $options['parents'];
danielebarchiesi@0 971 if (empty($token_parents)) {
danielebarchiesi@0 972 // If the parents array is currently empty, assume the token type is its
danielebarchiesi@0 973 // parent.
danielebarchiesi@0 974 $token_parents[] = $token_type;
danielebarchiesi@0 975 }
danielebarchiesi@0 976 elseif (in_array($token, array_slice($token_parents, 1))) {
danielebarchiesi@0 977 // Prevent duplicate recursive tokens. For example, this will prevent
danielebarchiesi@0 978 // the tree from generating the following tokens or deeper:
danielebarchiesi@0 979 // [comment:parent:parent]
danielebarchiesi@0 980 // [comment:parent:root:parent]
danielebarchiesi@0 981 continue;
danielebarchiesi@0 982 }
danielebarchiesi@0 983
danielebarchiesi@0 984 $token_parents[] = $token;
danielebarchiesi@0 985 if (!empty($token_info['dynamic'])) {
danielebarchiesi@0 986 $token_parents[] = '?';
danielebarchiesi@0 987 }
danielebarchiesi@0 988 $raw_token = '[' . implode(':', $token_parents) . ']';
danielebarchiesi@0 989 $tree[$raw_token] = $token_info;
danielebarchiesi@0 990 $tree[$raw_token]['raw token'] = $raw_token;
danielebarchiesi@0 991
danielebarchiesi@0 992 // Add the token's real name (leave out the base token type).
danielebarchiesi@0 993 $tree[$raw_token]['token'] = implode(':', array_slice($token_parents, 1));
danielebarchiesi@0 994
danielebarchiesi@0 995 // Add the token's parent as its raw token value.
danielebarchiesi@0 996 if (!empty($options['parents'])) {
danielebarchiesi@0 997 $tree[$raw_token]['parent'] = '[' . implode(':', $options['parents']) . ']';
danielebarchiesi@0 998 }
danielebarchiesi@0 999
danielebarchiesi@0 1000 // Fetch the child tokens.
danielebarchiesi@0 1001 if (!empty($token_info['type'])) {
danielebarchiesi@0 1002 $child_options = $options;
danielebarchiesi@0 1003 $child_options['depth']--;
danielebarchiesi@0 1004 $child_options['parents'] = $token_parents;
danielebarchiesi@0 1005 $tree[$raw_token]['children'] = _token_build_tree($token_info['type'], $child_options);
danielebarchiesi@0 1006 }
danielebarchiesi@0 1007 }
danielebarchiesi@0 1008
danielebarchiesi@0 1009 return $tree;
danielebarchiesi@0 1010 }
danielebarchiesi@0 1011
danielebarchiesi@0 1012 /**
danielebarchiesi@0 1013 * Get a translated menu link by its mlid, without access checking.
danielebarchiesi@0 1014 *
danielebarchiesi@0 1015 * This function is a copy of menu_link_load() but with its own cache and a
danielebarchiesi@0 1016 * simpler query to load the link. This also skips normal menu link access
danielebarchiesi@0 1017 * checking by using _token_menu_link_translate().
danielebarchiesi@0 1018 *
danielebarchiesi@0 1019 * @param $mlid
danielebarchiesi@0 1020 * The mlid of the menu item.
danielebarchiesi@0 1021 *
danielebarchiesi@0 1022 * @return
danielebarchiesi@0 1023 * A menu link translated for rendering.
danielebarchiesi@0 1024 *
danielebarchiesi@0 1025 * @see menu_link_load()
danielebarchiesi@0 1026 * @see _token_menu_link_translate()
danielebarchiesi@0 1027 */
danielebarchiesi@0 1028 function token_menu_link_load($mlid) {
danielebarchiesi@0 1029 $cache = &drupal_static(__FUNCTION__, array());
danielebarchiesi@0 1030
danielebarchiesi@0 1031 if (!is_numeric($mlid)) {
danielebarchiesi@0 1032 return FALSE;
danielebarchiesi@0 1033 }
danielebarchiesi@0 1034
danielebarchiesi@0 1035 if (!isset($cache[$mlid])) {
danielebarchiesi@0 1036 $item = db_query("SELECT * FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.mlid = :mlid", array(':mlid' => $mlid))->fetchAssoc();
danielebarchiesi@0 1037 if (!empty($item)) {
danielebarchiesi@0 1038 _token_menu_link_translate($item);
danielebarchiesi@0 1039 }
danielebarchiesi@0 1040 $cache[$mlid] = $item;
danielebarchiesi@0 1041 }
danielebarchiesi@0 1042
danielebarchiesi@0 1043 return $cache[$mlid];
danielebarchiesi@0 1044 }
danielebarchiesi@0 1045
danielebarchiesi@0 1046 /**
danielebarchiesi@0 1047 * Get a translated book menu link by its mlid, without access checking.
danielebarchiesi@0 1048 *
danielebarchiesi@0 1049 * This function is a copy of book_link_load() but with its own cache and a
danielebarchiesi@0 1050 * simpler query to load the link. This also skips normal menu link access
danielebarchiesi@0 1051 * checking by using _token_menu_link_translate().
danielebarchiesi@0 1052 *
danielebarchiesi@0 1053 * @param $mlid
danielebarchiesi@0 1054 * The mlid of the book menu item.
danielebarchiesi@0 1055 *
danielebarchiesi@0 1056 * @return
danielebarchiesi@0 1057 * A book menu link translated for rendering.
danielebarchiesi@0 1058 *
danielebarchiesi@0 1059 * @see book_link_load()
danielebarchiesi@0 1060 * @see _token_menu_link_translate()
danielebarchiesi@0 1061 */
danielebarchiesi@0 1062 function token_book_link_load($mlid) {
danielebarchiesi@0 1063 $cache = &drupal_static(__FUNCTION__, array());
danielebarchiesi@0 1064
danielebarchiesi@0 1065 if (!is_numeric($mlid)) {
danielebarchiesi@0 1066 return FALSE;
danielebarchiesi@0 1067 }
danielebarchiesi@0 1068
danielebarchiesi@0 1069 if (!isset($cache[$mlid])) {
danielebarchiesi@0 1070 $item = db_query("SELECT * FROM {menu_links} ml INNER JOIN {book} b ON b.mlid = ml.mlid LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.mlid = :mlid", array(':mlid' => $mlid))->fetchAssoc();
danielebarchiesi@0 1071 if (!empty($item)) {
danielebarchiesi@0 1072 _token_menu_link_translate($item);
danielebarchiesi@0 1073 }
danielebarchiesi@0 1074 $cache[$mlid] = $item;
danielebarchiesi@0 1075 }
danielebarchiesi@0 1076
danielebarchiesi@0 1077 return $cache[$mlid];
danielebarchiesi@0 1078 }
danielebarchiesi@0 1079
danielebarchiesi@0 1080 function _token_menu_link_translate(&$item) {
danielebarchiesi@0 1081 $map = array();
danielebarchiesi@0 1082
danielebarchiesi@0 1083 if (!is_array($item['options'])) {
danielebarchiesi@0 1084 $item['options'] = unserialize($item['options']);
danielebarchiesi@0 1085 }
danielebarchiesi@0 1086
danielebarchiesi@0 1087 if ($item['external']) {
danielebarchiesi@0 1088 $item['access'] = 1;
danielebarchiesi@0 1089 $item['href'] = $item['link_path'];
danielebarchiesi@0 1090 $item['title'] = $item['link_title'];
danielebarchiesi@0 1091 $item['localized_options'] = $item['options'];
danielebarchiesi@0 1092 }
danielebarchiesi@0 1093 else {
danielebarchiesi@0 1094 // Complete the path of the menu link with elements from the current path,
danielebarchiesi@0 1095 // if it contains dynamic placeholders (%).
danielebarchiesi@0 1096 $map = explode('/', $item['link_path']);
danielebarchiesi@0 1097 if (strpos($item['link_path'], '%') !== FALSE) {
danielebarchiesi@0 1098 // Invoke registered to_arg callbacks.
danielebarchiesi@0 1099 if (!empty($item['to_arg_functions'])) {
danielebarchiesi@0 1100 _menu_link_map_translate($map, $item['to_arg_functions']);
danielebarchiesi@0 1101 }
danielebarchiesi@0 1102 }
danielebarchiesi@0 1103 $item['href'] = implode('/', $map);
danielebarchiesi@0 1104
danielebarchiesi@0 1105 // Skip links containing untranslated arguments.
danielebarchiesi@0 1106 if (strpos($item['href'], '%') !== FALSE) {
danielebarchiesi@0 1107 $item['access'] = FALSE;
danielebarchiesi@0 1108 return FALSE;
danielebarchiesi@0 1109 }
danielebarchiesi@0 1110
danielebarchiesi@0 1111 $item['access'] = TRUE;
danielebarchiesi@0 1112 _menu_item_localize($item, $map, TRUE);
danielebarchiesi@0 1113 }
danielebarchiesi@0 1114
danielebarchiesi@0 1115 // Allow other customizations - e.g. adding a page-specific query string to the
danielebarchiesi@0 1116 // options array. For performance reasons we only invoke this hook if the link
danielebarchiesi@0 1117 // has the 'alter' flag set in the options array.
danielebarchiesi@0 1118 if (!empty($item['options']['alter'])) {
danielebarchiesi@0 1119 drupal_alter('translated_menu_link', $item, $map);
danielebarchiesi@0 1120 }
danielebarchiesi@0 1121
danielebarchiesi@0 1122 return $map;
danielebarchiesi@0 1123 }
danielebarchiesi@0 1124
danielebarchiesi@0 1125 /**
danielebarchiesi@0 1126 * Prepare a string for use as a valid token name.
danielebarchiesi@0 1127 *
danielebarchiesi@0 1128 * @param $name
danielebarchiesi@0 1129 * The token name to clean.
danielebarchiesi@0 1130 * @return
danielebarchiesi@0 1131 * The cleaned token name.
danielebarchiesi@0 1132 */
danielebarchiesi@0 1133 function token_clean_token_name($name) {
danielebarchiesi@0 1134 static $names = array();
danielebarchiesi@0 1135
danielebarchiesi@0 1136 if (!isset($names[$name])) {
danielebarchiesi@0 1137 $cleaned_name = strtr($name, array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => ''));
danielebarchiesi@0 1138 $cleaned_name = preg_replace('/[^\w\-]/i', '', $cleaned_name);
danielebarchiesi@0 1139 $cleaned_name = trim($cleaned_name, '-');
danielebarchiesi@0 1140 $names[$name] = $cleaned_name;
danielebarchiesi@0 1141 }
danielebarchiesi@0 1142
danielebarchiesi@0 1143 return $names[$name];
danielebarchiesi@0 1144 }
danielebarchiesi@0 1145
danielebarchiesi@0 1146 /**
danielebarchiesi@0 1147 * Do not use this function yet. Its API has not been finalized.
danielebarchiesi@0 1148 */
danielebarchiesi@0 1149 function token_render_array(array $array, array $options = array()) {
danielebarchiesi@0 1150 $rendered = array();
danielebarchiesi@0 1151 foreach (element_children($array) as $key) {
danielebarchiesi@0 1152 $value = $array[$key];
danielebarchiesi@0 1153 $rendered[] = is_array($value) ? render($value) : (string) $value;
danielebarchiesi@0 1154 }
danielebarchiesi@0 1155 if (!empty($options['sanitize'])) {
danielebarchiesi@0 1156 $rendered = array_map('check_plain', $rendered);
danielebarchiesi@0 1157 }
danielebarchiesi@0 1158 $join = isset($options['join']) ? $options['join'] : ', ';
danielebarchiesi@0 1159 return implode($join, $rendered);
danielebarchiesi@0 1160 }
danielebarchiesi@0 1161
danielebarchiesi@0 1162 /**
danielebarchiesi@0 1163 * Do not use this function yet. Its API has not been finalized.
danielebarchiesi@0 1164 */
danielebarchiesi@0 1165 function token_render_array_value($value, array $options = array()) {
danielebarchiesi@0 1166 $rendered = is_array($value) ? render($value) : (string) $value;
danielebarchiesi@0 1167 if (!empty($options['sanitize'])) {
danielebarchiesi@0 1168 $rendered = check_plain($rendered);
danielebarchiesi@0 1169 }
danielebarchiesi@0 1170 return $rendered;
danielebarchiesi@0 1171 }
danielebarchiesi@0 1172
danielebarchiesi@0 1173 /**
danielebarchiesi@0 1174 * Copy of drupal_render_cache_get() that does not care about request method.
danielebarchiesi@0 1175 */
danielebarchiesi@0 1176 function token_render_cache_get($elements) {
danielebarchiesi@0 1177 if (!$cid = drupal_render_cid_create($elements)) {
danielebarchiesi@0 1178 return FALSE;
danielebarchiesi@0 1179 }
danielebarchiesi@0 1180 $bin = isset($elements['#cache']['bin']) ? $elements['#cache']['bin'] : 'cache';
danielebarchiesi@0 1181
danielebarchiesi@0 1182 if (!empty($cid) && $cache = cache_get($cid, $bin)) {
danielebarchiesi@0 1183 // Add additional libraries, JavaScript, CSS and other data attached
danielebarchiesi@0 1184 // to this element.
danielebarchiesi@0 1185 if (isset($cache->data['#attached'])) {
danielebarchiesi@0 1186 drupal_process_attached($cache->data);
danielebarchiesi@0 1187 }
danielebarchiesi@0 1188 // Return the rendered output.
danielebarchiesi@0 1189 return $cache->data['#markup'];
danielebarchiesi@0 1190 }
danielebarchiesi@0 1191 return FALSE;
danielebarchiesi@0 1192 }
danielebarchiesi@0 1193
danielebarchiesi@0 1194 /**
danielebarchiesi@0 1195 * Coyp of drupal_render_cache_set() that does not care about request method.
danielebarchiesi@0 1196 */
danielebarchiesi@0 1197 function token_render_cache_set(&$markup, $elements) {
danielebarchiesi@0 1198 // This should only run of drupal_render_cache_set() did not.
danielebarchiesi@0 1199 if (in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD'))) {
danielebarchiesi@0 1200 return FALSE;
danielebarchiesi@0 1201 }
danielebarchiesi@0 1202
danielebarchiesi@0 1203 $original_method = $_SERVER['REQUEST_METHOD'];
danielebarchiesi@0 1204 $_SERVER['REQUEST_METHOD'] = 'GET';
danielebarchiesi@0 1205 drupal_render_cache_set($markup, $elements);
danielebarchiesi@0 1206 $_SERVER['REQUEST_METHOD'] = $original_method;
danielebarchiesi@0 1207 }
danielebarchiesi@0 1208
danielebarchiesi@0 1209 function token_menu_link_load_all_parents($mlid) {
danielebarchiesi@0 1210 $cache = &drupal_static(__FUNCTION__, array());
danielebarchiesi@0 1211
danielebarchiesi@0 1212 if (!is_numeric($mlid)) {
danielebarchiesi@0 1213 return array();
danielebarchiesi@0 1214 }
danielebarchiesi@0 1215
danielebarchiesi@0 1216 if (!isset($cache[$mlid])) {
danielebarchiesi@0 1217 $cache[$mlid] = array();
danielebarchiesi@0 1218 $plid = db_query("SELECT plid FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $mlid))->fetchField();
danielebarchiesi@0 1219 while ($plid && $parent = token_menu_link_load($plid)) {
danielebarchiesi@0 1220 $cache[$mlid] = array($plid => $parent['title']) + $cache[$mlid];
danielebarchiesi@0 1221 $plid = $parent['plid'];
danielebarchiesi@0 1222 }
danielebarchiesi@0 1223 }
danielebarchiesi@0 1224
danielebarchiesi@0 1225 return $cache[$mlid];
danielebarchiesi@0 1226 }
danielebarchiesi@0 1227
danielebarchiesi@0 1228 function token_taxonomy_term_load_all_parents($tid) {
danielebarchiesi@0 1229 $cache = &drupal_static(__FUNCTION__, array());
danielebarchiesi@0 1230
danielebarchiesi@0 1231 if (!is_numeric($tid)) {
danielebarchiesi@0 1232 return array();
danielebarchiesi@0 1233 }
danielebarchiesi@0 1234
danielebarchiesi@0 1235 if (!isset($cache[$tid])) {
danielebarchiesi@0 1236 $cache[$tid] = array();
danielebarchiesi@0 1237 $parents = taxonomy_get_parents_all($tid);
danielebarchiesi@0 1238 array_shift($parents); // Remove this term from the array.
danielebarchiesi@0 1239 $parents = array_reverse($parents);
danielebarchiesi@0 1240 foreach ($parents as $term) {
danielebarchiesi@0 1241 $cache[$tid][$term->tid] = entity_label('taxonomy_term', $term);
danielebarchiesi@0 1242 }
danielebarchiesi@0 1243 }
danielebarchiesi@0 1244
danielebarchiesi@0 1245 return $cache[$tid];
danielebarchiesi@0 1246 }
danielebarchiesi@0 1247
danielebarchiesi@0 1248 /**
danielebarchiesi@0 1249 * Load the preferred menu link associated with a node.
danielebarchiesi@0 1250 *
danielebarchiesi@0 1251 * @param $node
danielebarchiesi@0 1252 * A node object.
danielebarchiesi@0 1253 *
danielebarchiesi@0 1254 * @return
danielebarchiesi@0 1255 * A menu link array from token_menu_link_load() or FALSE if a menu link was
danielebarchiesi@0 1256 * not found.
danielebarchiesi@0 1257 *
danielebarchiesi@0 1258 * @see menu_node_prepare()
danielebarchiesi@0 1259 * @see token_menu_link_load()
danielebarchiesi@0 1260 */
danielebarchiesi@0 1261 function token_node_menu_link_load($node) {
danielebarchiesi@0 1262 $cache = &drupal_static(__FUNCTIon__, array());
danielebarchiesi@0 1263
danielebarchiesi@0 1264 if (!isset($cache[$node->nid])) {
danielebarchiesi@0 1265 $mlid = FALSE;
danielebarchiesi@0 1266
danielebarchiesi@0 1267 // Nodes do not have their menu links loaded via menu_node_load().
danielebarchiesi@0 1268 if (!isset($node->menu)) {
danielebarchiesi@0 1269 // We need to clone the node as menu_node_prepare() may cause data loss.
danielebarchiesi@0 1270 // @see http://drupal.org/node/1317926
danielebarchiesi@0 1271 $menu_node = clone $node;
danielebarchiesi@0 1272 menu_node_prepare($menu_node);
danielebarchiesi@0 1273 $mlid = !empty($menu_node->menu['mlid']) ? $menu_node->menu['mlid'] : FALSE;
danielebarchiesi@0 1274 }
danielebarchiesi@0 1275 else {
danielebarchiesi@0 1276 $mlid = !empty($node->menu['mlid']) ? $node->menu['mlid'] : FALSE;
danielebarchiesi@0 1277 }
danielebarchiesi@0 1278
danielebarchiesi@0 1279 $cache[$node->nid] = $mlid;
danielebarchiesi@0 1280 }
danielebarchiesi@0 1281
danielebarchiesi@0 1282 return $cache[$node->nid] ? token_menu_link_load($cache[$node->nid]) : FALSE;
danielebarchiesi@0 1283 }