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 }
|