diff --git a/composer.json b/composer.json index 0ff5930bec8d121efc9cb1a208eeb21400fcfdbf..5db980b183bdb027d272fa4c075c29a4800fe551 100644 --- a/composer.json +++ b/composer.json @@ -130,7 +130,7 @@ "drupal/social_media_links": "^2.6", "drupal/superfish": "1.2", "drupal/svg_image": "1.8", - "drupal/token": "1.0", + "drupal/token": "1.5", "drupal/userprotect": "1.0", "drupal/video_embed_field": "2.0", "drupal/views_accordion": "1.1", diff --git a/composer.lock b/composer.lock index 1da72fe096e4c4e1f7398efcc5ee75975dbdecb2..321bc118f7248d88ead81b44ed46a42f14d62a64 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "5eb47f8a36f62539ff7f81a51b48209d", + "content-hash": "16453ef5f39c4905da35b57f7a210083", "packages": [ { "name": "alchemy/zippy", @@ -5437,20 +5437,20 @@ }, { "name": "drupal/token", - "version": "1.0.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://git.drupal.org/project/token", - "reference": "8.x-1.0" + "reference": "8.x-1.5" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/token-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "d24c7f1ffddbd0fc56bc92bacae1c4ff769a4442" + "url": "https://ftp.drupal.org/files/projects/token-8.x-1.5.zip", + "reference": "8.x-1.5", + "shasum": "6382a7e1aabbd8246f1117a26bf4916d285b401d" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8.5" }, "type": "drupal-module", "extra": { @@ -5458,8 +5458,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1513810384", + "version": "8.x-1.5", + "datestamp": "1537557481", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index c834fb162f9e2587df64987e3bb5848846b98042..a7ebbd6436cf4712224a2f6562adfe10e99640d8 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -5607,21 +5607,21 @@ }, { "name": "drupal/token", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.5.0", + "version_normalized": "1.5.0.0", "source": { "type": "git", "url": "https://git.drupal.org/project/token", - "reference": "8.x-1.0" + "reference": "8.x-1.5" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/token-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "d24c7f1ffddbd0fc56bc92bacae1c4ff769a4442" + "url": "https://ftp.drupal.org/files/projects/token-8.x-1.5.zip", + "reference": "8.x-1.5", + "shasum": "6382a7e1aabbd8246f1117a26bf4916d285b401d" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8.5" }, "type": "drupal-module", "extra": { @@ -5629,8 +5629,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1513810384", + "version": "8.x-1.5", + "datestamp": "1537557481", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" diff --git a/web/modules/token/README.md b/web/modules/token/README.md index c37d33508414ea14eb85a663e1efcf92d5a5f2d5..c2f8d04c865eb70af645236be24cb0d055463a44 100644 --- a/web/modules/token/README.md +++ b/web/modules/token/README.md @@ -1,3 +1,13 @@ +CONTENTS OF THIS FILE +--------------------- + + * Introduction + * Recommended modules + * Installation + * Configuration + * Troubleshooting + * Maintainers + INTRODUCTION ------------ @@ -9,20 +19,28 @@ INTRODUCTION * To submit bug reports and feature suggestions, or to track changes: https://drupal.org/project/issues/token +RECOMMENDED MODULES +------------------- + + * No extra module is required. INSTALLATION ------------ -Install as usual, see - https://www.drupal.org/docs/8/extending-drupal-8/installing-contributed-modules-find-import-enable-configure-drupal-8 for further -information. + * Install as usual, see + https://www.drupal.org/docs/8/extending-drupal-8/installing-contributed-modules-find-import-enable-configure-drupal-8 for further + information. + +CONFIGURATION +------------- + * No configuration is needed. TROUBLESHOOTING --------------- -Token module doesn't provide any visible functions to the user on its own, it -just provides token handling services for other modules. + * Token module doesn't provide any visible functions to the user on its own, it + just provides token handling services for other modules. MAINTAINERS @@ -31,3 +49,4 @@ MAINTAINERS Current maintainers: * Dave Reid (https://drupal.org/user/53892) + * Sascha Grossenbacher (Berdir) (https://www.drupal.org/user/214652) diff --git a/web/modules/token/js/token.js b/web/modules/token/js/token.js index 0cd7621d10bb7cadf1a49954b109ee0376d6e07b..3a41d6259a18efde7c4d706769b993e8192ed9b8 100644 --- a/web/modules/token/js/token.js +++ b/web/modules/token/js/token.js @@ -1,5 +1,5 @@ -(function ($) { +(function ($, Drupal, drupalSettings) { 'use strict'; @@ -20,39 +20,74 @@ $('.token-click-insert .token-key', context).once('token-click-insert').each(function () { var newThis = $('<a href="javascript:void(0);" title="' + Drupal.t('Insert this token into your form') + '">' + $(this).html() + '</a>').click(function () { - if (typeof drupalSettings.tokenFocusedField == 'undefined') { - alert(Drupal.t('First click a text field to insert your tokens into.')); + var content = this.text; + + // Always work in normal text areas that currently have focus. + if (drupalSettings.tokenFocusedField && (drupalSettings.tokenFocusedField.tokenDialogFocus || drupalSettings.tokenFocusedField.tokenHasFocus)) { + insertAtCursor(drupalSettings.tokenFocusedField, content); + } + // Direct tinyMCE support. + else if (typeof(tinyMCE) != 'undefined' && tinyMCE.activeEditor) { + tinyMCE.activeEditor.execCommand('mceInsertContent', false, content); + } + // Direct CKEditor support. Only works if the field currently has focus, + // which is unusual since the dialog is open. + else if (typeof(CKEDITOR) != 'undefined' && CKEDITOR.currentInstance) { + CKEDITOR.currentInstance.insertHtml(content); + } + // Direct CodeMirror support. + else if (typeof(CodeMirror) != 'undefined' && drupalSettings.tokenFocusedField && $(drupalSettings.tokenFocusedField).parents('.CodeMirror').length) { + var editor = $(drupalSettings.tokenFocusedField).parents('.CodeMirror')[0].CodeMirror; + editor.replaceSelection(content); + editor.focus(); + } + // WYSIWYG support, should work in all editors if available. + else if (Drupal.wysiwyg && Drupal.wysiwyg.activeId) { + Drupal.wysiwyg.instances[Drupal.wysiwyg.activeId].insert(content) + } + // CKeditor module support. + else if (typeof(CKEDITOR) != 'undefined' && typeof(Drupal.ckeditorActiveId) != 'undefined') { + CKEDITOR.instances[Drupal.ckeditorActiveId].insertHtml(content); + } + else if (drupalSettings.tokenFocusedField) { + insertAtCursor(drupalSettings.tokenFocusedField, content); } else { - var myField = drupalSettings.tokenFocusedField; - var myValue = $(this).text(); - - // IE support. - if (document.selection) { - myField.focus(); - var sel = document.selection.createRange(); - sel.text = myValue; - } - - // MOZILLA/NETSCAPE support. - else if (myField.selectionStart || myField.selectionStart === '0') { - var startPos = myField.selectionStart; - var endPos = myField.selectionEnd; - myField.value = myField.value.substring(0, startPos) - + myValue - + myField.value.substring(endPos, myField.value.length); - } - else { - myField.value += myValue; - } - - $('html,body').animate({scrollTop: $(myField).offset().top}, 500); + alert(Drupal.t('First click a text field to insert your tokens into.')); } + return false; }); $(this).html(newThis); }); + + function insertAtCursor(editor, content) { + // Record the current scroll position. + var scroll = editor.scrollTop; + + // IE support. + if (document.selection) { + editor.focus(); + var sel = document.selection.createRange(); + sel.text = content; + } + + // Mozilla/Firefox/Netscape 7+ support. + else if (editor.selectionStart || editor.selectionStart == '0') { + var startPos = editor.selectionStart; + var endPos = editor.selectionEnd; + editor.value = editor.value.substring(0, startPos) + content + editor.value.substring(endPos, editor.value.length); + } + + // Fallback, just add to the end of the content. + else { + editor.value += content; + } + + // Ensure the textarea does not unexpectedly scroll. + editor.scrollTop = scroll; + } } }; -})(jQuery, drupalSettings); +})(jQuery, Drupal, drupalSettings); diff --git a/web/modules/token/src/Controller/TokenAutocompleteController.php b/web/modules/token/src/Controller/TokenAutocompleteController.php index a50da70b88292bbffc2b12707fca851b4cc66ac8..979f832a48df8913524191c2f2af9560fd838886 100644 --- a/web/modules/token/src/Controller/TokenAutocompleteController.php +++ b/web/modules/token/src/Controller/TokenAutocompleteController.php @@ -2,7 +2,6 @@ namespace Drupal\token\Controller; -use Drupal\Component\Utility\Unicode; use Drupal\Core\Controller\ControllerBase; use Drupal\token\TreeBuilderInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -48,9 +47,9 @@ public static function create(ContainerInterface $container) { public function autocomplete($token_type, $filter, Request $request) { $filter = substr($filter, strrpos($filter, '[')); - $matches = array(); + $matches = []; - if (!Unicode::strlen($filter)) { + if (!mb_strlen($filter)) { $matches["[{$token_type}:"] = 0; } else { diff --git a/web/modules/token/src/Controller/TokenCacheController.php b/web/modules/token/src/Controller/TokenCacheController.php index 39dc5b0f3e6efbc1c67870dd2cc7a6d73cf0dd9b..7f758d33557dfd3025fc579e9541345cdec14a5c 100644 --- a/web/modules/token/src/Controller/TokenCacheController.php +++ b/web/modules/token/src/Controller/TokenCacheController.php @@ -7,14 +7,14 @@ /** * Clears cache for tokens. */ -class TokenCacheController extends ControllerBase { +class TokenCacheController extends ControllerBase { /** * Clear caches and redirect back to the frontpage. */ public function flush() { token_clear_cache(); - drupal_set_message(t('Token registry caches cleared.')); + $this->messenger()->addMessage($this->t('Token registry caches cleared.')); return $this->redirect('<front>'); } diff --git a/web/modules/token/src/Controller/TokenTreeController.php b/web/modules/token/src/Controller/TokenTreeController.php index f233ab2340941386bc824e2e95b951f5e0331e4f..3edf40229c08c2c59fb677eb4676b46d9b570e4a 100644 --- a/web/modules/token/src/Controller/TokenTreeController.php +++ b/web/modules/token/src/Controller/TokenTreeController.php @@ -50,6 +50,17 @@ function outputTree(Request $request) { $build['#cache']['contexts'][] = 'url.query_args:options'; $build['#title'] = $this->t('Available tokens'); + // If this is an AJAX/modal request, add a wrapping div to the contents so + // that Drupal.behaviors.tokenTree and Drupal.behaviors.tokenAttach can + // stil find the elements they need to. + // @see https://www.drupal.org/project/token/issues/2994671 + // @see https://www.drupal.org/node/2940704 + // @see http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ + if ($request->isXmlHttpRequest()) { + $build['#prefix'] = '<div>'; + $build['#suffix'] = '</div>'; + } + return $build; } diff --git a/web/modules/token/src/Routing/RouteSubscriber.php b/web/modules/token/src/Routing/RouteSubscriber.php index ae6815a284583bbfd1e92cf65f40c7278ddf9b83..b856f43e6f851f8ea4c86bc8f93c9d2fc1070604 100644 --- a/web/modules/token/src/Routing/RouteSubscriber.php +++ b/web/modules/token/src/Routing/RouteSubscriber.php @@ -71,4 +71,5 @@ public static function getSubscribedEvents() { $events[RoutingEvents::ALTER] = array('onAlterRoutes', 100); return $events; } + } diff --git a/web/modules/token/src/Tests/TokenBlockTest.php b/web/modules/token/src/Tests/TokenBlockTest.php index 66e30255ec493d836143831f5adfde0010cd2c90..55de3b98814d0b0da1bd3875a82cd465f66a9ca2 100644 --- a/web/modules/token/src/Tests/TokenBlockTest.php +++ b/web/modules/token/src/Tests/TokenBlockTest.php @@ -1,6 +1,7 @@ <?php namespace Drupal\token\Tests; + use Drupal\block_content\Entity\BlockContent; use Drupal\block_content\Entity\BlockContentType; @@ -21,38 +22,38 @@ class TokenBlockTest extends TokenTestBase { /** * {@inheritdoc} */ - public function setUp($modules = array()) { + public function setUp($modules = []) { parent::setUp(); - $this->admin_user = $this->drupalCreateUser(array('access content', 'administer blocks')); + $this->admin_user = $this->drupalCreateUser(['access content', 'administer blocks']); $this->drupalLogin($this->admin_user); } public function testBlockTitleTokens() { $label = 'tokenblock'; - $bundle = BlockContentType::create(array( + $bundle = BlockContentType::create([ 'id' => $label, 'label' => $label, 'revision' => FALSE - )); + ]); $bundle->save(); - $block_content = BlockContent::create(array( + $block_content = BlockContent::create([ 'type' => $label, 'label' => '[current-page:title] block title', 'info' => 'Test token title block', 'body[value]' => 'This is the test token title block.', - )); + ]); $block_content->save(); - $block = $this->drupalPlaceBlock('block_content:' . $block_content->uuid(), array( + $block = $this->drupalPlaceBlock('block_content:' . $block_content->uuid(), [ 'label' => '[user:name]', - )); - $this->drupalGet($block->urlInfo()); + ]); + $this->drupalGet($block->toUrl()); // Ensure that the link to available tokens is present and correctly // positioned. $this->assertLink('Browse available tokens.'); $this->assertText('This field supports tokens. Browse available tokens.'); - $this->drupalPostForm(NULL, array(), t('Save block')); + $this->drupalPostForm(NULL, [], t('Save block')); // Ensure token validation is working on the block. $this->assertText('Title is using the following invalid tokens: [user:name].'); @@ -63,8 +64,8 @@ public function testBlockTitleTokens() { $block->save(); // Ensure that tokens are not double-escaped when output as a block title. - $this->drupalCreateContentType(array('type' => 'page')); - $node = $this->drupalCreateNode(array('title' => "Site's first node")); + $this->drupalCreateContentType(['type' => 'page']); + $node = $this->drupalCreateNode(['title' => "Site's first node"]); $this->drupalGet('node/' . $node->id()); // The apostraphe should only be escaped once. $this->assertRaw("Site's first node block title"); diff --git a/web/modules/token/src/Tests/TokenCurrentPageTest.php b/web/modules/token/src/Tests/TokenCurrentPageTest.php index cd8ac3729349ab63022404eecf84cc7927cf488a..096c24bc4ed25e0fb3c6ddae471eae1b69108e52 100644 --- a/web/modules/token/src/Tests/TokenCurrentPageTest.php +++ b/web/modules/token/src/Tests/TokenCurrentPageTest.php @@ -16,19 +16,19 @@ class TokenCurrentPageTest extends TokenTestBase { * * @var array */ - public static $modules = array('node'); + public static $modules = ['node']; function testCurrentPageTokens() { - $tokens = array( + $tokens = [ '[current-page:title]' => t('Log in'), - '[current-page:url]' => Url::fromRoute('user.login', [], array('absolute' => TRUE))->toString(), - '[current-page:url:absolute]' => Url::fromRoute('user.login', [], array('absolute' => TRUE))->toString(), + '[current-page:url]' => Url::fromRoute('user.login', [], ['absolute' => TRUE])->toString(), + '[current-page:url:absolute]' => Url::fromRoute('user.login', [], ['absolute' => TRUE])->toString(), '[current-page:url:relative]' => Url::fromRoute('user.login')->toString(), '[current-page:url:path]' => '/user/login', '[current-page:url:args:value:0]' => 'user', '[current-page:url:args:value:1]' => 'login', '[current-page:url:args:value:2]' => NULL, - '[current-page:url:unaliased]' => Url::fromRoute('user.login', [], array('absolute' => TRUE, 'alias' => TRUE))->toString(), + '[current-page:url:unaliased]' => Url::fromRoute('user.login', [], ['absolute' => TRUE, 'alias' => TRUE])->toString(), '[current-page:page-number]' => 1, '[current-page:query:foo]' => NULL, '[current-page:query:bar]' => NULL, @@ -36,20 +36,20 @@ function testCurrentPageTokens() { '[current-page:arg:0]' => 'user', '[current-page:arg:1]' => 'login', '[current-page:arg:2]' => NULL, - ); + ]; $this->assertPageTokens('user/login', $tokens); - $this->drupalCreateContentType(array('type' => 'page')); - $node = $this->drupalCreateNode(array('title' => 'Node title', 'path' => array('alias' => '/node-alias'))); - $tokens = array( + $this->drupalCreateContentType(['type' => 'page']); + $node = $this->drupalCreateNode(['title' => 'Node title', 'path' => ['alias' => '/node-alias']]); + $tokens = [ '[current-page:title]' => 'Node title', - '[current-page:url]' => $node->url('canonical', array('absolute' => TRUE)), - '[current-page:url:absolute]' => $node->url('canonical', array('absolute' => TRUE)), - '[current-page:url:relative]' => $node->url(), + '[current-page:url]' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(), + '[current-page:url:absolute]' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(), + '[current-page:url:relative]' => $node->toUrl()->toString(), '[current-page:url:alias]' => '/node-alias', '[current-page:url:args:value:0]' => 'node-alias', '[current-page:url:args:value:1]' => NULL, - '[current-page:url:unaliased]' => $node->url('canonical', array('absolute' => TRUE, 'alias' => TRUE)), + '[current-page:url:unaliased]' => $node->toUrl('canonical', ['absolute' => TRUE, 'alias' => TRUE])->toString(), '[current-page:url:unaliased:args:value:0]' => 'node', '[current-page:url:unaliased:args:value:1]' => $node->id(), '[current-page:url:unaliased:args:value:2]' => NULL, @@ -60,7 +60,7 @@ function testCurrentPageTokens() { '[current-page:arg:0]' => 'node', '[current-page:arg:1]' => 1, '[current-page:arg:2]' => NULL, - ); - $this->assertPageTokens("/node/{$node->id()}", $tokens, array(), array('url_options' => array('query' => array('foo' => 'bar')))); + ]; + $this->assertPageTokens("/node/{$node->id()}", $tokens, [], ['url_options' => ['query' => ['foo' => 'bar']]]); } } diff --git a/web/modules/token/src/Tests/TokenFieldUiTest.php b/web/modules/token/src/Tests/TokenFieldUiTest.php index f7983e73b59b2df17209ee7050ca9c57f28891ea..f72295f217fb6a0a57c2d80e24177a6412a87651 100644 --- a/web/modules/token/src/Tests/TokenFieldUiTest.php +++ b/web/modules/token/src/Tests/TokenFieldUiTest.php @@ -2,6 +2,8 @@ namespace Drupal\token\Tests; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; use Drupal\node\Entity\NodeType; use Drupal\node\Entity\Node; use Drupal\file\Entity\File; @@ -41,50 +43,50 @@ public function setUp($modules = []) { ]); $node_type->save(); - entity_create('field_storage_config', array( + FieldStorageConfig::create([ 'field_name' => 'field_body', 'entity_type' => 'node', 'type' => 'text_with_summary', - ))->save(); - entity_create('field_config', array( + ])->save(); + FieldConfig::create([ 'field_name' => 'field_body', 'label' => 'Body', 'entity_type' => 'node', 'bundle' => 'article', - ))->save(); - entity_create('field_storage_config', array( + ])->save(); + FieldStorageConfig::create([ 'field_name' => 'field_image', 'entity_type' => 'node', 'type' => 'image', - ))->save(); - entity_create('field_config', array( + ])->save(); + FieldConfig::create([ 'field_name' => 'field_image', 'label' => 'Image', 'entity_type' => 'node', 'bundle' => 'article', - ))->save(); - entity_create('field_storage_config', array( + ])->save(); + FieldStorageConfig::create([ 'field_name' => 'field_image_2', 'entity_type' => 'node', 'type' => 'image', - ))->save(); - entity_create('field_config', array( + ])->save(); + FieldConfig::create([ 'field_name' => 'field_image_2', 'label' => 'Image 2', 'entity_type' => 'node', 'bundle' => 'article', - ))->save(); - entity_create('field_storage_config', array( + ])->save(); + FieldStorageConfig::create([ 'field_name' => 'multivalued_field_image', 'entity_type' => 'node', 'type' => 'image', - ))->save(); - entity_create('field_config', array( + ])->save(); + FieldConfig::create([ 'field_name' => 'multivalued_field_image', 'label' => 'Multivalued field image', 'entity_type' => 'node', 'bundle' => 'article', - ))->save(); + ])->save(); entity_get_form_display('node', 'article', 'default') ->setComponent('field_body', [ diff --git a/web/modules/token/src/Tests/TokenMenuTest.php b/web/modules/token/src/Tests/TokenMenuTest.php index b9eb920617fc543944760cb3219543feca0db99a..1b2eda091be73032b1562660c72adcf337334d25 100644 --- a/web/modules/token/src/Tests/TokenMenuTest.php +++ b/web/modules/token/src/Tests/TokenMenuTest.php @@ -35,11 +35,11 @@ function testMenuTokens() { // Make sure we have a body field on the node type. $this->drupalCreateContentType(['type' => 'page']); // Add a menu. - $menu = entity_create('menu', array( + $menu = Menu::create([ 'id' => 'main-menu', 'label' => 'Main menu', 'description' => 'The <em>Main</em> menu is used on many sites to show the major sections of the site, often in a top navigation bar.', - )); + ]); $menu->save(); // Place the menu block. @@ -47,25 +47,25 @@ function testMenuTokens() { // Add a root link. /** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $root_link */ - $root_link = entity_create('menu_link_content', array( + $root_link = MenuLinkContent::create([ 'link' => ['uri' => 'internal:/admin'], 'title' => 'Administration', 'menu_name' => 'main-menu', - )); + ]); $root_link->save(); // Add another link with the root link as the parent. /** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $parent_link */ - $parent_link = entity_create('menu_link_content', array( + $parent_link = MenuLinkContent::create([ 'link' => ['uri' => 'internal:/admin/config'], 'title' => 'Configuration', 'menu_name' => 'main-menu', 'parent' => $root_link->getPluginId(), - )); + ]); $parent_link->save(); // Test menu link tokens. - $tokens = array( + $tokens = [ 'id' => $parent_link->getPluginId(), 'title' => 'Configuration', 'menu' => 'Main menu', @@ -73,13 +73,13 @@ function testMenuTokens() { 'menu:machine-name' => $menu->id(), 'menu:description' => 'The <em>Main</em> menu is used on many sites to show the major sections of the site, often in a top navigation bar.', 'menu:menu-link-count' => '2', - 'menu:edit-url' => Url::fromRoute('entity.menu.edit_form', ['menu' => 'main-menu'], array('absolute' => TRUE))->toString(), - 'url' => Url::fromRoute('system.admin_config', [], array('absolute' => TRUE))->toString(), - 'url:absolute' => Url::fromRoute('system.admin_config', [], array('absolute' => TRUE))->toString(), - 'url:relative' => Url::fromRoute('system.admin_config', [], array('absolute' => FALSE))->toString(), + 'menu:edit-url' => Url::fromRoute('entity.menu.edit_form', ['menu' => 'main-menu'], ['absolute' => TRUE])->toString(), + 'url' => Url::fromRoute('system.admin_config', [], ['absolute' => TRUE])->toString(), + 'url:absolute' => Url::fromRoute('system.admin_config', [], ['absolute' => TRUE])->toString(), + 'url:relative' => Url::fromRoute('system.admin_config', [], ['absolute' => FALSE])->toString(), 'url:path' => '/admin/config', 'url:alias' => '/admin/config', - 'edit-url' => Url::fromRoute('entity.menu_link_content.canonical', ['menu_link_content' => $parent_link->id()], array('absolute' => TRUE))->toString(), + 'edit-url' => Url::fromRoute('entity.menu_link_content.canonical', ['menu_link_content' => $parent_link->id()], ['absolute' => TRUE])->toString(), 'parent' => 'Administration', 'parent:id' => $root_link->getPluginId(), 'parent:title' => 'Administration', @@ -92,32 +92,32 @@ function testMenuTokens() { 'root:id' => $root_link->getPluginId(), 'root:parent' => NULL, 'root:root' => NULL, - ); - $this->assertTokens('menu-link', array('menu-link' => $parent_link), $tokens); + ]; + $this->assertTokens('menu-link', ['menu-link' => $parent_link], $tokens); // Add a node. $node = $this->drupalCreateNode(); // Allow main menu for this node type. - //$this->config('menu.entity.node.' . $node->getType())->set('available_menus', array('main-menu'))->save(); + //$this->config('menu.entity.node.' . $node->getType())->set('available_menus', ['main-menu'])->save(); // Add a node menu link. /** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $node_link */ - $node_link = entity_create('menu_link_content', array( - 'link' => ['uri' =>'entity:node/' . $node->id()], + $node_link = MenuLinkContent::create([ + 'link' => ['uri' => 'entity:node/' . $node->id()], 'title' => 'Node link', 'parent' => $parent_link->getPluginId(), 'menu_name' => 'main-menu', - )); + ]); $node_link->save(); // Test [node:menu] tokens. - $tokens = array( + $tokens = [ 'menu-link' => 'Node link', 'menu-link:id' => $node_link->getPluginId(), 'menu-link:title' => 'Node link', 'menu-link:menu' => 'Main menu', - 'menu-link:url' => $node->url('canonical', ['absolute' => TRUE]), + 'menu-link:url' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(), 'menu-link:url:path' => '/node/' . $node->id(), 'menu-link:edit-url' => $node_link->url('edit-form', ['absolute' => TRUE]), 'menu-link:parent' => 'Configuration', @@ -127,12 +127,12 @@ function testMenuTokens() { 'menu-link:parents:keys' => $root_link->getPluginId() . ', ' . $parent_link->getPluginId(), 'menu-link:root' => 'Administration', 'menu-link:root:id' => $root_link->getPluginId(), - ); - $this->assertTokens('node', array('node' => $node), $tokens); + ]; + $this->assertTokens('node', ['node' => $node], $tokens); // Reload the node which will not have $node->menu defined and re-test. $loaded_node = Node::load($node->id()); - $this->assertTokens('node', array('node' => $loaded_node), $tokens); + $this->assertTokens('node', ['node' => $loaded_node], $tokens); // Regression test for http://drupal.org/node/1317926 to ensure the // original node object is not changed when calling menu_node_prepare(). @@ -148,11 +148,11 @@ function testMenuTokens() { 'access administration pages', ])); // Setup node type menu options. - $edit = array( + $edit = [ 'menu_options[main-menu]' => 1, 'menu_options[main]' => 1, 'menu_parent' => 'main-menu:', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); // Use a menu-link token in the body. @@ -164,7 +164,7 @@ function testMenuTokens() { 'body[0][value]' => 'This is a [node:menu-link:title] token to the menu link title', 'menu[enabled]' => 1, 'menu[title]' => 'Test preview', - ], t('Save and publish')); + ], t('Save')); $node = $this->drupalGetNodeByTitle('Node menu title test'); $this->assertEqual('This is a Test preview token to the menu link title', $node->body->value); @@ -173,7 +173,7 @@ function testMenuTokens() { $link = menu_ui_get_menu_link_defaults($node); $this->drupalPostForm('admin/structure/menu/manage/main-menu', ['links[menu_plugin_id:' . $link['id'] . '][enabled]' => FALSE], t('Save')); $this->assertText('Menu Main menu has been updated.'); - $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published')); + $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save')); $this->assertNoLink('Test preview'); // Now test a parent link and token. @@ -186,7 +186,7 @@ function testMenuTokens() { $select = reset($selects); $options = $this->getAllOptions($select); // Filter to items with title containing 'Test preview'. - $options = array_filter($options, function(\SimpleXMLElement $item) { + $options = array_filter($options, function (\SimpleXMLElement $item) { return strpos((string) $item[0], 'Test preview') !== FALSE; }); $this->assertEqual(1, count($options)); @@ -195,17 +195,17 @@ function testMenuTokens() { 'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent', 'menu[enabled]' => 1, 'menu[title]' => 'Child link', - 'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(), - ], t('Save and publish')); + 'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(), + ], t('Save')); $node = $this->drupalGetNodeByTitle('Node menu title parent path test'); $this->assertEqual('This is a /admin/config token to the menu link parent', $node->body->value); // Now edit the node and update the parent and title. $this->drupalPostForm('node/' . $node->id() . '/edit', [ - 'menu[menu_parent]' => 'main-menu:' . $node_link->getPluginId(), + 'menu[menu_parent]' => 'main-menu:' . $node_link->getPluginId(), 'title[0][value]' => 'Node menu title edit parent path test', 'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent', - ], t('Save and keep published')); + ], t('Save')); $node = $this->drupalGetNodeByTitle('Node menu title edit parent path test', TRUE); $this->assertEqual(sprintf('This is a /node/%d token to the menu link parent', $loaded_node->id()), $node->body->value); @@ -218,7 +218,7 @@ function testMenuTokens() { $select = reset($selects); $options = $this->getAllOptions($select); // Filter to items with title containing 'Test preview'. - $options = array_filter($options, function(\SimpleXMLElement $item) { + $options = array_filter($options, function (\SimpleXMLElement $item) { return strpos((string) $item[0], 'Child link') !== FALSE; }); $this->assertEqual(1, count($options)); @@ -229,7 +229,7 @@ function testMenuTokens() { 'title[0][value]' => 'Node menu adding menu later test', 'body[0][value]' => 'Going to add a menu link on edit', 'menu[enabled]' => 0, - ], t('Save and publish')); + ], t('Save')); $node = $this->drupalGetNodeByTitle('Node menu adding menu later test'); // Now edit it and add a menu item. $this->drupalGet('node/' . $node->id() . '/edit'); @@ -238,8 +238,8 @@ function testMenuTokens() { 'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent', 'menu[enabled]' => 1, 'menu[title]' => 'Child link', - 'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(), - ], t('Save and keep published')); + 'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(), + ], t('Save')); $node = $this->drupalGetNodeByTitle('Node menu adding menu later test', TRUE); $this->assertEqual('This is a /admin/config token to the menu link parent', $node->body->value); // And make sure the menu link exists with the right URI. @@ -260,18 +260,18 @@ function testMenuTokens() { 'menu[enabled]' => 1, 'menu[title]' => 'menu link provided by node', ]; - $this->drupalPostForm('node/add/page', $edit, t('Save and publish')); + $this->drupalPostForm('node/add/page', $edit, t('Save')); $this->assertText('page ' . $node_title . ' has been created'); $node = $this->drupalGetNodeByTitle($node_title); - $menu_ui_link1 = entity_create('menu_link_content', [ + $menu_ui_link1 = MenuLinkContent::create([ 'link' => ['uri' => 'entity:node/' . $node->id()], 'title' => 'menu link 1 provided by menu ui', 'menu_name' => 'main-menu', ]); $menu_ui_link1->save(); - $menu_ui_link2 = entity_create('menu_link_content', [ + $menu_ui_link2 = MenuLinkContent::create([ 'link' => ['uri' => 'entity:node/' . $node->id()], 'title' => 'menu link 2 provided by menu ui', 'menu_name' => 'main-menu', @@ -306,7 +306,7 @@ function testMultilingualMenu() { ]); $node_type->save(); - $permissions = array( + $permissions = [ 'access administration pages', 'administer content translation', 'administer content types', @@ -316,18 +316,18 @@ function testMultilingualMenu() { 'edit any article content', 'translate any entity', 'administer menu', - ); + ]; $this->drupalLogin($this->drupalCreateUser($permissions)); // Enable translation for articles and menu links. $this->drupalGet('admin/config/regional/content-language'); - $edit = array( + $edit = [ 'entity_types[node]' => TRUE, 'entity_types[menu_link_content]' => TRUE, 'settings[node][article][translatable]' => TRUE, 'settings[node][article][fields][title]' => TRUE, 'settings[menu_link_content][menu_link_content][translatable]' => TRUE, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save configuration')); $this->assertText('Settings successfully updated.'); @@ -411,10 +411,10 @@ public function testMenuLinkParentsToken() { // - parent // - child-1 // - child-1-1 - Menu::create(array( + Menu::create([ 'id' => 'menu_test', 'label' => 'Test menu', - ))->save(); + ])->save(); $base_options = [ 'provider' => 'menu_test', 'menu_name' => 'menu_test', diff --git a/web/modules/token/src/Tests/TokenTestBase.php b/web/modules/token/src/Tests/TokenTestBase.php index 29c1ac3cdc1431688b423e820f200805189e1593..814ba776ff1bbc6d2e7b3eccd4b723c2b03d57f6 100644 --- a/web/modules/token/src/Tests/TokenTestBase.php +++ b/web/modules/token/src/Tests/TokenTestBase.php @@ -16,6 +16,6 @@ abstract class TokenTestBase extends WebTestBase { * * @var array */ - public static $modules = array('path', 'token', 'token_module_test'); + public static $modules = ['path', 'token', 'token_module_test']; } diff --git a/web/modules/token/src/Tests/TokenTestTrait.php b/web/modules/token/src/Tests/TokenTestTrait.php index b37cae9507feb2c85237b7963b719e541abdce78..471527459bed50d3ff3d862f89878223aa4b8d23 100644 --- a/web/modules/token/src/Tests/TokenTestTrait.php +++ b/web/modules/token/src/Tests/TokenTestTrait.php @@ -11,57 +11,57 @@ */ trait TokenTestTrait { - function assertToken($type, array $data, $token, $expected, array $options = array()) { - return $this->assertTokens($type, $data, array($token => $expected), $options); + function assertToken($type, array $data, $token, $expected, array $options = []) { + return $this->assertTokens($type, $data, [$token => $expected], $options); } - function assertTokens($type, array $data, array $tokens, array $options = array()) { + function assertTokens($type, array $data, array $tokens, array $options = []) { $input = $this->mapTokenNames($type, array_keys($tokens)); $bubbleable_metadata = new BubbleableMetadata(); $replacements = \Drupal::token()->generate($type, $input, $data, $options, $bubbleable_metadata); foreach ($tokens as $name => $expected) { $token = $input[$name]; if (!isset($expected)) { - $this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token))); + $this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token])); } elseif (!isset($replacements[$token])) { - $this->fail(t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token))); + $this->fail(t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token])); } elseif (!empty($options['regex'])) { - $this->assertTrue(preg_match('/^' . $expected . '$/', $replacements[$token]), t("Token value for @token was '@actual', matching regular expression pattern '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected))); + $this->assertTrue(preg_match('/^' . $expected . '$/', $replacements[$token]), t("Token value for @token was '@actual', matching regular expression pattern '@expected'.", ['@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected])); } else { - $this->assertEqual($replacements[$token], $expected, t("Token value for @token was '@actual', expected value '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected))); + $this->assertEqual($replacements[$token], $expected, t("Token value for @token was '@actual', expected value '@expected'.", ['@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected])); } } return $replacements; } - function mapTokenNames($type, array $tokens = array()) { - $return = array(); + function mapTokenNames($type, array $tokens = []) { + $return = []; foreach ($tokens as $token) { $return[$token] = "[$type:$token]"; } return $return; } - function assertNoTokens($type, array $data, array $tokens, array $options = array()) { + function assertNoTokens($type, array $data, array $tokens, array $options = []) { $input = $this->mapTokenNames($type, $tokens); $bubbleable_metadata = new BubbleableMetadata(); $replacements = \Drupal::token()->generate($type, $input, $data, $options, $bubbleable_metadata); foreach ($tokens as $name) { $token = $input[$name]; - $this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token))); + $this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token])); } } function saveAlias($source, $alias, $language = Language::LANGCODE_NOT_SPECIFIED) { - $alias = array( + $alias = [ 'source' => $source, 'alias' => $alias, 'language' => $language, - ); + ]; \Drupal::service('path.alias_storage')->save($alias['source'], $alias['alias']); return $alias; } @@ -74,22 +74,22 @@ function saveEntityAlias($entity_type, EntityInterface $entity, $alias, $languag /** * Make a page request and test for token generation. */ - function assertPageTokens($url, array $tokens, array $data = array(), array $options = array()) { + function assertPageTokens($url, array $tokens, array $data = [], array $options = []) { if (empty($tokens)) { return TRUE; } - $token_page_tokens = array( + $token_page_tokens = [ 'tokens' => $tokens, 'data' => $data, 'options' => $options, - ); + ]; \Drupal::state()->set('token_page_tokens', $token_page_tokens); - $options += array('url_options' => array()); + $options += ['url_options' => []]; $this->drupalGet($url, $options['url_options']); $this->refreshVariables(); - $result = \Drupal::state()->get('token_page_tokens', array()); + $result = \Drupal::state()->get('token_page_tokens', []); if (!isset($result['values']) || !is_array($result['values'])) { return $this->fail('Failed to generate tokens.'); @@ -97,13 +97,13 @@ function assertPageTokens($url, array $tokens, array $data = array(), array $opt foreach ($tokens as $token => $expected) { if (!isset($expected)) { - $this->assertTrue(!isset($result['values'][$token]) || $result['values'][$token] === $token, t("Token value for @token was not generated.", array('@token' => $token))); + $this->assertTrue(!isset($result['values'][$token]) || $result['values'][$token] === $token, t("Token value for @token was not generated.", ['@token' => $token])); } elseif (!isset($result['values'][$token])) { - $this->fail(t('Failed to generate token @token.', array('@token' => $token))); + $this->fail(t('Failed to generate token @token.', ['@token' => $token])); } else { - $this->assertIdentical($result['values'][$token], (string) $expected, t("Token value for @token was '@actual', expected value '@expected'.", array('@token' => $token, '@actual' => $result['values'][$token], '@expected' => $expected))); + $this->assertIdentical($result['values'][$token], (string) $expected, t("Token value for @token was '@actual', expected value '@expected'.", ['@token' => $token, '@actual' => $result['values'][$token], '@expected' => $expected])); } } } diff --git a/web/modules/token/src/Tests/TokenURLTest.php b/web/modules/token/src/Tests/TokenURLTest.php index 6241f3b6980019e4d40455f6efe7096b0cd42aa8..0a3bed0fcd9276c5f595312d7b617452cf912e18 100644 --- a/web/modules/token/src/Tests/TokenURLTest.php +++ b/web/modules/token/src/Tests/TokenURLTest.php @@ -16,7 +16,7 @@ class TokenURLTest extends TokenTestBase { * * @var array */ - public static $modules = array('node'); + public static $modules = ['node']; /** * {@inheritdoc} @@ -27,25 +27,25 @@ public function setUp() { } function testURLTokens() { - $url = new Url('entity.node.canonical', array('node' => 1)); - $tokens = array( + $url = new Url('entity.node.canonical', ['node' => 1]); + $tokens = [ 'absolute' => $url->setAbsolute()->toString(), 'relative' => $url->setAbsolute(FALSE)->toString(), 'path' => '/first-node', - 'brief' => preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->toString()), + 'brief' => preg_replace(['!^https?://!', '!/$!'], '', $url->setAbsolute()->toString()), 'args:value:0' => 'first-node', 'args:value:1' => NULL, 'args:value:N' => NULL, 'unaliased' => $url->setAbsolute()->setOption('alias', TRUE)->toString(), 'unaliased:relative' => $url->setAbsolute(FALSE)->setOption('alias', TRUE)->toString(), 'unaliased:path' => '/node/1', - 'unaliased:brief' => preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->setOption('alias', TRUE)->toString()), + 'unaliased:brief' => preg_replace(['!^https?://!', '!/$!'], '', $url->setAbsolute()->setOption('alias', TRUE)->toString()), 'unaliased:args:value:0' => 'node', 'unaliased:args:value:1' => '1', 'unaliased:args:value:2' => NULL, // Deprecated tokens. 'alias' => '/first-node', - ); - $this->assertTokens('url', array('url' => new Url('entity.node.canonical', array('node' => 1))), $tokens); + ]; + $this->assertTokens('url', ['url' => new Url('entity.node.canonical', ['node' => 1])], $tokens); } } diff --git a/web/modules/token/src/Tests/TokenUserTest.php b/web/modules/token/src/Tests/TokenUserTest.php index 2178c7e64a30e02dc82c3a1567e50d2bf9b0cade..cb320347046fb0c151b290d16385150f8b3bd0b0 100644 --- a/web/modules/token/src/Tests/TokenUserTest.php +++ b/web/modules/token/src/Tests/TokenUserTest.php @@ -2,6 +2,7 @@ namespace Drupal\token\Tests; +use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AnonymousUserSession; use Drupal\field\Entity\FieldStorageConfig; @@ -24,7 +25,7 @@ class TokenUserTest extends TokenTestBase { * * @var array */ - public static $modules = array('token_user_picture'); + public static $modules = ['token_user_picture']; /** * {@inheritdoc} @@ -32,10 +33,17 @@ class TokenUserTest extends TokenTestBase { public function setUp() { parent::setUp(); - $this->account = $this->drupalCreateUser(['administer users', 'administer account settings']); + $this->account = $this->drupalCreateUser([ + 'administer users', + 'administer account settings', + 'access content', + ]); $this->drupalLogin($this->account); } + /** + * Tests the user releated tokens. + */ public function testUserTokens() { // Enable user pictures. \Drupal::state()->set('user_pictures', 1); @@ -49,7 +57,7 @@ public function testUserTokens() { // Add a user picture to the account. $image = current($this->drupalGetTestFiles('image')); - $edit = array('files[user_picture_0]' => drupal_realpath($image->uri)); + $edit = ['files[user_picture_0]' => \Drupal::service('file_system')->realpath($image->uri)]; $this->drupalPostForm('user/' . $this->account->id() . '/edit', $edit, t('Save')); $storage = \Drupal::entityTypeManager()->getStorage('user'); @@ -65,14 +73,14 @@ public function testUserTokens() { ]; /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = \Drupal::service('renderer'); - $user_tokens = array( + $user_tokens = [ 'picture' => $renderer->renderPlain($picture), 'picture:fid' => $this->account->user_picture->target_id, 'picture:size-raw' => 125, 'ip-address' => NULL, 'roles' => implode(', ', $this->account->getRoles()), - ); - $this->assertTokens('user', array('user' => $this->account), $user_tokens); + ]; + $this->assertTokens('user', ['user' => $this->account], $user_tokens); // Remove the simpletest-created user role. $roles = $this->account->getRoles(); @@ -84,33 +92,36 @@ public function testUserTokens() { $storage->resetCache(); $this->account = $storage->load($this->account->id()); - $user_tokens = array( + $user_tokens = [ 'picture' => NULL, 'picture:fid' => NULL, 'ip-address' => NULL, 'roles' => 'authenticated', - 'roles:keys' => (string) DRUPAL_AUTHENTICATED_RID, - ); - $this->assertTokens('user', array('user' => $this->account), $user_tokens); + 'roles:keys' => AccountInterface::AUTHENTICATED_ROLE, + ]; + $this->assertTokens('user', ['user' => $this->account], $user_tokens); // The ip address token should work for the current user token type. - $tokens = array( + $tokens = [ 'ip-address' => \Drupal::request()->getClientIp(), - ); - $this->assertTokens('current-user', array(), $tokens); + ]; + $this->assertTokens('current-user', [], $tokens); $anonymous = new AnonymousUserSession(); - $tokens = array( + $tokens = [ 'roles' => 'anonymous', - 'roles:keys' => (string) DRUPAL_ANONYMOUS_RID, - ); - $this->assertTokens('user', array('user' => $anonymous), $tokens); + 'roles:keys' => AccountInterface::ANONYMOUS_ROLE, + ]; + $this->assertTokens('user', ['user' => $anonymous], $tokens); } + /** + * Test user account settings. + */ public function testUserAccountSettings() { $this->drupalGet('admin/config/people/accounts'); $this->assertText('The list of available tokens that can be used in e-mails is provided below.'); $this->assertLink('Browse available tokens.'); $this->assertLinkByHref('token/tree'); } -} \ No newline at end of file +} diff --git a/web/modules/token/src/Tests/Tree/TreeTest.php b/web/modules/token/src/Tests/Tree/TreeTest.php index ed1dd3cad4a856358c29986adf8da0af6095e1f3..7c72434765c6bdd97769503869ab50430a896154 100644 --- a/web/modules/token/src/Tests/Tree/TreeTest.php +++ b/web/modules/token/src/Tests/Tree/TreeTest.php @@ -137,7 +137,7 @@ public function testNodeTokens() { protected function getTokenTreeUrl($options = []) { $this->drupalGet('token_module_test/browse'); $this->assertTitle('Available Tokens | Drupal'); - $links = $this->xpath('//a[contains(@href, :href)]/@href', array(':href' => 'token/tree')); + $links = $this->xpath('//a[contains(@href, :href)]/@href', [':href' => 'token/tree']); $link = $this->getAbsoluteUrl((string) current($links)); if (!empty($options)) { $options = Json::encode($options); diff --git a/web/modules/token/src/Token.php b/web/modules/token/src/Token.php index 360ae351c059c0142053d6133585b1ce0147a826..b75af5ab2a4f71e9b29ece0035490275ce4438d5 100644 --- a/web/modules/token/src/Token.php +++ b/web/modules/token/src/Token.php @@ -65,9 +65,9 @@ public function getInfo() { } $this->tokenInfo = $token_info; - $this->cache->set($cache_id, $this->tokenInfo, CacheBackendInterface::CACHE_PERMANENT, array( + $this->cache->set($cache_id, $this->tokenInfo, CacheBackendInterface::CACHE_PERMANENT, [ static::TOKEN_INFO_CACHE_TAG, - )); + ]); } } @@ -136,7 +136,7 @@ public function getGlobalTokenTypes() { */ function getInvalidTokens($type, $tokens) { $token_info = $this->getInfo(); - $invalid_tokens = array(); + $invalid_tokens = []; foreach ($tokens as $token => $full_token) { if (isset($token_info['tokens'][$type][$token])) { @@ -162,7 +162,7 @@ function getInvalidTokens($type, $tokens) { } else { // Recursively check the chained tokens. - $sub_tokens = $this->findWithPrefix(array($token => $full_token), $parts[0]); + $sub_tokens = $this->findWithPrefix([$token => $full_token], $parts[0]); $invalid_tokens = array_merge($invalid_tokens, $this->getInvalidTokens($sub_token_info['type'], $sub_tokens)); } } @@ -184,7 +184,7 @@ public function getInvalidTokensByContext($value, array $valid_types = []) { $valid_types = array_merge($valid_types, $this->getGlobalTokenTypes()); } - $invalid_tokens = array(); + $invalid_tokens = []; $value_tokens = is_string($value) ? $this->scan($value) : $value; foreach ($value_tokens as $type => $tokens) { diff --git a/web/modules/token/src/TreeBuilder.php b/web/modules/token/src/TreeBuilder.php index 80ebca2355655b0152b6760ac497949469d97f2d..8e58ba33076acff439259f65d936372581aaa413 100644 --- a/web/modules/token/src/TreeBuilder.php +++ b/web/modules/token/src/TreeBuilder.php @@ -61,12 +61,12 @@ public function buildRenderable(array $token_types, array $options = []) { $token_types = array_merge($token_types, $this->tokenService->getGlobalTokenTypes()); } - $element = array( - /*'#cache' => array( - 'cid' => 'tree-rendered:' . hash('sha256', serialize(array('token_types' => $token_types, 'global_types' => NULL) + $variables)), - 'tags' => array(Token::TOKEN_INFO_CACHE_TAG), - ),*/ - ); + $element = [ + /*'#cache' => [ + 'cid' => 'tree-rendered:' . hash('sha256', serialize(['token_types' => $token_types, 'global_types' => NULL] + $variables)), + 'tags' => [Token::TOKEN_INFO_CACHE_TAG], + ],*/ + ]; // @todo Find a way to use the render cache for this. /*if ($cached_output = token_render_cache_get($element)) { diff --git a/web/modules/token/tests/modules/token_module_test/test_views/views.view.token_views_test.yml b/web/modules/token/tests/modules/token_module_test/test_views/views.view.token_views_test.yml new file mode 100644 index 0000000000000000000000000000000000000000..eeb150b0d5607548f16f93642f2fa9ada71afa78 --- /dev/null +++ b/web/modules/token/tests/modules/token_module_test/test_views/views.view.token_views_test.yml @@ -0,0 +1,130 @@ +langcode: en +status: true +dependencies: + module: + - user +id: token_views_test +label: token_views_test +module: views +description: '' +tag: '' +base_table: users_field_data +base_field: uid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: none + options: { } + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: some + options: + items_per_page: 5 + offset: 0 + style: + type: default + row: + type: fields + options: + default_field_elements: true + inline: { } + separator: '' + hide_empty: false + fields: + name: + id: name + table: users_field_data + field: name + entity_type: user + entity_field: name + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + plugin_id: field + relationship: none + group_type: group + admin_label: '' + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + click_sort_column: value + type: user_name + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + filters: { } + sorts: { } + title: token_views_test + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + filter_groups: + operator: AND + groups: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + tags: { } + block_1: + display_plugin: block + id: block_1 + display_title: Block + position: 1 + display_options: + display_extenders: { } diff --git a/web/modules/token/tests/modules/token_module_test/token_module_test.info.yml b/web/modules/token/tests/modules/token_module_test/token_module_test.info.yml index 342ef6c92250391286321240bd4a85a69b5fbbb2..037918b02633b333cbb05456eecf49cacc0eb669 100644 --- a/web/modules/token/tests/modules/token_module_test/token_module_test.info.yml +++ b/web/modules/token/tests/modules/token_module_test/token_module_test.info.yml @@ -5,8 +5,8 @@ package: Testing # core: 8.x hidden: TRUE -# Information added by Drupal.org packaging script on 2017-04-29 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-09-21 +version: '8.x-1.5' core: '8.x' project: 'token' -datestamp: 1493466847 +datestamp: 1537557488 diff --git a/web/modules/token/tests/modules/token_module_test/token_module_test.module b/web/modules/token/tests/modules/token_module_test/token_module_test.module index c26332075989730216dabef5f4696f63b0ab63db..c022b6575c9efb5034e44452063d9400d692fd55 100644 --- a/web/modules/token/tests/modules/token_module_test/token_module_test.module +++ b/web/modules/token/tests/modules/token_module_test/token_module_test.module @@ -4,14 +4,15 @@ * @file * Helper module for token tests. */ + use Drupal\node\NodeInterface; /** * Implements hook_page_attachments(). */ function token_module_test_page_attachments() { - if ($debug = \Drupal::state()->get('token_page_tokens', array())) { - $debug += array('tokens' => array(), 'data' => array(), 'options' => array()); + if ($debug = \Drupal::state()->get('token_page_tokens', [])) { + $debug += ['tokens' => [], 'data' => [], 'options' => []]; foreach (array_keys($debug['tokens']) as $token) { $debug['values'][$token] = \Drupal::token()->replace($token, $debug['data'], $debug['options']); } diff --git a/web/modules/token/tests/modules/token_module_test/token_module_test.tokens.inc b/web/modules/token/tests/modules/token_module_test/token_module_test.tokens.inc index ba8da53449f19ba09e1250282ae9ef65c95f2766..3adf457818af422d7fe843b4caae013e87ea1c15 100644 --- a/web/modules/token/tests/modules/token_module_test/token_module_test.tokens.inc +++ b/web/modules/token/tests/modules/token_module_test/token_module_test.tokens.inc @@ -4,10 +4,10 @@ * Implements hook_token_info() */ function token_module_test_token_info() { - $info['tokens']['node']['colons:in:name'] = array( + $info['tokens']['node']['colons:in:name'] = [ 'name' => t('A test token with colons in the name'), 'description' => NULL, - ); + ]; return $info; } diff --git a/web/modules/token/tests/modules/token_user_picture/token_user_picture.info.yml b/web/modules/token/tests/modules/token_user_picture/token_user_picture.info.yml index 4f8b9902693e6a8b02262b7822905f1bc5d91782..131f850284b8334e2dddd740d2380fec08c96c08 100644 --- a/web/modules/token/tests/modules/token_user_picture/token_user_picture.info.yml +++ b/web/modules/token/tests/modules/token_user_picture/token_user_picture.info.yml @@ -7,8 +7,8 @@ hidden: TRUE dependencies: - image -# Information added by Drupal.org packaging script on 2017-04-29 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-09-21 +version: '8.x-1.5' core: '8.x' project: 'token' -datestamp: 1493466847 +datestamp: 1537557488 diff --git a/web/modules/token/tests/src/Functional/UrlTest.php b/web/modules/token/tests/src/Functional/UrlTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0ae2788d866d473430e6adc25a9af31e0fc40b56 --- /dev/null +++ b/web/modules/token/tests/src/Functional/UrlTest.php @@ -0,0 +1,137 @@ +<?php + +namespace Drupal\Tests\token\Functional; + +use Drupal\block\Entity\Block; +use Drupal\node\Entity\Node; +use Drupal\node\Entity\NodeType; +use Drupal\Tests\BrowserTestBase; +use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait; + +/** + * Tests URL tokens. + * + * @group token + */ +class UrlTest extends BrowserTestBase { + + use AssertPageCacheContextsAndTagsTrait; + + /** + * The first testing node. + * + * @var \Drupal\node\NodeInterface + */ + protected $node1; + + /** + * The second testing node. + * + * @var \Drupal\node\NodeInterface + */ + protected $node2; + + /** + * Modules to install. + * + * @var string[] + */ + public static $modules = ['node', 'token', 'block']; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $node_type = NodeType::create(['type' => 'article', 'name' => 'Article']); + $node_type->save(); + + $this->node1 = Node::create([ + 'type' => 'article', + 'title' => 'Test Node 1', + ]); + $this->node1->save(); + + $this->node2 = Node::create([ + 'type' => 'article', + 'title' => 'Test Node 2', + ]); + $this->node2->save(); + + } + + /** + * Creates a block with token for title and tests cache contexts. + * + * @throws \Behat\Mink\Exception\ElementHtmlException + * @throws \Drupal\Core\Entity\EntityStorageException + */ + public function testBlockUrlTokenReplacement() { + + $node1_url = $this->node1->toUrl(); + $node2_url = $this->node2->toUrl(); + + // Using a @dataprovider causes repeated database installations and takes a + // very long time. + $tests = []; + $tests[] = [ + 'token' => 'prefix_[current-page:url:path]_suffix', + 'expected1' => 'prefix_/' . $node1_url->getInternalPath() . '_suffix', + 'expected2' => 'prefix_/' . $node2_url->getInternalPath() . '_suffix', + // A path can only be generated from a routed path. + 'expected3' => 'prefix_/_suffix', + ]; + $tests[] = [ + 'token' => 'prefix_[current-page:url]_suffix', + 'expected1' => 'prefix_' . $node1_url->setAbsolute()->toString() . '_suffix', + 'expected2' => 'prefix_' . $node2_url->setAbsolute()->toString() . '_suffix', + 'expected3' => 'prefix_' . $this->getAbsoluteUrl('does-not-exist') . '_suffix', + ]; + + // Place a standard block and use a token in the label. + $edit = [ + 'id' => 'token_url_test_block', + 'label' => 'label', + 'label_display' => TRUE, + ]; + $this->placeBlock('system_powered_by_block', $edit); + $block = Block::load('token_url_test_block'); + + $assert_session = $this->assertSession(); + + foreach ($tests as $test) { + // Set the block label. + $block->getPlugin()->setConfigurationValue('label', $test['token']); + $block->save(); + + // Go to the first node page and test that the token is correct. + $this->drupalGet($node1_url); + $assert_session->elementContains('css', '#block-token-url-test-block', $test['expected1']); + + // Go to the second node page and check that the block title has changed. + $this->drupalGet($node2_url); + $assert_session->elementContains('css', '#block-token-url-test-block', $test['expected2']); + + // Test the current page url on a 404 page. + $this->drupalGet('does-not-exist'); + $assert_session->statusCodeEquals(404); + $assert_session->elementContains('css', '#block-token-url-test-block', $test['expected3']); + } + + + // Can't do this test in the for loop above, it's too different. + $block->getPlugin()->setConfigurationValue('label', 'prefix_[current-page:query:unicorns]_suffix'); + $block->save(); + + // Test the parameter token. + $this->drupalGet($node1_url->setOption('query', ['unicorns' => 'fluffy'])); + $this->assertCacheContext('url.query_args'); + $assert_session->elementContains('css', '#block-token-url-test-block', 'prefix_fluffy_suffix'); + + // Change the parameter on the same page. + $this->drupalGet($node1_url->setOption('query', ['unicorns' => 'dead'])); + $assert_session->elementContains('css', '#block-token-url-test-block', 'prefix_dead_suffix'); + } + +} diff --git a/web/modules/token/tests/src/Kernel/ArrayTest.php b/web/modules/token/tests/src/Kernel/ArrayTest.php index a7f83ae4dded65e42736fd339fee8bc338d9f824..d484835b561bcadbecb04c94b4b49afae8a1640b 100644 --- a/web/modules/token/tests/src/Kernel/ArrayTest.php +++ b/web/modules/token/tests/src/Kernel/ArrayTest.php @@ -11,8 +11,8 @@ class ArrayTest extends KernelTestBase { function testArrayTokens() { // Test a simple array. - $array = array(0 => 'a', 1 => 'b', 2 => 'c', 4 => 'd'); - $tokens = array( + $array = [0 => 'a', 1 => 'b', 2 => 'c', 4 => 'd']; + $tokens = [ 'first' => 'a', 'last' => 'd', 'value:0' => 'a', @@ -27,19 +27,19 @@ function testArrayTokens() { 'join' => 'abcd', 'join:, ' => 'a, b, c, d', 'join: ' => 'a b c d', - ); - $this->assertTokens('array', array('array' => $array), $tokens); + ]; + $this->assertTokens('array', ['array' => $array], $tokens); // Test a mixed simple and render array. // 2 => c, 0 => a, 4 => d, 1 => b - $array = array( + $array = [ '#property' => 'value', 0 => 'a', - 1 => array('#markup' => 'b', '#weight' => 0.01), - 2 => array('#markup' => 'c', '#weight' => -10), - 4 => array('#markup' => 'd', '#weight' => 0), - ); - $tokens = array( + 1 => ['#markup' => 'b', '#weight' => 0.01], + 2 => ['#markup' => 'c', '#weight' => -10], + 4 => ['#markup' => 'd', '#weight' => 0], + ]; + $tokens = [ 'first' => 'c', 'last' => 'b', 'value:0' => 'a', @@ -54,7 +54,8 @@ function testArrayTokens() { 'join' => 'cadb', 'join:, ' => 'c, a, d, b', 'join: ' => 'c a d b', - ); - $this->assertTokens('array', array('array' => $array), $tokens); + ]; + $this->assertTokens('array', ['array' => $array], $tokens); } + } diff --git a/web/modules/token/tests/src/Kernel/BookTest.php b/web/modules/token/tests/src/Kernel/BookTest.php index 67a13eecd65f9dd83fdebbbcefbcce88c71964fd..215fdb54e27f352d81fbc939c7cf4fd32b6308aa 100644 --- a/web/modules/token/tests/src/Kernel/BookTest.php +++ b/web/modules/token/tests/src/Kernel/BookTest.php @@ -27,9 +27,9 @@ protected function setUp() { $this->installEntitySchema('user'); $this->installEntitySchema('node'); - $this->installSchema('book', array('book')); - $this->installSchema('node', array('node_access')); - $this->installConfig(array('node', 'book', 'field')); + $this->installSchema('book', ['book']); + $this->installSchema('node', ['node_access']); + $this->installConfig(['node', 'book', 'field']); } function testBookTokens() { @@ -63,12 +63,12 @@ function testBookTokens() { 'book:root' => $book_title, 'book:root:nid' => $book->id(), 'book:root:title' => $book_title, - 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(), + 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(), 'book:root:content-type' => 'Book page', 'book:parent' => null, 'book:parents' => null, ]; - $this->assertTokens('node', array('node' => $book), $tokens); + $this->assertTokens('node', ['node' => $book], $tokens); $tokens = [ 'nid' => $page1->id(), @@ -77,15 +77,15 @@ function testBookTokens() { 'book:root' => $book_title, 'book:root:nid' => $book->id(), 'book:root:title' => $book_title, - 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(), + 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(), 'book:root:content-type' => 'Book page', 'book:parent:nid' => $book->id(), 'book:parent:title' => $book_title, - 'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(), + 'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(), 'book:parents:count' => 1, 'book:parents:join:/' => $book_title, ]; - $this->assertTokens('node', array('node' => $page1), $tokens); + $this->assertTokens('node', ['node' => $page1], $tokens); $tokens = [ 'nid' => $page2->id(), @@ -94,14 +94,15 @@ function testBookTokens() { 'book:root' => $book_title, 'book:root:nid' => $book->id(), 'book:root:title' => $book_title, - 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(), + 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(), 'book:root:content-type' => 'Book page', 'book:parent:nid' => $page1->id(), 'book:parent:title' => $page1->getTitle(), - 'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $page1->id()], array('absolute' => TRUE))->toString(), + 'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $page1->id()], ['absolute' => TRUE])->toString(), 'book:parents:count' => 2, 'book:parents:join:/' => $book_title . '/' . $page1->getTitle(), ]; - $this->assertTokens('node', array('node' => $page2), $tokens); + $this->assertTokens('node', ['node' => $page2], $tokens); } + } diff --git a/web/modules/token/tests/src/Kernel/CommentTest.php b/web/modules/token/tests/src/Kernel/CommentTest.php index 499f087c39f4efc26f162521f3bac8aabdf186ab..63232c11fb4de9eb62ab7003b8576d755c0e6d25 100644 --- a/web/modules/token/tests/src/Kernel/CommentTest.php +++ b/web/modules/token/tests/src/Kernel/CommentTest.php @@ -64,21 +64,20 @@ function testCommentTokens() { // Fix http://example.com/index.php/comment/1 fails 'url:path' test. $parent_comment_path = $parent_comment->url(); - $tokens = array( - 'url' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(), - 'url:absolute' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(), - 'url:relative' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->toString(), + $tokens = [ + 'url' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(), + 'url:absolute' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(), + 'url:relative' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->toString(), 'url:path' => $parent_comment_path, 'parent:url:absolute' => NULL, - ); - $this->assertTokens('comment', array('comment' => $parent_comment), $tokens); + ]; + $this->assertTokens('comment', ['comment' => $parent_comment], $tokens); $comment = Comment::create([ 'entity_id' => $node->id(), 'pid' => $parent_comment->id(), 'entity_type' => 'node', 'field_name' => 'comment', - 'uid' => 1, 'name' => 'anonymous user', 'mail' => 'anonymous@example.com', 'subject' => $this->randomMachineName(), @@ -87,16 +86,16 @@ function testCommentTokens() { $comment->save(); // Fix http://example.com/index.php/comment/1 fails 'url:path' test. - $comment_path = Url::fromRoute('entity.comment.canonical', array('comment' => $comment->id()))->toString(); + $comment_path = Url::fromRoute('entity.comment.canonical', ['comment' => $comment->id()])->toString(); - $tokens = array( - 'url' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(), - 'url:absolute' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(), - 'url:relative' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->toString(), + $tokens = [ + 'url' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(), + 'url:absolute' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(), + 'url:relative' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->toString(), 'url:path' => $comment_path, - 'parent:url:absolute' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(), - ); - $this->assertTokens('comment', array('comment' => $comment), $tokens); + 'parent:url:absolute' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(), + ]; + $this->assertTokens('comment', ['comment' => $comment], $tokens); } } diff --git a/web/modules/token/tests/src/Kernel/DateTest.php b/web/modules/token/tests/src/Kernel/DateTest.php index c25bf030da3a720f22294cac9736a6c2ccf62a40..c120e1109eb298725ec1335aa04a64489a273b46 100644 --- a/web/modules/token/tests/src/Kernel/DateTest.php +++ b/web/modules/token/tests/src/Kernel/DateTest.php @@ -25,11 +25,12 @@ protected function setUp() { } function testDateTokens() { - $tokens = array( + $tokens = [ 'token_module_test' => '1984', 'invalid_format' => NULL, - ); + ]; - $this->assertTokens('date', array('date' => 453859200), $tokens); + $this->assertTokens('date', ['date' => 453859200], $tokens); } + } diff --git a/web/modules/token/tests/src/Kernel/EntityTest.php b/web/modules/token/tests/src/Kernel/EntityTest.php index 7ff471dfe5d4383c9963687f848cba5b99718e0d..caf575bc60914e9473da8324763d886b5af293df 100644 --- a/web/modules/token/tests/src/Kernel/EntityTest.php +++ b/web/modules/token/tests/src/Kernel/EntityTest.php @@ -2,8 +2,8 @@ namespace Drupal\Tests\token\Kernel; -use Drupal\Component\Utility\Unicode; use Drupal\node\Entity\Node; +use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; use Drupal\taxonomy\VocabularyInterface; @@ -55,20 +55,21 @@ function testEntityMapping() { $this->assertIdentical($mapper->getTokenTypeForEntityType('invalid'), FALSE); $this->assertIdentical($mapper->getTokenTypeForEntityType('invalid', TRUE), 'invalid'); - // Test that when we send the mis-matched entity type into token_replace() - // that we still get the tokens replaced. - $vocabulary = entity_load('taxonomy_vocabulary', 'tags'); + // Test that when we send the mis-matched entity type into + // Drupal\Core\Utility\Token::replace() that we still get the tokens + // replaced. + $vocabulary = Vocabulary::load('tags'); $term = $this->addTerm($vocabulary); - $this->assertIdentical(\Drupal::token()->replace('[vocabulary:name]', array('taxonomy_vocabulary' => $vocabulary)), $vocabulary->label()); - $this->assertIdentical(\Drupal::token()->replace('[term:name][term:vocabulary:name]', array('taxonomy_term' => $term)), $term->label() . $vocabulary->label()); + $this->assertIdentical(\Drupal::token()->replace('[vocabulary:name]', ['taxonomy_vocabulary' => $vocabulary]), $vocabulary->label()); + $this->assertIdentical(\Drupal::token()->replace('[term:name][term:vocabulary:name]', ['taxonomy_term' => $term]), $term->label() . $vocabulary->label()); } - function addTerm(VocabularyInterface $vocabulary, array $term = array()) { - $term += array( - 'name' => Unicode::strtolower($this->randomMachineName(5)), + function addTerm(VocabularyInterface $vocabulary, array $term = []) { + $term += [ + 'name' => mb_strtolower($this->randomMachineName(5)), 'vid' => $vocabulary->id(), - ); - $term = entity_create('taxonomy_term', $term); + ]; + $term = Term::create($term); $term->save(); return $term; } @@ -80,25 +81,26 @@ function testEntityOriginal() { $node = Node::create(['type' => 'page', 'title' => 'Original title']); $node->save(); - $tokens = array( + $tokens = [ 'nid' => $node->id(), 'title' => 'Original title', 'original' => NULL, 'original:nid' => NULL, - ); - $this->assertTokens('node', array('node' => $node), $tokens); + ]; + $this->assertTokens('node', ['node' => $node], $tokens); // Emulate the original entity property that would be available from // node_save() and change the title for the node. - $node->original = entity_load_unchanged('node', $node->id()); + $node->original = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($node->id()); $node->title = 'New title'; - $tokens = array( + $tokens = [ 'nid' => $node->id(), 'title' => 'New title', 'original' => 'Original title', 'original:nid' => $node->id(), - ); - $this->assertTokens('node', array('node' => $node), $tokens); + ]; + $this->assertTokens('node', ['node' => $node], $tokens); } + } diff --git a/web/modules/token/tests/src/Kernel/FieldTest.php b/web/modules/token/tests/src/Kernel/FieldTest.php index de94699f81761915097c60f2c8e5eadf8921dc5a..1d0b2de70ad73853770f346d4b89c84686d6eb72 100644 --- a/web/modules/token/tests/src/Kernel/FieldTest.php +++ b/web/modules/token/tests/src/Kernel/FieldTest.php @@ -16,8 +16,8 @@ use Drupal\contact\Entity\Message; use Drupal\Component\Utility\Html; use Drupal\Core\Field\FieldStorageDefinitionInterface; -use Drupal\taxonomy\Tests\TaxonomyTestTrait; use Drupal\language\Entity\ConfigurableLanguage; +use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait; /** * Tests field tokens. @@ -191,30 +191,32 @@ public function setUp() { $language->save(); // Add a datetime field. - $field_datetime_storage = FieldStorageConfig::create(array( - 'field_name' => 'field_datetime', - 'type' => 'datetime', - 'entity_type' => 'node', - 'settings' => array('datetime_type' => DateTimeItem::DATETIME_TYPE_DATETIME), - )); + $field_datetime_storage = FieldStorageConfig::create([ + 'field_name' => 'field_datetime', + 'type' => 'datetime', + 'entity_type' => 'node', + 'settings' => ['datetime_type' => DateTimeItem::DATETIME_TYPE_DATETIME], + 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ]); $field_datetime_storage->save(); $field_datetime = FieldConfig::create([ - 'field_storage' => $field_datetime_storage, - 'bundle' => 'article', + 'field_storage' => $field_datetime_storage, + 'bundle' => 'article', ]); $field_datetime->save(); // Add a daterange field. - $field_daterange_storage = FieldStorageConfig::create(array( - 'field_name' => 'field_daterange', - 'type' => 'daterange', - 'entity_type' => 'node', - 'settings' => array('datetime_type' => DateRangeItem::DATETIME_TYPE_DATETIME), - )); + $field_daterange_storage = FieldStorageConfig::create([ + 'field_name' => 'field_daterange', + 'type' => 'daterange', + 'entity_type' => 'node', + 'settings' => ['datetime_type' => DateRangeItem::DATETIME_TYPE_DATETIME], + 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ]); $field_daterange_storage->save(); $field_daterange = FieldConfig::create([ - 'field_storage' => $field_daterange_storage, - 'bundle' => 'article', + 'field_storage' => $field_daterange_storage, + 'bundle' => 'article', ]); $field_daterange->save(); } @@ -676,11 +678,17 @@ public function testDatetimeFieldTokens() { 'type' => 'article', ]); - $node->set('field_datetime', '1925-09-28T00:00:00')->save(); + $node->set('field_datetime', ['1925-09-28T00:00:00', '1930-10-28T00:00:00'])->save(); $this->assertTokens('node', ['node' => $node], [ 'field_datetime:date:custom:Y' => '1925', 'field_datetime:date:html_month' => '1925-09', - 'field_datetime:date' => $node->field_datetime->date->getTimestamp(), + 'field_datetime:date' => $node->get('field_datetime')->date->getTimestamp(), + 'field_datetime:0:date:custom:Y' => '1925', + 'field_datetime:0:date:html_month' => '1925-09', + 'field_datetime:0:date' => $node->get('field_datetime')->date->getTimestamp(), + 'field_datetime:1:date:custom:Y' => '1930', + 'field_datetime:1:date:html_month' => '1930-10', + 'field_datetime:1:date' => $node->get('field_datetime')->get(1)->date->getTimestamp(), ]); } @@ -689,19 +697,34 @@ public function testDatetimeFieldTokens() { */ public function testDatetimeRangeFieldTokens() { + /** @var \Drupal\node\NodeInterface $node */ $node = Node::create([ 'title' => 'Node for daterange field', 'type' => 'article', ]); - $node->field_daterange->value = '2013-12-22T00:00:00'; - $node->field_daterange->end_value = '2016-08-26T00:00:00'; + $node->get('field_daterange')->value = '2013-12-22T00:00:00'; + $node->get('field_daterange')->end_value = '2016-08-26T00:00:00'; + $node->get('field_daterange')->appendItem([ + 'value' => '2014-08-22T00:00:00', + 'end_value' => '2017-12-20T00:00:00', + ]); + $node->get('field_daterange')->value = '2013-12-22T00:00:00'; + $node->get('field_daterange')->end_value = '2016-08-26T00:00:00'; $node->save(); $this->assertTokens('node', ['node' => $node], [ 'field_daterange:start_date:html_month' => '2013-12', 'field_daterange:start_date:custom:Y' => '2013', 'field_daterange:end_date:custom:Y' => '2016', - 'field_daterange:start_date' => $node->field_daterange->start_date->getTimestamp(), + 'field_daterange:start_date' => $node->get('field_daterange')->start_date->getTimestamp(), + 'field_daterange:0:start_date:html_month' => '2013-12', + 'field_daterange:0:start_date:custom:Y' => '2013', + 'field_daterange:0:end_date:custom:Y' => '2016', + 'field_daterange:0:start_date' => $node->get('field_daterange')->start_date->getTimestamp(), + 'field_daterange:1:start_date:html_month' => '2014-08', + 'field_daterange:1:start_date:custom:Y' => '2014', + 'field_daterange:1:end_date:custom:Y' => '2017', + 'field_daterange:1:end_date' => $node->get('field_daterange')->get(1)->end_date->getTimestamp(), ]); } diff --git a/web/modules/token/tests/src/Kernel/FileTest.php b/web/modules/token/tests/src/Kernel/FileTest.php index 3a6a7fd643717e96490da5c13db0889334434083..6cfa98875b191c58256743225699b32958455484 100644 --- a/web/modules/token/tests/src/Kernel/FileTest.php +++ b/web/modules/token/tests/src/Kernel/FileTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\token\Kernel; +use Drupal\file\Entity\File; /** * Tests file tokens. * @@ -14,7 +15,7 @@ class FileTest extends KernelTestBase { * * @var array */ - public static $modules = array('file'); + public static $modules = ['file']; /** * {@inheritdoc} @@ -26,30 +27,31 @@ public function setUp() { function testFileTokens() { // Create a test file object. - $file = entity_create('file', array( + $file = File::create([ 'fid' => 1, 'filename' => 'test.png', 'filesize' => 100, 'uri' => 'public://images/test.png', 'filemime' => 'image/png', - )); + ]); - $tokens = array( + $tokens = [ 'basename' => 'test.png', 'extension' => 'png', 'size-raw' => 100, - ); - $this->assertTokens('file', array('file' => $file), $tokens); + ]; + $this->assertTokens('file', ['file' => $file], $tokens); // Test a file with no extension and a fake name. $file->filename = 'Test PNG image'; $file->uri = 'public://images/test'; - $tokens = array( + $tokens = [ 'basename' => 'test', 'extension' => '', 'size-raw' => 100, - ); - $this->assertTokens('file', array('file' => $file), $tokens); + ]; + $this->assertTokens('file', ['file' => $file], $tokens); } + } diff --git a/web/modules/token/tests/src/Kernel/NodeTest.php b/web/modules/token/tests/src/Kernel/NodeTest.php index e44b9abd0ec08fba26558e420d1349a324449ce9..846961a4db200b77ee80970c3bba8602fd15b04a 100644 --- a/web/modules/token/tests/src/Kernel/NodeTest.php +++ b/web/modules/token/tests/src/Kernel/NodeTest.php @@ -48,52 +48,53 @@ function testNodeTokens() { 'type' => 'page', 'title' => 'Source Title', 'revision_log' => $this->randomMachineName(), - 'path' => array('alias' => '/content/source-node') + 'path' => ['alias' => '/content/source-node'] ]); $page->save(); - $tokens = array( + $tokens = [ 'log' => $page->revision_log->value, 'url:path' => '/content/source-node', - 'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], array('absolute' => TRUE))->toString(), - 'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], array('absolute' => FALSE))->toString(), + 'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], ['absolute' => TRUE])->toString(), + 'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], ['absolute' => FALSE])->toString(), 'url:unaliased:path' => "/node/{$page->id()}", 'content-type' => 'Basic page', 'content-type:name' => 'Basic page', 'content-type:machine-name' => 'page', 'content-type:description' => "Use <em>basic pages</em> for your static content, such as an 'About us' page.", 'content-type:node-count' => 1, - 'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'page'], array('absolute' => TRUE))->toString(), + 'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'page'], ['absolute' => TRUE])->toString(), 'source:title' => 'Source Title', // Deprecated tokens. 'type' => 'page', 'type-name' => 'Basic page', 'url:alias' => '/content/source-node', - ); - $this->assertTokens('node', array('node' => $page), $tokens); + ]; + $this->assertTokens('node', ['node' => $page], $tokens); $article = Node::create([ 'type' => 'article', 'title' => 'Source Title', ]); $article->save(); - $tokens = array( + $tokens = [ 'log' => '', 'url:path' => "/node/{$article->id()}", - 'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], array('absolute' => TRUE))->toString(), - 'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], array('absolute' => FALSE))->toString(), + 'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], ['absolute' => TRUE])->toString(), + 'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], ['absolute' => FALSE])->toString(), 'url:unaliased:path' => "/node/{$article->id()}", 'content-type' => 'Article', 'content-type:name' => 'Article', 'content-type:machine-name' => 'article', 'content-type:description' => "Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.", 'content-type:node-count' => 1, - 'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'article'], array('absolute' => TRUE))->toString(), + 'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'article'], ['absolute' => TRUE])->toString(), 'source:title' => 'Source Title', // Deprecated tokens. 'type' => 'article', 'type-name' => 'Article', 'url:alias' => "/node/{$article->id()}", - ); - $this->assertTokens('node', array('node' => $article), $tokens); + ]; + $this->assertTokens('node', ['node' => $article], $tokens); } + } diff --git a/web/modules/token/tests/src/Kernel/RandomTest.php b/web/modules/token/tests/src/Kernel/RandomTest.php index a4b09303dbae21402893a5b4faef0f013b880aad..5162846cecafa81ff63b26e7fea3347c49cbc4d3 100644 --- a/web/modules/token/tests/src/Kernel/RandomTest.php +++ b/web/modules/token/tests/src/Kernel/RandomTest.php @@ -10,18 +10,19 @@ class RandomTest extends KernelTestBase { function testRandomTokens() { - $tokens = array( + $tokens = [ 'number' => '[0-9]{1,}', 'hash:md5' => '[0-9a-f]{32}', 'hash:sha1' => '[0-9a-f]{40}', 'hash:sha256' => '[0-9a-f]{64}', 'hash:invalid-algo' => NULL, - ); + ]; - $first_set = $this->assertTokens('random', array(), $tokens, array('regex' => TRUE)); - $second_set = $this->assertTokens('random', array(), $tokens, array('regex' => TRUE)); + $first_set = $this->assertTokens('random', [], $tokens, ['regex' => TRUE]); + $second_set = $this->assertTokens('random', [], $tokens, ['regex' => TRUE]); foreach ($first_set as $token => $value) { $this->assertNotIdentical($first_set[$token], $second_set[$token]); } } + } diff --git a/web/modules/token/tests/src/Kernel/TaxonomyTest.php b/web/modules/token/tests/src/Kernel/TaxonomyTest.php index 73274df0812adae950b622c76d6279715c8918e0..abc99ea4d4fbe381c60afe5cc51a06907a387c68 100644 --- a/web/modules/token/tests/src/Kernel/TaxonomyTest.php +++ b/web/modules/token/tests/src/Kernel/TaxonomyTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\token\Kernel; -use Drupal\Component\Utility\Unicode; +use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; use Drupal\language\Entity\ConfigurableLanguage; use Drupal\Core\Url; @@ -13,6 +13,7 @@ * @group token */ class TaxonomyTest extends KernelTestBase { + protected $vocab; /** @@ -20,7 +21,7 @@ class TaxonomyTest extends KernelTestBase { * * @var array */ - public static $modules = array('taxonomy', 'text', 'language'); + public static $modules = ['taxonomy', 'text', 'language']; /** * {@inheritdoc} @@ -43,31 +44,31 @@ public function setUp() { * Test the additional taxonomy term tokens. */ function testTaxonomyTokens() { - $root_term = $this->addTerm($this->vocab, array('name' => 'Root term', 'path' => array('alias' => '/root-term'))); - $tokens = array( - 'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(), - 'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(), - 'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => FALSE))->toString(), + $root_term = $this->addTerm($this->vocab, ['name' => 'Root term', 'path' => ['alias' => '/root-term']]); + $tokens = [ + 'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(), + 'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(), + 'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => FALSE])->toString(), 'url:path' => '/root-term', 'url:unaliased:path' => "/taxonomy/term/{$root_term->id()}", - 'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(), + 'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(), 'parents' => NULL, 'parents:count' => NULL, 'parents:keys' => NULL, 'root' => NULL, // Deprecated tokens 'url:alias' => '/root-term', - ); - $this->assertTokens('term', array('term' => $root_term), $tokens); - - $parent_term = $this->addTerm($this->vocab, array('name' => 'Parent term', 'parent' => $root_term->id())); - $tokens = array( - 'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(), - 'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(), - 'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => FALSE))->toString(), + ]; + $this->assertTokens('term', ['term' => $root_term], $tokens); + + $parent_term = $this->addTerm($this->vocab, ['name' => 'Parent term', 'parent' => $root_term->id()]); + $tokens = [ + 'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(), + 'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(), + 'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => FALSE])->toString(), 'url:path' => "/taxonomy/term/{$parent_term->id()}", 'url:unaliased:path' => "/taxonomy/term/{$parent_term->id()}", - 'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(), + 'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(), 'parents' => 'Root term', 'parents:count' => 1, 'parents:keys' => $root_term->id(), @@ -75,16 +76,16 @@ function testTaxonomyTokens() { 'root:tid' => $root_term->id(), // Deprecated tokens 'url:alias' => "/taxonomy/term/{$parent_term->id()}", - ); - $this->assertTokens('term', array('term' => $parent_term), $tokens); + ]; + $this->assertTokens('term', ['term' => $parent_term], $tokens); - $term = $this->addTerm($this->vocab, array('name' => 'Test term', 'parent' => $parent_term->id())); - $tokens = array( + $term = $this->addTerm($this->vocab, ['name' => 'Test term', 'parent' => $parent_term->id()]); + $tokens = [ 'parents' => 'Root term, Parent term', 'parents:count' => 2, - 'parents:keys' => implode(', ', array($root_term->id(), $parent_term->id())), - ); - $this->assertTokens('term', array('term' => $term), $tokens); + 'parents:keys' => implode(', ', [$root_term->id(), $parent_term->id()]), + ]; + $this->assertTokens('term', ['term' => $term], $tokens); } /** @@ -92,28 +93,28 @@ function testTaxonomyTokens() { */ function testVocabularyTokens() { $vocabulary = $this->vocab; - $tokens = array( + $tokens = [ 'machine-name' => 'tags', - 'edit-url' => Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], array('absolute' => TRUE))->toString(), - ); - $this->assertTokens('vocabulary', array('vocabulary' => $vocabulary), $tokens); + 'edit-url' => Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], ['absolute' => TRUE])->toString(), + ]; + $this->assertTokens('vocabulary', ['vocabulary' => $vocabulary], $tokens); } - function addVocabulary(array $vocabulary = array()) { - $vocabulary += array( - 'name' => Unicode::strtolower($this->randomMachineName(5)), - 'nodes' => array('article' => 'article'), - ); - $vocabulary = entity_create('taxonomy_vocabulary', $vocabulary)->save(); + function addVocabulary(array $vocabulary = []) { + $vocabulary += [ + 'name' => mb_strtolower($this->randomMachineName(5)), + 'nodes' => ['article' => 'article'], + ]; + $vocabulary = Vocabulary::create($vocabulary)->save(); return $vocabulary; } - function addTerm($vocabulary, array $term = array()) { - $term += array( - 'name' => Unicode::strtolower($this->randomMachineName(5)), + function addTerm($vocabulary, array $term = []) { + $term += [ + 'name' => mb_strtolower($this->randomMachineName(5)), 'vid' => $vocabulary->id(), - ); - $term = entity_create('taxonomy_term', $term); + ]; + $term = Term::create($term); $term->save(); return $term; } @@ -146,6 +147,8 @@ function testMultilingualTerms() { ])->save(); // Expect the parent term to be in the specified language. - $this->assertTokens('term', array('term' => $child_term), ['parents' => 'german-parent-term'], ['langcode' => 'de']); + $this->assertTokens('term', ['term' => $child_term], ['parents' => 'german-parent-term'], ['langcode' => 'de']); + $this->assertTokens('term', ['term' => $child_term], ['root' => 'german-parent-term'], ['langcode' => 'de']); } + } diff --git a/web/modules/token/tests/src/Kernel/UnitTest.php b/web/modules/token/tests/src/Kernel/UnitTest.php index c91f19433203c7493c499f4a86f9c590afad2132..c031e6bfb396bc390b3b4b0bd0b5a58a6935183a 100644 --- a/web/modules/token/tests/src/Kernel/UnitTest.php +++ b/web/modules/token/tests/src/Kernel/UnitTest.php @@ -33,9 +33,9 @@ public function setUp() { * Test invalid tokens. */ public function testGetInvalidTokens() { - $tests = array(); - $tests[] = array( - 'valid tokens' => array( + $tests = []; + $tests[] = [ + 'valid tokens' => [ '[node:title]', '[node:created:short]', '[node:created:custom:invalid]', @@ -46,8 +46,8 @@ public function testGetInvalidTokens() { '[current-date:short]', '[current-user:uid]', '[current-user:ip-address]', - ), - 'invalid tokens' => array( + ], + 'invalid tokens' => [ '[node:title:invalid]', '[node:created:invalid]', '[node:created:short:invalid]', @@ -62,11 +62,11 @@ public function testGetInvalidTokens() { '[node:type]', '[node:type-name]', '[date:short]', - ), - 'types' => array('node'), - ); - $tests[] = array( - 'valid tokens' => array( + ], + 'types' => ['node'], + ]; + $tests[] = [ + 'valid tokens' => [ '[node:title]', '[node:created:short]', '[node:created:custom:invalid]', @@ -77,8 +77,8 @@ public function testGetInvalidTokens() { '[user:uid]', '[current-date:short]', '[current-user:uid]', - ), - 'invalid tokens' => array( + ], + 'invalid tokens' => [ '[node:title:invalid]', '[node:created:invalid]', '[node:created:short:invalid]', @@ -91,9 +91,9 @@ public function testGetInvalidTokens() { '[node:tnid]', '[node:type]', '[node:type-name]', - ), - 'types' => array('all'), - ); + ], + 'types' => ['all'], + ]; foreach ($tests as $test) { $tokens = array_merge($test['valid tokens'], $test['invalid tokens']); @@ -116,4 +116,5 @@ public function testContentEntityOnlyTokens() { $this->assertNull($this->tokenService->getTokenInfo('user_role', 'url')); $this->assertNull($this->tokenService->getTypeInfo('user_role')); } + } diff --git a/web/modules/token/tests/src/Kernel/UrlTest.php b/web/modules/token/tests/src/Kernel/UrlTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1464095d07bab8c2de08ac10eb8b8778c5d0f6ae --- /dev/null +++ b/web/modules/token/tests/src/Kernel/UrlTest.php @@ -0,0 +1,88 @@ +<?php + +namespace Drupal\Tests\token\Kernel; + +use Drupal\Core\Url; +use Symfony\Component\HttpFoundation\Request; + +/** + * Test generic url token replacements. + * + * @group token + */ +class UrlTest extends KernelTestBase { + + /** + * The token service. + * + * @var \Drupal\Core\Utility\Token + */ + protected $token; + + /** + * The current request stack. + * + * @var \Symfony\Component\HttpFoundation\RequestStack + */ + protected $requestStack; + + /** + * The current route match. + * + * @var \Drupal\Core\Routing\CurrentRouteMatch + */ + protected $currentRouteMatch; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + $this->token = $this->container->get('token'); + $this->requestStack = $this->container->get('request_stack'); + $this->currentRouteMatch = $this->container->get('current_route_match'); + } + + /** + * Test the url token replacements for current requests. + * + * The method ::expectedCurrentRequestUrlResults() is not declared + * as a regular data provider, because it might use services from + * the global Drupal container, which is not initialized yet during + * the invocation of data providers. + */ + public function testCurrentRequestUrls() { + foreach ($this->expectedCurrentRequestUrlResults() as $data_set) { + list ($request, $text, $data, $options, $expected_output) = $data_set; + // Set the request as the current one. + $this->requestStack->pop(); + $this->requestStack->push($request); + $this->currentRouteMatch->resetRouteMatch(); + + $this->assertEquals($expected_output, $this->token->replace($text, $data, $options)); + } + } + + /** + * Provides a list of results to expect for ::testRequestUrls(). + * + * Each data set of this array holds the following order: + * - The request object to test for. + * - The input text as string. + * - The token data as array. + * - Further options for the token replacement as array. + * - The output to expect after token replacement. + * + * @return array + * The list of results to expect. + */ + public function expectedCurrentRequestUrlResults() { + return [ + [Request::createFromGlobals(), '[current-page:url]', [], [], Url::createFromRequest(Request::createFromGlobals())->setAbsolute()->toString()], + [Request::create('/should-not-exist'), '[current-page:url:path]', [], [], '/'], + [Request::create('/https://drupal.org/'), '[current-page:url:absolute]', [], [], '[current-page:url:absolute]'], + [Request::create('/https://drupal.org/'), '[current-page:url:absolute]', [], ['clear' => TRUE], ''], + ]; + } + +} diff --git a/web/modules/token/tests/src/Kernel/ViewsTest.php b/web/modules/token/tests/src/Kernel/ViewsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..884e4fcb4673a947c40694062f8693308fc821df --- /dev/null +++ b/web/modules/token/tests/src/Kernel/ViewsTest.php @@ -0,0 +1,50 @@ +<?php + +namespace Drupal\Tests\token\Kernel; + +use Drupal\views\Tests\ViewTestData; +use Drupal\views\Views; + +/** + * Test the views tokens. + * + * @group token + */ +class ViewsTest extends KernelTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['views', 'block']; + + /** + * Views used by this test. + * + * @var array + */ + public static $testViews = ['token_views_test']; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + $this->installEntitySchema('user'); + ViewTestData::createTestViews(get_class($this), ['token_module_test']); + } + + /** + * Tests path token replacements generated from a view without a path. + */ + public function testTokenReplacementNoPath() { + $token_handler = \Drupal::token(); + $view = Views::getView('token_views_test'); + $view->setDisplay('block_1'); + $view->execute(); + + $this->assertSame('', $token_handler->replace('[view:url]', ['view' => $view]), 'Token [view:url] is empty for views without path.'); + } + +} diff --git a/web/modules/token/token.info.yml b/web/modules/token/token.info.yml index ca8b3c88d80bdc401b3f621d498893d3764071b8..4919185b73eb4ef0442e302c365cb891e2519291 100644 --- a/web/modules/token/token.info.yml +++ b/web/modules/token/token.info.yml @@ -2,9 +2,11 @@ type: module name: Token description: Provides a user interface for the Token API and some missing core tokens. # core: 8.x +dependencies: + - drupal:system (>= 8.5) -# Information added by Drupal.org packaging script on 2017-04-29 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-09-21 +version: '8.x-1.5' core: '8.x' project: 'token' -datestamp: 1493466847 +datestamp: 1537557488 diff --git a/web/modules/token/token.install b/web/modules/token/token.install index 664b1af5cf57613dbf45f6c7b0ac73561485bb36..39af200049941c00784e33869565caa15d0e404e 100644 --- a/web/modules/token/token.install +++ b/web/modules/token/token.install @@ -9,7 +9,7 @@ * Implements hook_requirements(). */ function token_requirements($phase = 'runtime') { - $requirements = array(); + $requirements = []; if ($phase == 'runtime') { // Check for various token definition problems. @@ -24,11 +24,11 @@ function token_requirements($phase = 'runtime') { '#items' => $problems, ]; - $requirements['token-' . $problem_key] = array( + $requirements['token-' . $problem_key] = [ 'title' => $problem['label'], 'value' => \Drupal::service('renderer')->renderPlain($build), 'severity' => $problem['severity'], - ); + ]; } } } @@ -51,12 +51,12 @@ function token_install() { $storage = \Drupal::entityTypeManager()->getStorage('entity_view_mode'); // Add a token view mode if it does not already exist. if (!$storage->load("$entity_type.token")) { - $storage->create(array( + $storage->create([ 'targetEntityType' => $entity_type, 'id' => "$entity_type.token", 'status' => TRUE, 'label' => t('Token'), - ))->save(); + ])->save(); } } } @@ -65,7 +65,7 @@ function token_install() { * Build a list of Drupal 6 tokens and their Drupal 7 token names. */ function _token_upgrade_token_list() { - $tokens = array( + $tokens = [ // Global tokens 'user-name' => 'current-user:name', 'user-id' => 'current-user:id', @@ -142,7 +142,7 @@ function _token_upgrade_token_list() { //'date-in-tz' => '', 'account-url' => 'user:url', 'account-edit' => 'user:edit-url', - ); + ]; // Account for date tokens which need to be expanded. $tokens += _token_upgrade_token_date_list('site-', 'site:date'); @@ -160,8 +160,8 @@ function _token_upgrade_token_list() { * Build a list of Drupal 6 date tokens and their Drupal 7 token names. */ function _token_upgrade_token_date_list($old_token, $new_token) { - $tokens = array(); - $formats = array( + $tokens = []; + $formats = [ 'yyyy' => 'Y', 'yy' => 'y', 'month' => 'F', @@ -174,7 +174,7 @@ function _token_upgrade_token_date_list($old_token, $new_token) { 'ddd' => 'D', 'dd' => 'd', 'd' => 'j', - ); + ]; foreach ($formats as $token_format => $date_format) { $tokens[$old_token . $token_format] = "$new_token:custom:$date_format"; } @@ -198,7 +198,7 @@ function _token_upgrade_token_date_list($old_token, $new_token) { * * @see _token_upgrade_token_list() */ -function token_update_token_text($text, $updates = array(), $leading = '[', $trailing = ']') { +function token_update_token_text($text, $updates = [], $leading = '[', $trailing = ']') { $updates += _token_upgrade_token_list(); $regex = '/' . preg_quote($leading, '/') . '([^\s]*)' . preg_quote($trailing, '/') . '/'; preg_match_all($regex, $text, $matches); @@ -220,7 +220,7 @@ function token_update_token_text($text, $updates = array(), $leading = '[', $tra */ function token_get_token_problems() { // @todo Improve the duplicate checking to report which modules are the offenders. - //$token_info = array(); + //$token_info = []; //foreach (module_implements('token_info') as $module) { // $module_token_info = module_invoke($module, 'token_info'); // if (in_array($module, _token_core_supported_modules())) { @@ -230,7 +230,7 @@ function token_get_token_problems() { // if (is_array($module_token_info['types'])) { // foreach (array_keys($module_token_info['types']) as $type) { // if (is_array($module_token_info['types'][$type])) { - // $module_token_info['types'][$type] += array('module' => $module); + // $module_token_info['types'][$type] += ['module' => $module]; // } // } // } @@ -246,28 +246,28 @@ function token_get_token_problems() { //} $token_info = \Drupal::token()->getInfo(); - $token_problems = array( - 'not-array' => array( + $token_problems = [ + 'not-array' => [ 'label' => t('Tokens or token types not defined as arrays'), 'severity' => REQUIREMENT_ERROR, - ), - 'missing-info' => array( + ], + 'missing-info' => [ 'label' => t('Tokens or token types missing name property'), 'severity' => REQUIREMENT_WARNING, - ), - 'type-no-tokens' => array( + ], + 'type-no-tokens' => [ 'label' => t('Token types do not have any tokens defined'), 'severity' => REQUIREMENT_INFO, - ), - 'tokens-no-type' => array( + ], + 'tokens-no-type' => [ 'label' => t('Token types are not defined but have tokens'), 'severity' => REQUIREMENT_INFO, - ), - 'duplicate' => array( + ], + 'duplicate' => [ 'label' => t('Token or token types are defined by multiple modules'), 'severity' => REQUIREMENT_ERROR, - ), - ); + ], + ]; // Check token types for problems. foreach ($token_info['types'] as $type => $type_info) { @@ -313,4 +313,4 @@ function token_get_token_problems() { } return $token_problems; -} \ No newline at end of file +} diff --git a/web/modules/token/token.module b/web/modules/token/token.module index 32a38da645787ac4bae50da4cce9668c03fd57ef..0d4f2cea19c5b3afb667e4d7e6759a447d925019 100644 --- a/web/modules/token/token.module +++ b/web/modules/token/token.module @@ -6,7 +6,6 @@ */ use Drupal\Component\Render\PlainTextOutput; -use Drupal\Component\Utility\Unicode; use Drupal\Core\Block\BlockPluginInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Menu\MenuLinkInterface; @@ -47,7 +46,7 @@ function token_help($route_name, RouteMatchInterface $route_match) { * Return an array of the core modules supported by token.module. */ function _token_core_supported_modules() { - return array('book', 'field', 'menu_ui'); + return ['book', 'field', 'menu_ui']; } /** @@ -75,14 +74,16 @@ function token_theme() { * Implements hook_block_view_alter(). */ function token_block_view_alter(&$build, BlockPluginInterface $block) { - $label = $build['#configuration']['label']; - if ($label != '<none>') { - // The label is automatically escaped, avoid escaping it twice. - // @todo https://www.drupal.org/node/2580723 will add a method or option - // to the token API to do this, use that when available. - $bubbleable_metadata = BubbleableMetadata::createFromRenderArray($build); - $build['#configuration']['label'] = PlainTextOutput::renderFromHtml(\Drupal::token()->replace($label, [], [], $bubbleable_metadata)); - $bubbleable_metadata->applyTo($build); + if (isset($build['#configuration'])) { + $label = $build['#configuration']['label']; + if ($label != '<none>') { + // The label is automatically escaped, avoid escaping it twice. + // @todo https://www.drupal.org/node/2580723 will add a method or option + // to the token API to do this, use that when available. + $bubbleable_metadata = BubbleableMetadata::createFromRenderArray($build); + $build['#configuration']['label'] = PlainTextOutput::renderFromHtml(\Drupal::token()->replace($label, [], [], $bubbleable_metadata)); + $bubbleable_metadata->applyTo($build); + } } } @@ -95,9 +96,9 @@ function token_form_block_form_alter(&$form, FormStateInterface $form_state) { '#token_types' => [], ]; $rendered_token_tree = \Drupal::service('renderer')->render($token_tree); - $form['settings']['label']['#description'] = - t('This field supports tokens. @browse_tokens_link', ['@browse_tokens_link' => $rendered_token_tree]) - ; + $form['settings']['label']['#description'] = t('This field supports tokens. @browse_tokens_link', [ + '@browse_tokens_link' => $rendered_token_tree, + ]); $form['settings']['label']['#element_validate'][] = 'token_element_validate'; $form['settings']['label'] += ['#token_types' => []]; } @@ -106,7 +107,7 @@ function token_form_block_form_alter(&$form, FormStateInterface $form_state) { * Implements hook_field_info_alter(). */ function token_field_info_alter(&$info) { - $defaults = array( + $defaults = [ 'taxonomy_term_reference' => 'taxonomy_term_reference_plain', 'number_integer' => 'number_unformatted', 'number_decimal' => 'number_unformatted', @@ -120,10 +121,10 @@ function token_field_info_alter(&$info) { 'list_float' => 'list_default', 'list_string' => 'list_default', 'list_boolean' => 'list_default', - ); + ]; foreach ($defaults as $field_type => $default_token_formatter) { if (isset($info[$field_type])) { - $info[$field_type] += array('default_token_formatter' => $default_token_formatter); + $info[$field_type] += ['default_token_formatter' => $default_token_formatter]; } } } @@ -214,7 +215,7 @@ function token_entity_type_alter(array &$entity_types) { * Adds missing token support for core modules. */ function token_module_implements_alter(&$implementations, $hook) { - module_load_include('inc', 'token', 'token.tokens'); + \Drupal::moduleHandler()->loadInclude('token', 'inc', 'token.tokens'); if ($hook == 'tokens' || $hook == 'token_info' || $hook == 'token_info_alter' || $hook == 'tokens_alter') { foreach (_token_core_supported_modules() as $module) { @@ -226,7 +227,7 @@ function token_module_implements_alter(&$implementations, $hook) { // other modules. if (isset($implementations['token'])) { unset($implementations['token']); - $implementations = array_merge(array('token' => 'tokens'), $implementations); + $implementations = array_merge(['token' => 'tokens'], $implementations); } } } @@ -256,21 +257,21 @@ function _token_module($type, $name) { * * For example: * @code - * $form['my_node_text_element'] = array( + * $form['my_node_text_element'] = [ * '#type' => 'textfield', * '#title' => t('Some text to token-ize that has a node context.'), * '#default_value' => 'The title of this node is [node:title].', - * '#element_validate' => array('token_element_validate'), - * '#token_types' => array('node'), + * '#element_validate' => ['token_element_validate'], + * '#token_types' => ['node'], * '#min_tokens' => 1, * '#max_tokens' => 10, - * ); + * ]; * @endcode */ function token_element_validate($element, FormStateInterface $form_state) { $value = isset($element['#value']) ? $element['#value'] : $element['#default_value']; - if (!Unicode::strlen($value)) { + if (!mb_strlen($value)) { // Empty value needs no further validation since the element should depend // on using the '#required' FAPI property. return $element; @@ -281,13 +282,13 @@ function token_element_validate($element, FormStateInterface $form_state) { // Validate if an element must have a minimum number of tokens. if (isset($element['#min_tokens']) && count($tokens) < $element['#min_tokens']) { - $error = \Drupal::translation()->formatPlural($element['#min_tokens'], '%name must contain at least one token.', '%name must contain at least @count tokens.', array('%name' => $title)); + $error = \Drupal::translation()->formatPlural($element['#min_tokens'], '%name must contain at least one token.', '%name must contain at least @count tokens.', ['%name' => $title]); $form_state->setError($element, $error); } // Validate if an element must have a maximum number of tokens. if (isset($element['#max_tokens']) && count($tokens) > $element['#max_tokens']) { - $error = \Drupal::translation()->formatPlural($element['#max_tokens'], '%name must contain at most one token.', '%name must contain at most @count tokens.', array('%name' => $title)); + $error = \Drupal::translation()->formatPlural($element['#max_tokens'], '%name must contain at most one token.', '%name must contain at most @count tokens.', ['%name' => $title]); $form_state->setError($element, $error); } @@ -295,7 +296,7 @@ function token_element_validate($element, FormStateInterface $form_state) { if (isset($element['#token_types'])) { $invalid_tokens = \Drupal::token()->getInvalidTokensByContext($tokens, $element['#token_types']); if ($invalid_tokens) { - $form_state->setError($element, t('%name is using the following invalid tokens: @invalid-tokens.', array('%name' => $title, '@invalid-tokens' => implode(', ', $invalid_tokens)))); + $form_state->setError($element, t('%name is using the following invalid tokens: @invalid-tokens.', ['%name' => $title, '@invalid-tokens' => implode(', ', $invalid_tokens)])); } } @@ -318,19 +319,19 @@ function token_form_field_config_edit_form_alter(&$form, FormStateInterface $for // Date support needs to be implicitly added, as while technically it's not // a global token, it is a not only used but is the default value. // https://www.drupal.org/node/2642160 - $form['settings']['file_directory'] += array('#token_types' => array('date')); + $form['settings']['file_directory'] += ['#token_types' => ['date']]; $form['settings']['file_directory']['#description'] .= ' ' . t('This field supports tokens.'); } // Note that the description is tokenized via token_field_widget_form_alter(). $form['description']['#element_validate'][] = 'token_element_validate'; - $form['description'] += array('#token_types' => array()); + $form['description'] += ['#token_types' => []]; - $form['token_tree'] = array( + $form['token_tree'] = [ '#theme' => 'token_tree_link', - '#token_types' => array(), + '#token_types' => [], '#weight' => $form['description']['#weight'] + 0.5, - ); + ]; } /** @@ -340,18 +341,20 @@ function token_form_field_config_edit_form_alter(&$form, FormStateInterface $for * adds the token tree for a better token UI and selection. */ function token_form_action_form_alter(&$form, $form_state) { - switch ($form['plugin']['#value']) { - case 'action_message_action': - case 'action_send_email_action': - case 'action_goto_action': - $form['token_tree'] = [ - '#theme' => 'token_tree_link', - '#token_types' => 'all', - '#weight' => 100, - ]; - $form['actions']['#weight'] = 101; - // @todo Add token validation to the action fields that can use tokens. - break; + if (isset($form['plugin'])) { + switch ($form['plugin']['#value']) { + case 'action_message_action': + case 'action_send_email_action': + case 'action_goto_action': + $form['token_tree'] = [ + '#theme' => 'token_tree_link', + '#token_types' => 'all', + '#weight' => 100, + ]; + $form['actions']['#weight'] = 101; + // @todo Add token validation to the action fields that can use tokens. + break; + } } } @@ -380,6 +383,7 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s case 'email_cancel_confirm': // Do nothing, but allow execution to continue. break; + case 'email_activated': case 'email_blocked': case 'email_canceled': @@ -387,6 +391,7 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s // sub-element, so switch to that element instead. $element = &$form[$key]['settings']; break; + default: continue 2; } @@ -398,24 +403,24 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s elseif ($element[$sub_key]['#type'] == 'textfield' && substr($sub_key, -8) === '_subject') { // Add validation to subject textfields. $element[$sub_key]['#element_validate'][] = 'token_element_validate'; - $element[$sub_key] += array('#token_types' => array('user')); + $element[$sub_key] += ['#token_types' => ['user']]; } elseif ($element[$sub_key]['#type'] == 'textarea' && substr($sub_key, -5) === '_body') { // Add validation to body textareas. $element[$sub_key]['#element_validate'][] = 'token_element_validate'; - $element[$sub_key] += array('#token_types' => array('user')); + $element[$sub_key] += ['#token_types' => ['user']]; } } } // Add the token tree UI. - $form['email']['token_tree'] = array( + $form['email']['token_tree'] = [ '#theme' => 'token_tree_link', - '#token_types' => array('user'), + '#token_types' => ['user'], '#show_restricted' => TRUE, '#show_nested' => FALSE, '#weight' => 90, - ); + ]; } /** @@ -427,10 +432,10 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s * The cleaned token name. */ function token_clean_token_name($name) { - static $names = array(); + static $names = []; if (!isset($names[$name])) { - $cleaned_name = strtr($name, array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '')); + $cleaned_name = strtr($name, [' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '']); $cleaned_name = preg_replace('/[^\w\-]/i', '', $cleaned_name); $cleaned_name = trim($cleaned_name, '-'); $names[$name] = $cleaned_name; @@ -442,8 +447,8 @@ function token_clean_token_name($name) { /** * Do not use this function yet. Its API has not been finalized. */ -function token_render_array(array $array, array $options = array()) { - $rendered = array(); +function token_render_array(array $array, array $options = []) { + $rendered = []; /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = \Drupal::service('renderer'); @@ -459,7 +464,7 @@ function token_render_array(array $array, array $options = array()) { /** * Do not use this function yet. Its API has not been finalized. */ -function token_render_array_value($value, array $options = array()) { +function token_render_array_value($value, array $options = []) { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = \Drupal::service('renderer'); @@ -493,7 +498,7 @@ function token_render_cache_get($elements) { */ function token_render_cache_set(&$markup, $elements) { // This should only run of drupal_render_cache_set() did not. - if (in_array(\Drupal::request()->server->get('REQUEST_METHOD'), array('GET', 'HEAD'))) { + if (in_array(\Drupal::request()->server->get('REQUEST_METHOD'), ['GET', 'HEAD'])) { return FALSE; } @@ -515,10 +520,10 @@ function token_render_cache_set(&$markup, $elements) { * List of menu link parent titles. */ function token_menu_link_load_all_parents($plugin_id, $langcode) { - $cache = &drupal_static(__FUNCTION__, array()); + $cache = &drupal_static(__FUNCTION__, []); if (!isset($cache[$plugin_id][$langcode])) { - $cache[$plugin_id][$langcode] = array(); + $cache[$plugin_id][$langcode] = []; /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); $parent_ids = $menu_link_manager->getParentIds($plugin_id); @@ -526,7 +531,7 @@ function token_menu_link_load_all_parents($plugin_id, $langcode) { unset($parent_ids[$plugin_id]); foreach ($parent_ids as $parent_id) { $parent = $menu_link_manager->createInstance($parent_id); - $cache[$plugin_id][$langcode] = array($parent_id => token_menu_link_translated_title($parent, $langcode)) + $cache[$plugin_id][$langcode]; + $cache[$plugin_id][$langcode] = [$parent_id => token_menu_link_translated_title($parent, $langcode)] + $cache[$plugin_id][$langcode]; } } @@ -573,14 +578,14 @@ function token_menu_link_translated_title(MenuLinkInterface $menu_link, $langcod * The term parents collection. */ function token_taxonomy_term_load_all_parents($tid, $langcode) { - $cache = &drupal_static(__FUNCTION__, array()); + $cache = &drupal_static(__FUNCTION__, []); if (!is_numeric($tid)) { - return array(); + return []; } if (!isset($cache[$langcode][$tid])) { - $cache[$langcode][$tid] = array(); + $cache[$langcode][$tid] = []; /** @var \Drupal\taxonomy\TermStorageInterface $term_storage */ $term_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term'); $parents = $term_storage->loadAllParents($tid); @@ -601,7 +606,7 @@ function token_element_children(&$elements, $sort = FALSE) { $sort = isset($elements['#sorted']) ? !$elements['#sorted'] : $sort; // Filter out properties from the element, leaving only children. - $children = array(); + $children = []; $sortable = FALSE; foreach ($elements as $key => $value) { if ($key === '' || $key[0] !== '#') { @@ -639,15 +644,15 @@ function token_element_children(&$elements, $sort = FALSE) { * List of node titles of the book parents. */ function token_book_load_all_parents(array $book) { - $cache = &drupal_static(__FUNCTION__, array()); + $cache = &drupal_static(__FUNCTION__, []); if (empty($book['nid'])) { - return array(); + return []; } $nid = $book['nid']; if (!isset($cache[$nid])) { - $cache[$nid] = array(); + $cache[$nid] = []; $i = 1; while ($book["p$i"] != $nid) { $cache[$nid][] = Node::load($book["p$i"])->getTitle(); @@ -662,7 +667,7 @@ function token_book_load_all_parents(array $book) { * Implements hook_entity_base_field_info(). */ function token_entity_base_field_info(EntityTypeInterface $entity_type) { - // We add a psuedo entity-reference field to track the menu entry created + // We add a pseudo entity-reference field to track the menu entry created // from the node add/edit form so that tokens generated at that time that // reference the menu link can access the yet to be saved menu link. // @todo Revisit when https://www.drupal.org/node/2315773 is resolved. @@ -673,14 +678,14 @@ function token_entity_base_field_info(EntityTypeInterface $entity_type) { ->setRevisionable(TRUE) ->setSetting('target_type', 'menu_link_content') ->setTranslatable(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', - 'type' => 'hidden', - )) + 'region' => 'hidden', + ]) ->setComputed(TRUE) - ->setDisplayOptions('form', array( - 'type' => 'hidden', - )); + ->setDisplayOptions('form', [ + 'region' => 'hidden', + ]); return $fields; } @@ -740,19 +745,19 @@ function token_node_menu_link_submit($entity_type, NodeInterface $node, &$form, else { if ($node->isNew()) { // Create a new menu_link_content entity. - $entity = MenuLinkContent::create(array( + $entity = MenuLinkContent::create([ // Lets just reference the UUID for now, the link is not important for // token generation. 'link' => ['uri' => 'internal:/node/' . $node->uuid()], 'langcode' => $node->language()->getId(), - )); + ]); } else { // Create a new menu_link_content entity. - $entity = MenuLinkContent::create(array( + $entity = MenuLinkContent::create([ 'link' => ['uri' => 'entity:node/' . $node->id()], 'langcode' => $node->language()->getId(), - )); + ]); } } $entity->title->value = trim($values['title']); @@ -775,7 +780,7 @@ function token_node_menu_link_submit($entity_type, NodeInterface $node, &$form, function token_node_insert(NodeInterface $node) { if ($node->hasField('menu_link') && $menu_link = $node->menu_link->entity) { // Update the menu-link to point to the now saved node. - $menu_link->link = 'entity:node/' . $node->id(); + $menu_link->link = 'entity:node/' . $node->id(); $menu_link->save(); } } diff --git a/web/modules/token/token.pages.inc b/web/modules/token/token.pages.inc index 4b92df1f1f72c45ee6dfb6a604d9a3557fedcc70..0e417343dc5d3ec95770d23439361ed171a229b8 100644 --- a/web/modules/token/token.pages.inc +++ b/web/modules/token/token.pages.inc @@ -53,7 +53,7 @@ function template_preprocess_token_tree_link(&$variables) { 'draggable' => TRUE, 'autoResize' => FALSE, ]), - ]; + ]; $variables['link'] = Link::createFromRoute($variables['text'], 'token.tree', [], $variables['options'])->toRenderable(); $variables['url'] = new Url('token.tree', [], $variables['options']); diff --git a/web/modules/token/token.tokens.inc b/web/modules/token/token.tokens.inc index f6ad619109dfa0c8f13b7e8e9eb5484b44324796..7ee429107f4c6d392607cb71103e2b03d32beaab 100644 --- a/web/modules/token/token.tokens.inc +++ b/web/modules/token/token.tokens.inc @@ -4,19 +4,20 @@ * @file * Token callbacks for the token module. */ + use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\Render\Element; use Drupal\Component\Utility\Crypt; -use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\Html; use Drupal\Core\TypedData\DataReferenceDefinitionInterface; use Drupal\Core\Url; use Drupal\field\FieldStorageConfigInterface; use Drupal\menu_link_content\MenuLinkContentInterface; use Drupal\node\Entity\Node; +use Drupal\node\Entity\NodeType; use Drupal\node\NodeInterface; use Drupal\system\Entity\Menu; use Drupal\user\UserInterface; @@ -33,11 +34,11 @@ function token_token_info_alter(&$info) { // Force 'date' type tokens to require input and add a 'current-date' type. // @todo Remove when http://drupal.org/node/943028 is fixed. $info['types']['date']['needs-data'] = 'date'; - $info['types']['current-date'] = array( + $info['types']['current-date'] = [ 'name' => t('Current date'), 'description' => t('Tokens related to the current date and time.'), 'type' => 'date', - ); + ]; // Add a 'dynamic' key to any tokens that have chained but dynamic tokens. $info['tokens']['date']['custom']['dynamic'] = TRUE; @@ -87,22 +88,22 @@ function token_token_info_alter(&$info) { // Add [entity:url] tokens if they do not already exist. // @todo Support entity:label if (!isset($info['tokens'][$token_type]['url'])) { - $info['tokens'][$token_type]['url'] = array( + $info['tokens'][$token_type]['url'] = [ 'name' => t('URL'), - 'description' => t('The URL of the @entity.', array('@entity' => Unicode::strtolower($entity_info->getLabel()))), + 'description' => t('The URL of the @entity.', ['@entity' => mb_strtolower($entity_info->getLabel())]), 'module' => 'token', 'type' => 'url', - ); + ]; } // Add [entity:original] tokens if they do not already exist. if (!isset($info['tokens'][$token_type]['original'])) { - $info['tokens'][$token_type]['original'] = array( - 'name' => t('Original @entity', array('@entity' => Unicode::strtolower($entity_info->getLabel()))), - 'description' => t('The original @entity data if the @entity is being updated or saved.', array('@entity' => Unicode::strtolower($entity_info->getLabel()))), + $info['tokens'][$token_type]['original'] = [ + 'name' => t('Original @entity', ['@entity' => mb_strtolower($entity_info->getLabel())]), + 'description' => t('The original @entity data if the @entity is being updated or saved.', ['@entity' => mb_strtolower($entity_info->getLabel())]), 'module' => 'token', 'type' => $token_type, - ); + ]; } } @@ -112,11 +113,11 @@ function token_token_info_alter(&$info) { foreach ($date_format_types as $date_format_type => $date_format_type_info) { /* @var \Drupal\system\Entity\DateFormat $date_format_type_info */ if (!isset($info['tokens']['date'][$date_format_type])) { - $info['tokens']['date'][$date_format_type] = array( + $info['tokens']['date'][$date_format_type] = [ 'name' => Html::escape($date_format_type_info->label()), - 'description' => t("A date in '@type' format. (%date)", array('@type' => $date_format_type, '%date' => format_date(REQUEST_TIME, $date_format_type))), + 'description' => t("A date in '@type' format. (%date)", ['@type' => $date_format_type, '%date' => \Drupal::service('date.formatter')->format(\Drupal::time()->getRequestTime(), $date_format_type)]), 'module' => 'token', - ); + ]; } } } @@ -126,264 +127,264 @@ function token_token_info_alter(&$info) { */ function token_token_info() { // Node tokens. - $info['tokens']['node']['source'] = array( + $info['tokens']['node']['source'] = [ 'name' => t('Translation source node'), 'description' => t("The source node for this current node's translation set."), 'type' => 'node', - ); - $info['tokens']['node']['log'] = array( + ]; + $info['tokens']['node']['log'] = [ 'name' => t('Revision log message'), 'description' => t('The explanation of the most recent changes made to the node.'), - ); - $info['tokens']['node']['content-type'] = array( + ]; + $info['tokens']['node']['content-type'] = [ 'name' => t('Content type'), 'description' => t('The content type of the node.'), 'type' => 'content-type', - ); + ]; // Content type tokens. - $info['types']['content-type'] = array( + $info['types']['content-type'] = [ 'name' => t('Content types'), 'description' => t('Tokens related to content types.'), 'needs-data' => 'node_type', - ); - $info['tokens']['content-type']['name'] = array( + ]; + $info['tokens']['content-type']['name'] = [ 'name' => t('Name'), 'description' => t('The name of the content type.'), - ); - $info['tokens']['content-type']['machine-name'] = array( + ]; + $info['tokens']['content-type']['machine-name'] = [ 'name' => t('Machine-readable name'), 'description' => t('The unique machine-readable name of the content type.'), - ); - $info['tokens']['content-type']['description'] = array( + ]; + $info['tokens']['content-type']['description'] = [ 'name' => t('Description'), 'description' => t('The optional description of the content type.'), - ); - $info['tokens']['content-type']['node-count'] = array( + ]; + $info['tokens']['content-type']['node-count'] = [ 'name' => t('Node count'), 'description' => t('The number of nodes belonging to the content type.'), - ); - $info['tokens']['content-type']['edit-url'] = array( + ]; + $info['tokens']['content-type']['edit-url'] = [ 'name' => t('Edit URL'), 'description' => t("The URL of the content type's edit page."), // 'type' => 'url', - ); + ]; // Taxonomy term and vocabulary tokens. if (\Drupal::moduleHandler()->moduleExists('taxonomy')) { - $info['tokens']['term']['edit-url'] = array( + $info['tokens']['term']['edit-url'] = [ 'name' => t('Edit URL'), 'description' => t("The URL of the taxonomy term's edit page."), // 'type' => 'url', - ); - $info['tokens']['term']['parents'] = array( + ]; + $info['tokens']['term']['parents'] = [ 'name' => t('Parents'), 'description' => t("An array of all the term's parents, starting with the root."), 'type' => 'array', - ); - $info['tokens']['term']['root'] = array( + ]; + $info['tokens']['term']['root'] = [ 'name' => t('Root term'), 'description' => t("The root term of the taxonomy term."), 'type' => 'term', - ); + ]; - $info['tokens']['vocabulary']['machine-name'] = array( + $info['tokens']['vocabulary']['machine-name'] = [ 'name' => t('Machine-readable name'), 'description' => t('The unique machine-readable name of the vocabulary.'), - ); - $info['tokens']['vocabulary']['edit-url'] = array( + ]; + $info['tokens']['vocabulary']['edit-url'] = [ 'name' => t('Edit URL'), 'description' => t("The URL of the vocabulary's edit page."), // 'type' => 'url', - ); + ]; } // File tokens. - $info['tokens']['file']['basename'] = array( + $info['tokens']['file']['basename'] = [ 'name' => t('Base name'), 'description' => t('The base name of the file.'), - ); - $info['tokens']['file']['extension'] = array( + ]; + $info['tokens']['file']['extension'] = [ 'name' => t('Extension'), 'description' => t('The extension of the file.'), - ); - $info['tokens']['file']['size-raw'] = array( + ]; + $info['tokens']['file']['size-raw'] = [ 'name' => t('File byte size'), 'description' => t('The size of the file, in bytes.'), - ); + ]; // User tokens. // Add information on the restricted user tokens. - $info['tokens']['user']['cancel-url'] = array( + $info['tokens']['user']['cancel-url'] = [ 'name' => t('Account cancellation URL'), 'description' => t('The URL of the confirm delete page for the user account.'), 'restricted' => TRUE, // 'type' => 'url', - ); - $info['tokens']['user']['one-time-login-url'] = array( + ]; + $info['tokens']['user']['one-time-login-url'] = [ 'name' => t('One-time login URL'), 'description' => t('The URL of the one-time login page for the user account.'), 'restricted' => TRUE, // 'type' => 'url', - ); - $info['tokens']['user']['roles'] = array( + ]; + $info['tokens']['user']['roles'] = [ 'name' => t('Roles'), 'description' => t('The user roles associated with the user account.'), 'type' => 'array', - ); + ]; // Current user tokens. - $info['tokens']['current-user']['ip-address'] = array( + $info['tokens']['current-user']['ip-address'] = [ 'name' => t('IP address'), - 'description' => 'The IP address of the current user.', - ); + 'description' => t('The IP address of the current user.'), + ]; // Menu link tokens (work regardless if menu module is enabled or not). - $info['types']['menu-link'] = array( + $info['types']['menu-link'] = [ 'name' => t('Menu links'), 'description' => t('Tokens related to menu links.'), 'needs-data' => 'menu-link', - ); - $info['tokens']['menu-link']['mlid'] = array( + ]; + $info['tokens']['menu-link']['mlid'] = [ 'name' => t('Link ID'), 'description' => t('The unique ID of the menu link.'), - ); - $info['tokens']['menu-link']['title'] = array( + ]; + $info['tokens']['menu-link']['title'] = [ 'name' => t('Title'), 'description' => t('The title of the menu link.'), - ); - $info['tokens']['menu-link']['url'] = array( + ]; + $info['tokens']['menu-link']['url'] = [ 'name' => t('URL'), 'description' => t('The URL of the menu link.'), 'type' => 'url', - ); - $info['tokens']['menu-link']['parent'] = array( + ]; + $info['tokens']['menu-link']['parent'] = [ 'name' => t('Parent'), 'description' => t("The menu link's parent."), 'type' => 'menu-link', - ); - $info['tokens']['menu-link']['parents'] = array( + ]; + $info['tokens']['menu-link']['parents'] = [ 'name' => t('Parents'), 'description' => t("An array of all the menu link's parents, starting with the root."), 'type' => 'array', - ); - $info['tokens']['menu-link']['root'] = array( + ]; + $info['tokens']['menu-link']['root'] = [ 'name' => t('Root'), 'description' => t("The menu link's root."), 'type' => 'menu-link', - ); + ]; // Current page tokens. - $info['types']['current-page'] = array( + $info['types']['current-page'] = [ 'name' => t('Current page'), 'description' => t('Tokens related to the current page request.'), - ); - $info['tokens']['current-page']['title'] = array( + ]; + $info['tokens']['current-page']['title'] = [ 'name' => t('Title'), 'description' => t('The title of the current page.'), - ); - $info['tokens']['current-page']['url'] = array( + ]; + $info['tokens']['current-page']['url'] = [ 'name' => t('URL'), 'description' => t('The URL of the current page.'), 'type' => 'url', - ); - $info['tokens']['current-page']['page-number'] = array( + ]; + $info['tokens']['current-page']['page-number'] = [ 'name' => t('Page number'), 'description' => t('The page number of the current page when viewing paged lists.'), - ); - $info['tokens']['current-page']['query'] = array( + ]; + $info['tokens']['current-page']['query'] = [ 'name' => t('Query string value'), 'description' => t('The value of a specific query string field of the current page.'), 'dynamic' => TRUE, - ); + ]; // URL tokens. - $info['types']['url'] = array( + $info['types']['url'] = [ 'name' => t('URL'), 'description' => t('Tokens related to URLs.'), 'needs-data' => 'path', - ); - $info['tokens']['url']['path'] = array( + ]; + $info['tokens']['url']['path'] = [ 'name' => t('Path'), 'description' => t('The path component of the URL.'), - ); - $info['tokens']['url']['relative'] = array( + ]; + $info['tokens']['url']['relative'] = [ 'name' => t('Relative URL'), 'description' => t('The relative URL.'), - ); - $info['tokens']['url']['absolute'] = array( + ]; + $info['tokens']['url']['absolute'] = [ 'name' => t('Absolute URL'), 'description' => t('The absolute URL.'), - ); - $info['tokens']['url']['brief'] = array( + ]; + $info['tokens']['url']['brief'] = [ 'name' => t('Brief URL'), 'description' => t('The URL without the protocol and trailing backslash.'), - ); - $info['tokens']['url']['unaliased'] = array( + ]; + $info['tokens']['url']['unaliased'] = [ 'name' => t('Unaliased URL'), 'description' => t('The unaliased URL.'), 'type' => 'url', - ); - $info['tokens']['url']['args'] = array( + ]; + $info['tokens']['url']['args'] = [ 'name' => t('Arguments'), 'description' => t("The specific argument of the current page (e.g. 'arg:1' on the page 'node/1' returns '1')."), 'type' => 'array', - ); + ]; // Array tokens. - $info['types']['array'] = array( + $info['types']['array'] = [ 'name' => t('Array'), 'description' => t('Tokens related to arrays of strings.'), 'needs-data' => 'array', 'nested' => TRUE, - ); - $info['tokens']['array']['first'] = array( + ]; + $info['tokens']['array']['first'] = [ 'name' => t('First'), 'description' => t('The first element of the array.'), - ); - $info['tokens']['array']['last'] = array( + ]; + $info['tokens']['array']['last'] = [ 'name' => t('Last'), 'description' => t('The last element of the array.'), - ); - $info['tokens']['array']['count'] = array( + ]; + $info['tokens']['array']['count'] = [ 'name' => t('Count'), 'description' => t('The number of elements in the array.'), - ); - $info['tokens']['array']['reversed'] = array( + ]; + $info['tokens']['array']['reversed'] = [ 'name' => t('Reversed'), 'description' => t('The array reversed.'), 'type' => 'array', - ); - $info['tokens']['array']['keys'] = array( + ]; + $info['tokens']['array']['keys'] = [ 'name' => t('Keys'), 'description' => t('The array of keys of the array.'), 'type' => 'array', - ); - $info['tokens']['array']['join'] = array( + ]; + $info['tokens']['array']['join'] = [ 'name' => t('Imploded'), 'description' => t('The values of the array joined together with a custom string in-between each value.'), 'dynamic' => TRUE, - ); - $info['tokens']['array']['value'] = array( + ]; + $info['tokens']['array']['value'] = [ 'name' => t('Value'), 'description' => t('The specific value of the array.'), 'dynamic' => TRUE, - ); + ]; // Random tokens. - $info['types']['random'] = array( + $info['types']['random'] = [ 'name' => t('Random'), 'description' => t('Tokens related to random data.'), - ); - $info['tokens']['random']['number'] = array( + ]; + $info['tokens']['random']['number'] = [ 'name' => t('Number'), - 'description' => t('A random number from 0 to @max.', array('@max' => mt_getrandmax())), - ); - $info['tokens']['random']['hash'] = array( + 'description' => t('A random number from 0 to @max.', ['@max' => mt_getrandmax()]), + ]; + $info['tokens']['random']['hash'] = [ 'name' => t('Hash'), - 'description' => t('A random hash. The possible hashing algorithms are: @hash-algos.', array('@hash-algos' => implode(', ', hash_algos()))), + 'description' => t('A random hash. The possible hashing algorithms are: @hash-algos.', ['@hash-algos' => implode(', ', hash_algos())]), 'dynamic' => TRUE, - ); + ]; // Define image_with_image_style token type. if (\Drupal::moduleHandler()->moduleExists('image')) { @@ -427,10 +428,10 @@ function token_token_info() { /** * Implements hook_tokens(). */ -function token_tokens($type, array $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) { - $replacements = array(); +function token_tokens($type, array $tokens, array $data = [], array $options = [], BubbleableMetadata $bubbleable_metadata) { + $replacements = []; $language_manager = \Drupal::languageManager(); - $url_options = array('absolute' => TRUE); + $url_options = ['absolute' => TRUE]; if (isset($options['langcode'])) { $url_options['language'] = $language_manager->getLanguage($options['langcode']); $langcode = $options['langcode']; @@ -441,13 +442,13 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // Date tokens. if ($type == 'date') { - $date = !empty($data['date']) ? $data['date'] : REQUEST_TIME; + $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] = format_date($date, $name, '', NULL, $langcode); + $replacements[$original] = \Drupal::service('date.formatter')->format($date, $name, '', NULL, $langcode); } } } @@ -455,7 +456,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // Current date tokens. // @todo Remove when http://drupal.org/node/943028 is fixed. if ($type == 'current-date') { - $replacements += \Drupal::token()->generate('date', $tokens, array('date' => REQUEST_TIME), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('date', $tokens, ['date' => \Drupal::time()->getRequestTime()], $options, $bubbleable_metadata); } // Comment tokens. @@ -466,7 +467,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // Chained token relationships. if (($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url'))) { // Add fragment to url options. - $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])], $options, $bubbleable_metadata); } } @@ -480,6 +481,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option 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; @@ -489,13 +491,13 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // Chained token relationships. if (($parent_tokens = \Drupal::token()->findWithPrefix($tokens, 'source')) && $source_node = $node->getUntranslated()) { - $replacements += \Drupal::token()->generate('node', $parent_tokens, array('node' => $source_node), $options, $bubbleable_metadata); + $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 = node_type_load($node->bundle())) { - $replacements += \Drupal::token()->generate('content-type', $node_type_tokens, array('node_type' => $node_type), $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, array('url' => $node->urlInfo()), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $node->toUrl()], $options, $bubbleable_metadata); } } @@ -509,12 +511,15 @@ function token_tokens($type, array $tokens, array $data = array(), array $option 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') @@ -522,8 +527,9 @@ function token_tokens($type, array $tokens, array $data = array(), array $option ->execute(); $replacements[$original] = (int) $count; break; + case 'edit-url': - $replacements[$original] = $node_type->url('edit-form', $url_options); + $replacements[$original] = $node_type->toUrl('edit-form', $url_options)->toString(); break; } } @@ -553,6 +559,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option $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; @@ -561,19 +568,19 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // Chained token relationships. if (($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url'))) { - $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $term->urlInfo()), $options, $bubbleable_metadata); + $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('array' => $parents), $options, $bubbleable_metadata); + $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, array('term' => $root_term), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('term', $root_tokens, ['term' => $root_term], $options, $bubbleable_metadata); } } } @@ -587,6 +594,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option case 'machine-name': $replacements[$original] = $vocabulary->id(); break; + case 'edit-url': $replacements[$original] = Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], $url_options)->toString(); break; @@ -604,10 +612,12 @@ function token_tokens($type, array $tokens, array $data = array(), array $option $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; @@ -644,15 +654,15 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // 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, array('file' => $account->user_picture->entity), $options, $bubbleable_metadata); + $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, array('url' => $account->urlInfo()), $options, $bubbleable_metadata); + $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('array' => $roles_names), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('array', $role_tokens, ['array' => $roles_names], $options, $bubbleable_metadata); } } @@ -684,24 +694,28 @@ function token_tokens($type, array $tokens, array $data = array(), array $option case 'id': $replacements[$original] = $link->getPluginId(); break; + case 'title': $replacements[$original] = token_menu_link_translated_title($link, $langcode); break; + case 'url': $replacements[$original] = $link->getUrlObject()->setAbsolute()->toString(); break; - case 'parent': + 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)); @@ -714,41 +728,59 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // 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, array('menu-link' => $parent), $options, $bubbleable_metadata); + $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('array' => $parents), $options, $bubbleable_metadata); + $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, array('menu-link' => $root), $options, $bubbleable_metadata); + $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, array('url' => $link->getUrlObject()), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $link->getUrlObject()], $options, $bubbleable_metadata); } } // Current page tokens. if ($type == 'current-page') { + $request = \Drupal::request(); foreach ($tokens as $name => $original) { switch ($name) { case 'title': - $request = \Drupal::request(); $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': - $replacements[$original] = Url::fromRoute('<current>', [], $url_options)->toString(); + $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)) { + $replacements[$original] = $url->toString(); + } break; + case 'page-number': - if ($page = \Drupal::request()->query->get('page')) { + if ($page = $request->query->get('page')) { // @see PagerDefault::execute() $pager_page_array = explode(',', $page); $page = $pager_page_array[0]; @@ -774,6 +806,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // [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); @@ -784,8 +817,23 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // Chained token relationships. if ($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url')) { - $url = Url::fromRoute('<current>'); - $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $url), $options, $bubbleable_metadata); + $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); } } @@ -795,7 +843,11 @@ function token_tokens($type, array $tokens, array $data = array(), array $option $url = $data['url']; // To retrieve the correct path, modify a copy of the Url object. $path_url = clone $url; - $path = '/' . $path_url->setAbsolute(FALSE)->setOption('fragment', NULL)->getInternalPath(); + $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) { @@ -803,42 +855,47 @@ function token_tokens($type, array $tokens, array $data = array(), array $option $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': $replacements[$original] = $url->setAbsolute()->toString(); break; + case 'relative': $replacements[$original] = $url->setAbsolute(FALSE)->toString(); break; + case 'brief': - $replacements[$original] = preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->toString()); + $replacements[$original] = preg_replace(['!^https?://!', '!/$!'], '', $url->setAbsolute()->toString()); break; + case 'unaliased': $unaliased = clone $url; $replacements[$original] = $unaliased->setAbsolute()->setOption('alias', TRUE)->toString(); 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('array' => explode('/', ltrim($value, '/'))), $options, $bubbleable_metadata); + $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, array('url' => $url), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('url', $unaliased_tokens, ['url' => $url], $options, $bubbleable_metadata); } } @@ -850,8 +907,8 @@ function token_tokens($type, array $tokens, array $data = array(), array $option foreach ($tokens as $name => $original) { switch ($name) { case 'url': - if (_token_module($type, 'url') == 'token' && $url = $entity->url()) { - $replacements[$original] = $url; + if (_token_module($type, 'url') === 'token' && !$entity->isNew() && $entity->hasLinkTemplate('canonical')) { + $replacements[$original] = $entity->toUrl('canonical')->toString(); } break; @@ -866,20 +923,20 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // [entity:url:*] chained tokens. if (($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url')) && _token_module($type, 'url') == 'token') { - $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $entity->toUrl()), $options, $bubbleable_metadata); + $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, array($type => $entity->original), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate($type, $original_tokens, [$type => $entity->original], $options, $bubbleable_metadata); } // Pass through to an generic 'entity' token type generation. - $entity_data = array( + $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); } @@ -901,23 +958,28 @@ function token_tokens($type, array $tokens, array $data = array(), array $option $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; + $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, array('join' => '') + $options); + $replacements[$original] = token_render_array($array, ['join' => ''] + $options); break; } } @@ -934,18 +996,18 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // [array:join:*] dynamic tokens. if ($join_tokens = \Drupal::token()->findWithPrefix($tokens, 'join')) { foreach ($join_tokens as $join => $original) { - $replacements[$original] = token_render_array($array, array('join' => $join) + $options); + $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('array' => $keys), $options, $bubbleable_metadata); + $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' => array_reverse($array, TRUE)), array('array sort' => FALSE) + $options, $bubbleable_metadata); + $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. @@ -977,7 +1039,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option 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', array($type, $tokens, $data, $options, $bubbleable_metadata)); + $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 @@ -986,7 +1048,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option // 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', array('%type' => $type)), E_USER_WARNING); + trigger_error(t('Attempting to perform token replacement for token type %type without required data', ['%type' => $type]), E_USER_WARNING); } } @@ -997,50 +1059,50 @@ function token_tokens($type, array $tokens, array $data = array(), array $option * Implements hook_token_info() on behalf of book.module. */ function book_token_info() { - $info['types']['book'] = array( + $info['types']['book'] = [ 'name' => t('Book'), 'description' => t('Tokens related to books.'), 'needs-data' => 'book', - ); + ]; - $info['tokens']['book']['title'] = array( + $info['tokens']['book']['title'] = [ 'name' => t('Title'), 'description' => t('Title of the book.'), - ); - $info['tokens']['book']['author'] = array( + ]; + $info['tokens']['book']['author'] = [ 'name' => t('Author'), 'description' => t('The author of the book.'), 'type' => 'user', - ); - $info['tokens']['book']['root'] = array( + ]; + $info['tokens']['book']['root'] = [ 'name' => t('Root'), 'description' => t('Top level of the book.'), 'type' => 'node', - ); - $info['tokens']['book']['parent'] = array( + ]; + $info['tokens']['book']['parent'] = [ 'name' => t('Parent'), 'description' => t('Parent of the current page.'), 'type' => 'node', - ); - $info['tokens']['book']['parents'] = array( + ]; + $info['tokens']['book']['parents'] = [ 'name' => t('Parents'), 'description' => t("An array of all the node's parents, starting with the root."), 'type' => 'array', - ); + ]; - $info['tokens']['node']['book'] = array( + $info['tokens']['node']['book'] = [ 'name' => t('Book'), 'description' => t('The book page associated with the node.'), 'type' => 'book', - ); + ]; return $info; } /** * Implements hook_tokens() on behalf of book.module. */ -function book_tokens($type, $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) { - $replacements = array(); +function book_tokens($type, $tokens, array $data = [], array $options = [], BubbleableMetadata $bubbleable_metadata) { + $replacements = []; // Node tokens. if ($type == 'node' && !empty($data['node'])) { @@ -1049,12 +1111,12 @@ function book_tokens($type, $tokens, array $data = array(), array $options = arr if (!empty($book['bid'])) { if ($book_tokens = \Drupal::token()->findWithPrefix($tokens, 'book')) { $child_node = Node::load($book['nid']); - $replacements += \Drupal::token()->generate('book', $book_tokens, array('book' => $child_node), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('book', $book_tokens, ['book' => $child_node], $options, $bubbleable_metadata); } } } // Book tokens. - else if ($type == 'book' && !empty($data['book'])) { + elseif ($type == 'book' && !empty($data['book'])) { $book = $data['book']->book; if (!empty($book['bid'])) { @@ -1066,12 +1128,14 @@ function book_tokens($type, $tokens, array $data = array(), array $options = arr case 'title': $replacements[$original] = $book_node->getTitle(); break; + case 'parent': if (!empty($book['pid'])) { $parent_node = Node::load($book['pid']); $replacements[$original] = $parent_node->getTitle(); } break; + case 'parents': if ($parents = token_book_load_all_parents($book)) { $replacements[$original] = token_render_array($parents, $options); @@ -1081,18 +1145,18 @@ function book_tokens($type, $tokens, array $data = array(), array $options = arr } if ($book_tokens = \Drupal::token()->findWithPrefix($tokens, 'author')) { - $replacements += \Drupal::token()->generate('user', $book_tokens, array('user' => $book_node->getOwner()), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('user', $book_tokens, ['user' => $book_node->getOwner()], $options, $bubbleable_metadata); } if ($book_tokens = \Drupal::token()->findWithPrefix($tokens, 'root')) { - $replacements += \Drupal::token()->generate('node', $book_tokens, array('node' => $book_node), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('node', $book_tokens, ['node' => $book_node], $options, $bubbleable_metadata); } if (!empty($book['pid']) && $book_tokens = \Drupal::token()->findWithPrefix($tokens, 'parent')) { $parent_node = Node::load($book['pid']); - $replacements += \Drupal::token()->generate('node', $book_tokens, array('node' => $parent_node), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('node', $book_tokens, ['node' => $parent_node], $options, $bubbleable_metadata); } if ($book_tokens = \Drupal::token()->findWithPrefix($tokens, 'parents')) { $parents = token_book_load_all_parents($book); - $replacements += \Drupal::token()->generate('array', $book_tokens, array('array' => $parents), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('array', $book_tokens, ['array' => $parents], $options, $bubbleable_metadata); } } } @@ -1105,46 +1169,46 @@ function book_tokens($type, $tokens, array $data = array(), array $options = arr */ function menu_ui_token_info() { // Menu tokens. - $info['types']['menu'] = array( + $info['types']['menu'] = [ 'name' => t('Menus'), 'description' => t('Tokens related to menus.'), 'needs-data' => 'menu', - ); - $info['tokens']['menu']['name'] = array( + ]; + $info['tokens']['menu']['name'] = [ 'name' => t('Name'), 'description' => t("The name of the menu."), - ); - $info['tokens']['menu']['machine-name'] = array( + ]; + $info['tokens']['menu']['machine-name'] = [ 'name' => t('Machine-readable name'), 'description' => t("The unique machine-readable name of the menu."), - ); - $info['tokens']['menu']['description'] = array( + ]; + $info['tokens']['menu']['description'] = [ 'name' => t('Description'), 'description' => t('The optional description of the menu.'), - ); - $info['tokens']['menu']['menu-link-count'] = array( + ]; + $info['tokens']['menu']['menu-link-count'] = [ 'name' => t('Menu link count'), 'description' => t('The number of menu links belonging to the menu.'), - ); - $info['tokens']['menu']['edit-url'] = array( + ]; + $info['tokens']['menu']['edit-url'] = [ 'name' => t('Edit URL'), 'description' => t("The URL of the menu's edit page."), - ); + ]; - $info['tokens']['menu-link']['menu'] = array( + $info['tokens']['menu-link']['menu'] = [ 'name' => t('Menu'), 'description' => t('The menu of the menu link.'), 'type' => 'menu', - ); - $info['tokens']['menu-link']['edit-url'] = array( + ]; + $info['tokens']['menu-link']['edit-url'] = [ 'name' => t('Edit URL'), 'description' => t("The URL of the menu link's edit page."), - ); - $info['tokens']['node']['menu-link'] = array( + ]; + $info['tokens']['node']['menu-link'] = [ 'name' => t('Menu link'), 'description' => t("The menu link for this node."), 'type' => 'menu-link', - ); + ]; return $info; } @@ -1152,13 +1216,13 @@ function menu_ui_token_info() { /** * Implements hook_tokens() on behalf of menu_ui.module. */ -function menu_ui_tokens($type, $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) { - $replacements = array(); +function menu_ui_tokens($type, $tokens, array $data = [], array $options = [], BubbleableMetadata $bubbleable_metadata) { + $replacements = []; /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); - $url_options = array('absolute' => TRUE); + $url_options = ['absolute' => TRUE]; if (isset($options['langcode'])) { $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']); $langcode = $options['langcode']; @@ -1196,13 +1260,13 @@ function menu_ui_tokens($type, $tokens, array $data = array(), array $options = if ($menu_tokens = \Drupal::token()->findWithPrefix($tokens, 'menu-link')) { if ($node->getFieldDefinition('menu_link') && $menu_link = $node->menu_link->entity) { /** @var \Drupal\menu_link_content\MenuLinkContentInterface $menu_link */ - $replacements += \Drupal::token()->generate('menu-link', $menu_tokens, array('menu-link' => $menu_link), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('menu-link', $menu_tokens, ['menu-link' => $menu_link], $options, $bubbleable_metadata); } else { - $url = $node->urlInfo(); + $url = $node->toUrl(); if ($links = $menu_link_manager->loadLinksByRoute($url->getRouteName(), $url->getRouteParameters())) { $link = _token_menu_link_best_match($node, $links); - $replacements += \Drupal::token()->generate('menu-link', $menu_tokens, array('menu-link' => $link), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('menu-link', $menu_tokens, ['menu-link' => $link], $options, $bubbleable_metadata); } } } @@ -1234,7 +1298,7 @@ function menu_ui_tokens($type, $tokens, array $data = array(), array $options = // Chained token relationships. if (($menu_tokens = \Drupal::token()->findWithPrefix($tokens, 'menu')) && $menu = Menu::load($link->getMenuName())) { - $replacements += \Drupal::token()->generate('menu', $menu_tokens, array('menu' => $menu), $options, $bubbleable_metadata); + $replacements += \Drupal::token()->generate('menu', $menu_tokens, ['menu' => $menu], $options, $bubbleable_metadata); } } @@ -1318,17 +1382,13 @@ function field_token_info_alter(&$info) { // Make sure a token type exists for this entity. $token_type = \Drupal::service('token.entity_mapper')->getTokenTypeForEntityType($entity_type_id); - if (empty($token_type)) { + if (empty($token_type) || !isset($info['types'][$token_type])) { continue; } $fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type_id); foreach ($fields as $field_name => $field) { /** @var \Drupal\field\FieldStorageConfigInterface $field */ - // Ensure the token type exists. - if (!isset($info['types'][$token_type])) { - continue; - } // Ensure the token implements FieldStorageConfigInterface or is defined // in token module. @@ -1370,13 +1430,13 @@ function field_token_info_alter(&$info) { $cardinality = $field->getCardinality(); $cardinality = ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || $cardinality > 3) ? 3 : $cardinality; $field_token_name = $token_type . '-' . $field_name; - $info['tokens'][$token_type][$field_name] = array( + $info['tokens'][$token_type][$field_name] = [ 'name' => Html::escape($label), 'description' => $description, 'module' => 'token', // For multivalue fields the field token is a list type. 'type' => $cardinality > 1 ? "list<$field_token_name>" : $field_token_name, - ); + ]; // Field token type. $info['types'][$field_token_name] = [ @@ -1387,12 +1447,12 @@ function field_token_info_alter(&$info) { ]; // Field list token type. if ($cardinality > 1) { - $info['types']["list<$field_token_name>"] = array( - 'name' => t('List of @type values', array('@type' => Html::escape($label))), - 'description' => t('Tokens for lists of @type values.', array('@type' => Html::escape($label))), + $info['types']["list<$field_token_name>"] = [ + 'name' => t('List of @type values', ['@type' => Html::escape($label)]), + 'description' => t('Tokens for lists of @type values.', ['@type' => Html::escape($label)]), 'needs-data' => "list<$field_token_name>", 'nested' => TRUE, - ); + ]; } // Show a different token for each field delta. @@ -1443,7 +1503,7 @@ function field_token_info_alter(&$info) { $info['tokens'][$field_token_name]['date']['name'] .= ' ' . t('format'); $info['tokens'][$field_token_name]['date']['type'] = 'date'; } - if ($field->getType() == 'daterange') { + if ($field->getType() == 'daterange' || $field->getType() == 'date_recur') { $info['tokens'][$field_token_name]['start_date'] = $info['tokens'][$field_token_name]['value']; $info['tokens'][$field_token_name]['start_date']['name'] .= ' ' . t('format'); $info['tokens'][$field_token_name]['start_date']['type'] = 'date'; @@ -1488,8 +1548,8 @@ function _token_field_label($entity_type, $field_name) { /** * Implements hook_tokens() on behalf of field.module. */ -function field_tokens($type, $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) { - $replacements = array(); +function field_tokens($type, $tokens, array $data = [], array $options = [], BubbleableMetadata $bubbleable_metadata) { + $replacements = []; $langcode = isset($options['langcode']) ? $options['langcode'] : NULL; // Entity tokens. if ($type == 'entity' && !empty($data['entity_type']) && !empty($data['entity']) && !empty($data['token_type'])) { @@ -1573,7 +1633,7 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar } // Handle [entity:field_name:value] and [entity:field_name:0:value] // tokens. - else if ($field_tokens = \Drupal::token()->findWithPrefix($tokens, $field_name)) { + elseif ($field_tokens = \Drupal::token()->findWithPrefix($tokens, $field_name)) { $property_token_data = [ 'field_property' => TRUE, $data['entity_type'] . '-' . $field_name => $entity->$field_name, @@ -1639,52 +1699,57 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar // replacement. $property_name = isset($parts[1]) ? $parts[1] : 'url'; $entity = $field_item->entity; - $original_uri = $entity->getFileUri(); - - // Only generate the image derivative if needed. - if ($property_name === 'width' || $property_name === 'height') { - $dimensions = [ - 'width' => $field_item->width, - 'height' => $field_item->height, - ]; - $style->transformDimensions($dimensions, $original_uri); - $replacements[$original] = $dimensions[$property_name]; - } - elseif ($property_name === 'uri') { - $replacements[$original] = $style->buildUri($original_uri); - } - elseif ($property_name === 'url') { - $replacements[$original] = $style->buildUrl($original_uri); - } - else { - // Generate the image derivative, if it doesn't already exist. - $derivative_uri = $style->buildUri($original_uri); - $derivative_exists = TRUE; - if (!file_exists($derivative_uri)) { - $derivative_exists = $style->createDerivative($original_uri, $derivative_uri); + if (!empty($field_item->entity)) { + $original_uri = $entity->getFileUri(); + + // Only generate the image derivative if needed. + if ($property_name === 'width' || $property_name === 'height') { + $dimensions = [ + 'width' => $field_item->width, + 'height' => $field_item->height, + ]; + $style->transformDimensions($dimensions, $original_uri); + $replacements[$original] = $dimensions[$property_name]; } - if ($derivative_exists) { - $image = \Drupal::service('image.factory')->get($derivative_uri); - // Provide the replacement. - switch ($property_name) { - case 'mimetype': - $replacements[$original] = $image->getMimeType(); - break; - case 'filesize' : - $replacements[$original] = $image->getFileSize(); - break; + elseif ($property_name === 'uri') { + $replacements[$original] = $style->buildUri($original_uri); + } + elseif ($property_name === 'url') { + $replacements[$original] = $style->buildUrl($original_uri); + } + else { + // Generate the image derivative, if it doesn't already exist. + $derivative_uri = $style->buildUri($original_uri); + $derivative_exists = TRUE; + if (!file_exists($derivative_uri)) { + $derivative_exists = $style->createDerivative($original_uri, $derivative_uri); + } + if ($derivative_exists) { + $image = \Drupal::service('image.factory')->get($derivative_uri); + // Provide the replacement. + switch ($property_name) { + case 'mimetype': + $replacements[$original] = $image->getMimeType(); + break; + + case 'filesize': + $replacements[$original] = $image->getFileSize(); + break; + } } } } } - elseif (in_array($field_item->getFieldDefinition()->getType(), ['datetime', 'daterange']) && in_array($property_name, ['date', 'start_date', 'end_date'])) { - $datetime = $field_item->$property_name->getTimestamp(); - if($property_name == $token) { - $replacements[$original] = $datetime; + elseif (in_array($field_item->getFieldDefinition()->getType(), ['datetime', 'daterange', 'date_recur']) && in_array($property_name, ['date', 'start_date', 'end_date']) && !empty($field_item->$property_name)) { + $timestamp = $field_item->{$property_name}->getTimestamp(); + // If the token is an exact match for the property or the delta and the + // property, use the timestamp as-is. + if ($property_name == $token || "$delta:$property_name" == $token) { + $replacements[$original] = $timestamp; } else { - $field_tokens = \Drupal::token()->findWithPrefix($tokens, $property_name); - $replacements += \Drupal::token()->generate('date', $field_tokens, ['date' => $datetime], $options, $bubbleable_metadata); + $date_tokens = \Drupal::token()->findWithPrefix($filtered_tokens, $property_name); + $replacements += \Drupal::token()->generate('date', $date_tokens, ['date' => $timestamp], $options, $bubbleable_metadata); } } else { @@ -1713,7 +1778,7 @@ function token_pre_render_field_token($elements) { foreach ($deltas as $index => $delta) { // Do not add a suffix to the last item. if ($index < ($count - 1)) { - $elements[$delta] += array('#suffix' => $join); + $elements[$delta] += ['#suffix' => $join]; } } }