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');
$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('<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)));

View File

@ -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:
* <group>:<route parameters>:<metadata>
@ -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);

View File

@ -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);
}
/**

View File

@ -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']);
}
}
}

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'));
$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('<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->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('<div' . new Attribute(array('data-contextual-id' => $id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id)));