Issue #2488940 by plach: Contextual links are broken on multilingual sites

8.0.x
Alex Pott 2015-05-18 14:55:26 +01:00
parent 77e8f3095b
commit 0b1a9a3d12
6 changed files with 43 additions and 24 deletions

View File

@ -276,8 +276,8 @@ class DisplayBlockTest extends ViewTestBase {
$cached_block = $this->drupalPlaceBlock('views_block:test_view_block-block_1'); $cached_block = $this->drupalPlaceBlock('views_block:test_view_block-block_1');
$this->drupalGet('test-page'); $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'; $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() . ':|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() . ':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() // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder()
$this->assertRaw('<div' . new Attribute(array('data-contextual-id' => $id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); $this->assertRaw('<div' . new Attribute(array('data-contextual-id' => $id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id)));
$this->assertRaw('<div' . new Attribute(array('data-contextual-id' => $cached_id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $cached_id))); $this->assertRaw('<div' . new Attribute(array('data-contextual-id' => $cached_id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $cached_id)));

View File

@ -7,6 +7,7 @@
use Drupal\Component\Serialization\Json; use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\UrlHelper; use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Routing\RouteMatchInterface; 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. * Serializes #contextual_links property value array to a string.
* *
* Examples: * Examples:
* - node:node=1: * - node:node=1:langcode=en
* - views_ui_edit:view=frontpage:location=page&view_name=frontpage&view_display_id=page_1 * - views_ui_edit:view=frontpage:location=page&view_name=frontpage&view_display_id=page_1&langcode=en
* - menu:menu=tools:|block:block=bartik.tools: * - menu:menu=tools:langcode=en|block:block=bartik.tools:langcode=en
* *
* So, expressed in a pattern: * So, expressed in a pattern:
* <group>:<route parameters>:<metadata> * <group>:<route parameters>:<metadata>
@ -155,9 +156,15 @@ function contextual_contextual_links_view_alter(&$element, $items) {
*/ */
function _contextual_links_to_id($contextual_links) { function _contextual_links_to_id($contextual_links) {
$ids = array(); $ids = array();
$langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId();
foreach ($contextual_links as $group => $args) { foreach ($contextual_links as $group => $args) {
$route_parameters = UrlHelper::buildQuery($args['route_parameters']); $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}"; $ids[] = "{$group}:{$route_parameters}:{$metadata}";
} }
return implode('|', $ids); return implode('|', $ids);

View File

@ -8,6 +8,7 @@
namespace Drupal\contextual\Tests; namespace Drupal\contextual\Tests;
use Drupal\Component\Serialization\Json; use Drupal\Component\Serialization\Json;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\simpletest\WebTestBase; use Drupal\simpletest\WebTestBase;
use Drupal\Core\Template\Attribute; use Drupal\Core\Template\Attribute;
@ -45,7 +46,7 @@ class ContextualDynamicContextTest extends WebTestBase {
* *
* @var array * @var array
*/ */
public static $modules = array('contextual', 'node', 'views', 'views_ui'); public static $modules = array('contextual', 'node', 'views', 'views_ui', 'language');
protected function setUp() { protected function setUp() {
parent::setUp(); parent::setUp();
@ -53,6 +54,9 @@ class ContextualDynamicContextTest extends WebTestBase {
$this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
$this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); $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->editorUser = $this->drupalCreateUser(array('access content', 'access contextual links', 'edit any article content'));
$this->authenticatedUser = $this->drupalCreateUser(array('access content', 'access contextual links')); $this->authenticatedUser = $this->drupalCreateUser(array('access content', 'access contextual links'));
$this->anonymousUser = $this->drupalCreateUser(array('access content')); $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 // Now, on the front page, all article nodes should have contextual links
// placeholders, as should the view that contains them. // placeholders, as should the view that contains them.
$ids = array( $ids = [
'node:node=' . $node1->id() . ':changed=' . $node1->getChangedTime(), 'node:node=' . $node1->id() . ':changed=' . $node1->getChangedTime() . '&langcode=en',
'node:node=' . $node2->id() . ':changed=' . $node2->getChangedTime(), 'node:node=' . $node2->id() . ':changed=' . $node2->getChangedTime() . '&langcode=en',
'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime(), 'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime() . '&langcode=en',
'entity.view.edit_form:view=frontpage:location=page&name=frontpage&display_id=page_1', '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. // Editor user: can access contextual links and can edit articles.
$this->drupalGet('node'); $this->drupalGet('node');
@ -127,6 +131,12 @@ class ContextualDynamicContextTest extends WebTestBase {
$this->assertResponse(403); $this->assertResponse(403);
$this->renderContextualLinks($ids, 'node'); $this->renderContextualLinks($ids, 'node');
$this->assertResponse(403); $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);
} }
/** /**

View File

@ -38,10 +38,10 @@ class ContextualUnitTest extends KernelTestBase {
'route_parameters' => array( 'route_parameters' => array(
'node' => '14031991', 'node' => '14031991',
), ),
'metadata' => array() 'metadata' => array('langcode' => 'en'),
), ),
), ),
'id' => 'node:node=14031991:', 'id' => 'node:node=14031991:langcode=en',
); );
// Test branch conditions: // Test branch conditions:
@ -56,10 +56,10 @@ class ContextualUnitTest extends KernelTestBase {
'key' => 'baz', 'key' => 'baz',
'qux', '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: // Test branch conditions:
@ -75,10 +75,11 @@ class ContextualUnitTest extends KernelTestBase {
'metadata' => array( 'metadata' => array(
'location' => 'page', 'location' => 'page',
'display' => 'page_1', '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: // Test branch conditions:
@ -90,7 +91,7 @@ class ContextualUnitTest extends KernelTestBase {
'route_parameters' => array( 'route_parameters' => array(
'node' => '14031991', 'node' => '14031991',
), ),
'metadata' => array(), 'metadata' => array('langcode' => 'en'),
), ),
'foo' => array( 'foo' => array(
'route_parameters' => array( 'route_parameters' => array(
@ -98,14 +99,14 @@ class ContextualUnitTest extends KernelTestBase {
'key' => 'baz', 'key' => 'baz',
'qux', 'qux',
), ),
'metadata' => array(), 'metadata' => array('langcode' => 'en'),
), ),
'edge' => array( 'edge' => array(
'route_parameters' => array('20011988'), '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; return $tests;
@ -130,4 +131,5 @@ class ContextualUnitTest extends KernelTestBase {
$this->assertIdentical(_contextual_id_to_links($test['id']), $test['links']); $this->assertIdentical(_contextual_id_to_links($test['id']), $test['links']);
} }
} }
} }

View File

@ -567,7 +567,7 @@ class MenuTest extends MenuWebTestBase {
$block = $this->drupalPlaceBlock('system_menu_block:' . $custom_menu->id(), array('label' => 'Custom menu', 'provider' => 'system')); $block = $this->drupalPlaceBlock('system_menu_block:' . $custom_menu->id(), array('label' => 'Custom menu', 'provider' => 'system'));
$this->drupalGet('test-page'); $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() // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder()
$this->assertRaw('<div data-contextual-id="'. $id . '"></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); $this->assertRaw('<div data-contextual-id="'. $id . '"></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id)));

View File

@ -181,7 +181,7 @@ class DisplayTest extends UITestBase {
$this->container->get('router.builder')->rebuildIfNeeded(); $this->container->get('router.builder')->rebuildIfNeeded();
$this->drupalGet('test-display'); $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() // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder()
$this->assertRaw('<div' . new Attribute(array('data-contextual-id' => $id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); $this->assertRaw('<div' . new Attribute(array('data-contextual-id' => $id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id)));