1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
/**
|
4 |
|
|
* @file
|
5 |
|
|
* Token callbacks for the token module.
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
/**
|
9 |
|
|
* Implements hook_token_info_alter().
|
10 |
|
|
*/
|
11 |
|
|
function token_token_info_alter(&$info) {
|
12 |
|
|
// Force 'date' type tokens to require input and add a 'current-date' type.
|
13 |
|
|
// @todo Remove when http://drupal.org/node/943028 is fixed.
|
14 |
|
|
$info['types']['date']['needs-data'] = 'date';
|
15 |
|
|
$info['types']['current-date'] = array(
|
16 |
|
|
'name' => t('Current date'),
|
17 |
|
|
'description' => t('Tokens related to the current date and time.'),
|
18 |
|
|
'type' => 'date',
|
19 |
|
|
);
|
20 |
|
|
|
21 |
|
|
// Add a 'dynamic' key to any tokens that have chained but dynamic tokens.
|
22 |
|
|
$info['tokens']['date']['custom']['dynamic'] = TRUE;
|
23 |
|
|
|
24 |
|
|
// The [file:size] may not always return in kilobytes.
|
25 |
|
|
// @todo Remove when http://drupal.org/node/1193044 is fixed.
|
26 |
|
|
$info['tokens']['file']['size']['description'] = t('The size of the file.');
|
27 |
|
|
|
28 |
|
|
// Remove deprecated tokens from being listed.
|
29 |
|
|
unset($info['tokens']['node']['tnid']);
|
30 |
|
|
unset($info['tokens']['node']['type']);
|
31 |
|
|
unset($info['tokens']['node']['type-name']);
|
32 |
|
|
|
33 |
|
|
// Support 'url' type tokens for core tokens.
|
34 |
|
|
if (isset($info['tokens']['comment']['url']) && module_exists('comment')) {
|
35 |
|
|
$info['tokens']['comment']['url']['type'] = 'url';
|
36 |
|
|
}
|
37 |
|
|
$info['tokens']['node']['url']['type'] = 'url';
|
38 |
|
|
if (isset($info['tokens']['term']['url']) && module_exists('taxonomy')) {
|
39 |
|
|
$info['tokens']['term']['url']['type'] = 'url';
|
40 |
|
|
}
|
41 |
|
|
$info['tokens']['user']['url']['type'] = 'url';
|
42 |
|
|
|
43 |
|
|
// Add [token:url] tokens for any URI-able entities.
|
44 |
|
|
$entities = entity_get_info();
|
45 |
|
|
foreach ($entities as $entity => $entity_info) {
|
46 |
|
|
if (!isset($entity_info['token type'])) {
|
47 |
|
|
continue;
|
48 |
|
|
}
|
49 |
|
|
|
50 |
|
|
$token_type = $entity_info['token type'];
|
51 |
|
|
if (!isset($info['types'][$token_type]) || !isset($info['tokens'][$token_type])) {
|
52 |
|
|
continue;
|
53 |
|
|
}
|
54 |
|
|
|
55 |
|
|
// Add [entity:url] tokens if they do not already exist.
|
56 |
|
|
// @todo Support entity:label
|
57 |
|
|
if (!isset($info['tokens'][$token_type]['url']) && !empty($entity_info['uri callback'])) {
|
58 |
|
|
$info['tokens'][$token_type]['url'] = array(
|
59 |
|
|
'name' => t('URL'),
|
60 |
|
|
'description' => t('The URL of the @entity.', array('@entity' => drupal_strtolower($entity_info['label']))),
|
61 |
|
|
'module' => 'token',
|
62 |
|
|
'type' => 'url',
|
63 |
|
|
);
|
64 |
|
|
}
|
65 |
|
|
|
66 |
|
|
// Add [entity:original] tokens if they do not already exist.
|
67 |
|
|
if (!isset($info['tokens'][$token_type]['original'])) {
|
68 |
|
|
$info['tokens'][$token_type]['original'] = array(
|
69 |
|
|
'name' => t('Original @entity', array('@entity' => drupal_strtolower($entity_info['label']))),
|
70 |
|
|
'description' => t('The original @entity data if the @entity is being updated or saved.', array('@entity' => drupal_strtolower($entity_info['label']))),
|
71 |
|
|
'module' => 'token',
|
72 |
|
|
'type' => $token_type,
|
73 |
|
|
);
|
74 |
|
|
}
|
75 |
|
|
}
|
76 |
|
|
|
77 |
|
|
// Add support for custom date formats.
|
78 |
|
|
// @todo Remove when http://drupal.org/node/1173706 is fixed.
|
79 |
|
|
$date_format_types = system_get_date_types();
|
80 |
|
|
foreach ($date_format_types as $date_format_type => $date_format_type_info) {
|
81 |
|
|
if (!isset($info['tokens']['date'][$date_format_type])) {
|
82 |
|
|
$info['tokens']['date'][$date_format_type] = array(
|
83 |
|
|
'name' => check_plain($date_format_type_info['title']),
|
84 |
|
|
'description' => t("A date in '@type' format. (%date)", array('@type' => $date_format_type, '%date' => format_date(REQUEST_TIME, $date_format_type))),
|
85 |
|
|
'module' => 'token',
|
86 |
|
|
);
|
87 |
|
|
}
|
88 |
|
|
}
|
89 |
|
|
}
|
90 |
|
|
|
91 |
|
|
/**
|
92 |
|
|
* Implements hook_token_info().
|
93 |
|
|
*/
|
94 |
|
|
function token_token_info() {
|
95 |
|
|
// Node tokens.
|
96 |
|
|
$info['tokens']['node']['source'] = array(
|
97 |
|
|
'name' => t('Translation source node'),
|
98 |
|
|
'description' => t("The source node for this current node's translation set."),
|
99 |
|
|
'type' => 'node',
|
100 |
|
|
);
|
101 |
|
|
$info['tokens']['node']['log'] = array(
|
102 |
|
|
'name' => t('Revision log message'),
|
103 |
|
|
'description' => t('The explanation of the most recent changes made to the node.'),
|
104 |
|
|
);
|
105 |
|
|
$info['tokens']['node']['content-type'] = array(
|
106 |
|
|
'name' => t('Content type'),
|
107 |
|
|
'description' => t('The content type of the node.'),
|
108 |
|
|
'type' => 'content-type',
|
109 |
|
|
);
|
110 |
|
|
|
111 |
|
|
// Content type tokens.
|
112 |
|
|
$info['types']['content-type'] = array(
|
113 |
|
|
'name' => t('Content types'),
|
114 |
|
|
'description' => t('Tokens related to content types.'),
|
115 |
|
|
'needs-data' => 'node_type',
|
116 |
|
|
);
|
117 |
|
|
$info['tokens']['content-type']['name'] = array(
|
118 |
|
|
'name' => t('Name'),
|
119 |
|
|
'description' => t('The name of the content type.'),
|
120 |
|
|
);
|
121 |
|
|
$info['tokens']['content-type']['machine-name'] = array(
|
122 |
|
|
'name' => t('Machine-readable name'),
|
123 |
|
|
'description' => t('The unique machine-readable name of the content type.'),
|
124 |
|
|
);
|
125 |
|
|
$info['tokens']['content-type']['description'] = array(
|
126 |
|
|
'name' => t('Description'),
|
127 |
|
|
'description' => t('The optional description of the content type.'),
|
128 |
|
|
);
|
129 |
|
|
$info['tokens']['content-type']['node-count'] = array(
|
130 |
|
|
'name' => t('Node count'),
|
131 |
|
|
'description' => t('The number of nodes belonging to the content type.'),
|
132 |
|
|
);
|
133 |
|
|
$info['tokens']['content-type']['edit-url'] = array(
|
134 |
|
|
'name' => t('Edit URL'),
|
135 |
|
|
'description' => t("The URL of the content type's edit page."),
|
136 |
|
|
// 'type' => 'url',
|
137 |
|
|
);
|
138 |
|
|
|
139 |
|
|
// Taxonomy term and vocabulary tokens.
|
140 |
|
|
if (module_exists('taxonomy')) {
|
141 |
|
|
$info['tokens']['term']['edit-url'] = array(
|
142 |
|
|
'name' => t('Edit URL'),
|
143 |
|
|
'description' => t("The URL of the taxonomy term's edit page."),
|
144 |
|
|
// 'type' => 'url',
|
145 |
|
|
);
|
146 |
|
|
$info['tokens']['term']['parents'] = array(
|
147 |
|
|
'name' => t('Parents'),
|
148 |
|
|
'description' => t("An array of all the term's parents, starting with the root."),
|
149 |
|
|
'type' => 'array',
|
150 |
|
|
);
|
151 |
|
|
$info['tokens']['term']['root'] = array(
|
152 |
|
|
'name' => t('Root term'),
|
153 |
|
|
'description' => t("The root term of the taxonomy term."),
|
154 |
|
|
'type' => 'term',
|
155 |
|
|
);
|
156 |
|
|
|
157 |
|
|
$info['tokens']['vocabulary']['machine-name'] = array(
|
158 |
|
|
'name' => t('Machine-readable name'),
|
159 |
|
|
'description' => t('The unique machine-readable name of the vocabulary.'),
|
160 |
|
|
);
|
161 |
|
|
$info['tokens']['vocabulary']['edit-url'] = array(
|
162 |
|
|
'name' => t('Edit URL'),
|
163 |
|
|
'description' => t("The URL of the vocabulary's edit page."),
|
164 |
|
|
// 'type' => 'url',
|
165 |
|
|
);
|
166 |
|
|
}
|
167 |
|
|
|
168 |
|
|
// File tokens.
|
169 |
|
|
$info['tokens']['file']['basename'] = array(
|
170 |
|
|
'name' => t('Base name'),
|
171 |
|
|
'description' => t('The base name of the file.'),
|
172 |
|
|
);
|
173 |
|
|
$info['tokens']['file']['extension'] = array(
|
174 |
|
|
'name' => t('Extension'),
|
175 |
|
|
'description' => t('The extension of the file.'),
|
176 |
|
|
);
|
177 |
|
|
$info['tokens']['file']['size-raw'] = array(
|
178 |
|
|
'name' => t('File byte size'),
|
179 |
|
|
'description' => t('The size of the file, in bytes.'),
|
180 |
|
|
);
|
181 |
|
|
|
182 |
|
|
// User tokens.
|
183 |
|
|
// Add information on the restricted user tokens.
|
184 |
|
|
$info['tokens']['user']['cancel-url'] = array(
|
185 |
|
|
'name' => t('Account cancellation URL'),
|
186 |
|
|
'description' => t('The URL of the confirm delete page for the user account.'),
|
187 |
|
|
'restricted' => TRUE,
|
188 |
|
|
// 'type' => 'url',
|
189 |
|
|
);
|
190 |
|
|
$info['tokens']['user']['one-time-login-url'] = array(
|
191 |
|
|
'name' => t('One-time login URL'),
|
192 |
|
|
'description' => t('The URL of the one-time login page for the user account.'),
|
193 |
|
|
'restricted' => TRUE,
|
194 |
|
|
// 'type' => 'url',
|
195 |
|
|
);
|
196 |
|
|
if (variable_get('user_pictures', 0)) {
|
197 |
|
|
$info['tokens']['user']['picture'] = array(
|
198 |
|
|
'name' => t('Picture'),
|
199 |
|
|
'description' => t('The picture of the user.'),
|
200 |
|
|
'type' => 'file',
|
201 |
|
|
);
|
202 |
|
|
}
|
203 |
|
|
$info['tokens']['user']['roles'] = array(
|
204 |
|
|
'name' => t('Roles'),
|
205 |
|
|
'description' => t('The user roles associated with the user account.'),
|
206 |
|
|
'type' => 'array',
|
207 |
|
|
);
|
208 |
|
|
|
209 |
|
|
// Current user tokens.
|
210 |
|
|
$info['tokens']['current-user']['ip-address'] = array(
|
211 |
|
|
'name' => t('IP address'),
|
212 |
|
|
'description' => 'The IP address of the current user.',
|
213 |
|
|
);
|
214 |
|
|
|
215 |
|
|
// Menu link tokens (work regardless if menu module is enabled or not).
|
216 |
|
|
$info['types']['menu-link'] = array(
|
217 |
|
|
'name' => t('Menu links'),
|
218 |
|
|
'description' => t('Tokens related to menu links.'),
|
219 |
|
|
'needs-data' => 'menu-link',
|
220 |
|
|
);
|
221 |
|
|
$info['tokens']['menu-link']['mlid'] = array(
|
222 |
|
|
'name' => t('Link ID'),
|
223 |
|
|
'description' => t('The unique ID of the menu link.'),
|
224 |
|
|
);
|
225 |
|
|
$info['tokens']['menu-link']['title'] = array(
|
226 |
|
|
'name' => t('Title'),
|
227 |
|
|
'description' => t('The title of the menu link.'),
|
228 |
|
|
);
|
229 |
|
|
$info['tokens']['menu-link']['url'] = array(
|
230 |
|
|
'name' => t('URL'),
|
231 |
|
|
'description' => t('The URL of the menu link.'),
|
232 |
|
|
'type' => 'url',
|
233 |
|
|
);
|
234 |
|
|
$info['tokens']['menu-link']['parent'] = array(
|
235 |
|
|
'name' => t('Parent'),
|
236 |
|
|
'description' => t("The menu link's parent."),
|
237 |
|
|
'type' => 'menu-link',
|
238 |
|
|
);
|
239 |
|
|
$info['tokens']['menu-link']['parents'] = array(
|
240 |
|
|
'name' => t('Parents'),
|
241 |
|
|
'description' => t("An array of all the menu link's parents, starting with the root."),
|
242 |
|
|
'type' => 'array',
|
243 |
|
|
);
|
244 |
|
|
$info['tokens']['menu-link']['root'] = array(
|
245 |
|
|
'name' => t('Root'),
|
246 |
|
|
'description' => t("The menu link's root."),
|
247 |
|
|
'type' => 'menu-link',
|
248 |
|
|
);
|
249 |
|
|
|
250 |
|
|
// Current page tokens.
|
251 |
|
|
$info['types']['current-page'] = array(
|
252 |
|
|
'name' => t('Current page'),
|
253 |
|
|
'description' => t('Tokens related to the current page request.'),
|
254 |
|
|
);
|
255 |
|
|
$info['tokens']['current-page']['title'] = array(
|
256 |
|
|
'name' => t('Title'),
|
257 |
|
|
'description' => t('The title of the current page.'),
|
258 |
|
|
);
|
259 |
|
|
$info['tokens']['current-page']['url'] = array(
|
260 |
|
|
'name' => t('URL'),
|
261 |
|
|
'description' => t('The URL of the current page.'),
|
262 |
|
|
'type' => 'url',
|
263 |
|
|
);
|
264 |
|
|
$info['tokens']['current-page']['page-number'] = array(
|
265 |
|
|
'name' => t('Page number'),
|
266 |
|
|
'description' => t('The page number of the current page when viewing paged lists.'),
|
267 |
|
|
);
|
268 |
|
|
$info['tokens']['current-page']['query'] = array(
|
269 |
|
|
'name' => t('Query string value'),
|
270 |
|
|
'description' => t('The value of a specific query string field of the current page.'),
|
271 |
|
|
'dynamic' => TRUE,
|
272 |
|
|
);
|
273 |
|
|
|
274 |
|
|
// URL tokens.
|
275 |
|
|
$info['types']['url'] = array(
|
276 |
|
|
'name' => t('URL'),
|
277 |
|
|
'description' => t('Tokens related to URLs.'),
|
278 |
|
|
'needs-data' => 'path',
|
279 |
|
|
);
|
280 |
|
|
$info['tokens']['url']['path'] = array(
|
281 |
|
|
'name' => t('Path'),
|
282 |
|
|
'description' => t('The path component of the URL.'),
|
283 |
|
|
);
|
284 |
|
|
$info['tokens']['url']['relative'] = array(
|
285 |
|
|
'name' => t('Relative URL'),
|
286 |
|
|
'description' => t('The relative URL.'),
|
287 |
|
|
);
|
288 |
|
|
$info['tokens']['url']['absolute'] = array(
|
289 |
|
|
'name' => t('Absolute URL'),
|
290 |
|
|
'description' => t('The absolute URL.'),
|
291 |
|
|
);
|
292 |
|
|
$info['tokens']['url']['brief'] = array(
|
293 |
|
|
'name' => t('Brief URL'),
|
294 |
|
|
'description' => t('The URL without the protocol and trailing backslash.'),
|
295 |
|
|
);
|
296 |
|
|
$info['tokens']['url']['unaliased'] = array(
|
297 |
|
|
'name' => t('Unaliased URL'),
|
298 |
|
|
'description' => t('The unaliased URL.'),
|
299 |
|
|
'type' => 'url',
|
300 |
|
|
);
|
301 |
|
|
$info['tokens']['url']['args'] = array(
|
302 |
|
|
'name' => t('Arguments'),
|
303 |
|
|
'description' => t("The specific argument of the current page (e.g. 'arg:1' on the page 'node/1' returns '1')."),
|
304 |
|
|
'type' => 'array',
|
305 |
|
|
);
|
306 |
|
|
|
307 |
|
|
// Array tokens.
|
308 |
|
|
$info['types']['array'] = array(
|
309 |
|
|
'name' => t('Array'),
|
310 |
|
|
'description' => t('Tokens related to arrays of strings.'),
|
311 |
|
|
'needs-data' => 'array',
|
312 |
|
|
);
|
313 |
|
|
$info['tokens']['array']['first'] = array(
|
314 |
|
|
'name' => t('First'),
|
315 |
|
|
'description' => t('The first element of the array.'),
|
316 |
|
|
);
|
317 |
|
|
$info['tokens']['array']['last'] = array(
|
318 |
|
|
'name' => t('Last'),
|
319 |
|
|
'description' => t('The last element of the array.'),
|
320 |
|
|
);
|
321 |
|
|
$info['tokens']['array']['count'] = array(
|
322 |
|
|
'name' => t('Count'),
|
323 |
|
|
'description' => t('The number of elements in the array.'),
|
324 |
|
|
);
|
325 |
|
|
$info['tokens']['array']['reversed'] = array(
|
326 |
|
|
'name' => t('Reversed'),
|
327 |
|
|
'description' => t('The array reversed.'),
|
328 |
|
|
'type' => 'array',
|
329 |
|
|
);
|
330 |
|
|
$info['tokens']['array']['keys'] = array(
|
331 |
|
|
'name' => t('Keys'),
|
332 |
|
|
'description' => t('The array of keys of the array.'),
|
333 |
|
|
'type' => 'array',
|
334 |
|
|
);
|
335 |
|
|
$info['tokens']['array']['join'] = array(
|
336 |
|
|
'name' => t('Imploded'),
|
337 |
|
|
'description' => t('The values of the array joined together with a custom string in-between each value.'),
|
338 |
|
|
'dynamic' => TRUE,
|
339 |
|
|
);
|
340 |
|
|
$info['tokens']['array']['value'] = array(
|
341 |
|
|
'name' => t('Value'),
|
342 |
|
|
'description' => t('The specific value of the array.'),
|
343 |
|
|
'dynamic' => TRUE,
|
344 |
|
|
);
|
345 |
|
|
|
346 |
|
|
// Random tokens.
|
347 |
|
|
$info['types']['random'] = array(
|
348 |
|
|
'name' => t('Random'),
|
349 |
|
|
'description' => ('Tokens related to random data.'),
|
350 |
|
|
);
|
351 |
|
|
$info['tokens']['random']['number'] = array(
|
352 |
|
|
'name' => t('Number'),
|
353 |
|
|
'description' => t('A random number from 0 to @max.', array('@max' => mt_getrandmax())),
|
354 |
|
|
);
|
355 |
|
|
$info['tokens']['random']['hash'] = array(
|
356 |
|
|
'name' => t('Hash'),
|
357 |
|
|
'description' => t('A random hash. The possible hashing algorithms are: @hash-algos.', array('@hash-algos' => implode(', ', hash_algos()))),
|
358 |
|
|
'dynamic' => TRUE,
|
359 |
|
|
);
|
360 |
|
|
|
361 |
|
|
return $info;
|
362 |
|
|
}
|
363 |
|
|
|
364 |
|
|
/**
|
365 |
|
|
* Implements hook_tokens().
|
366 |
|
|
*/
|
367 |
|
|
function token_tokens($type, $tokens, array $data = array(), array $options = array()) {
|
368 |
|
|
$replacements = array();
|
369 |
|
|
|
370 |
|
|
$url_options = array('absolute' => TRUE);
|
371 |
|
|
if (isset($options['language'])) {
|
372 |
|
|
$url_options['language'] = $options['language'];
|
373 |
|
|
$language_code = $options['language']->language;
|
374 |
|
|
}
|
375 |
|
|
else {
|
376 |
|
|
$language_code = NULL;
|
377 |
|
|
}
|
378 |
|
|
|
379 |
|
|
$sanitize = !empty($options['sanitize']);
|
380 |
|
|
|
381 |
|
|
// Date tokens.
|
382 |
|
|
if ($type == 'date') {
|
383 |
|
|
$date = !empty($data['date']) ? $data['date'] : REQUEST_TIME;
|
384 |
|
|
|
385 |
|
|
// @todo Remove when http://drupal.org/node/1173706 is fixed.
|
386 |
|
|
$date_format_types = system_get_date_types();
|
387 |
|
|
foreach ($tokens as $name => $original) {
|
388 |
|
|
if (isset($date_format_types[$name]) && _token_module('date', $name) == 'token') {
|
389 |
|
|
$replacements[$original] = format_date($date, $name, '', NULL, $language_code);
|
390 |
|
|
}
|
391 |
|
|
}
|
392 |
|
|
}
|
393 |
|
|
|
394 |
|
|
// Current date tokens.
|
395 |
|
|
// @todo Remove when http://drupal.org/node/943028 is fixed.
|
396 |
|
|
if ($type == 'current-date') {
|
397 |
|
|
$replacements += token_generate('date', $tokens, array('date' => REQUEST_TIME), $options);
|
398 |
|
|
}
|
399 |
|
|
|
400 |
|
|
// Comment tokens.
|
401 |
|
|
if ($type == 'comment' && !empty($data['comment'])) {
|
402 |
|
|
$comment = $data['comment'];
|
403 |
|
|
|
404 |
|
|
// Chained token relationships.
|
405 |
|
|
if (($url_tokens = token_find_with_prefix($tokens, 'url'))) {
|
406 |
|
|
$replacements += token_generate('url', $url_tokens, entity_uri('comment', $comment), $options);
|
407 |
|
|
}
|
408 |
|
|
}
|
409 |
|
|
|
410 |
|
|
// Node tokens.
|
411 |
|
|
if ($type == 'node' && !empty($data['node'])) {
|
412 |
|
|
$node = $data['node'];
|
413 |
|
|
|
414 |
|
|
foreach ($tokens as $name => $original) {
|
415 |
|
|
switch ($name) {
|
416 |
|
|
case 'source':
|
417 |
|
|
if (!empty($node->tnid) && $source_node = node_load($node->tnid)) {
|
418 |
|
|
$title = $source_node->title;
|
419 |
|
|
$replacements[$original] = $sanitize ? filter_xss($title) : $title;
|
420 |
|
|
}
|
421 |
|
|
break;
|
422 |
|
|
case 'log':
|
423 |
|
|
$replacements[$original] = $sanitize ? filter_xss($node->log) : $node->log;
|
424 |
|
|
break;
|
425 |
|
|
case 'content-type':
|
426 |
|
|
$type_name = node_type_get_name($node);
|
427 |
|
|
$replacements[$original] = $sanitize ? check_plain($type_name) : $type_name;
|
428 |
|
|
break;
|
429 |
|
|
}
|
430 |
|
|
}
|
431 |
|
|
|
432 |
|
|
// Chained token relationships.
|
433 |
|
|
if (!empty($node->tnid) && ($source_tokens = token_find_with_prefix($tokens, 'source')) && $source_node = node_load($node->tnid)) {
|
434 |
|
|
$replacements += token_generate('node', $source_tokens, array('node' => $source_node), $options);
|
435 |
|
|
}
|
436 |
|
|
if (($node_type_tokens = token_find_with_prefix($tokens, 'content-type')) && $node_type = node_type_load($node->type)) {
|
437 |
|
|
$replacements += token_generate('content-type', $node_type_tokens, array('node_type' => $node_type), $options);
|
438 |
|
|
}
|
439 |
|
|
if (($url_tokens = token_find_with_prefix($tokens, 'url'))) {
|
440 |
|
|
$replacements += token_generate('url', $url_tokens, entity_uri('node', $node), $options);
|
441 |
|
|
}
|
442 |
|
|
}
|
443 |
|
|
|
444 |
|
|
// Content type tokens.
|
445 |
|
|
if ($type == 'content-type' && !empty($data['node_type'])) {
|
446 |
|
|
$node_type = $data['node_type'];
|
447 |
|
|
|
448 |
|
|
foreach ($tokens as $name => $original) {
|
449 |
|
|
switch ($name) {
|
450 |
|
|
case 'name':
|
451 |
|
|
$replacements[$original] = $sanitize ? check_plain($node_type->name) : $node_type->name;
|
452 |
|
|
break;
|
453 |
|
|
case 'machine-name':
|
454 |
|
|
// This is a machine name so does not ever need to be sanitized.
|
455 |
|
|
$replacements[$original] = $node_type->type;
|
456 |
|
|
break;
|
457 |
|
|
case 'description':
|
458 |
|
|
$replacements[$original] = $sanitize ? filter_xss($node_type->description) : $node_type->description;
|
459 |
|
|
break;
|
460 |
|
|
case 'node-count':
|
461 |
|
|
$query = db_select('node');
|
462 |
|
|
$query->condition('type', $node_type->type);
|
463 |
|
|
$query->addTag('node_type_node_count');
|
464 |
|
|
$count = $query->countQuery()->execute()->fetchField();
|
465 |
|
|
$replacements[$original] = (int) $count;
|
466 |
|
|
break;
|
467 |
|
|
case 'edit-url':
|
468 |
|
|
$replacements[$original] = url("admin/structure/types/manage/{$node_type->type}", $url_options);
|
469 |
|
|
break;
|
470 |
|
|
}
|
471 |
|
|
}
|
472 |
|
|
}
|
473 |
|
|
|
474 |
|
|
// Taxonomy term tokens.
|
475 |
|
|
if ($type == 'term' && !empty($data['term'])) {
|
476 |
|
|
$term = $data['term'];
|
477 |
|
|
|
478 |
|
|
foreach ($tokens as $name => $original) {
|
479 |
|
|
switch ($name) {
|
480 |
|
|
case 'edit-url':
|
481 |
|
|
$replacements[$original] = url("taxonomy/term/{$term->tid}/edit", $url_options);
|
482 |
|
|
break;
|
483 |
|
|
|
484 |
|
|
case 'parents':
|
485 |
|
|
if ($parents = token_taxonomy_term_load_all_parents($term->tid)) {
|
486 |
|
|
$replacements[$original] = token_render_array($parents, $options);
|
487 |
|
|
}
|
488 |
|
|
break;
|
489 |
|
|
|
490 |
|
|
case 'root':
|
491 |
|
|
$parents = taxonomy_get_parents_all($term->tid);
|
492 |
|
|
$root_term = end($parents);
|
493 |
|
|
if ($root_term->tid != $term->tid) {
|
494 |
|
|
$replacements[$original] = $sanitize ? check_plain($root_term->name) : $root_term->name;
|
495 |
|
|
}
|
496 |
|
|
break;
|
497 |
|
|
}
|
498 |
|
|
}
|
499 |
|
|
|
500 |
|
|
// Chained token relationships.
|
501 |
|
|
if (($url_tokens = token_find_with_prefix($tokens, 'url'))) {
|
502 |
|
|
$replacements += token_generate('url', $url_tokens, entity_uri('taxonomy_term', $term), $options);
|
503 |
|
|
}
|
504 |
|
|
// [term:parents:*] chained tokens.
|
505 |
|
|
if ($parents_tokens = token_find_with_prefix($tokens, 'parents')) {
|
506 |
|
|
if ($parents = token_taxonomy_term_load_all_parents($term->tid)) {
|
507 |
|
|
$replacements += token_generate('array', $parents_tokens, array('array' => $parents), $options);
|
508 |
|
|
}
|
509 |
|
|
}
|
510 |
|
|
if ($root_tokens = token_find_with_prefix($tokens, 'root')) {
|
511 |
|
|
$parents = taxonomy_get_parents_all($term->tid);
|
512 |
|
|
$root_term = end($parents);
|
513 |
|
|
if ($root_term->tid != $term->tid) {
|
514 |
|
|
$replacements += token_generate('term', $root_tokens, array('term' => $root_term), $options);
|
515 |
|
|
}
|
516 |
|
|
}
|
517 |
|
|
}
|
518 |
|
|
|
519 |
|
|
// Vocabulary tokens.
|
520 |
|
|
if ($type == 'vocabulary' && !empty($data['vocabulary'])) {
|
521 |
|
|
$vocabulary = $data['vocabulary'];
|
522 |
|
|
|
523 |
|
|
foreach ($tokens as $name => $original) {
|
524 |
|
|
switch ($name) {
|
525 |
|
|
case 'machine-name':
|
526 |
|
|
// This is a machine name so does not ever need to be sanitized.
|
527 |
|
|
$replacements[$original] = $vocabulary->machine_name;
|
528 |
|
|
break;
|
529 |
|
|
case 'edit-url':
|
530 |
|
|
$replacements[$original] = url("admin/structure/taxonomy/{$vocabulary->machine_name}/edit", $url_options);
|
531 |
|
|
break;
|
532 |
|
|
}
|
533 |
|
|
}
|
534 |
|
|
}
|
535 |
|
|
|
536 |
|
|
// File tokens.
|
537 |
|
|
if ($type == 'file' && !empty($data['file'])) {
|
538 |
|
|
$file = $data['file'];
|
539 |
|
|
|
540 |
|
|
foreach ($tokens as $name => $original) {
|
541 |
|
|
switch ($name) {
|
542 |
|
|
case 'basename':
|
543 |
|
|
$basename = pathinfo($file->uri, PATHINFO_BASENAME);
|
544 |
|
|
$replacements[$original] = $sanitize ? check_plain($basename) : $basename;
|
545 |
|
|
break;
|
546 |
|
|
case 'extension':
|
547 |
|
|
$extension = pathinfo($file->uri, PATHINFO_EXTENSION);
|
548 |
|
|
$replacements[$original] = $sanitize ? check_plain($extension) : $extension;
|
549 |
|
|
break;
|
550 |
|
|
case 'size-raw':
|
551 |
|
|
$replacements[$original] = (int) $file->filesize;
|
552 |
|
|
break;
|
553 |
|
|
}
|
554 |
|
|
}
|
555 |
|
|
}
|
556 |
|
|
|
557 |
|
|
// User tokens.
|
558 |
|
|
if ($type == 'user' && !empty($data['user'])) {
|
559 |
|
|
$account = $data['user'];
|
560 |
|
|
|
561 |
|
|
foreach ($tokens as $name => $original) {
|
562 |
|
|
switch ($name) {
|
563 |
|
|
case 'picture':
|
564 |
|
|
if (variable_get('user_pictures', 0)) {
|
565 |
|
|
$replacements[$original] = theme('user_picture', array('account' => $account));
|
566 |
|
|
}
|
567 |
|
|
break;
|
568 |
|
|
case 'roles':
|
569 |
|
|
// The roles array may be set from checkbox values so ensure it always
|
570 |
|
|
// has 'proper' data with the role names.
|
571 |
|
|
$roles = array_intersect_key(user_roles(), $account->roles);
|
572 |
|
|
$replacements[$original] = token_render_array($roles, $options);
|
573 |
|
|
break;
|
574 |
|
|
}
|
575 |
|
|
}
|
576 |
|
|
|
577 |
|
|
// Chained token relationships.
|
578 |
|
|
if (variable_get('user_pictures', 0) && !empty($account->picture) && ($picture_tokens = token_find_with_prefix($tokens, 'picture'))) {
|
579 |
|
|
// @todo Remove when core bug http://drupal.org/node/978028 is fixed.
|
580 |
|
|
$account->picture->description = '';
|
581 |
|
|
$replacements += token_generate('file', $picture_tokens, array('file' => $account->picture), $options);
|
582 |
|
|
}
|
583 |
|
|
if ($url_tokens = token_find_with_prefix($tokens, 'url')) {
|
584 |
|
|
$replacements += token_generate('url', $url_tokens, entity_uri('user', $account), $options);
|
585 |
|
|
}
|
586 |
|
|
if ($role_tokens = token_find_with_prefix($tokens, 'roles')) {
|
587 |
|
|
// The roles array may be set from checkbox values so ensure it always
|
588 |
|
|
// has 'proper' data with the role names.
|
589 |
|
|
$roles = array_intersect_key(user_roles(), $account->roles);
|
590 |
|
|
$replacements += token_generate('array', $role_tokens, array('array' => $roles), $options);
|
591 |
|
|
}
|
592 |
|
|
}
|
593 |
|
|
|
594 |
|
|
// Current user tokens.
|
595 |
|
|
if ($type == 'current-user') {
|
596 |
|
|
foreach ($tokens as $name => $original) {
|
597 |
|
|
switch ($name) {
|
598 |
|
|
case 'ip-address':
|
599 |
|
|
$ip = ip_address();
|
600 |
|
|
$replacements[$original] = $sanitize ? check_plain($ip) : $ip;
|
601 |
|
|
break;
|
602 |
|
|
}
|
603 |
|
|
}
|
604 |
|
|
}
|
605 |
|
|
|
606 |
|
|
// Menu link tokens.
|
607 |
|
|
if ($type == 'menu-link' && !empty($data['menu-link'])) {
|
608 |
|
|
$link = (array) $data['menu-link'];
|
609 |
|
|
|
610 |
|
|
if (!isset($link['title'])) {
|
611 |
|
|
// Re-load the link if it was not loaded via token_menu_link_load().
|
612 |
|
|
$link = token_menu_link_load($link['mlid']);
|
613 |
|
|
}
|
614 |
|
|
|
615 |
|
|
foreach ($tokens as $name => $original) {
|
616 |
|
|
switch ($name) {
|
617 |
|
|
case 'mlid':
|
618 |
|
|
$replacements[$original] = $link['mlid'];
|
619 |
|
|
break;
|
620 |
|
|
case 'title':
|
621 |
|
|
$replacements[$original] = $sanitize ? check_plain($link['title']) : $link['title'];
|
622 |
|
|
break;
|
623 |
|
|
case 'url':
|
624 |
|
|
$replacements[$original] = url($link['href'], $url_options);
|
625 |
|
|
break;
|
626 |
|
|
case 'parent':
|
627 |
|
|
if (!empty($link['plid']) && $parent = token_menu_link_load($link['plid'])) {
|
628 |
|
|
$replacements[$original] = $sanitize ? check_plain($parent['title']) : $parent['title'];
|
629 |
|
|
}
|
630 |
|
|
break;
|
631 |
|
|
case 'parents':
|
632 |
|
|
if ($parents = token_menu_link_load_all_parents($link['mlid'])) {
|
633 |
|
|
$replacements[$original] = token_render_array($parents, $options);
|
634 |
|
|
}
|
635 |
|
|
break;
|
636 |
|
|
case 'root';
|
637 |
|
|
if (!empty($link['p1']) && $link['p1'] != $link['mlid'] && $root = token_menu_link_load($link['p1'])) {
|
638 |
|
|
$replacements[$original] = $sanitize ? check_plain($root['title']) : $root['title'];
|
639 |
|
|
}
|
640 |
|
|
break;
|
641 |
|
|
}
|
642 |
|
|
}
|
643 |
|
|
|
644 |
|
|
// Chained token relationships.
|
645 |
|
|
if (!empty($link['plid']) && ($source_tokens = token_find_with_prefix($tokens, 'parent')) && $parent = token_menu_link_load($link['plid'])) {
|
646 |
|
|
$replacements += token_generate('menu-link', $source_tokens, array('menu-link' => $parent), $options);
|
647 |
|
|
}
|
648 |
|
|
// [menu-link:parents:*] chained tokens.
|
649 |
|
|
if ($parents_tokens = token_find_with_prefix($tokens, 'parents')) {
|
650 |
|
|
if ($parents = token_menu_link_load_all_parents($link['mlid'])) {
|
651 |
|
|
$replacements += token_generate('array', $parents_tokens, array('array' => $parents), $options);
|
652 |
|
|
}
|
653 |
|
|
}
|
654 |
|
|
if (!empty($link['p1']) && $link['p1'] != $link['mlid'] && ($root_tokens = token_find_with_prefix($tokens, 'root')) && $root = token_menu_link_load($link['p1'])) {
|
655 |
|
|
$replacements += token_generate('menu-link', $root_tokens, array('menu-link' => $root), $options);
|
656 |
|
|
}
|
657 |
|
|
if ($url_tokens = token_find_with_prefix($tokens, 'url')) {
|
658 |
|
|
$replacements += token_generate('url', $url_tokens, array('path' => $link['href']), $options);
|
659 |
|
|
}
|
660 |
|
|
}
|
661 |
|
|
|
662 |
|
|
// Current page tokens.
|
663 |
|
|
if ($type == 'current-page') {
|
664 |
|
|
$current_path = current_path();
|
665 |
|
|
|
666 |
|
|
foreach ($tokens as $name => $original) {
|
667 |
|
|
switch ($name) {
|
668 |
|
|
case 'title':
|
669 |
|
|
$title = drupal_get_title();
|
670 |
|
|
$replacements[$original] = $sanitize ? $title : decode_entities($title);
|
671 |
|
|
break;
|
672 |
|
|
case 'url':
|
673 |
|
|
$replacements[$original] = url($current_path, $url_options);
|
674 |
|
|
break;
|
675 |
|
|
case 'page-number':
|
676 |
|
|
if ($page = filter_input(INPUT_GET, 'page')) {
|
677 |
|
|
// @see PagerDefault::execute()
|
678 |
|
|
$pager_page_array = explode(',', $page);
|
679 |
|
|
$page = $pager_page_array[0];
|
680 |
|
|
}
|
681 |
|
|
$replacements[$original] = (int) $page + 1;
|
682 |
|
|
break;
|
683 |
|
|
}
|
684 |
|
|
}
|
685 |
|
|
|
686 |
|
|
// @deprecated
|
687 |
|
|
// [current-page:arg] dynamic tokens.
|
688 |
|
|
if ($arg_tokens = token_find_with_prefix($tokens, 'arg')) {
|
689 |
|
|
foreach ($arg_tokens as $name => $original) {
|
690 |
|
|
if (is_numeric($name) && ($arg = arg($name)) && isset($arg)) {
|
691 |
|
|
$replacements[$original] = $sanitize ? check_plain($arg) : $arg;
|
692 |
|
|
}
|
693 |
|
|
}
|
694 |
|
|
}
|
695 |
|
|
|
696 |
|
|
// [current-page:query] dynamic tokens.
|
697 |
|
|
if ($query_tokens = token_find_with_prefix($tokens, 'query')) {
|
698 |
|
|
foreach ($query_tokens as $name => $original) {
|
699 |
|
|
// @todo Should this use filter_input()?
|
700 |
|
|
if (isset($_GET[$name])) {
|
701 |
|
|
$replacements[$original] = $sanitize ? check_plain($_GET[$name]) : $_GET[$name];
|
702 |
|
|
}
|
703 |
|
|
}
|
704 |
|
|
}
|
705 |
|
|
|
706 |
|
|
// Chained token relationships.
|
707 |
|
|
if ($url_tokens = token_find_with_prefix($tokens, 'url')) {
|
708 |
|
|
$replacements += token_generate('url', $url_tokens, array('path' => $current_path), $options);
|
709 |
|
|
}
|
710 |
|
|
}
|
711 |
|
|
|
712 |
|
|
// URL tokens.
|
713 |
|
|
if ($type == 'url' && !empty($data['path'])) {
|
714 |
|
|
$path = $data['path'];
|
715 |
|
|
|
716 |
|
|
if (isset($data['options'])) {
|
717 |
|
|
// Merge in the URL options if available.
|
718 |
|
|
$url_options = $data['options'] + $url_options;
|
719 |
|
|
}
|
720 |
|
|
|
721 |
|
|
foreach ($tokens as $name => $original) {
|
722 |
|
|
switch ($name) {
|
723 |
|
|
case 'path':
|
724 |
|
|
$value = empty($url_options['alias']) ? drupal_get_path_alias($path, $language_code) : $path;
|
725 |
|
|
$replacements[$original] = $sanitize ? check_plain($value) : $value;
|
726 |
|
|
break;
|
727 |
|
|
case 'alias':
|
728 |
|
|
// @deprecated
|
729 |
|
|
$alias = drupal_get_path_alias($path, $language_code);
|
730 |
|
|
$replacements[$original] = $sanitize ? check_plain($alias) : $alias;
|
731 |
|
|
break;
|
732 |
|
|
case 'absolute':
|
733 |
|
|
$replacements[$original] = url($path, $url_options);
|
734 |
|
|
break;
|
735 |
|
|
case 'relative':
|
736 |
|
|
$replacements[$original] = url($path, array('absolute' => FALSE) + $url_options);
|
737 |
|
|
break;
|
738 |
|
|
case 'brief':
|
739 |
|
|
$replacements[$original] = preg_replace(array('!^https?://!', '!/$!'), '', url($path, $url_options));
|
740 |
|
|
break;
|
741 |
|
|
case 'unaliased':
|
742 |
|
|
$replacements[$original] = url($path, array('alias' => TRUE) + $url_options);
|
743 |
|
|
break;
|
744 |
|
|
case 'args':
|
745 |
|
|
$value = empty($url_options['alias']) ? drupal_get_path_alias($path, $language_code) : $path;
|
746 |
|
|
$replacements[$original] = token_render_array(arg(NULL, $value), $options);
|
747 |
|
|
break;
|
748 |
|
|
}
|
749 |
|
|
}
|
750 |
|
|
|
751 |
|
|
// [url:arg:*] chained tokens.
|
752 |
|
|
if ($arg_tokens = token_find_with_prefix($tokens, 'args')) {
|
753 |
|
|
$value = empty($url_options['alias']) ? drupal_get_path_alias($path, $language_code) : $path;
|
754 |
|
|
$replacements += token_generate('array', $arg_tokens, array('array' => arg(NULL, $value)), $options);
|
755 |
|
|
}
|
756 |
|
|
|
757 |
|
|
// [url:unaliased:*] chained tokens.
|
758 |
|
|
if ($unaliased_tokens = token_find_with_prefix($tokens, 'unaliased')) {
|
759 |
|
|
$unaliased_token_data['path'] = $path;
|
760 |
|
|
$unaliased_token_data['options'] = isset($data['options']) ? $data['options'] : array();
|
761 |
|
|
$unaliased_token_data['options']['alias'] = TRUE;
|
762 |
|
|
$replacements += token_generate('url', $unaliased_tokens, $unaliased_token_data, $options);
|
763 |
|
|
}
|
764 |
|
|
}
|
765 |
|
|
|
766 |
|
|
// Entity tokens.
|
767 |
|
|
if (!empty($data[$type]) && $entity_type = token_get_entity_mapping('token', $type)) {
|
768 |
|
|
$entity = $data[$type];
|
769 |
|
|
|
770 |
|
|
// Sometimes taxonomy terms are not properly loaded.
|
771 |
|
|
// @see http://drupal.org/node/870528
|
772 |
|
|
if ($entity_type == 'taxonomy_term' && !isset($entity->vocabulary_machine_name)) {
|
773 |
|
|
$entity->vocabulary_machine_name = db_query("SELECT machine_name FROM {taxonomy_vocabulary} WHERE vid = :vid", array(':vid' => $entity->vid))->fetchField();
|
774 |
|
|
}
|
775 |
|
|
|
776 |
|
|
foreach ($tokens as $name => $original) {
|
777 |
|
|
switch ($name) {
|
778 |
|
|
case 'url':
|
779 |
|
|
if (_token_module($type, 'url') == 'token' && $uri = entity_uri($entity_type, $entity)) {
|
780 |
|
|
$replacements[$original] = url($uri['path'], $uri['options']);
|
781 |
|
|
}
|
782 |
|
|
break;
|
783 |
|
|
|
784 |
|
|
case 'original':
|
785 |
|
|
if (_token_module($type, 'original') == 'token' && !empty($entity->original)) {
|
786 |
|
|
$label = entity_label($entity_type, $entity->original);
|
787 |
|
|
$replacements[$original] = $sanitize ? check_plain($label) : $label;
|
788 |
|
|
}
|
789 |
|
|
break;
|
790 |
|
|
}
|
791 |
|
|
}
|
792 |
|
|
|
793 |
|
|
// [entity:url:*] chained tokens.
|
794 |
|
|
if (($url_tokens = token_find_with_prefix($tokens, 'url')) && _token_module($type, 'url') == 'token') {
|
795 |
|
|
$replacements += token_generate('url', $url_tokens, entity_uri($entity_type, $entity), $options);
|
796 |
|
|
}
|
797 |
|
|
|
798 |
|
|
// [entity:original:*] chained tokens.
|
799 |
|
|
if (($original_tokens = token_find_with_prefix($tokens, 'original')) && _token_module($type, 'original') == 'token' && !empty($entity->original)) {
|
800 |
|
|
$replacements += token_generate($type, $original_tokens, array($type => $entity->original), $options);
|
801 |
|
|
}
|
802 |
|
|
|
803 |
|
|
// Pass through to an generic 'entity' token type generation.
|
804 |
|
|
$entity_data = array(
|
805 |
|
|
'entity_type' => $entity_type,
|
806 |
|
|
'entity' => $entity,
|
807 |
|
|
'token_type' => $type,
|
808 |
|
|
);
|
809 |
|
|
// @todo Investigate passing through more data like everything from entity_extract_ids().
|
810 |
|
|
$replacements += token_generate('entity', $tokens, $entity_data, $options);
|
811 |
|
|
}
|
812 |
|
|
|
813 |
|
|
// Array tokens.
|
814 |
|
|
if ($type == 'array' && !empty($data['array']) && is_array($data['array'])) {
|
815 |
|
|
$array = $data['array'];
|
816 |
|
|
|
817 |
|
|
$sort = isset($options['array sort']) ? $options['array sort'] : TRUE;
|
818 |
|
|
$keys = element_children($array, $sort);
|
819 |
|
|
|
820 |
|
|
foreach ($tokens as $name => $original) {
|
821 |
|
|
switch ($name) {
|
822 |
|
|
case 'first':
|
823 |
|
|
$value = $array[$keys[0]];
|
824 |
|
|
$value = is_array($value) ? render($value) : (string) $value;
|
825 |
|
|
$replacements[$original] = $sanitize ? check_plain($value) : $value;
|
826 |
|
|
break;
|
827 |
|
|
case 'last':
|
828 |
|
|
$value = $array[$keys[count($keys) - 1]];
|
829 |
|
|
$value = is_array($value) ? render($value) : (string) $value;
|
830 |
|
|
$replacements[$original] = $sanitize ? check_plain($value) : $value;
|
831 |
|
|
break;
|
832 |
|
|
case 'count':
|
833 |
|
|
$replacements[$original] = count($keys);
|
834 |
|
|
break;
|
835 |
|
|
case 'keys':
|
836 |
|
|
$replacements[$original] = token_render_array($keys, $options);
|
837 |
|
|
break;
|
838 |
|
|
case 'reversed':
|
839 |
|
|
$reversed = array_reverse($array, TRUE);
|
840 |
|
|
$replacements[$original] = token_render_array($reversed, $options);
|
841 |
|
|
break;
|
842 |
|
|
case 'join':
|
843 |
|
|
$replacements[$original] = token_render_array($array, array('join' => '') + $options);
|
844 |
|
|
break;
|
845 |
|
|
}
|
846 |
|
|
}
|
847 |
|
|
|
848 |
|
|
// [array:value:*] dynamic tokens.
|
849 |
|
|
if ($value_tokens = token_find_with_prefix($tokens, 'value')) {
|
850 |
|
|
foreach ($value_tokens as $key => $original) {
|
851 |
|
|
if ($key[0] !== '#' && isset($array[$key])) {
|
852 |
|
|
$replacements[$original] = token_render_array_value($array[$key], $options);
|
853 |
|
|
}
|
854 |
|
|
}
|
855 |
|
|
}
|
856 |
|
|
|
857 |
|
|
// [array:join:*] dynamic tokens.
|
858 |
|
|
if ($join_tokens = token_find_with_prefix($tokens, 'join')) {
|
859 |
|
|
foreach ($join_tokens as $join => $original) {
|
860 |
|
|
$replacements[$original] = token_render_array($array, array('join' => $join) + $options);
|
861 |
|
|
}
|
862 |
|
|
}
|
863 |
|
|
|
864 |
|
|
// [array:keys:*] chained tokens.
|
865 |
|
|
if ($key_tokens = token_find_with_prefix($tokens, 'keys')) {
|
866 |
|
|
$replacements += token_generate('array', $key_tokens, array('array' => $keys), $options);
|
867 |
|
|
}
|
868 |
|
|
|
869 |
|
|
// [array:reversed:*] chained tokens.
|
870 |
|
|
if ($reversed_tokens = token_find_with_prefix($tokens, 'reversed')) {
|
871 |
|
|
$replacements += token_generate('array', $reversed_tokens, array('array' => array_reverse($array, TRUE)), array('array sort' => FALSE) + $options);
|
872 |
|
|
}
|
873 |
|
|
|
874 |
|
|
// @todo Handle if the array values are not strings and could be chained.
|
875 |
|
|
}
|
876 |
|
|
|
877 |
|
|
// Random tokens.
|
878 |
|
|
if ($type == 'random') {
|
879 |
|
|
foreach ($tokens as $name => $original) {
|
880 |
|
|
switch ($name) {
|
881 |
|
|
case 'number':
|
882 |
|
|
$replacements[$original] = mt_rand();
|
883 |
|
|
break;
|
884 |
|
|
}
|
885 |
|
|
}
|
886 |
|
|
|
887 |
|
|
// [custom:hash:*] dynamic token.
|
888 |
|
|
if ($hash_tokens = token_find_with_prefix($tokens, 'hash')) {
|
889 |
|
|
$algos = hash_algos();
|
890 |
|
|
foreach ($hash_tokens as $name => $original) {
|
891 |
|
|
if (in_array($name, $algos)) {
|
892 |
|
|
$replacements[$original] = hash($name, drupal_random_bytes(55));
|
893 |
|
|
}
|
894 |
|
|
}
|
895 |
|
|
}
|
896 |
|
|
}
|
897 |
|
|
|
898 |
|
|
// If $type is a token type, $data[$type] is empty but $data[$entity_type] is
|
899 |
|
|
// not, re-run token replacements.
|
900 |
|
|
if (empty($data[$type]) && ($entity_type = token_get_entity_mapping('token', $type)) && $entity_type != $type && !empty($data[$entity_type]) && empty($options['recursive'])) {
|
901 |
|
|
$data[$type] = $data[$entity_type];
|
902 |
|
|
$options['recursive'] = TRUE;
|
903 |
|
|
$replacements += module_invoke_all('tokens', $type, $tokens, $data, $options);
|
904 |
|
|
}
|
905 |
|
|
|
906 |
|
|
// If the token type specifics a 'needs-data' value, and the value is not
|
907 |
|
|
// present in $data, then throw an error.
|
908 |
|
|
if (!empty($GLOBALS['drupal_test_info']['test_run_id'])) {
|
909 |
|
|
// Only check when tests are running.
|
910 |
|
|
$type_info = token_get_info($type);
|
911 |
|
|
if (!empty($type_info['needs-data']) && !isset($data[$type_info['needs-data']])) {
|
912 |
|
|
trigger_error(t('Attempting to perform token replacement for token type %type without required data', array('%type' => $type)), E_USER_WARNING);
|
913 |
|
|
}
|
914 |
|
|
}
|
915 |
|
|
|
916 |
|
|
return $replacements;
|
917 |
|
|
}
|
918 |
|
|
|
919 |
|
|
/**
|
920 |
|
|
* Implements hook_tokens_alter().
|
921 |
|
|
*
|
922 |
|
|
* Fix existing core tokens that do not work correctly.
|
923 |
|
|
*/
|
924 |
|
|
function token_tokens_alter(array &$replacements, array $context) {
|
925 |
|
|
$options = $context['options'];
|
926 |
|
|
|
927 |
|
|
$sanitize = !empty($options['sanitize']);
|
928 |
|
|
$langcode = !empty($options['language']->language) ? $options['language']->language : NULL;
|
929 |
|
|
|
930 |
|
|
// Comment token fixes.
|
931 |
|
|
if ($context['type'] == 'comment' && !empty($context['data']['comment'])) {
|
932 |
|
|
$comment = $context['data']['comment'];
|
933 |
|
|
|
934 |
|
|
foreach ($context['tokens'] as $name => $original) {
|
935 |
|
|
switch ($name) {
|
936 |
|
|
case 'name':
|
937 |
|
|
case 'author':
|
938 |
|
|
// @todo Remove when http://drupal.org/node/920056 is fixed.
|
939 |
|
|
if (!empty($comment->uid)) {
|
940 |
|
|
$account = user_load($comment->uid);
|
941 |
|
|
}
|
942 |
|
|
else {
|
943 |
|
|
$account = drupal_anonymous_user();
|
944 |
|
|
$account->name = $comment->name;
|
945 |
|
|
}
|
946 |
|
|
$name = format_username($account);
|
947 |
|
|
$replacements[$original] = $sanitize ? check_plain($name) : $name;
|
948 |
|
|
break;
|
949 |
|
|
}
|
950 |
|
|
}
|
951 |
|
|
}
|
952 |
|
|
|
953 |
|
|
// Node token fixes.
|
954 |
|
|
if ($context['type'] == 'node' && !empty($context['data']['node'])) {
|
955 |
|
|
$node = $context['data']['node'];
|
956 |
|
|
|
957 |
|
|
foreach ($context['tokens'] as $name => $original) {
|
958 |
|
|
switch ($name) {
|
959 |
|
|
case 'author':
|
960 |
|
|
// http://drupal.org/node/1185842 was fixed in core release 7.9.
|
961 |
|
|
if (version_compare(VERSION, '7.9', '<')) {
|
962 |
|
|
$account = user_load($node->uid);
|
963 |
|
|
$name = format_username($account);
|
964 |
|
|
$replacements[$original] = $sanitize ? check_plain($name) : $name;
|
965 |
|
|
}
|
966 |
|
|
break;
|
967 |
|
|
}
|
968 |
|
|
}
|
969 |
|
|
}
|
970 |
|
|
|
971 |
|
|
// File token fixes.
|
972 |
|
|
if ($context['type'] == 'file' && !empty($context['data']['file'])) {
|
973 |
|
|
$file = $context['data']['file'];
|
974 |
|
|
|
975 |
|
|
foreach ($context['tokens'] as $name => $original) {
|
976 |
|
|
switch ($name) {
|
977 |
|
|
case 'owner':
|
978 |
|
|
// http://drupal.org/node/978028 was fixed in core release 7.7.
|
979 |
|
|
if (version_compare(VERSION, '7.7', '<')) {
|
980 |
|
|
$account = user_load($file->uid);
|
981 |
|
|
$name = format_username($account);
|
982 |
|
|
$replacements[$original] = $sanitize ? check_plain($name) : $name;
|
983 |
|
|
}
|
984 |
|
|
break;
|
985 |
|
|
}
|
986 |
|
|
}
|
987 |
|
|
}
|
988 |
|
|
}
|
989 |
|
|
|
990 |
|
|
/**
|
991 |
|
|
* Implements hook_token_info() on behalf of book.module.
|
992 |
|
|
*/
|
993 |
|
|
function book_token_info() {
|
994 |
|
|
$info['tokens']['node']['book'] = array(
|
995 |
|
|
'name' => t('Book'),
|
996 |
|
|
'description' => t('The book page associated with the node.'),
|
997 |
|
|
'type' => 'menu-link',
|
998 |
|
|
);
|
999 |
|
|
return $info;
|
1000 |
|
|
}
|
1001 |
|
|
|
1002 |
|
|
/**
|
1003 |
|
|
* Implements hook_tokens() on behalf of book.module.
|
1004 |
|
|
*/
|
1005 |
|
|
function book_tokens($type, $tokens, array $data = array(), array $options = array()) {
|
1006 |
|
|
$replacements = array();
|
1007 |
|
|
$sanitize = !empty($options['sanitize']);
|
1008 |
|
|
|
1009 |
|
|
// Node tokens.
|
1010 |
|
|
if ($type == 'node' && !empty($data['node'])) {
|
1011 |
|
|
$node = $data['node'];
|
1012 |
|
|
|
1013 |
|
|
if (!empty($node->book['mlid'])) {
|
1014 |
|
|
$link = token_book_link_load($node->book['mlid']);
|
1015 |
|
|
|
1016 |
|
|
foreach ($tokens as $name => $original) {
|
1017 |
|
|
switch ($name) {
|
1018 |
|
|
case 'book':
|
1019 |
|
|
$replacements[$original] = $sanitize ? check_plain($link['title']) : $link['title'];
|
1020 |
|
|
break;
|
1021 |
|
|
}
|
1022 |
|
|
}
|
1023 |
|
|
|
1024 |
|
|
// Chained token relationships.
|
1025 |
|
|
if ($book_tokens = token_find_with_prefix($tokens, 'book')) {
|
1026 |
|
|
$replacements += token_generate('menu-link', $book_tokens, array('menu-link' => $link), $options);
|
1027 |
|
|
}
|
1028 |
|
|
}
|
1029 |
|
|
}
|
1030 |
|
|
|
1031 |
|
|
return $replacements;
|
1032 |
|
|
}
|
1033 |
|
|
|
1034 |
|
|
/**
|
1035 |
|
|
* Implements hook_token_info() on behalf of menu.module.
|
1036 |
|
|
*/
|
1037 |
|
|
function menu_token_info() {
|
1038 |
|
|
// Menu tokens.
|
1039 |
|
|
$info['types']['menu'] = array(
|
1040 |
|
|
'name' => t('Menus'),
|
1041 |
|
|
'description' => t('Tokens related to menus.'),
|
1042 |
|
|
'needs-data' => 'menu',
|
1043 |
|
|
);
|
1044 |
|
|
$info['tokens']['menu']['name'] = array(
|
1045 |
|
|
'name' => t('Name'),
|
1046 |
|
|
'description' => t("The name of the menu."),
|
1047 |
|
|
);
|
1048 |
|
|
$info['tokens']['menu']['machine-name'] = array(
|
1049 |
|
|
'name' => t('Machine-readable name'),
|
1050 |
|
|
'description' => t("The unique machine-readable name of the menu."),
|
1051 |
|
|
);
|
1052 |
|
|
$info['tokens']['menu']['description'] = array(
|
1053 |
|
|
'name' => t('Description'),
|
1054 |
|
|
'description' => t('The optional description of the menu.'),
|
1055 |
|
|
);
|
1056 |
|
|
$info['tokens']['menu']['menu-link-count'] = array(
|
1057 |
|
|
'name' => t('Menu link count'),
|
1058 |
|
|
'description' => t('The number of menu links belonging to the menu.'),
|
1059 |
|
|
);
|
1060 |
|
|
$info['tokens']['menu']['edit-url'] = array(
|
1061 |
|
|
'name' => t('Edit URL'),
|
1062 |
|
|
'description' => t("The URL of the menu's edit page."),
|
1063 |
|
|
);
|
1064 |
|
|
|
1065 |
|
|
$info['tokens']['menu-link']['menu'] = array(
|
1066 |
|
|
'name' => t('Menu'),
|
1067 |
|
|
'description' => t('The menu of the menu link.'),
|
1068 |
|
|
'type' => 'menu',
|
1069 |
|
|
);
|
1070 |
|
|
$info['tokens']['menu-link']['edit-url'] = array(
|
1071 |
|
|
'name' => t('Edit URL'),
|
1072 |
|
|
'description' => t("The URL of the menu link's edit page."),
|
1073 |
|
|
);
|
1074 |
|
|
$info['tokens']['node']['menu-link'] = array(
|
1075 |
|
|
'name' => t('Menu link'),
|
1076 |
|
|
'description' => t("The menu link for this node."),
|
1077 |
|
|
'type' => 'menu-link',
|
1078 |
|
|
);
|
1079 |
|
|
|
1080 |
|
|
return $info;
|
1081 |
|
|
}
|
1082 |
|
|
|
1083 |
|
|
/**
|
1084 |
|
|
* Implements hook_tokens() on behalf of menu.module.
|
1085 |
|
|
*/
|
1086 |
|
|
function menu_tokens($type, $tokens, array $data = array(), array $options = array()) {
|
1087 |
|
|
$replacements = array();
|
1088 |
|
|
|
1089 |
|
|
$url_options = array('absolute' => TRUE);
|
1090 |
|
|
if (isset($options['language'])) {
|
1091 |
|
|
$url_options['language'] = $options['language'];
|
1092 |
|
|
$language_code = $options['language']->language;
|
1093 |
|
|
}
|
1094 |
|
|
else {
|
1095 |
|
|
$language_code = NULL;
|
1096 |
|
|
}
|
1097 |
|
|
|
1098 |
|
|
$sanitize = !empty($options['sanitize']);
|
1099 |
|
|
|
1100 |
|
|
// Node tokens.
|
1101 |
|
|
if ($type == 'node' && !empty($data['node'])) {
|
1102 |
|
|
$node = $data['node'];
|
1103 |
|
|
|
1104 |
|
|
foreach ($tokens as $name => $original) {
|
1105 |
|
|
switch ($name) {
|
1106 |
|
|
case 'menu-link':
|
1107 |
|
|
if ($link = token_node_menu_link_load($node)) {
|
1108 |
|
|
$replacements[$original] = $sanitize ? check_plain($link['title']) : $link['title'];
|
1109 |
|
|
}
|
1110 |
|
|
break;
|
1111 |
|
|
}
|
1112 |
|
|
|
1113 |
|
|
// Chained token relationships.
|
1114 |
|
|
if ($menu_tokens = token_find_with_prefix($tokens, 'menu-link')) {
|
1115 |
|
|
if ($link = token_node_menu_link_load($node)) {
|
1116 |
|
|
$replacements += token_generate('menu-link', $menu_tokens, array('menu-link' => $link), $options);
|
1117 |
|
|
}
|
1118 |
|
|
}
|
1119 |
|
|
}
|
1120 |
|
|
}
|
1121 |
|
|
|
1122 |
|
|
// Menu link tokens.
|
1123 |
|
|
if ($type == 'menu-link' && !empty($data['menu-link'])) {
|
1124 |
|
|
$link = (array) $data['menu-link'];
|
1125 |
|
|
|
1126 |
|
|
foreach ($tokens as $name => $original) {
|
1127 |
|
|
switch ($name) {
|
1128 |
|
|
case 'menu':
|
1129 |
|
|
if ($menu = menu_load($link['menu_name'])) {
|
1130 |
|
|
$replacements[$original] = $sanitize ? check_plain($menu['title']) : $menu['title'];
|
1131 |
|
|
}
|
1132 |
|
|
break;
|
1133 |
|
|
case 'edit-url':
|
1134 |
|
|
$replacements[$original] = url("admin/structure/menu/item/{$link['mlid']}/edit", $url_options);
|
1135 |
|
|
break;
|
1136 |
|
|
}
|
1137 |
|
|
}
|
1138 |
|
|
|
1139 |
|
|
// Chained token relationships.
|
1140 |
|
|
if (($menu_tokens = token_find_with_prefix($tokens, 'menu')) && $menu = menu_load($link['menu_name'])) {
|
1141 |
|
|
$replacements += token_generate('menu', $menu_tokens, array('menu' => $menu), $options);
|
1142 |
|
|
}
|
1143 |
|
|
}
|
1144 |
|
|
|
1145 |
|
|
// Menu tokens.
|
1146 |
|
|
if ($type == 'menu' && !empty($data['menu'])) {
|
1147 |
|
|
$menu = (array) $data['menu'];
|
1148 |
|
|
|
1149 |
|
|
foreach ($tokens as $name => $original) {
|
1150 |
|
|
switch ($name) {
|
1151 |
|
|
case 'name':
|
1152 |
|
|
$replacements[$original] = $sanitize ? check_plain($menu['title']) : $menu['title'];
|
1153 |
|
|
break;
|
1154 |
|
|
case 'machine-name':
|
1155 |
|
|
// This is a machine name so does not ever need to be sanitized.
|
1156 |
|
|
$replacements[$original] = $menu['menu_name'];
|
1157 |
|
|
break;
|
1158 |
|
|
case 'description':
|
1159 |
|
|
$replacements[$original] = $sanitize ? filter_xss($menu['description']) : $menu['description'];
|
1160 |
|
|
break;
|
1161 |
|
|
case 'menu-link-count':
|
1162 |
|
|
$query = db_select('menu_links');
|
1163 |
|
|
$query->condition('menu_name', $menu['menu_name']);
|
1164 |
|
|
$query->addTag('menu_menu_link_count');
|
1165 |
|
|
$count = $query->countQuery()->execute()->fetchField();
|
1166 |
|
|
$replacements[$original] = (int) $count;
|
1167 |
|
|
break;
|
1168 |
|
|
case 'edit-url':
|
1169 |
|
|
$replacements[$original] = url("admin/structure/menu/manage/" . $menu['menu_name'], $url_options);
|
1170 |
|
|
break;
|
1171 |
|
|
}
|
1172 |
|
|
}
|
1173 |
|
|
}
|
1174 |
|
|
|
1175 |
|
|
return $replacements;
|
1176 |
|
|
}
|
1177 |
|
|
|
1178 |
|
|
/**
|
1179 |
|
|
* Implements hook_token_info() on behalf of profile.module.
|
1180 |
|
|
*/
|
1181 |
|
|
function profile_token_info() {
|
1182 |
|
|
$info = array();
|
1183 |
|
|
|
1184 |
|
|
foreach (_token_profile_fields() as $field) {
|
1185 |
|
|
$info['tokens']['user'][$field->token_name] = array(
|
1186 |
|
|
'name' => check_plain($field->title),
|
1187 |
|
|
'description' => t('@category @type field.', array('@category' => drupal_ucfirst($field->category), '@type' => $field->type)),
|
1188 |
|
|
);
|
1189 |
|
|
|
1190 |
|
|
switch ($field->type) {
|
1191 |
|
|
case 'date':
|
1192 |
|
|
$info['tokens']['user'][$field->token_name]['type'] = 'date';
|
1193 |
|
|
break;
|
1194 |
|
|
}
|
1195 |
|
|
}
|
1196 |
|
|
|
1197 |
|
|
return $info;
|
1198 |
|
|
}
|
1199 |
|
|
|
1200 |
|
|
/**
|
1201 |
|
|
* Implements hook_tokens() on behalf of profile.module.
|
1202 |
|
|
*/
|
1203 |
|
|
function profile_tokens($type, $tokens, array $data = array(), array $options = array()) {
|
1204 |
|
|
$replacements = array();
|
1205 |
|
|
$sanitize = !empty($options['sanitize']);
|
1206 |
|
|
$language_code = isset($options['language']) ? $options['language']->language : NULL;
|
1207 |
|
|
|
1208 |
|
|
if ($type == 'user' && !empty($data['user'])) {
|
1209 |
|
|
$account = $data['user'];
|
1210 |
|
|
|
1211 |
|
|
// Load profile fields if this is the global user account.
|
1212 |
|
|
// @see http://drupal.org/node/361471
|
1213 |
|
|
// @see http://drupal.org/node/967330
|
1214 |
|
|
if ($account->uid == $GLOBALS['user']->uid && isset($account->timestamp)) {
|
1215 |
|
|
$profile_users = array($account->uid => $account);
|
1216 |
|
|
profile_user_load($profile_users);
|
1217 |
|
|
$account = $profile_users[$account->uid];
|
1218 |
|
|
}
|
1219 |
|
|
|
1220 |
|
|
$profile_fields = _token_profile_fields();
|
1221 |
|
|
foreach ($tokens as $name => $original) {
|
1222 |
|
|
if (isset($profile_fields[$name]) && !empty($account->{$profile_fields[$name]->name})) {
|
1223 |
|
|
$value = $account->{$profile_fields[$name]->name};
|
1224 |
|
|
switch ($profile_fields[$name]->type) {
|
1225 |
|
|
case 'textarea':
|
1226 |
|
|
$replacements[$original] = $sanitize ? check_markup($value, filter_default_format($account), '', TRUE) : $value;
|
1227 |
|
|
break;
|
1228 |
|
|
case 'date':
|
1229 |
|
|
$timestamp = gmmktime(0, 0, 0, $value['month'], $value['day'], $value['year']);
|
1230 |
|
|
$replacements[$original] = format_date($timestamp, 'medium', '', NULL, $language_code);
|
1231 |
|
|
break;
|
1232 |
|
|
case 'url':
|
1233 |
|
|
$replacements[$original] = $sanitize ? check_url($value) : $value;
|
1234 |
|
|
break;
|
1235 |
|
|
case 'checkbox':
|
1236 |
|
|
// Checkbox field if checked should return the text.
|
1237 |
|
|
$replacements[$original] = $sanitize ? check_plain($profile_fields[$name]->title) : $profile_fields[$name]->title;
|
1238 |
|
|
break;
|
1239 |
|
|
case 'list':
|
1240 |
|
|
$value = preg_split("/[,\n\r]/", $value);
|
1241 |
|
|
$value = array_map('trim', $value);
|
1242 |
|
|
$value = implode(', ', $value);
|
1243 |
|
|
// Intentionally fall through to the default condition.
|
1244 |
|
|
default:
|
1245 |
|
|
$replacements[$original] = $sanitize ? check_plain($value) : $value;
|
1246 |
|
|
break;
|
1247 |
|
|
}
|
1248 |
|
|
}
|
1249 |
|
|
}
|
1250 |
|
|
|
1251 |
|
|
// Chained token relationships.
|
1252 |
|
|
foreach ($profile_fields as $field) {
|
1253 |
|
|
if ($field->type == 'date' && isset($account->{$field->name}) && $field_tokens = token_find_with_prefix($tokens, $field->token_name)) {
|
1254 |
|
|
$date = $account->{$field->name};
|
1255 |
|
|
$replacements += token_generate('date', $field_tokens, array('date' => gmmktime(0, 0, 0, $date['month'], $date['day'], $date['year'])), $options);
|
1256 |
|
|
}
|
1257 |
|
|
}
|
1258 |
|
|
}
|
1259 |
|
|
|
1260 |
|
|
return $replacements;
|
1261 |
|
|
}
|
1262 |
|
|
|
1263 |
|
|
/**
|
1264 |
|
|
* Fetch an array of profile field objects, keyed by token name.
|
1265 |
|
|
*/
|
1266 |
|
|
function _token_profile_fields() {
|
1267 |
|
|
$fields = &drupal_static(__FUNCTION__);
|
1268 |
|
|
|
1269 |
|
|
if (!isset($fields)) {
|
1270 |
|
|
$fields = array();
|
1271 |
|
|
$results = db_query("SELECT name, title, category, type FROM {profile_field}");
|
1272 |
|
|
foreach ($results as $field) {
|
1273 |
|
|
$field->token_name = token_clean_token_name($field->name);
|
1274 |
|
|
$fields[$field->token_name] = $field;
|
1275 |
|
|
}
|
1276 |
|
|
}
|
1277 |
|
|
|
1278 |
|
|
return $fields;
|
1279 |
|
|
}
|
1280 |
|
|
|
1281 |
|
|
/**
|
1282 |
|
|
* Fetch an array of field data used for tokens.
|
1283 |
|
|
*/
|
1284 |
|
|
function _token_field_info($field_name = NULL) {
|
1285 |
|
|
$info = &drupal_static(__FUNCTION__);
|
1286 |
|
|
|
1287 |
|
|
if (!isset($fields)) {
|
1288 |
|
|
if ($cached = cache_get('field:info', 'cache_token')) {
|
1289 |
|
|
$info = $cached->data;
|
1290 |
|
|
}
|
1291 |
|
|
else {
|
1292 |
|
|
$info = array();
|
1293 |
|
|
|
1294 |
|
|
$fields = field_info_fields();
|
1295 |
|
|
$instances = field_info_instances();
|
1296 |
|
|
$type_info = field_info_field_types();
|
1297 |
|
|
$entity_info = entity_get_info();
|
1298 |
|
|
|
1299 |
|
|
foreach ($fields as $field) {
|
1300 |
|
|
$key = $field['field_name'];
|
1301 |
|
|
if (!empty($field['bundles'])) {
|
1302 |
|
|
foreach (array_keys($field['bundles']) as $entity) {
|
1303 |
|
|
// Make sure a token type exists for this entity.
|
1304 |
|
|
$token_type = token_get_entity_mapping('entity', $entity);
|
1305 |
|
|
if (empty($token_type)) {
|
1306 |
|
|
continue;
|
1307 |
|
|
}
|
1308 |
|
|
|
1309 |
|
|
$info[$key]['token types'][] = $token_type;
|
1310 |
|
|
$info[$key] += array('labels' => array(), 'bundles' => array());
|
1311 |
|
|
|
1312 |
|
|
// Find which label is most commonly used.
|
1313 |
|
|
foreach ($field['bundles'][$entity] as $bundle) {
|
1314 |
|
|
// Field information will included fields attached to disabled
|
1315 |
|
|
// bundles, so check that the bundle exists before provided a
|
1316 |
|
|
// token for it.
|
1317 |
|
|
// @see http://drupal.org/node/1252566
|
1318 |
|
|
if (!isset($entity_info[$entity]['bundles'][$bundle])) {
|
1319 |
|
|
continue;
|
1320 |
|
|
}
|
1321 |
|
|
|
1322 |
|
|
$info[$key]['labels'][] = $instances[$entity][$bundle][$key]['label'];
|
1323 |
|
|
$info[$key]['bundles'][$token_type][$bundle] = $entity_info[$entity]['bundles'][$bundle]['label'];
|
1324 |
|
|
}
|
1325 |
|
|
}
|
1326 |
|
|
}
|
1327 |
|
|
|
1328 |
|
|
if (isset($info[$key])) {
|
1329 |
|
|
$labels = array_count_values($info[$key]['labels']);
|
1330 |
|
|
arsort($labels);
|
1331 |
|
|
$info[$key]['label'] = check_plain(key($labels));
|
1332 |
|
|
|
1333 |
|
|
// Generate a description for the token.
|
1334 |
|
|
$info[$key]['description'] = t('@type field.', array('@type' => $type_info[$field['type']]['label']));
|
1335 |
|
|
if ($also_known_as = array_unique(array_diff($info[$key]['labels'], array($info[$key]['label'])))) {
|
1336 |
|
|
$info[$key]['description'] .= ' ' . t('Also known as %labels.', array('%labels' => implode(', ', $also_known_as)));
|
1337 |
|
|
}
|
1338 |
|
|
}
|
1339 |
|
|
}
|
1340 |
|
|
|
1341 |
|
|
drupal_alter('token_field_info', $info);
|
1342 |
|
|
cache_set('field:info', $info, 'cache_token');
|
1343 |
|
|
}
|
1344 |
|
|
}
|
1345 |
|
|
|
1346 |
|
|
if (isset($field_name)) {
|
1347 |
|
|
return isset($info[$field_name]) ? $info[$field_name] : FALSE;
|
1348 |
|
|
}
|
1349 |
|
|
|
1350 |
|
|
return $info;
|
1351 |
|
|
}
|
1352 |
|
|
|
1353 |
|
|
/**
|
1354 |
|
|
* Implements hook_token_info_alter() on behalf of field.module.
|
1355 |
|
|
*
|
1356 |
|
|
* We use hook_token_info_alter() rather than hook_token_info() as other
|
1357 |
|
|
* modules may already have defined some field tokens.
|
1358 |
|
|
*/
|
1359 |
|
|
function field_token_info_alter(&$info) {
|
1360 |
|
|
$fields = _token_field_info();
|
1361 |
|
|
|
1362 |
|
|
// Attach field tokens to their respecitve entity tokens.
|
1363 |
|
|
foreach ($fields as $field_name => $field) {
|
1364 |
|
|
foreach (array_keys($field['bundles']) as $token_type) {
|
1365 |
|
|
// If a token already exists for this field, then don't add it.
|
1366 |
|
|
if (isset($info['tokens'][$token_type][$field_name])) {
|
1367 |
|
|
continue;
|
1368 |
|
|
}
|
1369 |
|
|
|
1370 |
|
|
// Ensure the tokens exist.
|
1371 |
|
|
if (!isset($info['types'][$token_type]) || !isset($info['tokens'][$token_type])) {
|
1372 |
|
|
continue;
|
1373 |
|
|
}
|
1374 |
|
|
|
1375 |
|
|
if ($token_type == 'comment' && $field_name == 'comment_body') {
|
1376 |
|
|
// Core provides the comment field as [comment:body].
|
1377 |
|
|
continue;
|
1378 |
|
|
}
|
1379 |
|
|
|
1380 |
|
|
$info['tokens'][$token_type][$field_name] = array(
|
1381 |
|
|
// Note that label and description have already been sanitized by _token_field_info().
|
1382 |
|
|
'name' => $field['label'],
|
1383 |
|
|
'description' => $field['description'],
|
1384 |
|
|
'module' => 'token',
|
1385 |
|
|
);
|
1386 |
|
|
}
|
1387 |
|
|
}
|
1388 |
|
|
}
|
1389 |
|
|
|
1390 |
|
|
/**
|
1391 |
|
|
* Implements hook_tokens() on behalf of field.module.
|
1392 |
|
|
*/
|
1393 |
|
|
function field_tokens($type, $tokens, array $data = array(), array $options = array()) {
|
1394 |
|
|
$replacements = array();
|
1395 |
|
|
$sanitize = !empty($options['sanitize']);
|
1396 |
|
|
$langcode = isset($options['language']) ? $options['language']->language : NULL;
|
1397 |
|
|
|
1398 |
|
|
// Entity tokens.
|
1399 |
|
|
if ($type == 'entity' && !empty($data['entity_type']) && !empty($data['entity']) && !empty($data['token_type'])) {
|
1400 |
|
|
$entity_type = $data['entity_type'];
|
1401 |
|
|
|
1402 |
|
|
// The field API does weird stuff to the entity, so let's clone it.
|
1403 |
|
|
$entity = clone $data['entity'];
|
1404 |
|
|
|
1405 |
|
|
// Reset the prepared view flag in case token generation is called from
|
1406 |
|
|
// inside field_attach_view().
|
1407 |
|
|
unset($entity->_field_view_prepared);
|
1408 |
|
|
|
1409 |
|
|
list(, , $bundle) = entity_extract_ids($entity_type, $entity);
|
1410 |
|
|
$fields = field_info_instances($entity_type, $bundle);
|
1411 |
|
|
|
1412 |
|
|
foreach (array_keys($fields) as $field_name) {
|
1413 |
|
|
// Do not continue if the field is empty.
|
1414 |
|
|
if (empty($entity->{$field_name})) {
|
1415 |
|
|
continue;
|
1416 |
|
|
}
|
1417 |
|
|
|
1418 |
|
|
// Replace the [entity:field-name] token only if token module added this
|
1419 |
|
|
// token.
|
1420 |
|
|
if (isset($tokens[$field_name]) && _token_module($data['token_type'], $field_name) == 'token') {
|
1421 |
|
|
$original = $tokens[$field_name];
|
1422 |
|
|
|
1423 |
|
|
$field_output = field_view_field($entity_type, $entity, $field_name, 'token', $langcode);
|
1424 |
|
|
$field_output['#token_options'] = $options;
|
1425 |
|
|
$field_output['#pre_render'][] = 'token_pre_render_field_token';
|
1426 |
|
|
$replacements[$original] = drupal_render($field_output);
|
1427 |
|
|
}
|
1428 |
|
|
}
|
1429 |
|
|
|
1430 |
|
|
// Remove the cloned object from memory.
|
1431 |
|
|
unset($entity);
|
1432 |
|
|
}
|
1433 |
|
|
|
1434 |
|
|
return $replacements;
|
1435 |
|
|
}
|
1436 |
|
|
|
1437 |
|
|
/**
|
1438 |
|
|
* Pre-render callback for field output used with tokens.
|
1439 |
|
|
*/
|
1440 |
|
|
function token_pre_render_field_token(&$elements) {
|
1441 |
|
|
// Remove the field theme hook, attachments, and JavaScript states.
|
1442 |
|
|
unset($elements['#theme']);
|
1443 |
|
|
unset($elements['#states']);
|
1444 |
|
|
unset($elements['#attached']);
|
1445 |
|
|
|
1446 |
|
|
// Prevent multi-value fields from appearing smooshed together by appending
|
1447 |
|
|
// a join suffix to all but the last value.
|
1448 |
|
|
$deltas = element_get_visible_children($elements);
|
1449 |
|
|
$count = count($deltas);
|
1450 |
|
|
if ($count > 1) {
|
1451 |
|
|
$join = isset($elements['#token_options']['join']) ? $elements['#token_options']['join'] : ", ";
|
1452 |
|
|
foreach ($deltas as $index => $delta) {
|
1453 |
|
|
// Do not add a suffix to the last item.
|
1454 |
|
|
if ($index < ($count - 1)) {
|
1455 |
|
|
$elements[$delta] += array('#suffix' => $join);
|
1456 |
|
|
}
|
1457 |
|
|
}
|
1458 |
|
|
}
|
1459 |
|
|
return $elements;
|
1460 |
|
|
} |