function token_tokens in Token 8
Same name and namespace in other branches
- 7 token.tokens.inc \token_tokens()
Implements hook_tokens().
File
- ./
token.tokens.inc, line 475 - Token callbacks for the token module.
Code
function token_tokens($type, array $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
$replacements = [];
$language_manager = \Drupal::languageManager();
$url_options = [
'absolute' => TRUE,
];
if (isset($options['langcode'])) {
$url_options['language'] = $language_manager
->getLanguage($options['langcode']);
$langcode = $options['langcode'];
}
else {
$langcode = $language_manager
->getCurrentLanguage()
->getId();
}
// Date tokens.
if ($type == 'date') {
$date = !empty($data['date']) ? $data['date'] : \Drupal::time()
->getRequestTime();
// @todo Remove when http://drupal.org/node/1173706 is fixed.
$date_format_types = \Drupal::entityTypeManager()
->getStorage('date_format')
->loadMultiple();
foreach ($tokens as $name => $original) {
if (isset($date_format_types[$name]) && _token_module('date', $name) == 'token') {
$replacements[$original] = \Drupal::service('date.formatter')
->format($date, $name, '', NULL, $langcode);
}
}
}
// Current date tokens.
// @todo Remove when http://drupal.org/node/943028 is fixed.
if ($type == 'current-date') {
$replacements += \Drupal::token()
->generate('date', $tokens, [
'date' => \Drupal::time()
->getRequestTime(),
], $options, $bubbleable_metadata);
}
// Comment tokens.
if ($type == 'comment' && !empty($data['comment'])) {
/* @var \Drupal\comment\CommentInterface $comment */
$comment = $data['comment'];
// Chained token relationships.
if ($url_tokens = \Drupal::token()
->findWithPrefix($tokens, 'url')) {
// Add fragment to url options.
$replacements += \Drupal::token()
->generate('url', $url_tokens, [
'url' => $comment
->toUrl('canonical', [
'fragment' => "comment-{$comment->id()}",
]),
], $options, $bubbleable_metadata);
}
}
// Node tokens.
if ($type == 'node' && !empty($data['node'])) {
/* @var \Drupal\node\NodeInterface $node */
$node = $data['node'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'log':
$replacements[$original] = (string) $node->revision_log->value;
break;
case 'content-type':
$type_name = \Drupal::entityTypeManager()
->getStorage('node_type')
->load($node
->getType())
->label();
$replacements[$original] = $type_name;
break;
}
}
// Chained token relationships.
if (($parent_tokens = \Drupal::token()
->findWithPrefix($tokens, 'source')) && ($source_node = $node
->getUntranslated())) {
$replacements += \Drupal::token()
->generate('node', $parent_tokens, [
'node' => $source_node,
], $options, $bubbleable_metadata);
}
if (($node_type_tokens = \Drupal::token()
->findWithPrefix($tokens, 'content-type')) && ($node_type = NodeType::load($node
->bundle()))) {
$replacements += \Drupal::token()
->generate('content-type', $node_type_tokens, [
'node_type' => $node_type,
], $options, $bubbleable_metadata);
}
if ($url_tokens = \Drupal::token()
->findWithPrefix($tokens, 'url')) {
$replacements += \Drupal::token()
->generate('url', $url_tokens, [
'url' => $node
->toUrl(),
], $options, $bubbleable_metadata);
}
}
// Content type tokens.
if ($type == 'content-type' && !empty($data['node_type'])) {
/* @var \Drupal\node\NodeTypeInterface $node_type */
$node_type = $data['node_type'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'name':
$replacements[$original] = $node_type
->label();
break;
case 'machine-name':
$replacements[$original] = $node_type
->id();
break;
case 'description':
$replacements[$original] = $node_type
->getDescription();
break;
case 'node-count':
$count = \Drupal::entityQueryAggregate('node')
->aggregate('nid', 'COUNT')
->condition('type', $node_type
->id())
->execute();
$replacements[$original] = (int) $count;
break;
case 'edit-url':
$result = $node_type
->toUrl('edit-form', $url_options)
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
break;
}
}
}
// Taxonomy term tokens.
if ($type == 'term' && !empty($data['term'])) {
/* @var \Drupal\taxonomy\TermInterface $term */
$term = $data['term'];
/** @var \Drupal\taxonomy\TermStorageInterface $term_storage */
$term_storage = \Drupal::entityTypeManager()
->getStorage('taxonomy_term');
foreach ($tokens as $name => $original) {
switch ($name) {
case 'edit-url':
$result = Url::fromRoute('entity.taxonomy_term.edit_form', [
'taxonomy_term' => $term
->id(),
], $url_options)
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
break;
case 'parents':
if ($parents = token_taxonomy_term_load_all_parents($term
->id(), $langcode)) {
$replacements[$original] = token_render_array($parents, $options);
}
break;
case 'root':
$parents = $term_storage
->loadAllParents($term
->id());
$root_term = end($parents);
if ($root_term
->id() != $term
->id()) {
$root_term = \Drupal::service('entity.repository')
->getTranslationFromContext($root_term, $langcode);
$replacements[$original] = $root_term
->label();
}
break;
}
}
// Chained token relationships.
if ($url_tokens = \Drupal::token()
->findWithPrefix($tokens, 'url')) {
$replacements += \Drupal::token()
->generate('url', $url_tokens, [
'url' => $term
->toUrl(),
], $options, $bubbleable_metadata);
}
// [term:parents:*] chained tokens.
if ($parents_tokens = \Drupal::token()
->findWithPrefix($tokens, 'parents')) {
if ($parents = token_taxonomy_term_load_all_parents($term
->id(), $langcode)) {
$replacements += \Drupal::token()
->generate('array', $parents_tokens, [
'array' => $parents,
], $options, $bubbleable_metadata);
}
}
if ($root_tokens = \Drupal::token()
->findWithPrefix($tokens, 'root')) {
$parents = $term_storage
->loadAllParents($term
->id());
$root_term = end($parents);
if ($root_term->tid != $term
->id()) {
$replacements += \Drupal::token()
->generate('term', $root_tokens, [
'term' => $root_term,
], $options, $bubbleable_metadata);
}
}
}
// Vocabulary tokens.
if ($type == 'vocabulary' && !empty($data['vocabulary'])) {
$vocabulary = $data['vocabulary'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'machine-name':
$replacements[$original] = $vocabulary
->id();
break;
case 'edit-url':
$result = Url::fromRoute('entity.taxonomy_vocabulary.edit_form', [
'taxonomy_vocabulary' => $vocabulary
->id(),
], $url_options)
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
break;
}
}
}
// File tokens.
if ($type == 'file' && !empty($data['file'])) {
$file = $data['file'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'basename':
$basename = pathinfo($file->uri->value, PATHINFO_BASENAME);
$replacements[$original] = $basename;
break;
case 'extension':
$extension = pathinfo($file->uri->value, PATHINFO_EXTENSION);
$replacements[$original] = $extension;
break;
case 'size-raw':
$replacements[$original] = (int) $file->filesize->value;
break;
}
}
}
// User tokens.
if ($type == 'user' && !empty($data['user'])) {
/* @var \Drupal\user\UserInterface $account */
$account = $data['user'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'picture':
if ($account instanceof UserInterface && $account
->hasField('user_picture')) {
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = \Drupal::service('renderer');
$output = [
'#theme' => 'user_picture',
'#account' => $account,
];
$replacements[$original] = $renderer
->renderPlain($output);
}
break;
case 'roles':
$roles = $account
->getRoles();
$roles_names = array_combine($roles, $roles);
$replacements[$original] = token_render_array($roles_names, $options);
break;
}
}
// Chained token relationships.
if ($account instanceof UserInterface && $account
->hasField('user_picture') && ($picture_tokens = \Drupal::token()
->findWithPrefix($tokens, 'picture'))) {
$replacements += \Drupal::token()
->generate('file', $picture_tokens, [
'file' => $account->user_picture->entity,
], $options, $bubbleable_metadata);
}
if ($url_tokens = \Drupal::token()
->findWithPrefix($tokens, 'url')) {
$replacements += \Drupal::token()
->generate('url', $url_tokens, [
'url' => $account
->toUrl(),
], $options, $bubbleable_metadata);
}
if ($role_tokens = \Drupal::token()
->findWithPrefix($tokens, 'roles')) {
$roles = $account
->getRoles();
$roles_names = array_combine($roles, $roles);
$replacements += \Drupal::token()
->generate('array', $role_tokens, [
'array' => $roles_names,
], $options, $bubbleable_metadata);
}
}
// Current user tokens.
if ($type == 'current-user') {
foreach ($tokens as $name => $original) {
switch ($name) {
case 'ip-address':
$ip = \Drupal::request()
->getClientIp();
$replacements[$original] = $ip;
break;
}
}
}
// Menu link tokens.
if ($type == 'menu-link' && !empty($data['menu-link'])) {
/** @var \Drupal\Core\Menu\MenuLinkInterface $link */
$link = $data['menu-link'];
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
if ($link instanceof MenuLinkContentInterface) {
$link = $menu_link_manager
->createInstance($link
->getPluginId());
}
foreach ($tokens as $name => $original) {
switch ($name) {
case 'id':
$replacements[$original] = $link
->getPluginId();
break;
case 'title':
$replacements[$original] = token_menu_link_translated_title($link, $langcode);
break;
case 'url':
$result = $link
->getUrlObject()
->setAbsolute()
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
break;
case 'parent':
/** @var \Drupal\Core\Menu\MenuLinkInterface $parent */
if ($link
->getParent() && ($parent = $menu_link_manager
->createInstance($link
->getParent()))) {
$replacements[$original] = token_menu_link_translated_title($parent, $langcode);
}
break;
case 'parents':
if ($parents = token_menu_link_load_all_parents($link
->getPluginId(), $langcode)) {
$replacements[$original] = token_render_array($parents, $options);
}
break;
case 'root':
if ($link
->getParent() && ($parent_ids = array_keys(token_menu_link_load_all_parents($link
->getPluginId(), $langcode)))) {
$root = $menu_link_manager
->createInstance(array_shift($parent_ids));
$replacements[$original] = token_menu_link_translated_title($root, $langcode);
}
break;
}
}
// Chained token relationships.
/** @var \Drupal\Core\Menu\MenuLinkInterface $parent */
if ($link
->getParent() && ($parent_tokens = \Drupal::token()
->findWithPrefix($tokens, 'parent')) && ($parent = $menu_link_manager
->createInstance($link
->getParent()))) {
$replacements += \Drupal::token()
->generate('menu-link', $parent_tokens, [
'menu-link' => $parent,
], $options, $bubbleable_metadata);
}
// [menu-link:parents:*] chained tokens.
if ($parents_tokens = \Drupal::token()
->findWithPrefix($tokens, 'parents')) {
if ($parents = token_menu_link_load_all_parents($link
->getPluginId(), $langcode)) {
$replacements += \Drupal::token()
->generate('array', $parents_tokens, [
'array' => $parents,
], $options, $bubbleable_metadata);
}
}
if (($root_tokens = \Drupal::token()
->findWithPrefix($tokens, 'root')) && $link
->getParent() && ($parent_ids = array_keys(token_menu_link_load_all_parents($link
->getPluginId(), $langcode)))) {
$root = $menu_link_manager
->createInstance(array_shift($parent_ids));
$replacements += \Drupal::token()
->generate('menu-link', $root_tokens, [
'menu-link' => $root,
], $options, $bubbleable_metadata);
}
if ($url_tokens = \Drupal::token()
->findWithPrefix($tokens, 'url')) {
$replacements += \Drupal::token()
->generate('url', $url_tokens, [
'url' => $link
->getUrlObject(),
], $options, $bubbleable_metadata);
}
}
// Language tokens.
if ($type == 'language' && !empty($langcode)) {
$language = $language_manager
->getLanguage($langcode);
if ($language) {
foreach ($tokens as $name => $original) {
switch ($name) {
case 'name':
$replacements[$original] = $language
->getName();
break;
case 'langcode':
$replacements[$original] = $langcode;
break;
case 'direction':
$replacements[$original] = $language
->getDirection();
break;
case 'domain':
if (!isset($language_url_domains)) {
$language_url_domains = \Drupal::config('language.negotiation')
->get('url.domains');
}
if (isset($language_url_domains[$langcode])) {
$replacements[$original] = $language_url_domains[$langcode];
}
break;
case 'prefix':
if (!isset($language_url_prefixes)) {
$language_url_prefixes = \Drupal::config('language.negotiation')
->get('url.prefixes');
}
if (isset($language_url_prefixes[$langcode])) {
$replacements[$original] = $language_url_prefixes[$langcode];
}
break;
}
}
}
}
// Current page tokens.
if ($type == 'current-page') {
$request = \Drupal::request();
foreach ($tokens as $name => $original) {
switch ($name) {
case 'title':
$route = $request->attributes
->get(RouteObjectInterface::ROUTE_OBJECT);
if ($route) {
$title = \Drupal::service('title_resolver')
->getTitle($request, $route);
$replacements[$original] = token_render_array_value($title);
}
break;
case 'url':
$bubbleable_metadata
->addCacheContexts([
'url.path',
]);
try {
$url = Url::createFromRequest($request)
->setOptions($url_options);
} catch (\Exception $e) {
// Url::createFromRequest() can fail, e.g. on 404 pages.
// Fall back and try again with Url::fromUserInput().
try {
$url = Url::fromUserInput($request
->getPathInfo(), $url_options);
} catch (\Exception $e) {
// Instantiation would fail again on malformed urls.
}
}
if (isset($url)) {
$result = $url
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
}
break;
case 'page-number':
if ($page = $request->query
->get('page')) {
// @see PagerDefault::execute()
$pager_page_array = explode(',', $page);
$page = $pager_page_array[0];
}
$replacements[$original] = (int) $page + 1;
break;
}
// [current-page:interface-language:*] chained tokens.
if ($language_interface_tokens = \Drupal::token()
->findWithPrefix($tokens, 'interface-language')) {
$language_interface = $language_manager
->getCurrentLanguage(LanguageInterface::TYPE_INTERFACE);
$langcode = $language_interface
->getId();
$replacements += \Drupal::token()
->generate('language', $language_interface_tokens, $data, [
'langcode' => $langcode,
] + $options, $bubbleable_metadata);
}
// [current-page:content-language:*] chained tokens.
if ($language_content_tokens = \Drupal::token()
->findWithPrefix($tokens, 'content-language')) {
$language_content = $language_manager
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT);
$langcode = $language_content
->getId();
$replacements += \Drupal::token()
->generate('language', $language_content_tokens, $data, [
'langcode' => $langcode,
] + $options, $bubbleable_metadata);
}
}
// @deprecated
// [current-page:arg] dynamic tokens.
if ($arg_tokens = \Drupal::token()
->findWithPrefix($tokens, 'arg')) {
$path = ltrim(\Drupal::service('path.current')
->getPath(), '/');
// Make sure its a system path.
$path = \Drupal::service('path_alias.manager')
->getPathByAlias($path);
foreach ($arg_tokens as $name => $original) {
$parts = explode('/', $path);
if (is_numeric($name) && isset($parts[$name])) {
$replacements[$original] = $parts[$name];
}
}
}
// [current-page:query] dynamic tokens.
if ($query_tokens = \Drupal::token()
->findWithPrefix($tokens, 'query')) {
$bubbleable_metadata
->addCacheContexts([
'url.query_args',
]);
foreach ($query_tokens as $name => $original) {
if (\Drupal::request()->query
->has($name)) {
$value = \Drupal::request()->query
->get($name);
$replacements[$original] = $value;
}
}
}
// Chained token relationships.
if ($url_tokens = \Drupal::token()
->findWithPrefix($tokens, 'url')) {
$url = NULL;
try {
$url = Url::createFromRequest($request)
->setOptions($url_options);
} catch (\Exception $e) {
// Url::createFromRequest() can fail, e.g. on 404 pages.
// Fall back and try again with Url::fromUserInput().
try {
$url = Url::fromUserInput($request
->getPathInfo(), $url_options);
} catch (\Exception $e) {
// Instantiation would fail again on malformed urls.
}
}
// Add cache contexts to ensure this token functions on a per-path basis
$bubbleable_metadata
->addCacheContexts([
'url.path',
]);
$replacements += \Drupal::token()
->generate('url', $url_tokens, [
'url' => $url,
], $options, $bubbleable_metadata);
}
}
// URL tokens.
if ($type == 'url' && !empty($data['url'])) {
/** @var \Drupal\Core\Url $url */
$url = $data['url'];
// To retrieve the correct path, modify a copy of the Url object.
$path_url = clone $url;
$path = '/';
// Ensure the URL is routed to avoid throwing an exception.
if ($url
->isRouted()) {
$path .= $path_url
->setAbsolute(FALSE)
->setOption('fragment', NULL)
->getInternalPath();
}
foreach ($tokens as $name => $original) {
switch ($name) {
case 'path':
$value = !$url
->getOption('alias') ? \Drupal::service('path_alias.manager')
->getAliasByPath($path, $langcode) : $path;
$replacements[$original] = $value;
break;
case 'alias':
// @deprecated
$alias = \Drupal::service('path_alias.manager')
->getAliasByPath($path, $langcode);
$replacements[$original] = $alias;
break;
case 'absolute':
$result = $url
->setAbsolute()
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
break;
case 'relative':
$result = $url
->setAbsolute(FALSE)
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
break;
case 'brief':
$result = $url
->setAbsolute()
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = preg_replace([
'!^https?://!',
'!/$!',
], '', $result
->getGeneratedUrl());
break;
case 'unaliased':
$unaliased = clone $url;
$result = $unaliased
->setAbsolute()
->setOption('alias', TRUE)
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
break;
case 'args':
$value = !$url
->getOption('alias') ? \Drupal::service('path_alias.manager')
->getAliasByPath($path, $langcode) : $path;
$replacements[$original] = token_render_array(explode('/', $value), $options);
break;
}
}
// [url:args:*] chained tokens.
if ($arg_tokens = \Drupal::token()
->findWithPrefix($tokens, 'args')) {
$value = !$url
->getOption('alias') ? \Drupal::service('path_alias.manager')
->getAliasByPath($path, $langcode) : $path;
$replacements += \Drupal::token()
->generate('array', $arg_tokens, [
'array' => explode('/', ltrim($value, '/')),
], $options, $bubbleable_metadata);
}
// [url:unaliased:*] chained tokens.
if ($unaliased_tokens = \Drupal::token()
->findWithPrefix($tokens, 'unaliased')) {
$url
->setOption('alias', TRUE);
$replacements += \Drupal::token()
->generate('url', $unaliased_tokens, [
'url' => $url,
], $options, $bubbleable_metadata);
}
}
// Entity tokens.
if (!empty($data[$type]) && ($entity_type = \Drupal::service('token.entity_mapper')
->getEntityTypeForTokenType($type))) {
/* @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $data[$type];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'url':
if (_token_module($type, 'url') === 'token' && !$entity
->isNew() && $entity
->hasLinkTemplate('canonical')) {
$result = $entity
->toUrl('canonical')
->toString(TRUE);
$bubbleable_metadata
->addCacheableDependency($result);
$replacements[$original] = $result
->getGeneratedUrl();
}
break;
case 'original':
if (_token_module($type, 'original') == 'token' && !empty($entity->original)) {
$label = $entity->original
->label();
$replacements[$original] = $label;
}
break;
}
}
// [entity:url:*] chained tokens.
if (($url_tokens = \Drupal::token()
->findWithPrefix($tokens, 'url')) && _token_module($type, 'url') == 'token') {
$replacements += \Drupal::token()
->generate('url', $url_tokens, [
'url' => $entity
->toUrl(),
], $options, $bubbleable_metadata);
}
// [entity:original:*] chained tokens.
if (($original_tokens = \Drupal::token()
->findWithPrefix($tokens, 'original')) && _token_module($type, 'original') == 'token' && !empty($entity->original)) {
$replacements += \Drupal::token()
->generate($type, $original_tokens, [
$type => $entity->original,
], $options, $bubbleable_metadata);
}
// [entity:language:*] chained tokens.
if (($language_tokens = \Drupal::token()
->findWithPrefix($tokens, 'language')) && _token_module($type, 'language') == 'token') {
$language_options = array_merge($options, [
'langcode' => $entity
->get('langcode')->value,
]);
$replacements += \Drupal::token()
->generate('language', $language_tokens, [], $language_options, $bubbleable_metadata);
}
// Pass through to an generic 'entity' token type generation.
$entity_data = [
'entity_type' => $entity_type,
'entity' => $entity,
'token_type' => $type,
];
// @todo Investigate passing through more data like everything from entity_extract_ids().
$replacements += \Drupal::token()
->generate('entity', $tokens, $entity_data, $options, $bubbleable_metadata);
}
// Array tokens.
if ($type == 'array' && !empty($data['array']) && is_array($data['array'])) {
$array = $data['array'];
$sort = isset($options['array sort']) ? $options['array sort'] : TRUE;
$keys = token_element_children($array, $sort);
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = \Drupal::service('renderer');
foreach ($tokens as $name => $original) {
switch ($name) {
case 'first':
$value = $array[$keys[0]];
$value = is_array($value) ? $renderer
->renderPlain($value) : (string) $value;
$replacements[$original] = $value;
break;
case 'last':
$value = $array[$keys[count($keys) - 1]];
$value = is_array($value) ? $renderer
->renderPlain($value) : (string) $value;
$replacements[$original] = $value;
break;
case 'count':
$replacements[$original] = count($keys);
break;
case 'keys':
$replacements[$original] = token_render_array($keys, $options);
break;
case 'reversed':
$reversed = array_reverse($array, TRUE);
$replacements[$original] = token_render_array($reversed, $options);
break;
case 'join':
$replacements[$original] = token_render_array($array, [
'join' => '',
] + $options);
break;
}
}
// [array:value:*] dynamic tokens.
if ($value_tokens = \Drupal::token()
->findWithPrefix($tokens, 'value')) {
foreach ($value_tokens as $key => $original) {
if ((is_int($key) || $key[0] !== '#') && isset($array[$key])) {
$replacements[$original] = token_render_array_value($array[$key], $options);
}
}
}
// [array:join:*] dynamic tokens.
if ($join_tokens = \Drupal::token()
->findWithPrefix($tokens, 'join')) {
foreach ($join_tokens as $join => $original) {
$replacements[$original] = token_render_array($array, [
'join' => $join,
] + $options);
}
}
// [array:keys:*] chained tokens.
if ($key_tokens = \Drupal::token()
->findWithPrefix($tokens, 'keys')) {
$replacements += \Drupal::token()
->generate('array', $key_tokens, [
'array' => $keys,
], $options, $bubbleable_metadata);
}
// [array:reversed:*] chained tokens.
if ($reversed_tokens = \Drupal::token()
->findWithPrefix($tokens, 'reversed')) {
$replacements += \Drupal::token()
->generate('array', $reversed_tokens, [
'array' => array_reverse($array, TRUE),
], [
'array sort' => FALSE,
] + $options, $bubbleable_metadata);
}
// @todo Handle if the array values are not strings and could be chained.
}
// Random tokens.
if ($type == 'random') {
foreach ($tokens as $name => $original) {
switch ($name) {
case 'number':
$replacements[$original] = mt_rand();
break;
}
}
// [custom:hash:*] dynamic token.
if ($hash_tokens = \Drupal::token()
->findWithPrefix($tokens, 'hash')) {
$algos = hash_algos();
foreach ($hash_tokens as $name => $original) {
if (in_array($name, $algos)) {
$replacements[$original] = hash($name, random_bytes(55));
}
}
}
}
// If $type is a token type, $data[$type] is empty but $data[$entity_type] is
// not, re-run token replacements.
if (empty($data[$type]) && ($entity_type = \Drupal::service('token.entity_mapper')
->getEntityTypeForTokenType($type)) && $entity_type != $type && !empty($data[$entity_type]) && empty($options['recursive'])) {
$data[$type] = $data[$entity_type];
$options['recursive'] = TRUE;
$replacements += \Drupal::moduleHandler()
->invokeAll('tokens', [
$type,
$tokens,
$data,
$options,
$bubbleable_metadata,
]);
}
// If the token type specifics a 'needs-data' value, and the value is not
// present in $data, then throw an error.
if (!empty($GLOBALS['drupal_test_info']['test_run_id'])) {
// Only check when tests are running.
$type_info = \Drupal::token()
->getTypeInfo($type);
if (!empty($type_info['needs-data']) && !isset($data[$type_info['needs-data']])) {
trigger_error(t('Attempting to perform token replacement for token type %type without required data', [
'%type' => $type,
]), E_USER_WARNING);
}
}
return $replacements;
}