Issue #2428103 by dawehner, amateescu, Berdir, AjitS: String formatter should link to its translation
parent
b5f7cccde4
commit
74db053104
|
@ -204,8 +204,15 @@ abstract class Entity implements EntityInterface {
|
|||
$uri
|
||||
->setOption('entity_type', $this->getEntityTypeId())
|
||||
->setOption('entity', $this);
|
||||
|
||||
// Display links by default based on the current language.
|
||||
if ($rel !== 'collection') {
|
||||
$options += ['language' => $this->language()];
|
||||
}
|
||||
|
||||
$uri_options = $uri->getOptions();
|
||||
$uri_options += $options;
|
||||
|
||||
return $uri->setOptions($uri_options);
|
||||
}
|
||||
|
||||
|
@ -323,13 +330,16 @@ abstract class Entity implements EntityInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function language() {
|
||||
$langcode = $this->{$this->getEntityType()->getKey('langcode')};
|
||||
$language = $this->languageManager()->getLanguage($langcode);
|
||||
if (!$language) {
|
||||
// Make sure we return a proper language object.
|
||||
$langcode = $this->langcode ?: LanguageInterface::LANGCODE_NOT_SPECIFIED;
|
||||
$language = new Language(array('id' => $langcode));
|
||||
if ($key = $this->getEntityType()->getKey('langcode')) {
|
||||
$langcode = $this->$key;
|
||||
$language = $this->languageManager()->getLanguage($langcode);
|
||||
if ($language) {
|
||||
return $language;
|
||||
}
|
||||
}
|
||||
// Make sure we return a proper language object.
|
||||
$langcode = !empty($this->langcode) ? $this->langcode : LanguageInterface::LANGCODE_NOT_SPECIFIED;
|
||||
$language = new Language(array('id' => $langcode));
|
||||
return $language;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\language\Tests\EntityUrlLanguageTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\language\Tests;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the language of entity URLs.
|
||||
* @group language
|
||||
*/
|
||||
class EntityUrlLanguageTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['language', 'entity_test', 'user', 'system'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('entity_test');
|
||||
$this->installEntitySchema('configurable_language');
|
||||
$this->installSchema('system', 'router');
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
// In order to reflect the changes for a multilingual site in the container
|
||||
// we have to rebuild it.
|
||||
ConfigurableLanguage::create(['id' => 'es'])->save();
|
||||
ConfigurableLanguage::create(['id' => 'fr'])->save();
|
||||
|
||||
$this->config('language.types')->setData([
|
||||
'configurable' => ['language_interface'],
|
||||
'negotiation' => ['language_interface' => ['enabled' => ['language-url' => 0]]],
|
||||
])->save();
|
||||
$this->config('language.negotiation')->setData([
|
||||
'url' => [
|
||||
'source' => 'path_prefix',
|
||||
'prefixes' => ['en' => 'en', 'es' => 'es', 'fr' => 'fr']
|
||||
],
|
||||
])->save();
|
||||
$this->kernel->rebuildContainer();
|
||||
$this->container = $this->kernel->getContainer();
|
||||
\Drupal::setContainer($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that entity URLs in a language have the right language prefix.
|
||||
*/
|
||||
public function testEntityUrlLanguage() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->addTranslation('es', ['name' => 'name spanish']);
|
||||
$entity->addTranslation('fr', ['name' => 'name french']);
|
||||
$entity->save();
|
||||
|
||||
$this->assertTrue(strpos($entity->urlInfo()->toString(), '/en/entity_test/' . $entity->id()) !== FALSE);
|
||||
$this->assertTrue(strpos($entity->getTranslation('es')->urlInfo()->toString(), '/es/entity_test/' . $entity->id()) !== FALSE);
|
||||
$this->assertTrue(strpos($entity->getTranslation('fr')->urlInfo()->toString(), '/fr/entity_test/' . $entity->id()) !== FALSE);
|
||||
}
|
||||
|
||||
}
|
|
@ -49,7 +49,9 @@ class StatisticsReportsTest extends StatisticsTestBase {
|
|||
$this->assertText('All time', 'Found the all time popular content.');
|
||||
$this->assertText('Last viewed', 'Found the last viewed popular content.');
|
||||
|
||||
$this->assertRaw(\Drupal::l($node->label(), $node->urlInfo()), 'Found link to visited node.');
|
||||
// statistics.module doesn't use node entities, prevent the node language
|
||||
// from being added to the options.
|
||||
$this->assertRaw(\Drupal::l($node->label(), $node->urlInfo('canonical', ['language' => NULL])), 'Found link to visited node.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -211,6 +211,8 @@ class TermIndexTest extends TaxonomyTestBase {
|
|||
|
||||
// Verify that the page breadcrumbs include a link to the parent term.
|
||||
$this->drupalGet('taxonomy/term/' . $term1->id());
|
||||
$this->assertRaw(\Drupal::l($term2->getName(), $term2->urlInfo()), 'Parent term link is displayed when viewing the node.');
|
||||
// Breadcrumbs are not rendered with a language, prevent the term
|
||||
// language from being added to the options.
|
||||
$this->assertRaw(\Drupal::l($term2->getName(), $term2->urlInfo('canonical', ['language' => NULL])), 'Parent term link is displayed when viewing the node.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,10 +122,10 @@ class FieldEntityLinkTest extends ViewUnitTestBase {
|
|||
if ($expected_result) {
|
||||
$path = $entity->url($template);
|
||||
$destination = $info[$template]['destination'] ? '?destination=/' : '';
|
||||
$expected_link = '<a href="' . $path . $destination . '">' . $info[$template]['label'] . '</a>';
|
||||
$expected_link = '<a href="' . $path . $destination . '" hreflang="en">' . $info[$template]['label'] . '</a>';
|
||||
}
|
||||
$link = $view->style_plugin->getField($index, $info[$template]['field_id']);
|
||||
$this->assertEqual($link, $expected_link, SafeMarkup::format('@template entity link behaves as expected.', ['@template' => $template]));
|
||||
$this->assertEqual($link, $expected_link);
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
|
|
@ -302,7 +302,8 @@ class FieldFieldTest extends ViewUnitTestBase {
|
|||
for ($i = 0; $i < 5; $i++) {
|
||||
$this->assertEqual($i + 1, $executable->getStyle()->getField($i, 'id'));
|
||||
$this->assertEqual('test ' . $i, $executable->getStyle()->getField($i, 'name'));
|
||||
$this->assertEqual('<a href="' . EntityTest::load($i + 1)->url() . '">test ' . $i . '</a>', $executable->getStyle()->getField($i, 'name_alias'));
|
||||
$entity = EntityTest::load($i + 1);
|
||||
$this->assertEqual('<a href="' . $entity->url() . '" hreflang="' . $entity->language()->getId() . '">test ' . $i . '</a>', $executable->getStyle()->getField($i, 'name_alias'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\Tests\Core\Entity;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Link;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
|
@ -31,6 +32,13 @@ class EntityLinkTest extends UnitTestCase {
|
|||
*/
|
||||
protected $linkGenerator;
|
||||
|
||||
/**
|
||||
* The mocked language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -39,10 +47,12 @@ class EntityLinkTest extends UnitTestCase {
|
|||
|
||||
$this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
|
||||
$this->linkGenerator = $this->getMock('Drupal\Core\Utility\LinkGeneratorInterface');
|
||||
$this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
$container->set('entity.manager', $this->entityManager);
|
||||
$container->set('link_generator', $this->linkGenerator);
|
||||
$container->set('language_manager', $this->languageManager);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
|
@ -52,6 +62,13 @@ class EntityLinkTest extends UnitTestCase {
|
|||
* @dataProvider providerTestLink
|
||||
*/
|
||||
public function testLink($entity_label, $link_text, $expected_text, $link_rel = 'canonical', array $link_options = []) {
|
||||
$language = new Language(['id' => 'es']);
|
||||
$link_options += ['language' => $language];
|
||||
$this->languageManager->expects($this->any())
|
||||
->method('getLanguage')
|
||||
->with('es')
|
||||
->willReturn($language);
|
||||
|
||||
$route_name_map = [
|
||||
'canonical' => 'entity.test_entity_type.canonical',
|
||||
'edit-form' => 'entity.test_entity_type.edit_form',
|
||||
|
@ -67,8 +84,10 @@ class EntityLinkTest extends UnitTestCase {
|
|||
->willReturn($route_name_map);
|
||||
$entity_type->expects($this->any())
|
||||
->method('getKey')
|
||||
->with('label')
|
||||
->willReturn('label');
|
||||
->willReturnMap([
|
||||
['label', 'label'],
|
||||
['langcode', 'langcode'],
|
||||
]);
|
||||
|
||||
$this->entityManager
|
||||
->expects($this->any())
|
||||
|
@ -78,7 +97,7 @@ class EntityLinkTest extends UnitTestCase {
|
|||
|
||||
/** @var \Drupal\Core\Entity\Entity $entity */
|
||||
$entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', [
|
||||
['id' => $entity_id, 'label' => $entity_label],
|
||||
['id' => $entity_id, 'label' => $entity_label, 'langcode' => 'es'],
|
||||
$entity_type_id
|
||||
]);
|
||||
|
||||
|
|
|
@ -7,8 +7,11 @@
|
|||
|
||||
namespace Drupal\Tests\Core\Entity;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityInterface;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -51,13 +54,39 @@ class EntityUrlTest extends UnitTestCase {
|
|||
*
|
||||
* @dataProvider providerTestUrlInfo
|
||||
*/
|
||||
public function testUrlInfo($entity_class, $link_template, $expected) {
|
||||
public function testUrlInfo($entity_class, $link_template, $expected, $langcode = NULL) {
|
||||
/** @var $entity \Drupal\Core\Entity\EntityInterface */
|
||||
$entity = $this->getMockForAbstractClass($entity_class, array(array('id' => 'test_entity_id'), 'test_entity_type'));
|
||||
$uri = $this->getTestUrlInfo($entity, $link_template);
|
||||
$uri = $this->getTestUrlInfo($entity, $link_template, [], $langcode);
|
||||
|
||||
$this->assertSame($expected, $uri->getRouteName());
|
||||
$this->assertSame($entity, $uri->getOption('entity'));
|
||||
|
||||
if ($langcode) {
|
||||
$this->assertEquals($langcode, $uri->getOption('language')->getId());
|
||||
}
|
||||
else {
|
||||
// The expected langcode for a config entity is 'en', because it sets the
|
||||
// value as default property.
|
||||
$expected_langcode = $entity instanceof ConfigEntityInterface ? 'en' : LanguageInterface::LANGCODE_NOT_SPECIFIED;
|
||||
$this->assertEquals($expected_langcode, $uri->getOption('language')->getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::urlInfo
|
||||
*/
|
||||
public function testUrlInfoWithSpecificLanguageInOptions() {
|
||||
/** @var $entity \Drupal\Core\Entity\EntityInterface */
|
||||
$entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', array(array('id' => 'test_entity_id'), 'test_entity_type'));
|
||||
|
||||
// Ensure that a specified language overrides the current translation
|
||||
// language.
|
||||
$uri = $this->getTestUrlInfo($entity, 'edit-form', [], 'en');
|
||||
$this->assertEquals('en', $uri->getOption('language')->getId());
|
||||
|
||||
$uri = $this->getTestUrlInfo($entity, 'edit-form', ['language' => new Language(['id' => 'fr'])], 'en');
|
||||
$this->assertEquals('fr', $uri->getOption('language')->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,10 +94,13 @@ class EntityUrlTest extends UnitTestCase {
|
|||
*/
|
||||
public function providerTestUrlInfo() {
|
||||
return array(
|
||||
array('Drupal\Core\Entity\Entity', 'edit-form', 'entity.test_entity_type.edit_form'),
|
||||
array('Drupal\Core\Config\Entity\ConfigEntityBase', 'edit-form', 'entity.test_entity_type.edit_form'),
|
||||
array('Drupal\Core\Entity\Entity', 'edit-form', 'entity.test_entity_type.edit_form', NULL),
|
||||
// Specify a langcode.
|
||||
array('Drupal\Core\Entity\Entity', 'edit-form', 'entity.test_entity_type.edit_form', 'es'),
|
||||
array('Drupal\Core\Entity\Entity', 'edit-form', 'entity.test_entity_type.edit_form', 'en'),
|
||||
array('Drupal\Core\Config\Entity\ConfigEntityBase', 'edit-form', 'entity.test_entity_type.edit_form', NULL),
|
||||
// Test that overriding the default $rel parameter works.
|
||||
array('Drupal\Core\Config\Entity\ConfigEntityBase', FALSE, 'entity.test_entity_type.edit_form'),
|
||||
array('Drupal\Core\Config\Entity\ConfigEntityBase', FALSE, 'entity.test_entity_type.edit_form', NULL),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -108,18 +140,24 @@ class EntityUrlTest extends UnitTestCase {
|
|||
* The test entity.
|
||||
* @param string $link_template
|
||||
* The link template.
|
||||
* @param string $langcode
|
||||
* The langcode.
|
||||
*
|
||||
* @return \Drupal\Core\Url
|
||||
* The URL for this entity's link template.
|
||||
*/
|
||||
protected function getTestUrlInfo(EntityInterface $entity, $link_template) {
|
||||
protected function getTestUrlInfo(EntityInterface $entity, $link_template, array $options = [], $langcode = NULL) {
|
||||
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
|
||||
$entity_type->expects($this->once())
|
||||
$entity_type->expects($this->any())
|
||||
->method('getLinkTemplates')
|
||||
->will($this->returnValue(array(
|
||||
'edit-form' => 'test_entity_type.edit',
|
||||
)));
|
||||
|
||||
if ($langcode) {
|
||||
$entity->langcode = $langcode;
|
||||
}
|
||||
|
||||
$this->entityManager
|
||||
->expects($this->any())
|
||||
->method('getDefinition')
|
||||
|
@ -128,10 +166,15 @@ class EntityUrlTest extends UnitTestCase {
|
|||
|
||||
// If no link template is given, call without a value to test the default.
|
||||
if ($link_template) {
|
||||
$uri = $entity->urlInfo($link_template);
|
||||
$uri = $entity->urlInfo($link_template, $options);
|
||||
}
|
||||
else {
|
||||
$uri = $entity->urlInfo();
|
||||
if ($entity instanceof ConfigEntityInterface) {
|
||||
$uri = $entity->urlInfo('edit-form', $options);
|
||||
}
|
||||
else {
|
||||
$uri = $entity->urlInfo('canonical', $options);
|
||||
}
|
||||
}
|
||||
|
||||
return $uri;
|
||||
|
@ -158,14 +201,14 @@ class EntityUrlTest extends UnitTestCase {
|
|||
*/
|
||||
public function testUrl() {
|
||||
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
|
||||
$entity_type->expects($this->exactly(5))
|
||||
$entity_type->expects($this->any())
|
||||
->method('getLinkTemplates')
|
||||
->will($this->returnValue(array(
|
||||
'canonical' => 'test_entity_type.view',
|
||||
)));
|
||||
|
||||
$this->entityManager
|
||||
->expects($this->exactly(5))
|
||||
->expects($this->any())
|
||||
->method('getDefinition')
|
||||
->with('test_entity_type')
|
||||
->will($this->returnValue($entity_type));
|
||||
|
@ -177,22 +220,20 @@ class EntityUrlTest extends UnitTestCase {
|
|||
$this->assertSame('', $no_link_entity->url('banana'));
|
||||
|
||||
$valid_entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', array(array('id' => 'test_entity_id'), 'test_entity_type'));
|
||||
$this->urlGenerator->expects($this->exactly(2))
|
||||
|
||||
$language = new Language(array('id' => LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
$this->urlGenerator->expects($this->any())
|
||||
->method('generateFromRoute')
|
||||
->will($this->returnValueMap(array(
|
||||
array(
|
||||
'entity.test_entity_type.canonical',
|
||||
array('test_entity_type' => 'test_entity_id'),
|
||||
array('entity_type' => 'test_entity_type', 'entity' => $valid_entity),
|
||||
'/entity/test_entity_type/test_entity_id',
|
||||
),
|
||||
array(
|
||||
'entity.test_entity_type.canonical',
|
||||
array('test_entity_type' => 'test_entity_id'),
|
||||
array('absolute' => TRUE, 'entity_type' => 'test_entity_type', 'entity' => $valid_entity),
|
||||
'http://drupal/entity/test_entity_type/test_entity_id',
|
||||
),
|
||||
)));
|
||||
// Sadly returnValueMap() uses ===, see \PHPUnit_Framework_MockObject_Stub_ReturnValueMap::invoke
|
||||
// so the $language object can't be compared directly.
|
||||
->willReturnCallback(function ($route_name, $route_parameters, $options) use ($language) {
|
||||
if ($route_name === 'entity.test_entity_type.canonical' && $route_parameters === array('test_entity_type' => 'test_entity_id') && array_keys($options) === ['entity_type', 'entity', 'language'] && $options['language'] == $language) {
|
||||
return '/entity/test_entity_type/test_entity_id';
|
||||
}
|
||||
if ($route_name === 'entity.test_entity_type.canonical' && $route_parameters === array('test_entity_type' => 'test_entity_id') && array_keys($options) === ['absolute', 'entity_type', 'entity', 'language'] && $options['language'] == $language) {
|
||||
return 'http://drupal/entity/test_entity_type/test_entity_id';
|
||||
}
|
||||
});
|
||||
|
||||
$this->assertSame('/entity/test_entity_type/test_entity_id', $valid_entity->url());
|
||||
$this->assertSame('http://drupal/entity/test_entity_type/test_entity_id', $valid_entity->url('canonical', array('absolute' => TRUE)));
|
||||
|
@ -205,14 +246,14 @@ class EntityUrlTest extends UnitTestCase {
|
|||
*/
|
||||
public function testGetSystemPath() {
|
||||
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
|
||||
$entity_type->expects($this->exactly(3))
|
||||
$entity_type->expects($this->any())
|
||||
->method('getLinkTemplates')
|
||||
->will($this->returnValue(array(
|
||||
'canonical' => 'entity.test_entity_type.canonical',
|
||||
)));
|
||||
|
||||
$this->entityManager
|
||||
->expects($this->exactly(3))
|
||||
->expects($this->any())
|
||||
->method('getDefinition')
|
||||
->with('test_entity_type')
|
||||
->will($this->returnValue($entity_type));
|
||||
|
|
Loading…
Reference in New Issue