View source  
  <?php
namespace Drupal\Tests\entity_reference_revisions\Kernel;
use Drupal\entity_composite_relationship_test\Entity\EntityTestCompositeRelationship;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
use Drupal\Tests\node\Traits\NodeCreationTrait;
class EntityReferenceRevisionsCompositeTranslatableFieldTest extends EntityKernelTestBase {
  use ContentTypeCreationTrait;
  use NodeCreationTrait;
  
  public static $modules = array(
    'node',
    'field',
    'entity_reference_revisions',
    'entity_composite_relationship_test',
    'language',
    'content_translation',
  );
  
  protected $database;
  
  protected $entityTypeManager;
  
  protected function setUp() {
    parent::setUp();
    ConfigurableLanguage::createFromLangcode('de')
      ->save();
    ConfigurableLanguage::createFromLangcode('fr')
      ->save();
    $this
      ->installEntitySchema('entity_test_composite');
    $this
      ->installSchema('node', [
      'node_access',
    ]);
    
    NodeType::create([
      'type' => 'article',
      'name' => 'Article',
    ])
      ->save();
    
    $field_storage = FieldStorageConfig::create(array(
      'field_name' => 'composite_reference',
      'entity_type' => 'node',
      'type' => 'entity_reference_revisions',
      'settings' => array(
        'target_type' => 'entity_test_composite',
      ),
    ));
    $field_storage
      ->save();
    $field = FieldConfig::create(array(
      'field_storage' => $field_storage,
      'bundle' => 'article',
      'translatable' => TRUE,
    ));
    $field
      ->save();
    
    $this->database = \Drupal::database();
    $this->entityTypeManager = \Drupal::entityTypeManager();
    
    \Drupal::service('content_translation.manager')
      ->setEnabled('node', 'article', TRUE);
    \Drupal::service('content_translation.manager')
      ->setEnabled('entity_test_composite', 'entity_test_composite', TRUE);
    \Drupal::service('content_translation.manager')
      ->setBundleTranslationSettings('node', 'article', [
      'untranslatable_fields_hide' => TRUE,
    ]);
    \Drupal::service('entity_type.bundle.info')
      ->clearCachedBundles();
  }
  
