Commit 167be1c0 authored by maximpodorov's avatar maximpodorov Committed by miro_dietiker

Issue #2961399 by Berdir, yongt9412, merauluka, maximpodorov, eyilmaz,...

Issue #2961399 by Berdir, yongt9412, merauluka, maximpodorov, eyilmaz, cosmicdreams, petermallett: Support parallel translation forward revisions on untranslatable fields
parent ed5effb9
......@@ -6,6 +6,8 @@
*/
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\TranslatableRevisionableStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
......@@ -218,3 +220,63 @@ function entity_reference_revisions_form_field_ui_field_storage_add_form_alter(a
unset($form['add']['new_storage_type']['#options'][(string) t('Reference revisions')]['entity_reference_revisions']);
$form['add']['new_storage_type']['#options'][(string) t('Reference revisions')]['entity_reference_revisions'] = t('Other…');
}
/**
* Implements hook_entity_revision_create().
*/
function entity_reference_revisions_entity_revision_create(ContentEntityInterface $new_revision, ContentEntityInterface $entity, $keep_untranslatable_fields) {
$entity_type_manager = \Drupal::entityTypeManager();
$storage = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId());
foreach ($entity->getFieldDefinitions() as $field_name => $field_definition) {
if ($field_definition->getType() == 'entity_reference_revisions' && !$field_definition->isTranslatable()) {
$target_entity_type_id = $field_definition->getSetting('target_type');
if ($entity_type_manager->getDefinition($target_entity_type_id)->get('entity_revision_parent_id_field')) {
// The default implementation copied the values from the current
// default revision into the field since it is not translatable.
// Take the originally referenced entity, create a new revision
// of it and set that instead on the new entity revision.
$active_langcode = $entity->language()->getId();
$target_storage = \Drupal::entityTypeManager()->getStorage($target_entity_type_id);
if ($target_storage instanceof TranslatableRevisionableStorageInterface) {
$items = $entity->get($field_name);
$translation_items = NULL;
if (!$new_revision->isDefaultTranslation() && $storage instanceof TranslatableRevisionableStorageInterface) {
$translation_items = $items;
$items = $storage->load($new_revision->id())->get($field_name);
}
$values = [];
foreach ($items as $delta => $item) {
// Use the item from the translation if it exists.
// If we have translation items, use that if one with the matching
// target id exists.
if ($translation_items) {
foreach ($translation_items as $translation_item) {
if ($item->target_id == $translation_item->target_id) {
$item = $translation_item;
break;
}
}
}
/** @var \Drupal\Core\Entity\ContentEntityInterface $target_entity */
$target_entity = $item->entity;
if (!$target_entity->hasTranslation($active_langcode)) {
$target_entity->addTranslation($active_langcode, $target_entity->toArray());
}
$target_entity = $item->entity->getTranslation($active_langcode);
$revised_entity = $target_storage->createRevision($target_entity, $new_revision->isDefaultRevision(), $keep_untranslatable_fields);
// Restore the revision ID.
$revision_key = $revised_entity->getEntityType()->getKey('revision');
$revised_entity->set($revision_key, $revised_entity->getLoadedRevisionId());
$values[$delta] = $revised_entity;
}
$new_revision->set($field_name, $values);
}
}
}
}
}
......@@ -3,6 +3,8 @@
namespace Drupal\entity_reference_revisions;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldItemListTranslationChangesInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\EntityReferenceFieldItemList;
......@@ -122,4 +124,28 @@ class EntityReferenceRevisionsFieldItemList extends EntityReferenceFieldItemList
return $default_value;
}
/**
* {@inheritdoc}
*/
public function hasAffectingChanges(FieldItemListInterface $original_items, $langcode) {
// If there are fewer items, then it is a change.
if (count($this) < count($original_items)) {
return TRUE;
}
foreach ($this as $delta => $item) {
// If this is a different entity, then it is an affecting change.
if (!$original_items->offsetExists($delta) || $item->target_id != $original_items[$delta]->target_id) {
return TRUE;
}
// If it is the same entity, only consider it as having affecting changes
// if the target entity itself has changes.
if ($item->entity && $item->entity->hasTranslation($langcode) && $item->entity->getTranslation($langcode)->hasTranslationChanges()) {
return TRUE;
}
}
return FALSE;
}
}
......@@ -18,6 +18,7 @@ use Drupal\entity_test\Entity\EntityTestMulRev;
* revision_table = "entity_test_composite_revision",
* data_table = "entity_test_composite_field_data",
* revision_data_table = "entity_test_composite_field_revision",
* content_translation_ui_skip = TRUE,
* translatable = TRUE,
* entity_revision_parent_type_field = "parent_type",
* entity_revision_parent_id_field = "parent_id",
......
......@@ -9,8 +9,8 @@ use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\simpletest\ContentTypeCreationTrait;
use Drupal\simpletest\NodeCreationTrait;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
use Drupal\Tests\node\Traits\NodeCreationTrait;
/**
* Tests the entity_reference_revisions composite relationship.
......@@ -102,12 +102,15 @@ class EntityReferenceRevisionsCompositeTest extends EntityKernelTestBase {
$this->assertEquals(1, $composite_revisions_count);
// Create a node with a reference to the test composite entity.
/** @var \Drupal\node\NodeInterface $node */
$node = Node::create(array(
'title' => $this->randomMachineName(),
'type' => 'article',
'composite_reference' => $composite,
));
$node->save();
$node->set('composite_reference', $composite);
$this->assertTrue($node->hasTranslationChanges());
$node->save();
// Assert that there is only 1 revision when creating a node.
$node_revisions_count = \Drupal::entityQuery('node')->condition('nid', $node->id())->allRevisions()->count()->execute();
......@@ -146,6 +149,14 @@ class EntityReferenceRevisionsCompositeTest extends EntityKernelTestBase {
$this->assertNotEqual('2nd revision', $node->getTitle(), 'Node did not keep changed title after reversion.');
$this->assertNotEqual($original_composite_revision, $node->composite_reference[0]->target_revision_id, 'Composite entity got new revision when its host reverted to an old revision.');
// Test that removing/changing composite references results in translation
// changes.
$node->set('composite_reference', []);
$this->assertTrue($node->hasTranslationChanges());
// Revert the changes to avoid interfering with the delete test.
$node->set('composite_reference', $composite);
// Test that the composite entity is deleted when its parent is deleted.
$node->delete();
$this->assertNull(EntityTestCompositeRelationship::load($composite->id()));
......
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