annotate sites/all/modules/token/token.pages.inc @ 0:ff03f76ab3fe

initial version
author danieleb <danielebarchiesi@me.com>
date Wed, 21 Aug 2013 18:51:11 +0100
parents
children
rev   line source
danielebarchiesi@0 1 <?php
danielebarchiesi@0 2
danielebarchiesi@0 3 /**
danielebarchiesi@0 4 * @file
danielebarchiesi@0 5 * User page callbacks for the token module.
danielebarchiesi@0 6 */
danielebarchiesi@0 7
danielebarchiesi@0 8 /**
danielebarchiesi@0 9 * Theme a link to a token tree either as a regular link or a dialog.
danielebarchiesi@0 10 */
danielebarchiesi@0 11 function theme_token_tree_link($variables) {
danielebarchiesi@0 12 if (empty($variables['text'])) {
danielebarchiesi@0 13 $variables['text'] = t('Browse available tokens.');
danielebarchiesi@0 14 }
danielebarchiesi@0 15
danielebarchiesi@0 16 if (!empty($variables['dialog'])) {
danielebarchiesi@0 17 drupal_add_library('token', 'dialog');
danielebarchiesi@0 18 $variables['options']['attributes']['class'][] = 'token-dialog';
danielebarchiesi@0 19 }
danielebarchiesi@0 20
danielebarchiesi@0 21 $info = token_theme();
danielebarchiesi@0 22 $variables['options']['query']['options'] = array_intersect_key($variables, $info['token_tree']['variables']);
danielebarchiesi@0 23
danielebarchiesi@0 24 // We should never pass the dialog option to theme_token_tree(). It is only
danielebarchiesi@0 25 // used for this function.
danielebarchiesi@0 26 unset($variables['options']['query']['options']['dialog']);
danielebarchiesi@0 27
danielebarchiesi@0 28 // Add a security token so that the tree page should only work when used
danielebarchiesi@0 29 // when the dialog link is output with theme('token_tree_link').
danielebarchiesi@0 30 $variables['options']['query']['token'] = drupal_get_token('token-tree:' . serialize($variables['options']['query']['options']));
danielebarchiesi@0 31
danielebarchiesi@0 32 // Because PHP converts query strings with arrays into a different syntax on
danielebarchiesi@0 33 // the next request, the options have to be encoded with JSON in the query
danielebarchiesi@0 34 // string so that we can reliably decode it for token comparison.
danielebarchiesi@0 35 $variables['options']['query']['options'] = drupal_json_encode($variables['options']['query']['options']);
danielebarchiesi@0 36
danielebarchiesi@0 37 // Set the token tree to open in a separate window.
danielebarchiesi@0 38 $variables['options']['attributes'] + array('target' => '_blank');
danielebarchiesi@0 39
danielebarchiesi@0 40 return l($variables['text'], 'token/tree', $variables['options']);
danielebarchiesi@0 41 }
danielebarchiesi@0 42
danielebarchiesi@0 43 /**
danielebarchiesi@0 44 * Page callback to output a token tree as an empty page.
danielebarchiesi@0 45 */
danielebarchiesi@0 46 function token_page_output_tree() {
danielebarchiesi@0 47 $options = isset($_GET['options']) ? drupal_json_decode($_GET['options']) : array();
danielebarchiesi@0 48
danielebarchiesi@0 49 // Check the token against the serialized options to prevent random access to
danielebarchiesi@0 50 // the token browser page.
danielebarchiesi@0 51 if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'token-tree:' . serialize($options))) {
danielebarchiesi@0 52 return MENU_ACCESS_DENIED;
danielebarchiesi@0 53 }
danielebarchiesi@0 54
danielebarchiesi@0 55 // Force the dialog option to be false so we're not creating a dialog within
danielebarchiesi@0 56 // a dialog.
danielebarchiesi@0 57 $options['dialog'] = FALSE;
danielebarchiesi@0 58
danielebarchiesi@0 59 $output = theme('token_tree', $options);
danielebarchiesi@0 60 print '<html><head>' . drupal_get_css() . drupal_get_js() . '</head>';
danielebarchiesi@0 61 print '<body class="token-tree">' . $output . '</body></html>';
danielebarchiesi@0 62 drupal_exit();
danielebarchiesi@0 63 }
danielebarchiesi@0 64
danielebarchiesi@0 65 /**
danielebarchiesi@0 66 * Theme a tree table.
danielebarchiesi@0 67 *
danielebarchiesi@0 68 * @ingroup themeable
danielebarchiesi@0 69 */
danielebarchiesi@0 70 function theme_tree_table($variables) {
danielebarchiesi@0 71 foreach ($variables['rows'] as &$row) {
danielebarchiesi@0 72 $row += array('class' => array());
danielebarchiesi@0 73 if (!empty($row['parent'])) {
danielebarchiesi@0 74 $row['class'][] = 'child-of-' . $row['parent'];
danielebarchiesi@0 75 unset($row['parent']);
danielebarchiesi@0 76 }
danielebarchiesi@0 77 }
danielebarchiesi@0 78
danielebarchiesi@0 79 if (!empty($variables['rows'])) {
danielebarchiesi@0 80 drupal_add_library('token', 'treeTable');
danielebarchiesi@0 81 }
danielebarchiesi@0 82
danielebarchiesi@0 83 return theme('table', $variables);
danielebarchiesi@0 84 }
danielebarchiesi@0 85
danielebarchiesi@0 86 /**
danielebarchiesi@0 87 * Provide a 'tree' display of nested tokens.
danielebarchiesi@0 88 *
danielebarchiesi@0 89 * @ingroup themeable
danielebarchiesi@0 90 */
danielebarchiesi@0 91 function theme_token_tree($variables) {
danielebarchiesi@0 92 if (!empty($variables['dialog'])) {
danielebarchiesi@0 93 return theme_token_tree_link($variables);
danielebarchiesi@0 94 }
danielebarchiesi@0 95
danielebarchiesi@0 96 $token_types = $variables['token_types'];
danielebarchiesi@0 97 $info = token_get_info();
danielebarchiesi@0 98
danielebarchiesi@0 99 if ($token_types == 'all') {
danielebarchiesi@0 100 $token_types = array_keys($info['types']);
danielebarchiesi@0 101 }
danielebarchiesi@0 102 elseif ($variables['global_types']) {
danielebarchiesi@0 103 $token_types = array_merge($token_types, token_get_global_token_types());
danielebarchiesi@0 104 }
danielebarchiesi@0 105
danielebarchiesi@0 106 $element = array(
danielebarchiesi@0 107 '#cache' => array(
danielebarchiesi@0 108 'cid' => 'tree-rendered:' . hash('sha256', serialize(array('token_types' => $token_types, 'global_types' => NULL) + $variables)),
danielebarchiesi@0 109 'bin' => 'cache_token',
danielebarchiesi@0 110 ),
danielebarchiesi@0 111 );
danielebarchiesi@0 112 if ($cached_output = token_render_cache_get($element)) {
danielebarchiesi@0 113 return $cached_output;
danielebarchiesi@0 114 }
danielebarchiesi@0 115
danielebarchiesi@0 116 $options = array(
danielebarchiesi@0 117 'flat' => TRUE,
danielebarchiesi@0 118 'restricted' => $variables['show_restricted'],
danielebarchiesi@0 119 'depth' => $variables['recursion_limit'],
danielebarchiesi@0 120 );
danielebarchiesi@0 121 $multiple_token_types = (count($token_types) > 1);
danielebarchiesi@0 122 $rows = array();
danielebarchiesi@0 123
danielebarchiesi@0 124 foreach ($info['types'] as $type => $type_info) {
danielebarchiesi@0 125 if (!in_array($type, $token_types)) {
danielebarchiesi@0 126 continue;
danielebarchiesi@0 127 }
danielebarchiesi@0 128
danielebarchiesi@0 129 if ($multiple_token_types) {
danielebarchiesi@0 130 $row = _token_token_tree_format_row($type, $type_info, TRUE);
danielebarchiesi@0 131 unset($row['data']['value']);
danielebarchiesi@0 132 $rows[] = $row;
danielebarchiesi@0 133 }
danielebarchiesi@0 134
danielebarchiesi@0 135 $tree = token_build_tree($type, $options);
danielebarchiesi@0 136 foreach ($tree as $token => $token_info) {
danielebarchiesi@0 137 if (!empty($token_info['restricted']) && empty($variables['show_restricted'])) {
danielebarchiesi@0 138 continue;
danielebarchiesi@0 139 }
danielebarchiesi@0 140 if ($multiple_token_types && !isset($token_info['parent'])) {
danielebarchiesi@0 141 $token_info['parent'] = $type;
danielebarchiesi@0 142 }
danielebarchiesi@0 143 $row = _token_token_tree_format_row($token, $token_info);
danielebarchiesi@0 144 unset($row['data']['value']);
danielebarchiesi@0 145 $rows[] = $row;
danielebarchiesi@0 146 }
danielebarchiesi@0 147 }
danielebarchiesi@0 148
danielebarchiesi@0 149 $element += array(
danielebarchiesi@0 150 '#theme' => 'tree_table',
danielebarchiesi@0 151 '#header' => array(
danielebarchiesi@0 152 t('Name'),
danielebarchiesi@0 153 t('Token'),
danielebarchiesi@0 154 t('Description'),
danielebarchiesi@0 155 ),
danielebarchiesi@0 156 '#rows' => $rows,
danielebarchiesi@0 157 '#attributes' => array('class' => array('token-tree')),
danielebarchiesi@0 158 '#empty' => t('No tokens available'),
danielebarchiesi@0 159 '#attached' => array(
danielebarchiesi@0 160 'js' => array(drupal_get_path('module', 'token') . '/token.js'),
danielebarchiesi@0 161 'css' => array(drupal_get_path('module', 'token') . '/token.css'),
danielebarchiesi@0 162 'library' => array(array('token', 'treeTable')),
danielebarchiesi@0 163 ),
danielebarchiesi@0 164 );
danielebarchiesi@0 165
danielebarchiesi@0 166 if ($variables['click_insert']) {
danielebarchiesi@0 167 $element['#caption'] = t('Click a token to insert it into the field you\'ve last clicked.');
danielebarchiesi@0 168 $element['#attributes']['class'][] = 'token-click-insert';
danielebarchiesi@0 169 }
danielebarchiesi@0 170
danielebarchiesi@0 171 $output = drupal_render($element);
danielebarchiesi@0 172 token_render_cache_set($output, $element);
danielebarchiesi@0 173 return $output;
danielebarchiesi@0 174 }
danielebarchiesi@0 175
danielebarchiesi@0 176 /**
danielebarchiesi@0 177 * Build a row in the token tree.
danielebarchiesi@0 178 */
danielebarchiesi@0 179 function _token_token_tree_format_row($token, array $token_info, $is_group = FALSE) {
danielebarchiesi@0 180 // Build a statically cached array of default values. This is around four
danielebarchiesi@0 181 // times as efficient as building the base array from scratch each time this
danielebarchiesi@0 182 // function is called.
danielebarchiesi@0 183 static $defaults = array(
danielebarchiesi@0 184 'id' => '',
danielebarchiesi@0 185 'class' => array(),
danielebarchiesi@0 186 'data' => array(
danielebarchiesi@0 187 'name' => '',
danielebarchiesi@0 188 'token' => '',
danielebarchiesi@0 189 'value' => '',
danielebarchiesi@0 190 'description' => '',
danielebarchiesi@0 191 ),
danielebarchiesi@0 192 );
danielebarchiesi@0 193
danielebarchiesi@0 194 $row = $defaults;
danielebarchiesi@0 195 $row['id'] = _token_clean_css_identifier($token);
danielebarchiesi@0 196 $row['data']['name'] = $token_info['name'];
danielebarchiesi@0 197 $row['data']['description'] = $token_info['description'];
danielebarchiesi@0 198
danielebarchiesi@0 199 if ($is_group) {
danielebarchiesi@0 200 // This is a token type/group.
danielebarchiesi@0 201 $row['class'][] = 'token-group';
danielebarchiesi@0 202 }
danielebarchiesi@0 203 else {
danielebarchiesi@0 204 // This is a token.
danielebarchiesi@0 205 $row['data']['token']['data'] = $token;
danielebarchiesi@0 206 $row['data']['token']['class'][] = 'token-key';
danielebarchiesi@0 207 if (isset($token_info['value'])) {
danielebarchiesi@0 208 $row['data']['value'] = $token_info['value'];
danielebarchiesi@0 209 }
danielebarchiesi@0 210 if (!empty($token_info['parent'])) {
danielebarchiesi@0 211 $row['parent'] = _token_clean_css_identifier($token_info['parent']);
danielebarchiesi@0 212 }
danielebarchiesi@0 213 }
danielebarchiesi@0 214
danielebarchiesi@0 215 return $row;
danielebarchiesi@0 216 }
danielebarchiesi@0 217
danielebarchiesi@0 218 /**
danielebarchiesi@0 219 * Wrapper function for drupal_clean_css_identifier() for use with tokens.
danielebarchiesi@0 220 *
danielebarchiesi@0 221 * This trims any brackets from the token and also cleans the colon character
danielebarchiesi@0 222 * to a hyphen.
danielebarchiesi@0 223 *
danielebarchiesi@0 224 * @see drupal_clean_css_identifier()
danielebarchiesi@0 225 */
danielebarchiesi@0 226 function _token_clean_css_identifier($id) {
danielebarchiesi@0 227 static $replacements = array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '', ':' => '--', '?' => '', '<' => '-', '>' => '-');
danielebarchiesi@0 228 return 'token-' . rtrim(strtr(trim($id, '[]'), $replacements), '-');
danielebarchiesi@0 229 }
danielebarchiesi@0 230
danielebarchiesi@0 231 /**
danielebarchiesi@0 232 * Menu callback; prints the available tokens and values for an object.
danielebarchiesi@0 233 */
danielebarchiesi@0 234 function token_devel_token_object($entity_type, $entity, $token_type = NULL) {
danielebarchiesi@0 235 $header = array(
danielebarchiesi@0 236 t('Token'),
danielebarchiesi@0 237 t('Value'),
danielebarchiesi@0 238 );
danielebarchiesi@0 239 $rows = array();
danielebarchiesi@0 240
danielebarchiesi@0 241 $options = array(
danielebarchiesi@0 242 'flat' => TRUE,
danielebarchiesi@0 243 'values' => TRUE,
danielebarchiesi@0 244 'data' => array($entity_type => $entity),
danielebarchiesi@0 245 );
danielebarchiesi@0 246 if (!isset($token_type)) {
danielebarchiesi@0 247 $token_type = $entity_type;
danielebarchiesi@0 248 }
danielebarchiesi@0 249 $tree = token_build_tree($token_type, $options);
danielebarchiesi@0 250 foreach ($tree as $token => $token_info) {
danielebarchiesi@0 251 if (!empty($token_info['restricted'])) {
danielebarchiesi@0 252 continue;
danielebarchiesi@0 253 }
danielebarchiesi@0 254 if (!isset($token_info['value']) && !empty($token_info['parent']) && !isset($tree[$token_info['parent']]['value'])) {
danielebarchiesi@0 255 continue;
danielebarchiesi@0 256 }
danielebarchiesi@0 257 $row = _token_token_tree_format_row($token, $token_info);
danielebarchiesi@0 258 unset($row['data']['description']);
danielebarchiesi@0 259 unset($row['data']['name']);
danielebarchiesi@0 260 $rows[] = $row;
danielebarchiesi@0 261 }
danielebarchiesi@0 262
danielebarchiesi@0 263 $build['tokens'] = array(
danielebarchiesi@0 264 '#theme' => 'tree_table',
danielebarchiesi@0 265 '#header' => $header,
danielebarchiesi@0 266 '#rows' => $rows,
danielebarchiesi@0 267 '#attributes' => array('class' => array('token-tree')),
danielebarchiesi@0 268 '#empty' => t('No tokens available.'),
danielebarchiesi@0 269 '#attached' => array(
danielebarchiesi@0 270 'js' => array(drupal_get_path('module', 'token') . '/token.js'),
danielebarchiesi@0 271 'css' => array(drupal_get_path('module', 'token') . '/token.css'),
danielebarchiesi@0 272 ),
danielebarchiesi@0 273 );
danielebarchiesi@0 274
danielebarchiesi@0 275 return $build;
danielebarchiesi@0 276 }
danielebarchiesi@0 277
danielebarchiesi@0 278 /**
danielebarchiesi@0 279 * Page callback to clear the token registry caches.
danielebarchiesi@0 280 */
danielebarchiesi@0 281 function token_flush_cache_callback() {
danielebarchiesi@0 282 if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], current_path())) {
danielebarchiesi@0 283 return MENU_NOT_FOUND;
danielebarchiesi@0 284 }
danielebarchiesi@0 285
danielebarchiesi@0 286 token_clear_cache();
danielebarchiesi@0 287 drupal_set_message(t('Token registry caches cleared.'));
danielebarchiesi@0 288 drupal_goto();
danielebarchiesi@0 289 }
danielebarchiesi@0 290
danielebarchiesi@0 291 function token_autocomplete() {
danielebarchiesi@0 292 $args = func_get_args();
danielebarchiesi@0 293 $string = implode('/', $args);
danielebarchiesi@0 294
danielebarchiesi@0 295 $token_info = token_info();
danielebarchiesi@0 296
danielebarchiesi@0 297 preg_match_all('/\[([^\s\]:]*):?([^\s\]]*)?\]?/', $string, $matches);
danielebarchiesi@0 298 $types = $matches[1];
danielebarchiesi@0 299 $tokens = $matches[2];
danielebarchiesi@0 300
danielebarchiesi@0 301 foreach ($types as $index => $type) {
danielebarchiesi@0 302 if (!empty($tokens[$index]) || isset($token_info['types'][$type])) {
danielebarchiesi@0 303 token_autocomplete_token($type, $tokens[$index]);
danielebarchiesi@0 304 }
danielebarchiesi@0 305 else {
danielebarchiesi@0 306 token_autocomplete_type($type);
danielebarchiesi@0 307 }
danielebarchiesi@0 308 }
danielebarchiesi@0 309
danielebarchiesi@0 310 }
danielebarchiesi@0 311
danielebarchiesi@0 312 function token_autocomplete_type($string = '') {
danielebarchiesi@0 313 $token_info = token_info();
danielebarchiesi@0 314 $types = $token_info['types'];
danielebarchiesi@0 315 $matches = array();
danielebarchiesi@0 316
danielebarchiesi@0 317 foreach ($types as $type => $info) {
danielebarchiesi@0 318 if (!$string || strpos($type, $string) === 0) {
danielebarchiesi@0 319 $type_key = "[{$type}:";
danielebarchiesi@0 320 $matches[$type_key] = levenshtein($type, $string);
danielebarchiesi@0 321 }
danielebarchiesi@0 322 }
danielebarchiesi@0 323
danielebarchiesi@0 324 if ($string) {
danielebarchiesi@0 325 asort($matches);
danielebarchiesi@0 326 }
danielebarchiesi@0 327 else {
danielebarchiesi@0 328 ksort($matches);
danielebarchiesi@0 329 }
danielebarchiesi@0 330
danielebarchiesi@0 331 $matches = drupal_map_assoc(array_keys($matches));
danielebarchiesi@0 332 drupal_json_output($matches);
danielebarchiesi@0 333 }
danielebarchiesi@0 334
danielebarchiesi@0 335 function token_autocomplete_token($token_type) {
danielebarchiesi@0 336 $args = func_get_args();
danielebarchiesi@0 337 array_shift($args);
danielebarchiesi@0 338 $string = trim(implode('/', $args));
danielebarchiesi@0 339 $string = substr($string, strrpos($string, '['));
danielebarchiesi@0 340
danielebarchiesi@0 341 $token_type = $token_type['type'];
danielebarchiesi@0 342 $matches = array();
danielebarchiesi@0 343
danielebarchiesi@0 344 if (!drupal_strlen($string)) {
danielebarchiesi@0 345 $matches["[{$token_type}:"] = 0;
danielebarchiesi@0 346 }
danielebarchiesi@0 347 else {
danielebarchiesi@0 348 $depth = max(1, substr_count($string, ':'));
danielebarchiesi@0 349 $tree = token_build_tree($token_type, array('flat' => TRUE, 'depth' => $depth));
danielebarchiesi@0 350 foreach (array_keys($tree) as $token) {
danielebarchiesi@0 351 if (strpos($token, $string) === 0) {
danielebarchiesi@0 352 $matches[$token] = levenshtein($token, $string);
danielebarchiesi@0 353 if (isset($tree[$token]['children'])) {
danielebarchiesi@0 354 $token = rtrim($token, ':]') . ':';
danielebarchiesi@0 355 $matches[$token] = levenshtein($token, $string);
danielebarchiesi@0 356 }
danielebarchiesi@0 357 }
danielebarchiesi@0 358 }
danielebarchiesi@0 359 }
danielebarchiesi@0 360
danielebarchiesi@0 361 asort($matches);
danielebarchiesi@0 362 $matches = drupal_map_assoc(array_keys($matches));
danielebarchiesi@0 363 drupal_json_output($matches);
danielebarchiesi@0 364 }