  public function testCompositePendingRevisionTranslation() {
    
    $node_storage = \Drupal::entityTypeManager()
      ->getStorage('node');
    
    $composite = EntityTestCompositeRelationship::create([
      'langcode' => 'en',
      'name' => 'Initial Source Composite',
    ]);
    $composite
      ->save();
    
    $node = Node::create([
      'langcode' => 'en',
      'title' => 'Initial Source Node',
      'type' => 'article',
      'composite_reference' => $composite,
    ]);
    $node
      ->save();
    
    $node = $node_storage
      ->load($node
      ->id());
    
    $this
      ->assertRevisionCount(1, 'node', $node
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite
      ->id());
    
    $composite_de = $node
      ->get('composite_reference')->entity
      ->createDuplicate();
    $composite_de
      ->set('langcode', 'de');
    $composite_de
      ->set('name', 'Pending Revision Composite #1 DE');
    
    $node_de = $node
      ->addTranslation('de', [
      'title' => 'Pending Revision Node #1 DE',
      'composite_reference' => $composite_de,
    ] + $node
      ->toArray());
    $node_de
      ->setNewRevision(TRUE);
    $node_de
      ->isDefaultRevision(FALSE);
    $node_de
      ->save();
    
    $this
      ->assertRevisionCount(2, 'node', $node
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_de
      ->id());
    
    
    $node_revision = $node_storage
      ->loadRevision($node_de
      ->getRevisionId());
    $this
      ->assertFalse($node_revision
      ->isDefaultRevision());
    $this
      ->assertFalse((bool) $node_revision
      ->isRevisionTranslationAffected());
    $this
      ->assertEquals('Initial Source Node', $node_revision
      ->label());
    $this
      ->assertTrue($node_revision
      ->get('composite_reference')->entity
      ->isDefaultRevision());
    $this
      ->assertEquals('Initial Source Composite', $node_revision
      ->get('composite_reference')->entity
      ->label());
    $this
      ->assertFalse($node_revision
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertEquals($node
      ->get('composite_reference')->target_revision_id, $node_revision
      ->get('composite_reference')->target_revision_id);
    $node_de = $node_revision
      ->getTranslation('de');
    $this
      ->assertTrue((bool) $node_de
      ->isRevisionTranslationAffected());
    $this
      ->assertEquals('Pending Revision Node #1 DE', $node_de
      ->label());
    
    $this
      ->assertTrue($node_de
      ->get('composite_reference')->entity
      ->isDefaultRevision());
    $this
      ->assertEquals('Pending Revision Composite #1 DE', $node_de
      ->get('composite_reference')->entity
      ->label());
    $this
      ->assertNotEquals($node
      ->get('composite_reference')->target_revision_id, $node_de
      ->get('composite_reference')->target_revision_id);
    
    $node = $node_storage
      ->load($node
      ->id());
    $this
      ->assertFalse($node
      ->hasTranslation('de'));
    $this
      ->assertEquals('Initial Source Node', $node
      ->label());
    $this
      ->assertFalse($node
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertEquals('Initial Source Composite', $node
      ->get('composite_reference')->entity
      ->label());
    
    $composite_fr = $node
      ->get('composite_reference')->entity
      ->createDuplicate();
    $composite_fr
      ->set('langcode', 'fr');
    $composite_fr
      ->set('name', 'Pending Revision Composite #1 FR');
    $node_fr = $node
      ->addTranslation('fr', [
      'title' => 'Pending Revision Node #1 FR',
      'composite_reference' => $composite_fr,
    ] + $node
      ->toArray());
    $node_fr
      ->setNewRevision(TRUE);
    $node_fr
      ->isDefaultRevision(FALSE);
    $node_fr
      ->save();
    
    $this
      ->assertRevisionCount(3, 'node', $node
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_de
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_fr
      ->id());
    
    
    $node_revision = $node_storage
      ->loadRevision($node_fr
      ->getRevisionId());
    $this
      ->assertFalse($node_revision
      ->isDefaultRevision());
    $this
      ->assertFalse((bool) $node_revision
      ->isRevisionTranslationAffected());
    $this
      ->assertEquals('Initial Source Node', $node_revision
      ->label());
    $this
      ->assertTrue($node_revision
      ->get('composite_reference')->entity
      ->isDefaultRevision());
    $this
      ->assertEquals('Initial Source Composite', $node_revision
      ->get('composite_reference')->entity
      ->label());
    $this
      ->assertFalse($node_revision
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertEquals($node
      ->get('composite_reference')->target_revision_id, $node_revision
      ->get('composite_reference')->target_revision_id);
    $node_fr = $node_revision
      ->getTranslation('fr');
    $this
      ->assertTrue((bool) $node_fr
      ->isRevisionTranslationAffected());
    $this
      ->assertEquals('Pending Revision Node #1 FR', $node_fr
      ->label());
    $this
      ->assertTrue($node_fr
      ->get('composite_reference')->entity
      ->isDefaultRevision());
    $this
      ->assertEquals('Pending Revision Composite #1 FR', $node_fr
      ->get('composite_reference')->entity
      ->label());
    $this
      ->assertNotEquals($node
      ->get('composite_reference')->target_revision_id, $node_fr
      ->get('composite_reference')->target_revision_id);
    $node_de = $node_storage
      ->loadRevision($node_de
      ->getRevisionId())
      ->getTranslation('de');
    $this
      ->assertTrue((bool) $node_de
      ->isRevisionTranslationAffected());
    $this
      ->assertEquals('Pending Revision Node #1 DE', $node_de
      ->label());
    $this
      ->assertTrue($node_de
      ->get('composite_reference')->entity
      ->isDefaultRevision());
    $this
      ->assertEquals('Pending Revision Composite #1 DE', $node_de
      ->get('composite_reference')->entity
      ->label());
    $this
      ->assertNotEquals($node
      ->get('composite_reference')->target_revision_id, $node_de
      ->get('composite_reference')->target_revision_id);
    
    $node = $node_storage
      ->load($node
      ->id());
    $this
      ->assertFalse($node
      ->hasTranslation('de'));
    $this
      ->assertEquals('Initial Source Node', $node
      ->label());
    $this
      ->assertFalse($node
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertEquals('Initial Source Composite', $node
      ->get('composite_reference')->entity
      ->label());
    
    $initial_revision_id = $node
      ->getRevisionId();
    $node
      ->get('composite_reference')->entity
      ->set('name', 'Updated Source Composite');
    $node
      ->setTitle('Updated Source Node');
    $node
      ->setNewRevision(TRUE);
    $node
      ->save();
    
    $this
      ->assertRevisionCount(4, 'node', $node
      ->id());
    $this
      ->assertRevisionCount(2, 'entity_test_composite', $composite
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_de
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_fr
      ->id());
    
    $node = $node_storage
      ->load($node
      ->id());
    $this
      ->assertTrue($node
      ->isDefaultRevision());
    $this
      ->assertFalse($node
      ->hasTranslation('de'));
    $this
      ->assertFalse($node
      ->hasTranslation('fr'));
    $this
      ->assertTrue((bool) $node
      ->isRevisionTranslationAffected());
    $this
      ->assertEquals('Updated Source Node', $node
      ->label());
    $this
      ->assertTrue($node
      ->get('composite_reference')->entity
      ->isDefaultRevision());
    $this
      ->assertFalse($node
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertEquals('Updated Source Composite', $node
      ->get('composite_reference')->entity
      ->label());
    $node_initial = $node_storage
      ->loadRevision($initial_revision_id);
    $this
      ->assertFalse($node_initial
      ->isDefaultRevision());
    $this
      ->assertFalse($node_initial
      ->hasTranslation('de'));
    $this
      ->assertFalse($node_initial
      ->hasTranslation('fr'));
    $this
      ->assertEquals('Initial Source Node', $node_initial
      ->label());
    $this
      ->assertFalse($node_initial
      ->get('composite_reference')->entity
      ->isDefaultRevision());
    $this
      ->assertFalse($node_initial
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertEquals('Initial Source Composite', $node_initial
      ->get('composite_reference')->entity
      ->label());
    
    $node_storage
      ->createRevision($node_fr
      ->getTranslation('fr'))
      ->save();
    
    $this
      ->assertRevisionCount(5, 'node', $node
      ->id());
    $this
      ->assertRevisionCount(2, 'entity_test_composite', $composite
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_de
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_fr
      ->id());
    
    $node = $node_storage
      ->load($node
      ->id());
    $this
      ->assertTrue($node
      ->isDefaultRevision());
    $this
      ->assertFalse($node
      ->hasTranslation('de'));
    $this
      ->assertTrue($node
      ->hasTranslation('fr'));
    $node_fr = $node
      ->getTranslation('fr');
    $this
      ->assertFalse((bool) $node
      ->isRevisionTranslationAffected());
    $this
      ->assertTrue((bool) $node
      ->getTranslation('fr')
      ->isRevisionTranslationAffected());
    $this
      ->assertEquals('Updated Source Node', $node
      ->label());
    $this
      ->assertTrue($node
      ->get('composite_reference')->entity
      ->isDefaultRevision());
    $this
      ->assertFalse($node
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertTrue($node_fr
      ->get('composite_reference')->entity
      ->hasTranslation('fr'));
    $this
      ->assertEquals('Pending Revision Node #1 FR', $node_fr
      ->label());
    $this
      ->assertEquals('Pending Revision Composite #1 FR', $node_fr
      ->get('composite_reference')->entity
      ->getTranslation('fr')
      ->label());
    $this
      ->assertEquals('Updated Source Composite', $node
      ->get('composite_reference')->entity
      ->label());
    
    $node_storage
      ->createRevision($node_de
      ->getTranslation('de'))
      ->save();
    
    $this
      ->assertRevisionCount(6, 'node', $node
      ->id());
    $this
      ->assertRevisionCount(2, 'entity_test_composite', $composite
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_de
      ->id());
    $this
      ->assertRevisionCount(1, 'entity_test_composite', $composite_fr
      ->id());
    
    $node = $node_storage
      ->load($node
      ->id());
    $this
      ->assertTrue($node
      ->isDefaultRevision());
    $this
      ->assertTrue($node
      ->hasTranslation('de'));
    $this
      ->assertTrue($node
      ->hasTranslation('fr'));
    $node_fr = $node
      ->getTranslation('fr');
    $node_de = $node
      ->getTranslation('de');
    $this
      ->assertFalse((bool) $node
      ->isRevisionTranslationAffected());
    $this
      ->assertFalse((bool) $node
      ->getTranslation('fr')
      ->isRevisionTranslationAffected());
    $this
      ->assertTrue((bool) $node
      ->getTranslation('de')
      ->isRevisionTranslationAffected());
    $this
      ->assertEquals('Updated Source Node', $node
      ->label());
    
    $this
      ->assertTrue($node
      ->get('composite_reference')->entity
      ->hasTranslation('en'));
    $this
      ->assertFalse($node
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertFalse($node
      ->get('composite_reference')->entity
      ->hasTranslation('fr'));
    $this
      ->assertFalse($node_fr
      ->get('composite_reference')->entity
      ->hasTranslation('en'));
    $this
      ->assertTrue($node_fr
      ->get('composite_reference')->entity
      ->hasTranslation('fr'));
    $this
      ->assertFalse($node_fr
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertFalse($node_de
      ->get('composite_reference')->entity
      ->hasTranslation('en'));
    $this
      ->assertTrue($node_de
      ->get('composite_reference')->entity
      ->hasTranslation('de'));
    $this
      ->assertFalse($node_de
      ->get('composite_reference')->entity
      ->hasTranslation('fr'));
    $this
      ->assertEquals('Pending Revision Node #1 FR', $node_fr
      ->label());
    $this
      ->assertEquals('Pending Revision Composite #1 FR', $node_fr
      ->get('composite_reference')->entity
      ->getTranslation('fr')
      ->label());
    $this
      ->assertEquals('Pending Revision Node #1 DE', $node_de
      ->label());
    $this
      ->assertEquals('Pending Revision Composite #1 DE', $node_de
      ->get('composite_reference')->entity
      ->getTranslation('de')
      ->label());
    $this
      ->assertEquals('Updated Source Composite', $node
      ->get('composite_reference')->entity
      ->label());
  }
  
  protected function assertRevisionCount($expected, $entity_type_id, $entity_id) {
    $id_field = \Drupal::entityTypeManager()
      ->getDefinition($entity_type_id)
      ->getKey('id');
    $revision_count = \Drupal::entityQuery($entity_type_id)
      ->condition($id_field, $entity_id)
      ->allRevisions()
      ->count()
      ->execute();
    $this
      ->assertEquals($expected, $revision_count);
  }
}