Skip to content
Snippets Groups Projects
Commit 00fc5a35 authored by Justin Toupin's avatar Justin Toupin
Browse files

Issue #3312974: Async translations do not correctly clone the source paragraph

parent e33ca877
No related branches found
No related tags found
1 merge request!108Issue #3312974: Async translations do not correctly clone the source paragraph
...@@ -7,12 +7,13 @@ ...@@ -7,12 +7,13 @@
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Html;
use Drupal\paragraphs\ParagraphInterface;
use Drupal\Component\Serialization\Json; use Drupal\Component\Serialization\Json;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\paragraphs\ParagraphInterface;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\layout_paragraphs\Utility\Dialog; use Drupal\layout_paragraphs\Utility\Dialog;
use Drupal\paragraphs\Entity\ParagraphsType; use Drupal\paragraphs\Entity\ParagraphsType;
use Drupal\Core\Entity\FieldableEntityInterface;
/** /**
* Implements hook_help(). * Implements hook_help().
...@@ -375,6 +376,89 @@ function layout_paragraphs_paragraph_presave(ParagraphInterface $paragraph) { ...@@ -375,6 +376,89 @@ function layout_paragraphs_paragraph_presave(ParagraphInterface $paragraph) {
} }
} }
/**
* Implements hook_entity_translation_create().
*
* Supports asynchronous translations by duplicating paragraphs referenced
* by an entity reference revisions field that is translatable, updating parent
* uuid references in layouts.
*/
function layout_paragraphs_entity_translation_create(FieldableEntityInterface $entity) {
$entity_type_manager = \Drupal::entityTypeManager();
$paragraph_storage = $entity_type_manager->getStorage('paragraph');
/** @var \Drupal\field\FieldConfigInterface[] $field_definitions */
$field_definitions = $entity_type_manager->getStorage('field_config')
->loadByProperties([
'entity_type' => $entity->getEntityTypeId(),
'bundle' => $entity->bundle(),
'field_type' => 'entity_reference_revisions',
]);
$langcode_key = $entity->getEntityType()->getKey('langcode');
$langcode = $entity->get($langcode_key)->value;
foreach ($field_definitions as $field_definition) {
if ($field_definition->isTranslatable() === FALSE) {
continue;
}
if ($field_definition->getFieldStorageDefinition()->getSetting('target_type') !== 'paragraph') {
continue;
}
$async_values = [];
$values = $entity->get($field_definition->getName())->getValue() ?? [];
// Get the list of referenced paragraphs using the available property.
$paragraphs = array_map(function ($value) use ($paragraph_storage) {
if (isset($value['entity'])) {
$paragraph = $value['entity'];
}
elseif (isset($value['target_revision_id'])) {
$paragraph = $paragraph_storage->loadRevision($value['target_revision_id']);
}
elseif (isset($value['target_id'])) {
$paragraph = $paragraph_storage->load($value['target_id']);
}
return $paragraph ?? NULL;
}, $values);
// Save an array of the original uuids.
$original_uuids = array_map(function ($paragraph) {
return $paragraph->uuid();
}, $paragraphs);
// Duplicate the paragraphs.
$duplicates = array_map(function ($paragraph) use ($langcode) {
$duplicate = $paragraph->createDuplicate();
$langcode_key = $duplicate->getEntityType()->getKey('langcode');
$duplicate->set($langcode_key, $langcode);
return $duplicate;
}, $paragraphs);
// Get an array of new uuids so we can map references to parents uuids.
$new_uuids = array_map(function ($paragraph) {
return $paragraph->uuid();
}, $duplicates);
// Map old uuids to new uuids.
$uuid_map = array_combine($original_uuids, $new_uuids);
// Update references to the correct, new parent uuids in the
// behavior settings.
$async_values = array_map(function ($paragraph) use ($uuid_map) {
$behavior_settings = $paragraph->getAllBehaviorSettings();
$parent_uuid = $behavior_settings['layout_paragraphs']['parent_uuid'] ?? NULL;
if (!empty($parent_uuid)) {
$behavior_settings['layout_paragraphs']['parent_uuid'] = $uuid_map[$parent_uuid];
$paragraph->setAllBehaviorSettings($behavior_settings);
}
return $paragraph;
}, $duplicates);
$entity->set($field_definition->getName(), $async_values);
}
}
/** /**
* Returns a list of all sibling paragraphs given a single paragraph. * Returns a list of all sibling paragraphs given a single paragraph.
* *
......
...@@ -322,6 +322,7 @@ class LayoutParagraphsWidget extends WidgetBase implements ContainerFactoryPlugi ...@@ -322,6 +322,7 @@ class LayoutParagraphsWidget extends WidgetBase implements ContainerFactoryPlugi
$items[$delta]->entity = $paragraph; $items[$delta]->entity = $paragraph;
} }
} }
$this->layoutParagraphsLayout->setParagraphsReferenceField($items);
$this->tempstore->set($this->layoutParagraphsLayout); $this->tempstore->set($this->layoutParagraphsLayout);
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
namespace Drupal\Tests\layout_paragraphs\FunctionalJavascript; namespace Drupal\Tests\layout_paragraphs\FunctionalJavascript;
use Drupal\language\Entity\ConfigurableLanguage; use Drupal\language\Entity\ConfigurableLanguage;
use Behat\Mink\Exception\ExpectationException;
/** /**
* Tests various translation contexts for Layout Paragraphs. * Tests various translation contexts for Layout Paragraphs.
...@@ -40,6 +41,41 @@ class TranslationTest extends BuilderTestBase { ...@@ -40,6 +41,41 @@ class TranslationTest extends BuilderTestBase {
*/ */
public function testAsymmetricTranslations() { public function testAsymmetricTranslations() {
$this->testContentTranslations(TRUE); $this->testContentTranslations(TRUE);
/** @var Drupal\node\Entity\Node $node */
$node = \Drupal::entityTypeManager()
->getStorage('node')
->load(1);
$paragraphs = $node->field_content->referencedEntities();
$src_paragraph_ids = array_map(function ($paragraph) {
return $paragraph->id();
}, $paragraphs);
$src_paragraph_languages = array_unique(array_map(function ($paragraph) {
return $paragraph->language()->getId();
}, $paragraphs));
$translation = $node->getTranslation('de');
$paragraphs = $translation->field_content->referencedEntities();
$translation_paragraph_ids = array_map(function ($paragraph) {
return $paragraph->id();
}, $paragraphs);
$translation_paragraph_languages = array_unique(array_map(function ($paragraph) {
return $paragraph->language()->getId();
}, $paragraphs));
if (count($src_paragraph_languages) > 1) {
throw new ExpectationException('There should only be one language in source paragraphs.', $this->getSession()->getDriver());
}
if (count($translation_paragraph_languages) > 1) {
throw new ExpectationException('There should only be one language in translated paragraphs.', $this->getSession()->getDriver());
}
if ($translation_paragraph_languages == $src_paragraph_languages) {
throw new ExpectationException('Translated paragraphs should be in a different language than source paragraphs.', $this->getSession()->getDriver());
}
if (count(array_intersect($src_paragraph_ids, $translation_paragraph_ids)) > 0) {
throw new ExpectationException('Async translations should duplicate paragraphs, not just translate them.', $this->getSession()->getDriver());
}
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment