annotate core/lib/Drupal/Core/Utility/token.api.php @ 19:fa3358dc1485 tip

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