Commit 4f00351e authored by webchick's avatar webchick

Issue #2129039 by plach, jthorson, pfrenssen, nyirocsaba, Gábor Hojtsy:...

Issue #2129039 by plach, jthorson, pfrenssen, nyirocsaba, Gábor Hojtsy: Integrity constraint violation when translating body field.
parent 3cf0801b
...@@ -904,9 +904,18 @@ public function __clone() { ...@@ -904,9 +904,18 @@ public function __clone() {
// Avoid deep-cloning when we are initializing a translation object, since // Avoid deep-cloning when we are initializing a translation object, since
// it will represent the same entity, only with a different active language. // it will represent the same entity, only with a different active language.
if (!$this->translationInitialize) { if (!$this->translationInitialize) {
foreach ($this->fields as $name => $properties) { $definitions = $this->getPropertyDefinitions();
foreach ($properties as $langcode => $property) { foreach ($this->fields as $name => $values) {
$this->fields[$name][$langcode] = clone $property; $this->fields[$name] = array();
// Untranslatable fields may have multiple references for the same field
// object keyed by language. To avoid creating different field objects
// we retain just the original value, as references will be recreated
// later as needed.
if (empty($definitions[$name]['translatable']) && count($values) > 1) {
$values = array_intersect_key($values, array(Language::LANGCODE_DEFAULT => TRUE));
}
foreach ($values as $langcode => $items) {
$this->fields[$name][$langcode] = clone $items;
$this->fields[$name][$langcode]->setContext($name, $this); $this->fields[$name][$langcode]->setContext($name, $this);
} }
} }
......
...@@ -176,6 +176,10 @@ public function form(array $form, array &$form_state) { ...@@ -176,6 +176,10 @@ public function form(array $form, array &$form_state) {
* @see \Drupal\Core\Entity\EntityFormController::form() * @see \Drupal\Core\Entity\EntityFormController::form()
*/ */
public function processForm($element, $form_state, $form) { public function processForm($element, $form_state, $form) {
// If the form is cached, process callbacks may not have a valid reference
// to the entity object, hence we must restore it.
$this->entity = $form_state['controller']->getEntity();
// Assign the weights configured in the form display. // Assign the weights configured in the form display.
foreach ($this->getFormDisplay($form_state)->getComponents() as $name => $options) { foreach ($this->getFormDisplay($form_state)->getComponents() as $name => $options) {
if (isset($element[$name])) { if (isset($element[$name])) {
......
...@@ -124,13 +124,20 @@ protected function getEditorPermissions() { ...@@ -124,13 +124,20 @@ protected function getEditorPermissions() {
return array(); return array();
} }
/**
* Returns an array of permissions needed for the administrator.
*/
protected function getAdministratorPermissions() {
return array_merge($this->getEditorPermissions(), $this->getTranslatorPermissions(), array('administer content translation'));
}
/** /**
* Creates and activates translator, editor and admin users. * Creates and activates translator, editor and admin users.
*/ */
protected function setupUsers() { protected function setupUsers() {
$this->translator = $this->drupalCreateUser($this->getTranslatorPermissions(), 'translator'); $this->translator = $this->drupalCreateUser($this->getTranslatorPermissions(), 'translator');
$this->editor = $this->drupalCreateUser($this->getEditorPermissions(), 'editor'); $this->editor = $this->drupalCreateUser($this->getEditorPermissions(), 'editor');
$this->administrator = $this->drupalCreateUser(array_merge($this->getEditorPermissions(), $this->getTranslatorPermissions()), 'administrator'); $this->administrator = $this->drupalCreateUser($this->getAdministratorPermissions(), 'administrator');
$this->drupalLogin($this->translator); $this->drupalLogin($this->translator);
} }
......
...@@ -22,6 +22,13 @@ class NodeTranslationUITest extends ContentTranslationUITest { ...@@ -22,6 +22,13 @@ class NodeTranslationUITest extends ContentTranslationUITest {
*/ */
public static $modules = array('block', 'language', 'content_translation', 'node', 'datetime', 'field_ui'); public static $modules = array('block', 'language', 'content_translation', 'node', 'datetime', 'field_ui');
/**
* The profile to install as a basis for testing.
*
* @var string
*/
protected $profile = 'standard';
public static function getInfo() { public static function getInfo() {
return array( return array(
'name' => 'Node translation UI', 'name' => 'Node translation UI',
...@@ -34,15 +41,15 @@ function setUp() { ...@@ -34,15 +41,15 @@ function setUp() {
$this->entityType = 'node'; $this->entityType = 'node';
$this->bundle = 'article'; $this->bundle = 'article';
parent::setUp(); parent::setUp();
// Ensure the help message is shown even with prefixed paths.
$this->drupalPlaceBlock('system_help_block', array('region' => 'content')); $this->drupalPlaceBlock('system_help_block', array('region' => 'content'));
}
/** // Display the language selector.
* Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::setupBundle(). $this->drupalLogin($this->administrator);
*/ $edit = array('language_configuration[language_show]' => TRUE);
protected function setupBundle() { $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type'));
parent::setupBundle(); $this->drupalLogin($this->translator);
$this->drupalCreateContentType(array('type' => $this->bundle, 'name' => $this->bundle));
} }
/** /**
...@@ -52,6 +59,20 @@ protected function getTranslatorPermissions() { ...@@ -52,6 +59,20 @@ protected function getTranslatorPermissions() {
return array_merge(parent::getTranslatorPermissions(), array('administer nodes', "edit any $this->bundle content")); return array_merge(parent::getTranslatorPermissions(), array('administer nodes', "edit any $this->bundle content"));
} }
/**
* {@inheritdoc}
*/
protected function getEditorPermissions() {
return array('administer nodes', 'create article content');
}
/**
* {@inheritdoc}
*/
protected function getAdministratorPermissions() {
return array_merge(parent::getAdministratorPermissions(), array('access administration pages', 'administer content types', 'administer node fields', 'access content overview', 'bypass node access'));
}
/** /**
* Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getNewEntityValues(). * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getNewEntityValues().
*/ */
...@@ -59,6 +80,22 @@ protected function getNewEntityValues($langcode) { ...@@ -59,6 +80,22 @@ protected function getNewEntityValues($langcode) {
return array('title' => $this->randomName()) + parent::getNewEntityValues($langcode); return array('title' => $this->randomName()) + parent::getNewEntityValues($langcode);
} }
/**
* {@inheritdoc}
*/
protected function createEntity($values, $langcode, $bundle_name = NULL) {
$this->drupalLogin($this->editor);
$edit = array(
'title' => $values['title'],
"{$this->fieldName}[0][value]" => $values[$this->fieldName][0]['value'],
'langcode' => $langcode,
);
$this->drupalPostForm('node/add/article', $edit,t('Save and publish'));
$this->drupalLogin($this->translator);
$node = $this->drupalGetNodeByTitle($values['title']);
return $node->id();
}
/** /**
* Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getFormSubmitAction(). * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getFormSubmitAction().
*/ */
...@@ -136,11 +173,10 @@ protected function doTestAuthoringInfo() { ...@@ -136,11 +173,10 @@ protected function doTestAuthoringInfo() {
* Tests translate link on content admin page. * Tests translate link on content admin page.
*/ */
function testTranslateLinkContentAdminPage() { function testTranslateLinkContentAdminPage() {
$this->admin_user = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'administer nodes', 'bypass node access')); $this->drupalLogin($this->administrator);
$this->drupalLogin($this->admin_user);
$page = $this->drupalCreateNode(array('type' => 'page')); $page = $this->drupalCreateNode(array('type' => 'page'));
$article = $this->drupalCreateNode(array('type' => 'article')); $article = $this->drupalCreateNode(array('type' => 'article', 'langcode' => $this->langcodes[0]));
// Verify translation links. // Verify translation links.
$this->drupalGet('admin/content'); $this->drupalGet('admin/content');
...@@ -153,8 +189,7 @@ function testTranslateLinkContentAdminPage() { ...@@ -153,8 +189,7 @@ function testTranslateLinkContentAdminPage() {
* Tests field translation form. * Tests field translation form.
*/ */
function testFieldTranslationForm() { function testFieldTranslationForm() {
$admin_user = $this->drupalCreateUser(array_merge($this->getTranslatorPermissions(), array('access administration pages', 'bypass node access', 'administer node fields'))); $this->drupalLogin($this->administrator);
$this->drupalLogin($admin_user);
$article = $this->drupalCreateNode(array('type' => 'article', 'langcode' => 'en')); $article = $this->drupalCreateNode(array('type' => 'article', 'langcode' => 'en'));
......
...@@ -483,6 +483,17 @@ function testEntityTranslationAPI() { ...@@ -483,6 +483,17 @@ function testEntityTranslationAPI() {
$translation = $cloned->getTranslation($langcode); $translation = $cloned->getTranslation($langcode);
$this->assertNotIdentical($entity, $translation->getUntranslated(), 'A cloned entity object has no reference to the original one.'); $this->assertNotIdentical($entity, $translation->getUntranslated(), 'A cloned entity object has no reference to the original one.');
// Check that untranslatable field references keep working after serializing
// and cloning the entity.
$entity = $this->reloadEntity($entity);
$type = $this->randomName();
$entity->getTranslation($langcode)->type->value = $type;
$entity = unserialize(serialize($entity));
$cloned = clone $entity;
$translation = $cloned->getTranslation($langcode);
$translation->type->value = strrev($type);
$this->assertEqual($cloned->type->value, $translation->type->value, 'Untranslatable field references keep working after serializing and cloning the entity.');
// Check that per-language defaults are properly populated. // Check that per-language defaults are properly populated.
$entity = $this->reloadEntity($entity); $entity = $this->reloadEntity($entity);
$instance_id = implode('.', array($entity->entityType(), $entity->bundle(), $this->field_name)); $instance_id = implode('.', array($entity->entityType(), $entity->bundle(), $this->field_name));
......
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