summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwebchick2014-08-29 06:56:26 (GMT)
committerwebchick2014-08-29 06:56:26 (GMT)
commit68755a3bbfaef7b2507bb5c053a631e9f3b320cc (patch)
treedce7daa985aa378194c705af3001b7f6888539bf
parent777bc650e4f93843fdb1f8ba48052febc6ac74e7 (diff)
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.
-rw-r--r--core/lib/Drupal/Core/Entity/ContentEntityBase.php6
-rw-r--r--core/modules/content_translation/src/Access/ContentTranslationOverviewAccess.php8
-rw-r--r--core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php2
-rw-r--r--core/modules/content_translation/src/Tests/ContentTranslationContextualLinksTest.php47
-rw-r--r--core/modules/node/src/Tests/NodeTranslationUITest.php15
-rw-r--r--core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php45
6 files changed, 105 insertions, 18 deletions
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index 220f459..586da85 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -246,8 +246,10 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
* {@inheritdoc}
*/
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);
- return !empty($bundles[$this->bundle()]['translatable']);
+ return !empty($bundles[$this->bundle()]['translatable']) && empty($this->getUntranslated()->language()->locked) && $this->languageManager()->isMultilingual();
}
/**
@@ -513,7 +515,7 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
*/
public function getFieldDefinitions() {
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;
}
diff --git a/core/modules/content_translation/src/Access/ContentTranslationOverviewAccess.php b/core/modules/content_translation/src/Access/ContentTranslationOverviewAccess.php
index 5104db7..893b8b1 100644
--- a/core/modules/content_translation/src/Access/ContentTranslationOverviewAccess.php
+++ b/core/modules/content_translation/src/Access/ContentTranslationOverviewAccess.php
@@ -47,7 +47,8 @@ class ContentTranslationOverviewAccess implements AccessInterface {
*/
public function access(Request $request, AccountInterface $account) {
$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.
$bundle = $entity->bundle();
@@ -59,6 +60,11 @@ class ContentTranslationOverviewAccess implements AccessInterface {
return static::ALLOW;
}
+ // Check "translate any entity" permission.
+ if ($account->hasPermission('translate any entity')) {
+ return static::ALLOW;
+ }
+
// Check per entity permission.
$permission = "translate {$entity_type}";
if ($definition->getPermissionGranularity() == 'bundle') {
diff --git a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
index b5124ef..ce8bd57 100644
--- a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
+++ b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
@@ -61,10 +61,8 @@ class ContentTranslationRouteSubscriber extends RouteSubscriberBase {
),
array(
'_access_content_translation_overview' => $entity_type_id,
- '_permission' => 'translate any entity',
),
array(
- '_access_mode' => AccessManagerInterface::ACCESS_MODE_ANY,
'parameters' => array(
$entity_type_id => array(
'type' => 'entity:' . $entity_type_id,
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationContextualLinksTest.php b/core/modules/content_translation/src/Tests/ContentTranslationContextualLinksTest.php
index 203a33e..9033d83 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationContextualLinksTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationContextualLinksTest.php
@@ -8,6 +8,7 @@
namespace Drupal\content_translation\Tests;
use Drupal\Component\Serialization\Json;
+use Drupal\Core\Language\Language;
use Drupal\node\Entity\NodeType;
use Drupal\simpletest\WebTestBase;
@@ -40,6 +41,13 @@ class ContentTranslationContextualLinksTest extends WebTestBase {
protected $translator;
/**
+ * The enabled languages.
+ *
+ * @var array
+ */
+ protected $langcodes;
+
+ /**
* Modules to enable.
*
* @var array
@@ -55,11 +63,48 @@ class ContentTranslationContextualLinksTest extends WebTestBase {
protected function 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.
$this->bundle = $this->randomMachineName();
$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.
$permissions = array(
'access contextual links',
@@ -76,7 +121,7 @@ class ContentTranslationContextualLinksTest extends WebTestBase {
public function testContentTranslationContextualLinks() {
// Create a node.
$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);
// Check that the translate link appears on the node page.
diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php
index a43a642..59416a3 100644
--- a/core/modules/node/src/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/src/Tests/NodeTranslationUITest.php
@@ -194,6 +194,9 @@ class NodeTranslationUITest extends ContentTranslationUITest {
$this->drupalPostForm('admin/appearance', $edit, t('Save configuration'));
$this->drupalGet('node/' . $article->id() . '/translations');
$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 @@ class NodeTranslationUITest extends ContentTranslationUITest {
$this->drupalCreateContentType(array('type' => $disabledBundle, 'name' => $disabledBundle));
// 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
- // {content_translation} table.
+ // Make sure that nothing was inserted into the {content_translation} table.
$rows = db_query('SELECT * FROM {content_translation}')->fetchAll();
- $this->assertEqual(1, count($rows));
- $this->assertEqual($enabledNode->id(), reset($rows)->entity_id);
+ $this->assertEqual(0, count($rows));
+
+ // Ensure the translation tab is not accessible.
+ $this->drupalGet('node/' . $node->id() . '/translations');
+ $this->assertResponse(403);
}
/**
diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
index 5226be2..39f8d76 100644
--- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
@@ -10,6 +10,7 @@ namespace Drupal\Tests\Core\Entity;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldItemBase;
+use Drupal\Core\Language\LanguageInterface;
use Drupal\Tests\UnitTestCase;
use Drupal\Core\Language\Language;
@@ -34,6 +35,13 @@ class ContentEntityBaseUnitTest extends UnitTestCase {
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.
*
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -103,8 +111,8 @@ class ContentEntityBaseUnitTest extends UnitTestCase {
$this->id = 1;
$values = array(
'id' => $this->id,
- 'langcode' => 'en',
'uuid' => '3bb9ee60-bea5-4622-b89b-a63319d10b3a',
+ 'defaultLangcode' => array(LanguageInterface::LANGCODE_DEFAULT => 'en'),
);
$this->entityTypeId = $this->randomMachineName();
$this->bundle = $this->randomMachineName();
@@ -129,18 +137,20 @@ class ContentEntityBaseUnitTest extends UnitTestCase {
->disableOriginalConstructor()
->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->expects($this->any())
->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())
->method('getLanguage')
->with('en')
- ->will($this->returnValue($language));
+ ->will($this->returnValue($english));
$this->languageManager->expects($this->any())
- ->method('getCurrentLanguage')
- ->will($this->returnValue($language));
+ ->method('getLanguage')
+ ->with(LanguageInterface::LANGCODE_NOT_SPECIFIED)
+ ->will($this->returnValue($not_specified));
$this->fieldTypePluginManager = $this->getMockBuilder('\Drupal\Core\Field\FieldTypePluginManager')
->disableOriginalConstructor()
@@ -170,6 +180,9 @@ class ContentEntityBaseUnitTest extends UnitTestCase {
->with($this->entityTypeId, $this->bundle)
->will($this->returnValue($this->fieldDefinitions));
$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 @@ class ContentEntityBaseUnitTest extends UnitTestCase {
* @covers ::isTranslatable
*/
public function testIsTranslatable() {
- $this->entityManager->expects($this->at(0))
+ $this->entityManager->expects($this->any())
->method('getBundleInfo')
->with($this->entityTypeId)
->will($this->returnValue(array(
@@ -256,7 +269,25 @@ class ContentEntityBaseUnitTest extends UnitTestCase {
'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->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());
}