diff --git a/core/core.services.yml b/core/core.services.yml index 9fb9ebd25e268730359b68f9cd79f2090bb1722d..2e186aea1380ddf178987a3e306bfd2fca880b94 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -390,3 +390,6 @@ services: class: Drupal\system\Plugin\ImageToolkitInterface factory_method: getDefaultToolkit factory_service: image.toolkit.manager + token: + class: Drupal\Core\Utility\Token + arguments: ['@module_handler'] diff --git a/core/includes/common.inc b/core/includes/common.inc index d4d9961510f35f8058b68046f5a10823d740ed32..4087a42083f79a972bcc84667c0c261c34308761 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -4569,7 +4569,6 @@ function _drupal_bootstrap_code() { require_once DRUPAL_ROOT . '/core/includes/form.inc'; require_once DRUPAL_ROOT . '/core/includes/mail.inc'; require_once DRUPAL_ROOT . '/core/includes/ajax.inc'; - require_once DRUPAL_ROOT . '/core/includes/token.inc'; require_once DRUPAL_ROOT . '/core/includes/errors.inc'; require_once DRUPAL_ROOT . '/core/includes/schema.inc'; require_once DRUPAL_ROOT . '/core/includes/entity.inc'; diff --git a/core/includes/token.inc b/core/includes/token.inc deleted file mode 100644 index c1f1c6ca780641ecb0a9d533e961adcd33032f41..0000000000000000000000000000000000000000 --- a/core/includes/token.inc +++ /dev/null @@ -1,265 +0,0 @@ -<?php - -/** - * @file - * Drupal placeholder/token replacement system. - * - * API functions for replacing placeholders in text with meaningful values. - * - * For example: When configuring automated emails, an administrator enters - * standard text for the email. Variables like the title of a node and the date - * the email was sent can be entered as placeholders like [node:title] and - * [date:short]. When a Drupal module prepares to send the email, it can call - * the token_replace() function, passing in the text. The token system will - * scan the text for placeholder tokens, give other modules an opportunity to - * replace them with meaningful text, then return the final product to the - * original module. - * - * Tokens follow the form: [$type:$name], where $type is a general class of - * tokens like 'node', 'user', or 'comment' and $name is the name of a given - * placeholder. For example, [node:title] or [node:created:since]. - * - * In addition to raw text containing placeholders, modules may pass in an array - * of objects to be used when performing the replacement. The objects should be - * keyed by the token type they correspond to. For example: - * - * @code - * // Load a node and a user, then replace tokens in the text. - * $text = 'On [date:short], [user:name] read [node:title].'; - * $node = node_load(1); - * $user = user_load(1); - * - * // [date:...] tokens use the current date automatically. - * $data = array('node' => $node, 'user' => $user); - * return token_replace($text, $data); - * @endcode - * - * Some tokens may be chained in the form of [$type:$pointer:$name], where $type - * is a normal token type, $pointer is a reference to another token type, and - * $name is the name of a given placeholder. For example, [node:author:mail]. In - * that example, 'author' is a pointer to the 'user' account that created the - * node, and 'mail' is a placeholder available for any 'user'. - * - * @see token_replace() - * @see hook_tokens() - * @see hook_token_info() - */ - -/** - * Replaces all tokens in a given string with appropriate values. - * - * @param string $text - * A string potentially containing replaceable tokens. - * @param array $data - * (optional) An array of keyed objects. For simple replacement scenarios - * 'node', 'user', and others are common keys, with an accompanying node or - * user object being the value. Some token types, like 'site', do not require - * any explicit information from $data and can be replaced even if it is - * empty. - * @param array $options - * (optional) A keyed array of settings and flags to control the token - * replacement process. Supported options are: - * - langcode: A language code to be used when generating locale-sensitive - * tokens. - * - callback: A callback function that will be used to post-process the - * array of token replacements after they are generated. For example, a - * module using tokens in a text-only email might provide a callback to - * strip HTML entities from token values before they are inserted into the - * final text. - * - clear: A boolean flag indicating that tokens should be removed from the - * final text if no replacement value can be generated. - * - sanitize: A boolean flag indicating that tokens should be sanitized for - * display to a web browser. Defaults to TRUE. Developers who set this - * option to FALSE assume responsibility for running filter_xss(), - * check_plain() or other appropriate scrubbing functions before displaying - * data to users. - * - * @return string - * Text with tokens replaced. - */ -function token_replace($text, array $data = array(), array $options = array()) { - $text_tokens = token_scan($text); - if (empty($text_tokens)) { - return $text; - } - - $replacements = array(); - foreach ($text_tokens as $type => $tokens) { - $replacements += token_generate($type, $tokens, $data, $options); - if (!empty($options['clear'])) { - $replacements += array_fill_keys($tokens, ''); - } - } - - // Optionally alter the list of replacement values. - if (!empty($options['callback'])) { - $function = $options['callback']; - $function($replacements, $data, $options); - } - - $tokens = array_keys($replacements); - $values = array_values($replacements); - - return str_replace($tokens, $values, $text); -} - -/** - * Builds a list of all token-like patterns that appear in the text. - * - * @param string $text - * The text to be scanned for possible tokens. - * - * @return array - * An associative array of discovered tokens, grouped by type. - */ -function token_scan($text) { - // Matches tokens with the following pattern: [$type:$name] - // $type and $name may not contain [ ] characters. - // $type may not contain : or whitespace characters, but $name may. - preg_match_all('/ - \[ # [ - pattern start - ([^\s\[\]:]*) # match $type not containing whitespace : [ or ] - : # : - separator - ([^\[\]]*) # match $name not containing [ or ] - \] # ] - pattern end - /x', $text, $matches); - - $types = $matches[1]; - $tokens = $matches[2]; - - // Iterate through the matches, building an associative array containing - // $tokens grouped by $types, pointing to the version of the token found in - // the source text. For example, $results['node']['title'] = '[node:title]'; - $results = array(); - for ($i = 0; $i < count($tokens); $i++) { - $results[$types[$i]][$tokens[$i]] = $matches[0][$i]; - } - - return $results; -} - -/** - * Generates replacement values for a list of tokens. - * - * @param string $type - * The type of token being replaced. 'node', 'user', and 'date' are common. - * @param array $tokens - * An array of tokens to be replaced, keyed by the literal text of the token - * as it appeared in the source text. - * @param array $data - * (optional) An array of keyed objects. For simple replacement scenarios - * 'node', 'user', and others are common keys, with an accompanying node or - * user object being the value. Some token types, like 'site', do not require - * any explicit information from $data and can be replaced even if it is - * empty. - * @param array $options - * (optional) A keyed array of settings and flags to control the token - * replacement process. Supported options are: - * - langcode: A language code to be used when generating locale-sensitive - * tokens. - * - callback: A callback function that will be used to post-process the - * array of token replacements after they are generated. Can be used when - * modules require special formatting of token text, for example URL - * encoding or truncation to a specific length. - * - sanitize: A boolean flag indicating that tokens should be sanitized for - * display to a web browser. Developers who set this option to FALSE assume - * responsibility for running filter_xss(), check_plain() or other - * appropriate scrubbing functions before displaying data to users. - * - * @return array - * An associative array of replacement values, keyed by the original 'raw' - * tokens that were found in the source text. For example: - * $results['[node:title]'] = 'My new node'; - * - * @see hook_tokens() - * @see hook_tokens_alter() - */ -function token_generate($type, array $tokens, array $data = array(), array $options = array()) { - $options += array('sanitize' => TRUE); - $replacements = module_invoke_all('tokens', $type, $tokens, $data, $options); - - // Allow other modules to alter the replacements. - $context = array( - 'type' => $type, - 'tokens' => $tokens, - 'data' => $data, - 'options' => $options, - ); - drupal_alter('tokens', $replacements, $context); - - return $replacements; -} - -/** - * Returns a list of tokens that begin with a specific prefix. - * - * Used to extract a group of 'chained' tokens (such as [node:author:name]) - * from the full list of tokens found in text. For example: - * @code - * $data = array( - * 'author:name' => '[node:author:name]', - * 'title' => '[node:title]', - * 'created' => '[node:created]', - * ); - * $results = token_find_with_prefix($data, 'author'); - * $results == array('name' => '[node:author:name]'); - * @endcode - * - * @param array $tokens - * A keyed array of tokens, and their original raw form in the source text. - * @param string $prefix - * A textual string to be matched at the beginning of the token. - * @param string $delimiter - * (optional) A string containing the character that separates the prefix from - * the rest of the token. Defaults to ':'. - * - * @return array - * An associative array of discovered tokens, with the prefix and delimiter - * stripped from the key. - */ -function token_find_with_prefix(array $tokens, $prefix, $delimiter = ':') { - $results = array(); - foreach ($tokens as $token => $raw) { - $parts = explode($delimiter, $token, 2); - if (count($parts) == 2 && $parts[0] == $prefix) { - $results[$parts[1]] = $raw; - } - } - return $results; -} - -/** - * Returns metadata describing supported tokens. - * - * The metadata array contains token type, name, and description data as well - * as an optional pointer indicating that the token chains to another set of - * tokens. - * - * For example: - * @code - * $data['types']['node'] = array( - * 'name' => t('Nodes'), - * 'description' => t('Tokens related to node objects.'), - * ); - * $data['tokens']['node']['title'] = array( - * 'name' => t('Title'), - * 'description' => t('The title of the current node.'), - * ); - * $data['tokens']['node']['author'] = array( - * 'name' => t('Author'), - * 'description' => t('The author of the current node.'), - * 'type' => 'user', - * ); - * @endcode - * - * @return array - * An associative array of token information, grouped by token type. - */ -function token_info() { - $data = &drupal_static(__FUNCTION__); - if (!isset($data)) { - $data = module_invoke_all('token_info'); - drupal_alter('token_info', $data); - } - return $data; -} diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php index c9ab39ddb763ec28ad0d89bc10d27d3b3811b096..9be666927de6c2681c29695ff10446b0e0b71941 100644 --- a/core/lib/Drupal.php +++ b/core/lib/Drupal.php @@ -341,4 +341,14 @@ public static function typedData() { return static::$container->get('typed_data'); } + /** + * Returns the token service. + * + * @return \Drupal\Core\Utility\Token + * The token service. + */ + public static function token() { + return static::$container->get('token'); + } + } diff --git a/core/lib/Drupal/Core/Utility/Token.php b/core/lib/Drupal/Core/Utility/Token.php new file mode 100644 index 0000000000000000000000000000000000000000..29fef78a91cbb902514be3ae3d9b3665ed1566ac --- /dev/null +++ b/core/lib/Drupal/Core/Utility/Token.php @@ -0,0 +1,309 @@ +<?php + +/** + * @file + * Definition of Drupal\Core\Utility\Token. + */ + +namespace Drupal\Core\Utility; + +use Drupal\Core\Extension\ModuleHandlerInterface; + +/** + * Drupal placeholder/token replacement system. + * + * API functions for replacing placeholders in text with meaningful values. + * + * For example: When configuring automated emails, an administrator enters + * standard text for the email. Variables like the title of a node and the date + * the email was sent can be entered as placeholders like [node:title] and + * [date:short]. When a Drupal module prepares to send the email, it can call + * the Token::replace() function, passing in the text. The token system will + * scan the text for placeholder tokens, give other modules an opportunity to + * replace them with meaningful text, then return the final product to the + * original module. + * + * Tokens follow the form: [$type:$name], where $type is a general class of + * tokens like 'node', 'user', or 'comment' and $name is the name of a given + * placeholder. For example, [node:title] or [node:created:since]. + * + * In addition to raw text containing placeholders, modules may pass in an array + * of objects to be used when performing the replacement. The objects should be + * keyed by the token type they correspond to. For example: + * + * @code + * // Load a node and a user, then replace tokens in the text. + * $text = 'On [date:short], [user:name] read [node:title].'; + * $node = node_load(1); + * $user = user_load(1); + * + * // [date:...] tokens use the current date automatically. + * $data = array('node' => $node, 'user' => $user); + * return Token::replace($text, $data); + * @endcode + * + * Some tokens may be chained in the form of [$type:$pointer:$name], where $type + * is a normal token type, $pointer is a reference to another token type, and + * $name is the name of a given placeholder. For example, [node:author:mail]. In + * that example, 'author' is a pointer to the 'user' account that created the + * node, and 'mail' is a placeholder available for any 'user'. + * + * @see Token::replace() + * @see hook_tokens() + * @see hook_token_info() + */ +class Token { + + /** + * Token definitions. + * + * @var array|null + * An array of token definitions, or NULL when the definitions are not set. + * + * @see self::setInfo() + * @see self::getInfo() + * @see self::resetInfo() + */ + protected $tokenInfo; + + /** + * The module handler service. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * Constructor. + * + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + */ + public function __construct(ModuleHandlerInterface $module_handler) { + $this->moduleHandler = $module_handler; + } + + /** + * Replaces all tokens in a given string with appropriate values. + * + * @param string $text + * A string potentially containing replaceable tokens. + * @param array $data + * (optional) An array of keyed objects. For simple replacement scenarios + * 'node', 'user', and others are common keys, with an accompanying node or + * user object being the value. Some token types, like 'site', do not require + * any explicit information from $data and can be replaced even if it is + * empty. + * @param array $options + * (optional) A keyed array of settings and flags to control the token + * replacement process. Supported options are: + * - langcode: A language code to be used when generating locale-sensitive + * tokens. + * - callback: A callback function that will be used to post-process the + * array of token replacements after they are generated. For example, a + * module using tokens in a text-only email might provide a callback to + * strip HTML entities from token values before they are inserted into the + * final text. + * - clear: A boolean flag indicating that tokens should be removed from the + * final text if no replacement value can be generated. + * - sanitize: A boolean flag indicating that tokens should be sanitized for + * display to a web browser. Defaults to TRUE. Developers who set this + * option to FALSE assume responsibility for running filter_xss(), + * check_plain() or other appropriate scrubbing functions before displaying + * data to users. + * + * @return string + * Text with tokens replaced. + */ + public function replace($text, array $data = array(), array $options = array()) { + $text_tokens = $this->scan($text); + if (empty($text_tokens)) { + return $text; + } + + $replacements = array(); + foreach ($text_tokens as $type => $tokens) { + $replacements += $this->generate($type, $tokens, $data, $options); + if (!empty($options['clear'])) { + $replacements += array_fill_keys($tokens, ''); + } + } + + // Optionally alter the list of replacement values. + if (!empty($options['callback'])) { + $function = $options['callback']; + $function($replacements, $data, $options); + } + + $tokens = array_keys($replacements); + $values = array_values($replacements); + + return str_replace($tokens, $values, $text); + } + + /** + * Builds a list of all token-like patterns that appear in the text. + * + * @param string $text + * The text to be scanned for possible tokens. + * + * @return array + * An associative array of discovered tokens, grouped by type. + */ + public function scan($text) { + // Matches tokens with the following pattern: [$type:$name] + // $type and $name may not contain [ ] characters. + // $type may not contain : or whitespace characters, but $name may. + preg_match_all('/ + \[ # [ - pattern start + ([^\s\[\]:]*) # match $type not containing whitespace : [ or ] + : # : - separator + ([^\[\]]*) # match $name not containing [ or ] + \] # ] - pattern end + /x', $text, $matches); + + $types = $matches[1]; + $tokens = $matches[2]; + + // Iterate through the matches, building an associative array containing + // $tokens grouped by $types, pointing to the version of the token found in + // the source text. For example, $results['node']['title'] = '[node:title]'; + $results = array(); + for ($i = 0; $i < count($tokens); $i++) { + $results[$types[$i]][$tokens[$i]] = $matches[0][$i]; + } + + return $results; + } + + /** + * Generates replacement values for a list of tokens. + * + * @param string $type + * The type of token being replaced. 'node', 'user', and 'date' are common. + * @param array $tokens + * An array of tokens to be replaced, keyed by the literal text of the token + * as it appeared in the source text. + * @param array $data + * (optional) An array of keyed objects. For simple replacement scenarios + * 'node', 'user', and others are common keys, with an accompanying node or + * user object being the value. Some token types, like 'site', do not require + * any explicit information from $data and can be replaced even if it is + * empty. + * @param array $options + * (optional) A keyed array of settings and flags to control the token + * replacement process. Supported options are: + * - langcode: A language code to be used when generating locale-sensitive + * tokens. + * - callback: A callback function that will be used to post-process the + * array of token replacements after they are generated. Can be used when + * modules require special formatting of token text, for example URL + * encoding or truncation to a specific length. + * - sanitize: A boolean flag indicating that tokens should be sanitized for + * display to a web browser. Developers who set this option to FALSE assume + * responsibility for running filter_xss(), check_plain() or other + * appropriate scrubbing functions before displaying data to users. + * + * @return array + * An associative array of replacement values, keyed by the original 'raw' + * tokens that were found in the source text. For example: + * $results['[node:title]'] = 'My new node'; + * + * @see hook_tokens() + * @see hook_tokens_alter() + */ + public function generate($type, array $tokens, array $data = array(), array $options = array()) { + $options += array('sanitize' => TRUE); + $replacements = $this->moduleHandler->invokeAll('tokens', array($type, $tokens, $data, $options)); + + // Allow other modules to alter the replacements. + $context = array( + 'type' => $type, + 'tokens' => $tokens, + 'data' => $data, + 'options' => $options, + ); + $this->moduleHandler->alter('tokens', $replacements, $context); + + return $replacements; + } + + /** + * Returns a list of tokens that begin with a specific prefix. + * + * Used to extract a group of 'chained' tokens (such as [node:author:name]) + * from the full list of tokens found in text. For example: + * @code + * $data = array( + * 'author:name' => '[node:author:name]', + * 'title' => '[node:title]', + * 'created' => '[node:created]', + * ); + * $results = Token::findWithPrefix($data, 'author'); + * $results == array('name' => '[node:author:name]'); + * @endcode + * + * @param array $tokens + * A keyed array of tokens, and their original raw form in the source text. + * @param string $prefix + * A textual string to be matched at the beginning of the token. + * @param string $delimiter + * (optional) A string containing the character that separates the prefix from + * the rest of the token. Defaults to ':'. + * + * @return array + * An associative array of discovered tokens, with the prefix and delimiter + * stripped from the key. + */ + public function findWithPrefix(array $tokens, $prefix, $delimiter = ':') { + $results = array(); + foreach ($tokens as $token => $raw) { + $parts = explode($delimiter, $token, 2); + if (count($parts) == 2 && $parts[0] == $prefix) { + $results[$parts[1]] = $raw; + } + } + return $results; + } + + /** + * Returns metadata describing supported tokens. + * + * The metadata array contains token type, name, and description data as well + * as an optional pointer indicating that the token chains to another set of + * tokens. + * + * @return array + * An associative array of token information, grouped by token type. The + * array structure is identical to that of hook_token_info(). + * + * @see hook_token_info() + */ + public function getInfo() { + if (is_null($this->tokenInfo)) { + $this->tokenInfo = $this->moduleHandler->invokeAll('token_info'); + $this->moduleHandler->alter('token_info', $this->tokenInfo); + } + + return $this->tokenInfo; + } + + /** + * Sets metadata describing supported tokens. + * + * @param array $tokens + * Token metadata that has an identical structure to the return value of + * hook_token_info(). + * + * @see hook_token_info() + */ + public function setInfo(array $tokens) { + $this->tokenInfo = $tokens; + } + + /** + * Resets metadata describing supported tokens. + */ + public function resetInfo() { + $this->tokenInfo = NULL; + } +} diff --git a/core/modules/action/action.module b/core/modules/action/action.module index a4e259f2115888bff4bdfca6dd71485468dfa7cd..7ff568b0bb3d05d47205cec747a5cfe624af7719 100644 --- a/core/modules/action/action.module +++ b/core/modules/action/action.module @@ -564,11 +564,11 @@ function action_send_email_action_submit($form, $form_state) { * @param array $context * Array with the following elements: * - 'recipient': E-mail message recipient. This will be passed through - * token_replace(). + * \Drupal\Core\Utility\Token::replace(). * - 'subject': The subject of the message. This will be passed through - * token_replace(). + * \Drupal\Core\Utility\Token::replace(). * - 'message': The message to send. This will be passed through - * token_replace(). + * \Drupal\Core\Utility\Token::replace(). * - Other elements will be used as the data for token replacement. * * @ingroup actions @@ -578,7 +578,7 @@ function action_send_email_action($entity, $context) { $context['node'] = $entity; } - $recipient = token_replace($context['recipient'], $context); + $recipient = Drupal::token()->replace($context['recipient'], $context); // If the recipient is a registered user with a language preference, use // the recipient's preferred language. Otherwise, use the system default @@ -633,7 +633,7 @@ function action_message_action_submit($form, $form_state) { * @param array $context * Array with the following elements: * - 'message': The message to send. This will be passed through - * token_replace(). + * \Drupal\Core\Utility\Token::replace(). * - Other elements will be used as the data for token replacement in * the message. * @@ -644,7 +644,7 @@ function action_message_action(&$entity, $context = array()) { $context['node'] = $entity; } - $context['message'] = token_replace(filter_xss_admin($context['message']), $context); + $context['message'] = Drupal::token()->replace(filter_xss_admin($context['message']), $context); drupal_set_message($context['message']); } @@ -685,11 +685,11 @@ function action_goto_action_submit($form, $form_state) { * @param array $context * Array with the following elements: * - 'url': URL to redirect to. This will be passed through - * token_replace(). + * \Drupal\Core\Utility\Token::replace(). * - Other elements will be used as the data for token replacement. * * @ingroup actions. */ function action_goto_action($entity, $context) { - drupal_goto(token_replace($context['url'], $context)); + drupal_goto(Drupal::token()->replace($context['url'], $context)); } diff --git a/core/modules/comment/comment.tokens.inc b/core/modules/comment/comment.tokens.inc index 715b63d104075d22123f8272639464bfd433efcd..d938c27b6e61e827474fd7c5e220d4d0402caf84 100644 --- a/core/modules/comment/comment.tokens.inc +++ b/core/modules/comment/comment.tokens.inc @@ -103,6 +103,8 @@ function comment_token_info() { * Implements hook_tokens(). */ function comment_tokens($type, $tokens, array $data = array(), array $options = array()) { + $token_service = Drupal::token(); + $url_options = array('absolute' => TRUE); if (isset($options['langcode'])) { $url_options['language'] = language_load($options['langcode']); @@ -198,25 +200,25 @@ function comment_tokens($type, $tokens, array $data = array(), array $options = } // Chained token relationships. - if ($node_tokens = token_find_with_prefix($tokens, 'node')) { + if ($node_tokens = $token_service->findwithPrefix($tokens, 'node')) { $node = $comment->nid->entity; - $replacements += token_generate('node', $node_tokens, array('node' => $node), $options); + $replacements += $token_service->generate('node', $node_tokens, array('node' => $node), $options); } - if ($date_tokens = token_find_with_prefix($tokens, 'created')) { - $replacements += token_generate('date', $date_tokens, array('date' => $comment->created->value), $options); + if ($date_tokens = $token_service->findwithPrefix($tokens, 'created')) { + $replacements += $token_service->generate('date', $date_tokens, array('date' => $comment->created->value), $options); } - if ($date_tokens = token_find_with_prefix($tokens, 'changed')) { - $replacements += token_generate('date', $date_tokens, array('date' => $comment->changed->value), $options); + if ($date_tokens = $token_service->findwithPrefix($tokens, 'changed')) { + $replacements += $token_service->generate('date', $date_tokens, array('date' => $comment->changed->value), $options); } - if (($parent_tokens = token_find_with_prefix($tokens, 'parent')) && $parent = $comment->pid->entity) { - $replacements += token_generate('comment', $parent_tokens, array('comment' => $parent), $options); + if (($parent_tokens = $token_service->findwithPrefix($tokens, 'parent')) && $parent = $comment->pid->entity) { + $replacements += $token_service->generate('comment', $parent_tokens, array('comment' => $parent), $options); } - if (($author_tokens = token_find_with_prefix($tokens, 'author')) && $account = $comment->uid->entity) { - $replacements += token_generate('user', $author_tokens, array('user' => $account), $options); + if (($author_tokens = $token_service->findwithPrefix($tokens, 'author')) && $account = $comment->uid->entity) { + $replacements += $token_service->generate('user', $author_tokens, array('user' => $account), $options); } } elseif ($type == 'node' & !empty($data['node'])) { diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php index 6bcc9923206300f4e7b1438b612897d3ece1760a..92be58f3a921ae9247a0b24734beee45a9ece3ff 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php @@ -23,6 +23,7 @@ public static function getInfo() { * Creates a comment, then tests the tokens generated from it. */ function testCommentTokenReplacement() { + $token_service = \Drupal::token(); $language_interface = language(LANGUAGE_TYPE_INTERFACE); $url_options = array( 'absolute' => TRUE, @@ -72,7 +73,7 @@ function testCommentTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('comment' => $comment), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('comment' => $comment), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Sanitized comment token %token replaced.', array('%token' => $input))); } @@ -88,7 +89,7 @@ function testCommentTokenReplacement() { $tests['[comment:author:name]'] = $this->admin_user->name; foreach ($tests as $input => $expected) { - $output = token_replace($input, array('comment' => $comment), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); + $output = $token_service->replace($input, array('comment' => $comment), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized comment token %token replaced.', array('%token' => $input))); } @@ -101,7 +102,7 @@ function testCommentTokenReplacement() { $tests['[node:comment-count-new]'] = 2; foreach ($tests as $input => $expected) { - $output = token_replace($input, array('node' => $node), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('node' => $node), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Node comment token %token replaced.', array('%token' => $input))); } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php index ac6582eb38dd26437a9384b3d649e17bb31421f4..64c83a2d303691bdbba86ee04a5ffd34cf66c076 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php @@ -105,7 +105,7 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f $delta = isset($get_delta) ? $get_delta : 0; $element = array( '#title' => check_plain($instance['label']), - '#description' => field_filter_xss(token_replace($instance['description'])), + '#description' => field_filter_xss(\Drupal::token()->replace($instance['description'])), ); $element = $this->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state); @@ -196,7 +196,7 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper'); $title = check_plain($instance['label']); - $description = field_filter_xss(token_replace($instance['description'])); + $description = field_filter_xss(\Drupal::token()->replace($instance['description'])); $elements = array(); diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index e3a7d7ce38469b0b1619f3d22eccf39088618c5e..f3f2c0a5db6d1edf60b4e8db314448ce9ef4307e 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -352,18 +352,19 @@ function file_field_widget_upload_validators($field, $instance) { * @param $instance * A field instance array. * @param $data - * An array of token objects to pass to token_replace(). + * An array of token objects to pass to + * \Drupal\Core\Utility\Token::replace(). * * @return * A file directory URI with tokens replaced. * - * @see token_replace() + * @see \Drupal\Core\Utility\Token::replace() */ function file_field_widget_uri($field, $instance, $data = array()) { $destination = trim($instance['settings']['file_directory'], '/'); // Replace tokens. - $destination = token_replace($destination, $data); + $destination = Drupal::token()->replace($destination, $data); return $field['settings']['uri_scheme'] . '://' . $destination; } diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php index d963b8918f0de1ee61ec0a08e841a5587cf976b4..c8612080c3208352197d08d663f5cc4c7638094e 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php @@ -60,7 +60,7 @@ function testUploadPath() { // Do token replacement using the same user which uploaded the file, not // the user running the test case. $data = array('user' => $this->admin_user); - $subdirectory = token_replace('[user:uid]/[user:name]', $data); + $subdirectory = \Drupal::token()->replace('[user:uid]/[user:name]', $data); $this->assertPathMatch('public://' . $subdirectory . '/' . $test_file->filename, $node_file->uri, t('The file %file was uploaded to the correct path with token replacements.', array('%file' => $node_file->uri))); } diff --git a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php index 4d56b7b0814bda30d369b50e09797cf56a9e6763..36b32b16445184c53524e23bbb3ae2fc8a4f4245 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php @@ -23,6 +23,7 @@ public static function getInfo() { * Creates a file, then tests the tokens generated from it. */ function testFileTokenReplacement() { + $token_service = \Drupal::token(); $language_interface = language(LANGUAGE_TYPE_INTERFACE); $url_options = array( 'absolute' => TRUE, @@ -65,7 +66,7 @@ function testFileTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), t('No empty tokens generated.')); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('file' => $file), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('file' => $file), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, t('Sanitized file token %token replaced.', array('%token' => $input))); } @@ -76,7 +77,7 @@ function testFileTokenReplacement() { $tests['[file:size]'] = format_size($file->filesize); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('file' => $file), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); + $output = $token_service->replace($input, array('file' => $file), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); $this->assertEqual($output, $expected, t('Unsanitized file token %token replaced.', array('%token' => $input))); } } diff --git a/core/modules/link/link.module b/core/modules/link/link.module index 064ad913358021f7bbcdb586e8f9a879b2dbd285..82824213e529ea0e445c6ac9456ea50abea539c1 100644 --- a/core/modules/link/link.module +++ b/core/modules/link/link.module @@ -362,7 +362,7 @@ function link_field_formatter_view(EntityInterface $entity, $field, $instance, $ if (empty($settings['url_only']) && !empty($item['title'])) { // Unsanitizied token replacement here because $options['html'] is FALSE // by default in theme_link(). - $link_title = token_replace($item['title'], array($entity->entityType() => $entity), array('sanitize' => FALSE, 'clear' => TRUE)); + $link_title = Drupal::token()->replace($item['title'], array($entity->entityType() => $entity), array('sanitize' => FALSE, 'clear' => TRUE)); } // Trim the link title to the desired length. diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php index d17de34eff62f15dd9842695bbd541029ee086b7..7a9e5f0762ac6f8e3e3be20c34ffc4952b8f9333 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php @@ -23,6 +23,7 @@ public static function getInfo() { * Creates a node, then tests the tokens generated from it. */ function testNodeTokenReplacement() { + $token_service = \Drupal::token(); $language_interface = language(LANGUAGE_TYPE_INTERFACE); $url_options = array( 'absolute' => TRUE, @@ -66,7 +67,7 @@ function testNodeTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('node' => $node), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('node' => $node), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Sanitized node token %token replaced.', array('%token' => $input))); } @@ -78,7 +79,7 @@ function testNodeTokenReplacement() { $tests['[node:author:name]'] = user_format_name($account); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('node' => $node), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); + $output = $token_service->replace($input, array('node' => $node), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized node token %token replaced.', array('%token' => $input))); } @@ -99,7 +100,7 @@ function testNodeTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('node' => $node), array('language' => $language_interface)); + $output = $token_service->replace($input, array('node' => $node), array('language' => $language_interface)); $this->assertEqual($output, $expected, format_string('Sanitized node token %token replaced for node without a summary.', array('%token' => $input))); } @@ -107,7 +108,7 @@ function testNodeTokenReplacement() { $tests['[node:summary]'] = $node->body[$node->langcode][0]['value']; foreach ($tests as $input => $expected) { - $output = token_replace($input, array('node' => $node), array('language' => $language_interface, 'sanitize' => FALSE)); + $output = $token_service->replace($input, array('node' => $node), array('language' => $language_interface, 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized node token %token replaced for node without a summary.', array('%token' => $input))); } } diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc index c882450217afc71b2fcee950cec63ae3d8735c1c..d1c921130f49320e66f2e8986c63e4b5847ea41e 100644 --- a/core/modules/node/node.tokens.inc +++ b/core/modules/node/node.tokens.inc @@ -90,6 +90,8 @@ function node_token_info() { * Implements hook_tokens(). */ function node_tokens($type, $tokens, array $data = array(), array $options = array()) { + $token_service = Drupal::token(); + $url_options = array('absolute' => TRUE); if (isset($options['langcode'])) { $url_options['language'] = language_load($options['langcode']); @@ -197,17 +199,17 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr } } - if ($author_tokens = token_find_with_prefix($tokens, 'author')) { + if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) { $author = user_load($node->uid); - $replacements += token_generate('user', $author_tokens, array('user' => $author), $options); + $replacements += $token_service->generate('user', $author_tokens, array('user' => $author), $options); } - if ($created_tokens = token_find_with_prefix($tokens, 'created')) { - $replacements += token_generate('date', $created_tokens, array('date' => $node->created), $options); + if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) { + $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->created), $options); } - if ($changed_tokens = token_find_with_prefix($tokens, 'changed')) { - $replacements += token_generate('date', $changed_tokens, array('date' => $node->changed), $options); + if ($changed_tokens = $token_service->findWithPrefix($tokens, 'changed')) { + $replacements += $token_service->generate('date', $changed_tokens, array('date' => $node->changed), $options); } } diff --git a/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsTokenReplaceTest.php b/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsTokenReplaceTest.php index fad28078df7d38b4961732795e1c7c7c669e8406..0a657468a18b9cdf7a982e12a75114c91c7e43be 100644 --- a/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsTokenReplaceTest.php +++ b/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsTokenReplaceTest.php @@ -54,7 +54,7 @@ function testStatisticsTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('node' => $node), array('langcode' => $language_interface->langcode)); + $output = \Drupal::token()->replace($input, array('node' => $node), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Statistics token %token replaced.', array('%token' => $input))); } } diff --git a/core/modules/statistics/statistics.tokens.inc b/core/modules/statistics/statistics.tokens.inc index c2c8fc3cbc506a778b07425b6f6b9d50ceb379d9..27f628e50c69ed44019f36d3156feb8be96bd43d 100644 --- a/core/modules/statistics/statistics.tokens.inc +++ b/core/modules/statistics/statistics.tokens.inc @@ -32,6 +32,8 @@ function statistics_token_info() { * Implements hook_tokens(). */ function statistics_tokens($type, $tokens, array $data = array(), array $options = array()) { + $token_service = Drupal::token(); + $url_options = array('absolute' => TRUE); $replacements = array(); @@ -53,9 +55,9 @@ function statistics_tokens($type, $tokens, array $data = array(), array $options } } - if ($created_tokens = token_find_with_prefix($tokens, 'last-view')) { + if ($created_tokens = $token_service->findWithPrefix($tokens, 'last-view')) { $statistics = statistics_get($node->nid); - $replacements += token_generate('date', $created_tokens, array('date' => $statistics['timestamp']), $options); + $replacements += $token_service->generate('date', $created_tokens, array('date' => $statistics['timestamp']), $options); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php b/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php index 3859041980114b863f3ff92521b7c082ea5daf3d..e869c7108605806934cb26e5950a2a8f12bdc520 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php @@ -25,6 +25,8 @@ public static function getInfo() { * Creates a user and a node, then tests the tokens generated from them. */ function testTokenReplacement() { + $token_service = \Drupal::token(); + // Create the initial objects. $account = $this->drupalCreateUser(); $node = $this->drupalCreateNode(array('uid' => $account->uid)); @@ -47,34 +49,35 @@ function testTokenReplacement() { $target .= format_date(REQUEST_TIME, 'short', '', NULL, $language_interface->langcode); // Test that the clear parameter cleans out non-existent tokens. - $result = token_replace($source, array('node' => $node), array('langcode' => $language_interface->langcode, 'clear' => TRUE)); + $result = $token_service->replace($source, array('node' => $node), array('langcode' => $language_interface->langcode, 'clear' => TRUE)); $result = $this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens cleared out.'); // Test without using the clear parameter (non-existent token untouched). $target .= '[user:name]'; $target .= '[bogus:token]'; - $result = token_replace($source, array('node' => $node), array('langcode' => $language_interface->langcode)); + $result = $token_service->replace($source, array('node' => $node), array('langcode' => $language_interface->langcode)); $this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens ignored.'); - // Check that the results of token_generate are sanitized properly. This does NOT - // test the cleanliness of every token -- just that the $sanitize flag is being - // passed properly through the call stack and being handled correctly by a 'known' - // token, [node:title]. + // Check that the results of Token::generate are sanitized properly. This + // does NOT test the cleanliness of every token -- just that the $sanitize + // flag is being passed properly through the call stack and being handled + // correctly by a 'known' token, [node:title]. $raw_tokens = array('title' => '[node:title]'); - $generated = token_generate('node', $raw_tokens, array('node' => $node)); + $generated = $token_service->generate('node', $raw_tokens, array('node' => $node)); $this->assertEqual($generated['[node:title]'], check_plain($node->title), 'Token sanitized.'); - $generated = token_generate('node', $raw_tokens, array('node' => $node), array('sanitize' => FALSE)); + $generated = $token_service->generate('node', $raw_tokens, array('node' => $node), array('sanitize' => FALSE)); $this->assertEqual($generated['[node:title]'], $node->title, 'Unsanitized token generated properly.'); // Test token replacement when the string contains no tokens. - $this->assertEqual(token_replace('No tokens here.'), 'No tokens here.'); + $this->assertEqual($token_service->replace('No tokens here.'), 'No tokens here.'); } /** * Test whether token-replacement works in various contexts. */ function testSystemTokenRecognition() { + $token_service = \Drupal::token(); $language_interface = language(LANGUAGE_TYPE_INTERFACE); // Generate prefixes and suffixes for the token context. @@ -95,7 +98,7 @@ function testSystemTokenRecognition() { foreach ($tests as $test) { $input = $test['prefix'] . '[site:name]' . $test['suffix']; $expected = $test['prefix'] . 'Drupal' . $test['suffix']; - $output = token_replace($input, array(), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array(), array('langcode' => $language_interface->langcode)); $this->assertTrue($output == $expected, format_string('Token recognized in string %string', array('%string' => $input))); } } @@ -104,6 +107,7 @@ function testSystemTokenRecognition() { * Tests the generation of all system site information tokens. */ function testSystemSiteTokenReplacement() { + $token_service = \Drupal::token(); $language_interface = language(LANGUAGE_TYPE_INTERFACE); $url_options = array( 'absolute' => TRUE, @@ -129,7 +133,7 @@ function testSystemSiteTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array(), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array(), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Sanitized system site information token %token replaced.', array('%token' => $input))); } @@ -138,7 +142,7 @@ function testSystemSiteTokenReplacement() { $tests['[site:slogan]'] = config('system.site')->get('slogan'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array(), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); + $output = $token_service->replace($input, array(), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized system site information token %token replaced.', array('%token' => $input))); } } @@ -147,6 +151,7 @@ function testSystemSiteTokenReplacement() { * Tests the generation of all system date tokens. */ function testSystemDateTokenReplacement() { + $token_service = \Drupal::token(); $language_interface = language(LANGUAGE_TYPE_INTERFACE); // Set time to one hour before request. @@ -165,7 +170,7 @@ function testSystemDateTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('date' => $date), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('date' => $date), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Date token %token replaced.', array('%token' => $input))); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/System/TokenScanTest.php b/core/modules/system/lib/Drupal/system/Tests/System/TokenScanTest.php index fffe6ae73af552fd68a9095f7683be1500669a9f..ce29a08623773573bbb1c149e4a3800e7c73918d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/TokenScanTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/TokenScanTest.php @@ -31,7 +31,7 @@ function testTokenScan() { $text = 'First a [valid:simple], but dummy token, and a dummy [valid:token with: spaces].'; $text .= 'Then a [not valid:token].'; $text .= 'Last an existing token: [node:author:name].'; - $token_wannabes = token_scan($text); + $token_wannabes = \Drupal::token()->scan($text); $this->assertTrue(isset($token_wannabes['valid']['simple']), 'A simple valid token has been matched.'); $this->assertTrue(isset($token_wannabes['valid']['token with: spaces']), 'A valid token with space characters in the token name has been matched.'); diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index 13aa535ad89c47141323f6c84857568ce24cca3b..73ec88e7f64084e1daf775ca9fc225658e9351da 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -3166,11 +3166,12 @@ function hook_url_outbound_alter(&$path, &$options, $original_path) { /** * Provide replacement values for placeholder tokens. * - * This hook is invoked when someone calls token_replace(). That function first - * scans the text for [type:token] patterns, and splits the needed tokens into - * groups by type. Then hook_tokens() is invoked on each token-type group, - * allowing your module to respond by providing replacement text for any of - * the tokens in the group that your module knows how to process. + * This hook is invoked when someone calls + * \Drupal\Core\Utility\Token::replace(). That function first scans the text for + * [type:token] patterns, and splits the needed tokens into groups by type. + * Then hook_tokens() is invoked on each token-type group, allowing your module + * to respond by providing replacement text for any of the tokens in the group + * that your module knows how to process. * * A module implementing this hook should also implement hook_token_info() in * order to list its available tokens on editing screens. @@ -3185,10 +3186,11 @@ function hook_url_outbound_alter(&$path, &$options, $original_path) { * original text. * @param $data * (optional) An associative array of data objects to be used when generating - * replacement values, as supplied in the $data parameter to token_replace(). + * replacement values, as supplied in the $data parameter to + * \Drupal\Core\Utility\Token::replace(). * @param $options * (optional) An associative array of options for token replacement; see - * token_replace() for possible values. + * \Drupal\Core\Utility\Token::replace() for possible values. * * @return * An associative array of replacement values, keyed by the raw [type:token] @@ -3198,6 +3200,8 @@ function hook_url_outbound_alter(&$path, &$options, $original_path) { * @see hook_tokens_alter() */ function hook_tokens($type, $tokens, array $data = array(), array $options = array()) { + $token_service = Drupal::token(); + $url_options = array('absolute' => TRUE); if (isset($options['langcode'])) { $url_options['language'] = language_load($options['langcode']); @@ -3240,13 +3244,13 @@ function hook_tokens($type, $tokens, array $data = array(), array $options = arr } } - if ($author_tokens = token_find_with_prefix($tokens, 'author')) { + if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) { $author = user_load($node->uid); - $replacements += token_generate('user', $author_tokens, array('user' => $author), $options); + $replacements += $token_service->generate('user', $author_tokens, array('user' => $author), $options); } - if ($created_tokens = token_find_with_prefix($tokens, 'created')) { - $replacements += token_generate('date', $created_tokens, array('date' => $node->created), $options); + if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) { + $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->created), $options); } } @@ -3302,9 +3306,10 @@ function hook_tokens_alter(array &$replacements, array $context) { * provides a list of types and tokens to be displayed on text editing screens, * so that people editing text can see what their token options are. * - * The actual token replacement is done by token_replace(), which invokes - * hook_tokens(). Your module will need to implement that hook in order to - * generate token replacements from the tokens defined here. + * The actual token replacement is done by + * \Drupal\Core\Utility\Token::replace(), which invokes hook_tokens(). Your + * module will need to implement that hook in order to generate token + * replacements from the tokens defined here. * * @return * An associative array of available tokens and token types. The outer array @@ -3313,12 +3318,13 @@ function hook_tokens_alter(array &$replacements, array $context) { * an associative array with the following components: * - name: The translated human-readable short name of the token type. * - description: A translated longer description of the token type. - * - needs-data: The type of data that must be provided to token_replace() - * in the $data argument (i.e., the key name in $data) in order for tokens - * of this type to be used in the $text being processed. For instance, if - * the token needs a node object, 'needs-data' should be 'node', and to - * use this token in token_replace(), the caller needs to supply a node - * object as $data['node']. Some token data can also be supplied + * - needs-data: The type of data that must be provided to + * \Drupal\Core\Utility\Token::replace() in the $data argument (i.e., the + * key name in $data) in order for tokens of this type to be used in the + * $text being processed. For instance, if the token needs a node object, + * 'needs-data' should be 'node', and to use this token in + * \Drupal\Core\Utility\Token::replace(), the caller needs to supply a + * node object as $data['node']. Some token data can also be supplied * indirectly; for instance, a node object in $data supplies a user object * (the author of the node), allowing user tokens to be used when only * a node data object is supplied. @@ -3331,8 +3337,8 @@ function hook_tokens_alter(array &$replacements, array $context) { * - type (optional): A 'needs-data' data type supplied by this token, which * should match a 'needs-data' value from another token type. For example, * the node author token provides a user object, which can then be used - * for token replacement data in token_replace() without having to supply - * a separate user object. + * for token replacement data in \Drupal\Core\Utility\Token::replace() + * without having to supply a separate user object. * * @see hook_token_info_alter() * @see hook_tokens() diff --git a/core/modules/system/system.module b/core/modules/system/system.module index ebe55483f238ec71bd4466098c48b7f92439f1f7..3b1205a0561431ea963c8bb445ab00cf84bdc13f 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -3591,10 +3591,12 @@ function system_cron() { * Implements hook_mail(). */ function system_mail($key, &$message, $params) { + $token_service = Drupal::token(); + $context = $params['context']; - $subject = token_replace($context['subject'], $context); - $body = token_replace($context['message'], $context); + $subject = $token_service->replace($context['subject'], $context); + $body = $token_service->replace($context['message'], $context); $message['subject'] .= str_replace(array("\r", "\n"), '', $subject); $message['body'][] = $body; diff --git a/core/modules/system/system.tokens.inc b/core/modules/system/system.tokens.inc index a5e7ad2d77ac90cd1ac2fc30cfa606843947eb52..241ed54d3ba819b38167e58978c7e5bdd0b78565 100644 --- a/core/modules/system/system.tokens.inc +++ b/core/modules/system/system.tokens.inc @@ -129,6 +129,8 @@ function system_token_info() { * Implements hook_tokens(). */ function system_tokens($type, $tokens, array $data = array(), array $options = array()) { + $token_service = Drupal::token(); + $url_options = array('absolute' => TRUE); if (isset($options['langcode'])) { $url_options['language'] = language_load($options['langcode']); @@ -205,7 +207,7 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a } } - if ($created_tokens = token_find_with_prefix($tokens, 'custom')) { + if ($created_tokens = $token_service->findWithPrefix($tokens, 'custom')) { foreach ($created_tokens as $name => $original) { $replacements[$original] = format_date($date, 'custom', $name, NULL, $langcode); } @@ -256,12 +258,12 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a } } - if ($date_tokens = token_find_with_prefix($tokens, 'timestamp')) { - $replacements += token_generate('date', $date_tokens, array('date' => $file->timestamp), $options); + if ($date_tokens = $token_service->findWithPrefix($tokens, 'timestamp')) { + $replacements += $token_service->generate('date', $date_tokens, array('date' => $file->timestamp), $options); } - if (($owner_tokens = token_find_with_prefix($tokens, 'owner')) && $account = user_load($file->uid)) { - $replacements += token_generate('user', $owner_tokens, array('user' => $account), $options); + if (($owner_tokens = $token_service->findWithPrefix($tokens, 'owner')) && $account = user_load($file->uid)) { + $replacements += $token_service->generate('user', $owner_tokens, array('user' => $account), $options); } } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php index ea731520132b6952beaae7093fe3505f9850337d..a792aad913d27986d049dd3f5b7c6adf7c15d3d4 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php @@ -62,6 +62,7 @@ function setUp() { * Creates some terms and a node, then tests the tokens generated from them. */ function testTaxonomyTokenReplacement() { + $token_service = \Drupal::token(); $language_interface = language(LANGUAGE_TYPE_INTERFACE); // Create two taxonomy terms. @@ -91,7 +92,7 @@ function testTaxonomyTokenReplacement() { $tests['[term:vocabulary:name]'] = check_plain($this->vocabulary->name); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('term' => $term1), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('term' => $term1), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input))); } @@ -111,7 +112,7 @@ function testTaxonomyTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('term' => $term2), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('term' => $term2), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input))); } @@ -122,7 +123,7 @@ function testTaxonomyTokenReplacement() { $tests['[term:vocabulary:name]'] = $this->vocabulary->name; foreach ($tests as $input => $expected) { - $output = token_replace($input, array('term' => $term2), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); + $output = $token_service->replace($input, array('term' => $term2), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized taxonomy term token %token replaced.', array('%token' => $input))); } @@ -138,7 +139,7 @@ function testTaxonomyTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Sanitized taxonomy vocabulary token %token replaced.', array('%token' => $input))); } @@ -147,7 +148,7 @@ function testTaxonomyTokenReplacement() { $tests['[vocabulary:description]'] = $this->vocabulary->description; foreach ($tests as $input => $expected) { - $output = token_replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); + $output = $token_service->replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized taxonomy vocabulary token %token replaced.', array('%token' => $input))); } } diff --git a/core/modules/taxonomy/taxonomy.tokens.inc b/core/modules/taxonomy/taxonomy.tokens.inc index 34099cebe29b12a9808429248a0207815b2110b5..00819f6c798b1314f115017df14fa0749625a5d1 100644 --- a/core/modules/taxonomy/taxonomy.tokens.inc +++ b/core/modules/taxonomy/taxonomy.tokens.inc @@ -89,6 +89,8 @@ function taxonomy_token_info() { * Implements hook_tokens(). */ function taxonomy_tokens($type, $tokens, array $data = array(), array $options = array()) { + $token_service = Drupal::token(); + $replacements = array(); $sanitize = !empty($options['sanitize']); @@ -136,14 +138,14 @@ function taxonomy_tokens($type, $tokens, array $data = array(), array $options = } } - if ($vocabulary_tokens = token_find_with_prefix($tokens, 'vocabulary')) { + if ($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'vocabulary')) { $vocabulary = taxonomy_vocabulary_load($term->bundle()); - $replacements += token_generate('vocabulary', $vocabulary_tokens, array('vocabulary' => $vocabulary), $options); + $replacements += $token_service->generate('vocabulary', $vocabulary_tokens, array('vocabulary' => $vocabulary), $options); } - if (($vocabulary_tokens = token_find_with_prefix($tokens, 'parent')) && $parents = taxonomy_term_load_parents($term->tid)) { + if (($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'parent')) && $parents = taxonomy_term_load_parents($term->tid)) { $parent = array_pop($parents); - $replacements += token_generate('term', $vocabulary_tokens, array('term' => $parent), $options); + $replacements += $token_service->generate('term', $vocabulary_tokens, array('term' => $parent), $options); } } diff --git a/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php b/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php index d14e8267051a8397b095b120628e2e7b7c17d0be..e7fbec78e665675ba0268c1cd59ae5a938a7e9d7 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php @@ -42,6 +42,7 @@ public function setUp() { * Creates a user, then tests the tokens generated from it. */ function testUserTokenReplacement() { + $token_service = \Drupal::token(); $language_interface = language(LANGUAGE_TYPE_INTERFACE); $url_options = array( 'absolute' => TRUE, @@ -75,7 +76,7 @@ function testUserTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('user' => $account), array('langcode' => $language_interface->langcode)); + $output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->langcode)); $this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', array('%token' => $input))); } @@ -85,7 +86,7 @@ function testUserTokenReplacement() { $tests['[current-user:name]'] = user_format_name($global_account); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('user' => $account), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); + $output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE)); $this->assertEqual($output, $expected, format_string('Unsanitized user token %token replaced.', array('%token' => $input))); } @@ -97,7 +98,7 @@ function testUserTokenReplacement() { // Generate tokens with interface language. $link = url('user', array('absolute' => TRUE)); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('user' => $account), array('langcode' => $language_interface->langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE)); + $output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE)); $this->assertTrue(strpos($output, $link) === 0, 'Generated URL is in interface language.'); } @@ -106,7 +107,7 @@ function testUserTokenReplacement() { $account->save(); $link = url('user', array('language' => language_load($account->preferred_langcode), 'absolute' => TRUE)); foreach ($tests as $input => $expected) { - $output = token_replace($input, array('user' => $account), array('callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE)); + $output = $token_service->replace($input, array('user' => $account), array('callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE)); $this->assertTrue(strpos($output, $link) === 0, "Generated URL is in the user's preferred language."); } @@ -114,7 +115,7 @@ function testUserTokenReplacement() { $link = url('user', array('language' => language_load('de'), 'absolute' => TRUE)); foreach ($tests as $input => $expected) { foreach (array($user1, $user2) as $account) { - $output = token_replace($input, array('user' => $account), array('langcode' => 'de', 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE)); + $output = $token_service->replace($input, array('user' => $account), array('langcode' => 'de', 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE)); $this->assertTrue(strpos($output, $link) === 0, "Generated URL in in the requested language."); } } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index ead593b87a4b21d83f7e518047c41ae3742e160f..eddc8c3d596e15d98ea082a4e8eec15a7c11ee59 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1731,6 +1731,7 @@ function user_view_multiple($accounts, $view_mode = 'full', $langcode = NULL) { * Implements hook_mail(). */ function user_mail($key, &$message, $params) { + $token_service = Drupal::token(); $langcode = $message['langcode']; $variables = array('user' => $params['account']); @@ -1745,8 +1746,8 @@ function user_mail($key, &$message, $params) { // We do not sanitize the token replacement, since the output of this // replacement is intended for an e-mail message, not a web browser. $token_options = array('langcode' => $langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE); - $message['subject'] .= token_replace($mail_config->get($key . '.subject'), $variables, $token_options); - $message['body'][] = token_replace($mail_config->get($key . '.body'), $variables, $token_options); + $message['subject'] .= $token_service->replace($mail_config->get($key . '.subject'), $variables, $token_options); + $message['body'][] = $token_service->replace($mail_config->get($key . '.body'), $variables, $token_options); // Return the previous config context. config_context_leave(); @@ -1755,8 +1756,9 @@ function user_mail($key, &$message, $params) { /** * Token callback to add unsafe tokens for user mails. * - * This function is used by the token_replace() to set up some additional - * tokens that can be used in email messages generated by user_mail(). + * This function is used by \Drupal\Core\Utility\Token::replace() to set up + * some additional tokens that can be used in email messages generated by + * user_mail(). * * @param $replacements * An associative array variable containing mappings from token names to @@ -1768,7 +1770,7 @@ function user_mail($key, &$message, $params) { * - login: The account login name. * - pass: The hashed account login password. * @param $options - * Unused parameter required by the token_replace() function. + * Unused parameter required by \Drupal\Core\Utility\Token::replace(). */ function user_mail_tokens(&$replacements, $data, $options) { if (isset($data['user'])) { diff --git a/core/modules/user/user.tokens.inc b/core/modules/user/user.tokens.inc index bc37434aec27af803e136e25b50efa2aef55e845..185ad6e3a46f99edbad017b9ad8889f698309581 100644 --- a/core/modules/user/user.tokens.inc +++ b/core/modules/user/user.tokens.inc @@ -62,6 +62,8 @@ function user_token_info() { * Implements hook_tokens(). */ function user_tokens($type, $tokens, array $data = array(), array $options = array()) { + + $token_service = Drupal::token(); $url_options = array('absolute' => TRUE); if (isset($options['langcode'])) { $url_options['language'] = language_load($options['langcode']); @@ -113,18 +115,18 @@ function user_tokens($type, $tokens, array $data = array(), array $options = arr } } - if ($login_tokens = token_find_with_prefix($tokens, 'last-login')) { - $replacements += token_generate('date', $login_tokens, array('date' => $account->login), $options); + if ($login_tokens = $token_service->findWithPrefix($tokens, 'last-login')) { + $replacements += $token_service->generate('date', $login_tokens, array('date' => $account->login), $options); } - if ($registered_tokens = token_find_with_prefix($tokens, 'created')) { - $replacements += token_generate('date', $registered_tokens, array('date' => $account->created), $options); + if ($registered_tokens = $token_service->findWithPrefix($tokens, 'created')) { + $replacements += $token_service->generate('date', $registered_tokens, array('date' => $account->created), $options); } } if ($type == 'current-user') { $account = user_load($GLOBALS['user']->uid); - $replacements += token_generate('user', $tokens, array('user' => $account), $options); + $replacements += $token_service->generate('user', $tokens, array('user' => $account), $options); } return $replacements; diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php index 8fa7034d2c89fa2a8e26834d9dc60d4766793221..2c360024277d5aa80df1cbfe17f843fa6f676378 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php @@ -251,13 +251,13 @@ public function usesOptions() { * @param string $string * The string to preform the token replacement on. * @param array $options - * An array of options, as passed to token_replace. + * An array of options, as passed to \Drupal\Core\Utility\Token::replace(). * * @return string * The tokenized string. */ public function globalTokenReplace($string = '', array $options = array()) { - return token_replace($string, array('view' => $this->view), $options); + return \Drupal::token()->replace($string, array('view' => $this->view), $options); } /** @@ -274,7 +274,7 @@ public function globalTokenReplace($string = '', array $options = array()) { * An array of available token replacement info or tokens, grouped by type. */ public function getAvailableGlobalTokens($prepared = FALSE, array $types = array()) { - $info = token_info(); + $info = \Drupal::token()->getInfo(); // Site and view tokens should always be available. $types += array('site', 'view'); $available = array_intersect_key($info['tokens'], array_flip($types)); diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/AreaTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/AreaTest.php index 1ee08da333e1ed43d89a612db9db2e8f9b18ec6e..b8e5f6f45dbee46aefa56268e0c59126d7e6048f 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/AreaTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/AreaTest.php @@ -151,7 +151,7 @@ public function testRenderAreaToken() { // Test we have the site:name token in the output. $output = $view->preview(); $output = drupal_render($output); - $expected = token_replace('[site:name]'); + $expected = \Drupal::token()->replace('[site:name]'); $this->assertTrue(strpos($output, $expected) !== FALSE); } diff --git a/core/modules/views/lib/Drupal/views/Tests/TokenReplaceTest.php b/core/modules/views/lib/Drupal/views/Tests/TokenReplaceTest.php index dcf14333889053f931d63207c4e2d5d5f23fd97c..6bea0431e8614b08600607296d95475cb841209e 100644 --- a/core/modules/views/lib/Drupal/views/Tests/TokenReplaceTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/TokenReplaceTest.php @@ -38,6 +38,7 @@ function setUp() { * Tests core token replacements generated from a view. */ function testTokenReplacement() { + $token_handler = \Drupal::token(); $view = views_get_view('test_tokens'); $view->setDisplay('page_1'); $this->executeView($view); @@ -57,7 +58,7 @@ function testTokenReplacement() { ); foreach ($expected as $token => $expected_output) { - $output = token_replace($token, array('view' => $view)); + $output = $token_handler->replace($token, array('view' => $view)); $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', array('%token' => $token))); } } diff --git a/core/modules/views/views.tokens.inc b/core/modules/views/views.tokens.inc index 9128744d20b5051b1059e2e1ddfb1d1c2c511eee..fc119b81658b152d0a8f25919a76af1d8896d56c 100644 --- a/core/modules/views/views.tokens.inc +++ b/core/modules/views/views.tokens.inc @@ -67,6 +67,8 @@ function views_token_info() { * Implements hook_tokens(). */ function views_tokens($type, $tokens, array $data = array(), array $options = array()) { + $token_service = Drupal::token(); + $url_options = array('absolute' => TRUE); if (isset($options['language'])) { $url_options['language'] = $options['language']; @@ -127,9 +129,9 @@ function views_tokens($type, $tokens, array $data = array(), array $options = ar } // [view:url:*] nested tokens. This only works if Token module is installed. - if ($url_tokens = token_find_with_prefix($tokens, 'url')) { + if ($url_tokens = $token_service->findWithPrefix($tokens, 'url')) { if ($path = $view->getUrl()) { - $replacements += token_generate('url', $url_tokens, array('path' => $path), $options); + $replacements += $token_service->generate('url', $url_tokens, array('path' => $path), $options); } } }