diff --git a/core/modules/block/src/Tests/Views/DisplayBlockTest.php b/core/modules/block/src/Tests/Views/DisplayBlockTest.php index 7f3665a8923..56e7354791e 100644 --- a/core/modules/block/src/Tests/Views/DisplayBlockTest.php +++ b/core/modules/block/src/Tests/Views/DisplayBlockTest.php @@ -276,8 +276,8 @@ class DisplayBlockTest extends ViewTestBase { $cached_block = $this->drupalPlaceBlock('views_block:test_view_block-block_1'); $this->drupalGet('test-page'); - $id = 'block:block=' . $block->id() . ':|entity.view.edit_form:view=test_view_block:location=block&name=test_view_block&display_id=block_1'; - $cached_id = 'block:block=' . $cached_block->id() . ':|entity.view.edit_form:view=test_view_block:location=block&name=test_view_block&display_id=block_1'; + $id = 'block:block=' . $block->id() . ':langcode=en|entity.view.edit_form:view=test_view_block:location=block&name=test_view_block&display_id=block_1&langcode=en'; + $cached_id = 'block:block=' . $cached_block->id() . ':langcode=en|entity.view.edit_form:view=test_view_block:location=block&name=test_view_block&display_id=block_1&langcode=en'; // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() $this->assertRaw(' $id)) . '>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); $this->assertRaw(' $cached_id)) . '>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $cached_id))); diff --git a/core/modules/contextual/contextual.module b/core/modules/contextual/contextual.module index b7e8ef24ff2..a0cd5b640cd 100644 --- a/core/modules/contextual/contextual.module +++ b/core/modules/contextual/contextual.module @@ -7,6 +7,7 @@ use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\UrlHelper; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Routing\RouteMatchInterface; /** @@ -137,9 +138,9 @@ function contextual_contextual_links_view_alter(&$element, $items) { * Serializes #contextual_links property value array to a string. * * Examples: - * - node:node=1: - * - views_ui_edit:view=frontpage:location=page&view_name=frontpage&view_display_id=page_1 - * - menu:menu=tools:|block:block=bartik.tools: + * - node:node=1:langcode=en + * - views_ui_edit:view=frontpage:location=page&view_name=frontpage&view_display_id=page_1&langcode=en + * - menu:menu=tools:langcode=en|block:block=bartik.tools:langcode=en * * So, expressed in a pattern: * :: @@ -155,9 +156,15 @@ function contextual_contextual_links_view_alter(&$element, $items) { */ function _contextual_links_to_id($contextual_links) { $ids = array(); + $langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId(); foreach ($contextual_links as $group => $args) { $route_parameters = UrlHelper::buildQuery($args['route_parameters']); - $metadata = UrlHelper::buildQuery((isset($args['metadata'])) ? $args['metadata'] : array()); + $args += ['metadata' => []]; + // Add the current URL language to metadata so a different ID will be + // computed when URLs vary by language. This allows to store different + // language-aware contextual links on the client side. + $args['metadata'] += ['langcode' => $langcode]; + $metadata = UrlHelper::buildQuery($args['metadata']); $ids[] = "{$group}:{$route_parameters}:{$metadata}"; } return implode('|', $ids); diff --git a/core/modules/contextual/src/Tests/ContextualDynamicContextTest.php b/core/modules/contextual/src/Tests/ContextualDynamicContextTest.php index 20d55cd178b..01eb4f57d0f 100644 --- a/core/modules/contextual/src/Tests/ContextualDynamicContextTest.php +++ b/core/modules/contextual/src/Tests/ContextualDynamicContextTest.php @@ -8,6 +8,7 @@ namespace Drupal\contextual\Tests; use Drupal\Component\Serialization\Json; +use Drupal\language\Entity\ConfigurableLanguage; use Drupal\simpletest\WebTestBase; use Drupal\Core\Template\Attribute; @@ -45,7 +46,7 @@ class ContextualDynamicContextTest extends WebTestBase { * * @var array */ - public static $modules = array('contextual', 'node', 'views', 'views_ui'); + public static $modules = array('contextual', 'node', 'views', 'views_ui', 'language'); protected function setUp() { parent::setUp(); @@ -53,6 +54,9 @@ class ContextualDynamicContextTest extends WebTestBase { $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + ConfigurableLanguage::createFromLangcode('it')->save(); + $this->rebuildContainer(); + $this->editorUser = $this->drupalCreateUser(array('access content', 'access contextual links', 'edit any article content')); $this->authenticatedUser = $this->drupalCreateUser(array('access content', 'access contextual links')); $this->anonymousUser = $this->drupalCreateUser(array('access content')); @@ -77,12 +81,12 @@ class ContextualDynamicContextTest extends WebTestBase { // Now, on the front page, all article nodes should have contextual links // placeholders, as should the view that contains them. - $ids = array( - 'node:node=' . $node1->id() . ':changed=' . $node1->getChangedTime(), - 'node:node=' . $node2->id() . ':changed=' . $node2->getChangedTime(), - 'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime(), - 'entity.view.edit_form:view=frontpage:location=page&name=frontpage&display_id=page_1', - ); + $ids = [ + 'node:node=' . $node1->id() . ':changed=' . $node1->getChangedTime() . '&langcode=en', + 'node:node=' . $node2->id() . ':changed=' . $node2->getChangedTime() . '&langcode=en', + 'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime() . '&langcode=en', + 'entity.view.edit_form:view=frontpage:location=page&name=frontpage&display_id=page_1&langcode=en', + ]; // Editor user: can access contextual links and can edit articles. $this->drupalGet('node'); @@ -127,6 +131,12 @@ class ContextualDynamicContextTest extends WebTestBase { $this->assertResponse(403); $this->renderContextualLinks($ids, 'node'); $this->assertResponse(403); + + // Verify that link language is properly handled. + $node3->addTranslation('it')->save(); + $id = 'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime() . '&langcode=it'; + $this->drupalGet('node', ['language' => ConfigurableLanguage::createFromLangcode('it')]); + $this->assertContextualLinkPlaceHolder($id); } /** diff --git a/core/modules/contextual/src/Tests/ContextualUnitTest.php b/core/modules/contextual/src/Tests/ContextualUnitTest.php index bd145f646fe..f164051d6b5 100644 --- a/core/modules/contextual/src/Tests/ContextualUnitTest.php +++ b/core/modules/contextual/src/Tests/ContextualUnitTest.php @@ -38,10 +38,10 @@ class ContextualUnitTest extends KernelTestBase { 'route_parameters' => array( 'node' => '14031991', ), - 'metadata' => array() + 'metadata' => array('langcode' => 'en'), ), ), - 'id' => 'node:node=14031991:', + 'id' => 'node:node=14031991:langcode=en', ); // Test branch conditions: @@ -56,10 +56,10 @@ class ContextualUnitTest extends KernelTestBase { 'key' => 'baz', 'qux', ), - 'metadata' => array(), + 'metadata' => array('langcode' => 'en'), ), ), - 'id' => 'foo:0=bar&key=baz&1=qux:', + 'id' => 'foo:0=bar&key=baz&1=qux:langcode=en', ); // Test branch conditions: @@ -75,10 +75,11 @@ class ContextualUnitTest extends KernelTestBase { 'metadata' => array( 'location' => 'page', 'display' => 'page_1', + 'langcode' => 'en', ), ), ), - 'id' => 'views_ui_edit:view=frontpage:location=page&display=page_1', + 'id' => 'views_ui_edit:view=frontpage:location=page&display=page_1&langcode=en', ); // Test branch conditions: @@ -90,7 +91,7 @@ class ContextualUnitTest extends KernelTestBase { 'route_parameters' => array( 'node' => '14031991', ), - 'metadata' => array(), + 'metadata' => array('langcode' => 'en'), ), 'foo' => array( 'route_parameters' => array( @@ -98,14 +99,14 @@ class ContextualUnitTest extends KernelTestBase { 'key' => 'baz', 'qux', ), - 'metadata' => array(), + 'metadata' => array('langcode' => 'en'), ), 'edge' => array( 'route_parameters' => array('20011988'), - 'metadata' => array(), + 'metadata' => array('langcode' => 'en'), ), ), - 'id' => 'node:node=14031991:|foo:0=bar&key=baz&1=qux:|edge:0=20011988:', + 'id' => 'node:node=14031991:langcode=en|foo:0=bar&key=baz&1=qux:langcode=en|edge:0=20011988:langcode=en', ); return $tests; @@ -130,4 +131,5 @@ class ContextualUnitTest extends KernelTestBase { $this->assertIdentical(_contextual_id_to_links($test['id']), $test['links']); } } + } diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/src/Tests/MenuTest.php index 722548f04d7..de0ec7a6d27 100644 --- a/core/modules/menu_ui/src/Tests/MenuTest.php +++ b/core/modules/menu_ui/src/Tests/MenuTest.php @@ -567,7 +567,7 @@ class MenuTest extends MenuWebTestBase { $block = $this->drupalPlaceBlock('system_menu_block:' . $custom_menu->id(), array('label' => 'Custom menu', 'provider' => 'system')); $this->drupalGet('test-page'); - $id = 'block:block=' . $block->id() . ':|menu:menu=' . $custom_menu->id() . ':'; + $id = 'block:block=' . $block->id() . ':langcode=en|menu:menu=' . $custom_menu->id() . ':langcode=en'; // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() $this->assertRaw('
', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); diff --git a/core/modules/views_ui/src/Tests/DisplayTest.php b/core/modules/views_ui/src/Tests/DisplayTest.php index 12c06bded26..a735c219bf4 100644 --- a/core/modules/views_ui/src/Tests/DisplayTest.php +++ b/core/modules/views_ui/src/Tests/DisplayTest.php @@ -181,7 +181,7 @@ class DisplayTest extends UITestBase { $this->container->get('router.builder')->rebuildIfNeeded(); $this->drupalGet('test-display'); - $id = 'entity.view.edit_form:view=test_display:location=page&name=test_display&display_id=page_1'; + $id = 'entity.view.edit_form:view=test_display:location=page&name=test_display&display_id=page_1&langcode=en'; // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() $this->assertRaw(' $id)) . '>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id)));