Commit 68755a3b authored by webchick's avatar webchick

Issue #2188675 by Gábor Hojtsy, marthinal, fran seva, robertdbailey,...

Issue #2188675 by Gábor Hojtsy, marthinal, fran seva, robertdbailey, Jalandhar, vijaycs85, dlu, kfritsche, YesCT, pfrenssen: Fixed Translate local task always visible, leads to WSOD.
parent 777bc650
...@@ -246,8 +246,10 @@ public function getRevisionId() { ...@@ -246,8 +246,10 @@ public function getRevisionId() {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function isTranslatable() { public function isTranslatable() {
// Check that the bundle is translatable, the entity has a language defined
// and if we have more than one language on the site.
$bundles = $this->entityManager()->getBundleInfo($this->entityTypeId); $bundles = $this->entityManager()->getBundleInfo($this->entityTypeId);
return !empty($bundles[$this->bundle()]['translatable']); return !empty($bundles[$this->bundle()]['translatable']) && empty($this->getUntranslated()->language()->locked) && $this->languageManager()->isMultilingual();
} }
/** /**
...@@ -513,7 +515,7 @@ public function getFieldDefinition($name) { ...@@ -513,7 +515,7 @@ public function getFieldDefinition($name) {
*/ */
public function getFieldDefinitions() { public function getFieldDefinitions() {
if (!isset($this->fieldDefinitions)) { if (!isset($this->fieldDefinitions)) {
$this->fieldDefinitions = \Drupal::entityManager()->getFieldDefinitions($this->entityTypeId, $this->bundle()); $this->fieldDefinitions = $this->entityManager()->getFieldDefinitions($this->entityTypeId, $this->bundle());
} }
return $this->fieldDefinitions; return $this->fieldDefinitions;
} }
......
...@@ -47,7 +47,8 @@ public function __construct(EntityManagerInterface $manager) { ...@@ -47,7 +47,8 @@ public function __construct(EntityManagerInterface $manager) {
*/ */
public function access(Request $request, AccountInterface $account) { public function access(Request $request, AccountInterface $account) {
$entity_type = $request->attributes->get('entity_type_id'); $entity_type = $request->attributes->get('entity_type_id');
if ($entity = $request->attributes->get($entity_type)) { $entity = $request->attributes->get($entity_type);
if ($entity && $entity->isTranslatable()) {
// Get entity base info. // Get entity base info.
$bundle = $entity->bundle(); $bundle = $entity->bundle();
...@@ -59,6 +60,11 @@ public function access(Request $request, AccountInterface $account) { ...@@ -59,6 +60,11 @@ public function access(Request $request, AccountInterface $account) {
return static::ALLOW; return static::ALLOW;
} }
// Check "translate any entity" permission.
if ($account->hasPermission('translate any entity')) {
return static::ALLOW;
}
// Check per entity permission. // Check per entity permission.
$permission = "translate {$entity_type}"; $permission = "translate {$entity_type}";
if ($definition->getPermissionGranularity() == 'bundle') { if ($definition->getPermissionGranularity() == 'bundle') {
......
...@@ -61,10 +61,8 @@ protected function alterRoutes(RouteCollection $collection) { ...@@ -61,10 +61,8 @@ protected function alterRoutes(RouteCollection $collection) {
), ),
array( array(
'_access_content_translation_overview' => $entity_type_id, '_access_content_translation_overview' => $entity_type_id,
'_permission' => 'translate any entity',
), ),
array( array(
'_access_mode' => AccessManagerInterface::ACCESS_MODE_ANY,
'parameters' => array( 'parameters' => array(
$entity_type_id => array( $entity_type_id => array(
'type' => 'entity:' . $entity_type_id, 'type' => 'entity:' . $entity_type_id,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Drupal\content_translation\Tests; namespace Drupal\content_translation\Tests;
use Drupal\Component\Serialization\Json; use Drupal\Component\Serialization\Json;
use Drupal\Core\Language\Language;
use Drupal\node\Entity\NodeType; use Drupal\node\Entity\NodeType;
use Drupal\simpletest\WebTestBase; use Drupal\simpletest\WebTestBase;
...@@ -39,6 +40,13 @@ class ContentTranslationContextualLinksTest extends WebTestBase { ...@@ -39,6 +40,13 @@ class ContentTranslationContextualLinksTest extends WebTestBase {
*/ */
protected $translator; protected $translator;
/**
* The enabled languages.
*
* @var array
*/
protected $langcodes;
/** /**
* Modules to enable. * Modules to enable.
* *
...@@ -55,11 +63,48 @@ class ContentTranslationContextualLinksTest extends WebTestBase { ...@@ -55,11 +63,48 @@ class ContentTranslationContextualLinksTest extends WebTestBase {
protected function setUp() { protected function setUp() {
parent::setUp(); parent::setUp();
// Set up an additional language.
$this->langcodes = array(language_default()->id, 'es');
language_save(new Language(array('id' => 'es')));
// Create a content type. // Create a content type.
$this->bundle = $this->randomMachineName(); $this->bundle = $this->randomMachineName();
$this->contentType = $this->drupalCreateContentType(array('type' => $this->bundle)); $this->contentType = $this->drupalCreateContentType(array('type' => $this->bundle));
// Enable translation for the current entity type and ensure the change is
// picked up.
content_translation_set_config('node', $this->bundle, 'enabled', TRUE);
drupal_static_reset();
\Drupal::entityManager()->clearCachedBundles();
\Drupal::service('router.builder')->rebuild();
// Add a translatable field to the content type.
entity_create('field_storage_config', array(
'name' => 'field_test_text',
'entity_type' => 'node',
'type' => 'text',
'cardinality' => 1,
'translatable' => TRUE,
))->save();
entity_create('field_instance_config', array(
'entity_type' => 'node',
'field_name' => 'field_test_text',
'bundle' => $this->bundle,
'label' => 'Test text-field',
))->save();
entity_get_form_display('node', $this->bundle, 'default')
->setComponent('field_test_text', array(
'type' => 'text_textfield',
'weight' => 0,
))
->save();
// Enable content translation.
$configuration = array(
'langcode' => language_default()->id,
'language_show' => TRUE,
);
language_save_default_configuration('node', $this->bundle, $configuration);
// Create a translator user. // Create a translator user.
$permissions = array( $permissions = array(
'access contextual links', 'access contextual links',
...@@ -76,7 +121,7 @@ protected function setUp() { ...@@ -76,7 +121,7 @@ protected function setUp() {
public function testContentTranslationContextualLinks() { public function testContentTranslationContextualLinks() {
// Create a node. // Create a node.
$title = $this->randomString(); $title = $this->randomString();
$this->drupalCreateNode(array('type' => $this->bundle, 'title' => $title)); $this->drupalCreateNode(array('type' => $this->bundle, 'title' => $title, 'langcode' => 'en'));
$node = $this->drupalGetNodeByTitle($title); $node = $this->drupalGetNodeByTitle($title);
// Check that the translate link appears on the node page. // Check that the translate link appears on the node page.
......
...@@ -194,6 +194,9 @@ function testTranslationLinkTheme() { ...@@ -194,6 +194,9 @@ function testTranslationLinkTheme() {
$this->drupalPostForm('admin/appearance', $edit, t('Save configuration')); $this->drupalPostForm('admin/appearance', $edit, t('Save configuration'));
$this->drupalGet('node/' . $article->id() . '/translations'); $this->drupalGet('node/' . $article->id() . '/translations');
$this->assertNoRaw('"theme":"seven"', 'Translation uses frontend theme if edit is frontend.'); $this->assertNoRaw('"theme":"seven"', 'Translation uses frontend theme if edit is frontend.');
// Assert presence of translation page itself (vs. DisabledBundle below).
$this->assertResponse(200);
} }
/** /**
...@@ -205,13 +208,15 @@ public function testDisabledBundle() { ...@@ -205,13 +208,15 @@ public function testDisabledBundle() {
$this->drupalCreateContentType(array('type' => $disabledBundle, 'name' => $disabledBundle)); $this->drupalCreateContentType(array('type' => $disabledBundle, 'name' => $disabledBundle));
// Create a node for each bundle. // Create a node for each bundle.
$enabledNode = $this->drupalCreateNode(array('type' => $this->bundle)); $node = $this->drupalCreateNode(array('type' => $this->bundle));
// Make sure that only a single row was inserted into the // Make sure that nothing was inserted into the {content_translation} table.
// {content_translation} table.
$rows = db_query('SELECT * FROM {content_translation}')->fetchAll(); $rows = db_query('SELECT * FROM {content_translation}')->fetchAll();
$this->assertEqual(1, count($rows)); $this->assertEqual(0, count($rows));
$this->assertEqual($enabledNode->id(), reset($rows)->entity_id);
// Ensure the translation tab is not accessible.
$this->drupalGet('node/' . $node->id() . '/translations');
$this->assertResponse(403);
} }
/** /**
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldItemBase; use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Tests\UnitTestCase; use Drupal\Tests\UnitTestCase;
use Drupal\Core\Language\Language; use Drupal\Core\Language\Language;
...@@ -33,6 +34,13 @@ class ContentEntityBaseUnitTest extends UnitTestCase { ...@@ -33,6 +34,13 @@ class ContentEntityBaseUnitTest extends UnitTestCase {
*/ */
protected $entity; protected $entity;
/**
* An entity with no defined language to test.
*
* @var \Drupal\Core\Entity\ContentEntityBase|\PHPUnit_Framework_MockObject_MockObject
*/
protected $entityUnd;
/** /**
* The entity type used for testing. * The entity type used for testing.
* *
...@@ -103,8 +111,8 @@ protected function setUp() { ...@@ -103,8 +111,8 @@ protected function setUp() {
$this->id = 1; $this->id = 1;
$values = array( $values = array(
'id' => $this->id, 'id' => $this->id,
'langcode' => 'en',
'uuid' => '3bb9ee60-bea5-4622-b89b-a63319d10b3a', 'uuid' => '3bb9ee60-bea5-4622-b89b-a63319d10b3a',
'defaultLangcode' => array(LanguageInterface::LANGCODE_DEFAULT => 'en'),
); );
$this->entityTypeId = $this->randomMachineName(); $this->entityTypeId = $this->randomMachineName();
$this->bundle = $this->randomMachineName(); $this->bundle = $this->randomMachineName();
...@@ -129,18 +137,20 @@ protected function setUp() { ...@@ -129,18 +137,20 @@ protected function setUp() {
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$language = new Language(array('id' => 'en')); $english = new Language(array('id' => 'en'));
$not_specified = new Language(array('id' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'locked' => TRUE));
$this->languageManager = $this->getMock('\Drupal\Core\Language\LanguageManagerInterface'); $this->languageManager = $this->getMock('\Drupal\Core\Language\LanguageManagerInterface');
$this->languageManager->expects($this->any()) $this->languageManager->expects($this->any())
->method('getLanguages') ->method('getLanguages')
->will($this->returnValue(array('en' => $language))); ->will($this->returnValue(array('en' => $english, LanguageInterface::LANGCODE_NOT_SPECIFIED => $not_specified)));
$this->languageManager->expects($this->any()) $this->languageManager->expects($this->any())
->method('getLanguage') ->method('getLanguage')
->with('en') ->with('en')
->will($this->returnValue($language)); ->will($this->returnValue($english));
$this->languageManager->expects($this->any()) $this->languageManager->expects($this->any())
->method('getCurrentLanguage') ->method('getLanguage')
->will($this->returnValue($language)); ->with(LanguageInterface::LANGCODE_NOT_SPECIFIED)
->will($this->returnValue($not_specified));
$this->fieldTypePluginManager = $this->getMockBuilder('\Drupal\Core\Field\FieldTypePluginManager') $this->fieldTypePluginManager = $this->getMockBuilder('\Drupal\Core\Field\FieldTypePluginManager')
->disableOriginalConstructor() ->disableOriginalConstructor()
...@@ -170,6 +180,9 @@ protected function setUp() { ...@@ -170,6 +180,9 @@ protected function setUp() {
->with($this->entityTypeId, $this->bundle) ->with($this->entityTypeId, $this->bundle)
->will($this->returnValue($this->fieldDefinitions)); ->will($this->returnValue($this->fieldDefinitions));
$this->entity = $this->getMockForAbstractClass('\Drupal\Core\Entity\ContentEntityBase', array($values, $this->entityTypeId, $this->bundle)); $this->entity = $this->getMockForAbstractClass('\Drupal\Core\Entity\ContentEntityBase', array($values, $this->entityTypeId, $this->bundle));
$values['defaultLangcode'] = array(LanguageInterface::LANGCODE_DEFAULT => LanguageInterface::LANGCODE_NOT_SPECIFIED);
$this->entityUnd = $this->getMockForAbstractClass('\Drupal\Core\Entity\ContentEntityBase', array($values, $this->entityTypeId, $this->bundle));
} }
/** /**
...@@ -248,7 +261,7 @@ public function testGetRevisionId() { ...@@ -248,7 +261,7 @@ public function testGetRevisionId() {
* @covers ::isTranslatable * @covers ::isTranslatable
*/ */
public function testIsTranslatable() { public function testIsTranslatable() {
$this->entityManager->expects($this->at(0)) $this->entityManager->expects($this->any())
->method('getBundleInfo') ->method('getBundleInfo')
->with($this->entityTypeId) ->with($this->entityTypeId)
->will($this->returnValue(array( ->will($this->returnValue(array(
...@@ -256,7 +269,25 @@ public function testIsTranslatable() { ...@@ -256,7 +269,25 @@ public function testIsTranslatable() {
'translatable' => TRUE, 'translatable' => TRUE,
), ),
))); )));
$this->languageManager->expects($this->any())
->method('isMultilingual')
->will($this->returnValue(TRUE));
$this->assertTrue($this->entity->language()->id == 'en');
$this->assertFalse($this->entity->language()->locked);
$this->assertTrue($this->entity->isTranslatable()); $this->assertTrue($this->entity->isTranslatable());
$this->assertTrue($this->entityUnd->language()->id == LanguageInterface::LANGCODE_NOT_SPECIFIED);
$this->assertTrue($this->entityUnd->language()->locked);
$this->assertFalse($this->entityUnd->isTranslatable());
}
/**
* @covers ::isTranslatable
*/
public function testIsTranslatableForMonolingual() {
$this->languageManager->expects($this->any())
->method('isMultilingual')
->will($this->returnValue(FALSE));
$this->assertFalse($this->entity->isTranslatable()); $this->assertFalse($this->entity->isTranslatable());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment