Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / lib / Drupal / Core / Utility / token.api.php
1 <?php
2
3 /**
4  * @file
5  * Hooks related to the Token system.
6  */
7
8 use Drupal\user\Entity\User;
9
10 /**
11  * @addtogroup hooks
12  * @{
13  */
14
15 /**
16  * Provide replacement values for placeholder tokens.
17  *
18  * This hook is invoked when someone calls
19  * \Drupal\Core\Utility\Token::replace(). That function first scans the text for
20  * [type:token] patterns, and splits the needed tokens into groups by type.
21  * Then hook_tokens() is invoked on each token-type group, allowing your module
22  * to respond by providing replacement text for any of the tokens in the group
23  * that your module knows how to process.
24  *
25  * A module implementing this hook should also implement hook_token_info() in
26  * order to list its available tokens on editing screens.
27  *
28  * @param $type
29  *   The machine-readable name of the type (group) of token being replaced, such
30  *   as 'node', 'user', or another type defined by a hook_token_info()
31  *   implementation.
32  * @param $tokens
33  *   An array of tokens to be replaced. The keys are the machine-readable token
34  *   names, and the values are the raw [type:token] strings that appeared in the
35  *   original text.
36  * @param array $data
37  *   An associative array of data objects to be used when generating replacement
38  *   values, as supplied in the $data parameter to
39  *   \Drupal\Core\Utility\Token::replace().
40  * @param array $options
41  *   An associative array of options for token replacement; see
42  *   \Drupal\Core\Utility\Token::replace() for possible values.
43  * @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata
44  *   The bubbleable metadata. Prior to invoking this hook,
45  *   \Drupal\Core\Utility\Token::generate() collects metadata for all of the
46  *   data objects in $data. For any data sources not in $data, but that are
47  *   used by the token replacement logic, such as global configuration (e.g.,
48  *   'system.site') and related objects (e.g., $node->getOwner()),
49  *   implementations of this hook must add the corresponding metadata.
50  *   For example:
51  *   @code
52  *     $bubbleable_metadata->addCacheableDependency(\Drupal::config('system.site'));
53  *     $bubbleable_metadata->addCacheableDependency($node->getOwner());
54  *   @endcode
55  *
56  *   Additionally, implementations of this hook, must forward
57  *   $bubbleable_metadata to the chained tokens that they invoke.
58  *   For example:
59  *   @code
60  *     if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
61  *       $replacements = $token_service->generate('date', $created_tokens, array('date' => $node->getCreatedTime()), $options, $bubbleable_metadata);
62  *     }
63  *   @endcode
64  *
65  * @return array
66  *   An associative array of replacement values, keyed by the raw [type:token]
67  *   strings from the original text. The returned values must be either plain
68  *   text strings, or an object implementing MarkupInterface if they are
69  *   HTML-formatted.
70  *
71  * @see hook_token_info()
72  * @see hook_tokens_alter()
73  */
74 function hook_tokens($type, $tokens, array $data, array $options, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {
75   $token_service = \Drupal::token();
76
77   $url_options = ['absolute' => TRUE];
78   if (isset($options['langcode'])) {
79     $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
80     $langcode = $options['langcode'];
81   }
82   else {
83     $langcode = NULL;
84   }
85   $replacements = [];
86
87   if ($type == 'node' && !empty($data['node'])) {
88     /** @var \Drupal\node\NodeInterface $node */
89     $node = $data['node'];
90
91     foreach ($tokens as $name => $original) {
92       switch ($name) {
93         // Simple key values on the node.
94         case 'nid':
95           $replacements[$original] = $node->nid;
96           break;
97
98         case 'title':
99           $replacements[$original] = $node->getTitle();
100           break;
101
102         case 'edit-url':
103           $replacements[$original] = $node->url('edit-form', $url_options);
104           break;
105
106         // Default values for the chained tokens handled below.
107         case 'author':
108           $account = $node->getOwner() ? $node->getOwner() : User::load(0);
109           $replacements[$original] = $account->label();
110           $bubbleable_metadata->addCacheableDependency($account);
111           break;
112
113         case 'created':
114           $replacements[$original] = format_date($node->getCreatedTime(), 'medium', '', NULL, $langcode);
115           break;
116       }
117     }
118
119     if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
120       $replacements += $token_service->generate('user', $author_tokens, ['user' => $node->getOwner()], $options, $bubbleable_metadata);
121     }
122
123     if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
124       $replacements += $token_service->generate('date', $created_tokens, ['date' => $node->getCreatedTime()], $options, $bubbleable_metadata);
125     }
126   }
127
128   return $replacements;
129 }
130
131 /**
132  * Alter replacement values for placeholder tokens.
133  *
134  * @param $replacements
135  *   An associative array of replacements returned by hook_tokens().
136  * @param $context
137  *   The context in which hook_tokens() was called. An associative array with
138  *   the following keys, which have the same meaning as the corresponding
139  *   parameters of hook_tokens():
140  *   - 'type'
141  *   - 'tokens'
142  *   - 'data'
143  *   - 'options'
144  * @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata
145  *   The bubbleable metadata. In case you alter an existing token based upon
146  *   a data source that isn't in $context['data'], you must add that
147  *   dependency to $bubbleable_metadata.
148  *
149  * @see hook_tokens()
150  */
151 function hook_tokens_alter(array &$replacements, array $context, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {
152   $options = $context['options'];
153
154   if (isset($options['langcode'])) {
155     $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
156     $langcode = $options['langcode'];
157   }
158   else {
159     $langcode = NULL;
160   }
161
162   if ($context['type'] == 'node' && !empty($context['data']['node'])) {
163     $node = $context['data']['node'];
164
165     // Alter the [node:title] token, and replace it with the rendered content
166     // of a field (field_title).
167     if (isset($context['tokens']['title'])) {
168       $title = $node->field_title->view('default');
169       $replacements[$context['tokens']['title']] = drupal_render($title);
170     }
171   }
172 }
173
174 /**
175  * Provide information about available placeholder tokens and token types.
176  *
177  * Tokens are placeholders that can be put into text by using the syntax
178  * [type:token], where type is the machine-readable name of a token type, and
179  * token is the machine-readable name of a token within this group. This hook
180  * provides a list of types and tokens to be displayed on text editing screens,
181  * so that people editing text can see what their token options are.
182  *
183  * The actual token replacement is done by
184  * \Drupal\Core\Utility\Token::replace(), which invokes hook_tokens(). Your
185  * module will need to implement that hook in order to generate token
186  * replacements from the tokens defined here.
187  *
188  * @return
189  *   An associative array of available tokens and token types. The outer array
190  *   has two components:
191  *   - types: An associative array of token types (groups). Each token type is
192  *     an associative array with the following components:
193  *     - name: The translated human-readable short name of the token type.
194  *     - description (optional): A translated longer description of the token
195  *       type.
196  *     - needs-data: The type of data that must be provided to
197  *       \Drupal\Core\Utility\Token::replace() in the $data argument (i.e., the
198  *       key name in $data) in order for tokens of this type to be used in the
199  *       $text being processed. For instance, if the token needs a node object,
200  *       'needs-data' should be 'node', and to use this token in
201  *       \Drupal\Core\Utility\Token::replace(), the caller needs to supply a
202  *       node object as $data['node']. Some token data can also be supplied
203  *       indirectly; for instance, a node object in $data supplies a user object
204  *       (the author of the node), allowing user tokens to be used when only
205  *       a node data object is supplied.
206  *   - tokens: An associative array of tokens. The outer array is keyed by the
207  *     group name (the same key as in the types array). Within each group of
208  *     tokens, each token item is keyed by the machine name of the token, and
209  *     each token item has the following components:
210  *     - name: The translated human-readable short name of the token.
211  *     - description (optional): A translated longer description of the token.
212  *     - type (optional): A 'needs-data' data type supplied by this token, which
213  *       should match a 'needs-data' value from another token type. For example,
214  *       the node author token provides a user object, which can then be used
215  *       for token replacement data in \Drupal\Core\Utility\Token::replace()
216  *       without having to supply a separate user object.
217  *
218  * @see hook_token_info_alter()
219  * @see hook_tokens()
220  */
221 function hook_token_info() {
222   $type = [
223     'name' => t('Nodes'),
224     'description' => t('Tokens related to individual nodes.'),
225     'needs-data' => 'node',
226   ];
227
228   // Core tokens for nodes.
229   $node['nid'] = [
230     'name' => t("Node ID"),
231     'description' => t("The unique ID of the node."),
232   ];
233   $node['title'] = [
234     'name' => t("Title"),
235   ];
236   $node['edit-url'] = [
237     'name' => t("Edit URL"),
238     'description' => t("The URL of the node's edit page."),
239   ];
240
241   // Chained tokens for nodes.
242   $node['created'] = [
243     'name' => t("Date created"),
244     'type' => 'date',
245   ];
246   $node['author'] = [
247     'name' => t("Author"),
248     'type' => 'user',
249   ];
250
251   return [
252     'types' => ['node' => $type],
253     'tokens' => ['node' => $node],
254   ];
255 }
256
257 /**
258  * Alter the metadata about available placeholder tokens and token types.
259  *
260  * @param $data
261  *   The associative array of token definitions from hook_token_info().
262  *
263  * @see hook_token_info()
264  */
265 function hook_token_info_alter(&$data) {
266   // Modify description of node tokens for our site.
267   $data['tokens']['node']['nid'] = [
268     'name' => t("Node ID"),
269     'description' => t("The unique ID of the article."),
270   ];
271   $data['tokens']['node']['title'] = [
272     'name' => t("Title"),
273     'description' => t("The title of the article."),
274   ];
275
276   // Chained tokens for nodes.
277   $data['tokens']['node']['created'] = [
278     'name' => t("Date created"),
279     'description' => t("The date the article was posted."),
280     'type' => 'date',
281   ];
282 }
283
284 /**
285  * @} End of "addtogroup hooks".
286  */