You are here

protected function EntityTranslationTest::doTestMultilingualProperties in Drupal 10

Same name and namespace in other branches
  1. 8 core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php \Drupal\KernelTests\Core\Entity\EntityTranslationTest::doTestMultilingualProperties()
  2. 9 core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php \Drupal\KernelTests\Core\Entity\EntityTranslationTest::doTestMultilingualProperties()

Executes the multilingual property tests for the given entity type.

Parameters

string $entity_type: The entity type to run the tests with.

File

core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php, line 157

Class

EntityTranslationTest
Tests entity translation functionality.

Namespace

Drupal\KernelTests\Core\Entity

Code

protected function doTestMultilingualProperties($entity_type) {
  $langcode_key = $this->entityTypeManager
    ->getDefinition($entity_type)
    ->getKey('langcode');
  $default_langcode_key = $this->entityTypeManager
    ->getDefinition($entity_type)
    ->getKey('default_langcode');
  $name = $this
    ->randomMachineName();
  $uid = mt_rand(0, 127);
  $langcode = $this->langcodes[0];

  // Create a language neutral entity and check that properties are stored
  // as language neutral.
  $storage = $this->container
    ->get('entity_type.manager')
    ->getStorage($entity_type);
  $entity = $storage
    ->create([
    'name' => $name,
    'user_id' => $uid,
    $langcode_key => LanguageInterface::LANGCODE_NOT_SPECIFIED,
  ]);
  $entity
    ->save();
  $entity = $storage
    ->load($entity
    ->id());
  $default_langcode = $entity
    ->language()
    ->getId();
  $this
    ->assertEquals(LanguageInterface::LANGCODE_NOT_SPECIFIED, $default_langcode, new FormattableMarkup('%entity_type: Entity created as language neutral.', [
    '%entity_type' => $entity_type,
  ]));
  $field = $entity
    ->getTranslation(LanguageInterface::LANGCODE_DEFAULT)
    ->get('name');
  $this
    ->assertEquals($name, $field->value, new FormattableMarkup('%entity_type: The entity name has been correctly stored as language neutral.', [
    '%entity_type' => $entity_type,
  ]));
  $this
    ->assertEquals($default_langcode, $field
    ->getLangcode(), new FormattableMarkup('%entity_type: The field object has the expect langcode.', [
    '%entity_type' => $entity_type,
  ]));
  $this
    ->assertEquals($uid, $entity
    ->getTranslation(LanguageInterface::LANGCODE_DEFAULT)
    ->get('user_id')->target_id, new FormattableMarkup('%entity_type: The entity author has been correctly stored as language neutral.', [
    '%entity_type' => $entity_type,
  ]));
  $translation = $entity
    ->getTranslation(LanguageInterface::LANGCODE_DEFAULT);
  $field = $translation
    ->get('name');
  $this
    ->assertEquals($name, $field->value, new FormattableMarkup('%entity_type: The entity name defaults to neutral language.', [
    '%entity_type' => $entity_type,
  ]));
  $this
    ->assertEquals($default_langcode, $field
    ->getLangcode(), new FormattableMarkup('%entity_type: The field object has the expect langcode.', [
    '%entity_type' => $entity_type,
  ]));
  $this
    ->assertEquals($uid, $translation
    ->get('user_id')->target_id, new FormattableMarkup('%entity_type: The entity author defaults to neutral language.', [
    '%entity_type' => $entity_type,
  ]));
  $field = $entity
    ->get('name');
  $this
    ->assertEquals($name, $field->value, new FormattableMarkup('%entity_type: The entity name can be retrieved without specifying a language.', [
    '%entity_type' => $entity_type,
  ]));
  $this
    ->assertEquals($default_langcode, $field
    ->getLangcode(), new FormattableMarkup('%entity_type: The field object has the expect langcode.', [
    '%entity_type' => $entity_type,
  ]));
  $this
    ->assertEquals($uid, $entity
    ->get('user_id')->target_id, new FormattableMarkup('%entity_type: The entity author can be retrieved without specifying a language.', [
    '%entity_type' => $entity_type,
  ]));

  // Create a language-aware entity and check that properties are stored
  // as language-aware.
  $entity = $this->container
    ->get('entity_type.manager')
    ->getStorage($entity_type)
    ->create([
    'name' => $name,
    'user_id' => $uid,
    $langcode_key => $langcode,
  ]);
  $entity
    ->save();
  $entity = $storage
    ->load($entity
    ->id());
  $default_langcode = $entity
    ->language()
    ->getId();
  $this
    ->assertEquals($langcode, $default_langcode, new FormattableMarkup('%entity_type: Entity created as language specific.', [
    '%entity_type' => $entity_type,
  ]));
  $field = $entity
    ->getTranslation($langcode)
    ->get('name');
  $this
    ->assertEquals($name, $field->value, new FormattableMarkup('%entity_type: The entity name has been correctly stored as a language-aware property.', [
    '%entity_type' => $entity_type,
  ]));
  $this
    ->assertEquals($default_langcode, $field
    ->getLangcode(), new FormattableMarkup('%entity_type: The field object has the expect langcode.', [
    '%entity_type' => $entity_type,
  ]));
  $this
    ->assertEquals($uid, $entity
    ->getTranslation($langcode)
    ->get('user_id')->target_id, new FormattableMarkup('%entity_type: The entity author has been correctly stored as a language-aware property.', [
    '%entity_type' => $entity_type,
  ]));

  // Create property translations.
  $properties = [];
  $default_langcode = $langcode;
  foreach ($this->langcodes as $langcode) {
    if ($langcode != $default_langcode) {
      $properties[$langcode] = [
        'name' => [
          0 => $this
            ->randomMachineName(),
        ],
        'user_id' => [
          0 => mt_rand(128, 256),
        ],
      ];
    }
    else {
      $properties[$langcode] = [
        'name' => [
          0 => $name,
        ],
        'user_id' => [
          0 => $uid,
        ],
      ];
    }
    $translation = $entity
      ->hasTranslation($langcode) ? $entity
      ->getTranslation($langcode) : $entity
      ->addTranslation($langcode);
    foreach ($properties[$langcode] as $field_name => $values) {
      $translation
        ->set($field_name, $values);
    }
  }
  $entity
    ->save();

  // Check that property translation were correctly stored.
  $entity = $storage
    ->load($entity
    ->id());
  foreach ($this->langcodes as $langcode) {
    $args = [
      '%entity_type' => $entity_type,
      '%langcode' => $langcode,
    ];
    $field = $entity
      ->getTranslation($langcode)
      ->get('name');
    $this
      ->assertEquals($properties[$langcode]['name'][0], $field->value, new FormattableMarkup('%entity_type: The entity name has been correctly stored for language %langcode.', $args));
    $field_langcode = $langcode == $entity
      ->language()
      ->getId() ? $default_langcode : $langcode;
    $this
      ->assertEquals($field
      ->getLangcode(), $field_langcode, new FormattableMarkup('%entity_type: The field object has the expected langcode  %langcode.', $args));
    $this
      ->assertEquals($entity
      ->getTranslation($langcode)
      ->get('user_id')->target_id, $properties[$langcode]['user_id'][0], new FormattableMarkup('%entity_type: The entity author has been correctly stored for language %langcode.', $args));
  }

  // Test query conditions (cache is reset at each call).
  $translated_id = $entity
    ->id();

  // Create an additional entity with only the uid set. The uid for the
  // original language is the same of one used for a translation.
  $langcode = $this->langcodes[1];

  /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
  $storage = $this->container
    ->get('entity_type.manager')
    ->getStorage($entity_type);
  $storage
    ->create([
    'user_id' => $properties[$langcode]['user_id'],
    'name' => 'some name',
    $langcode_key => LanguageInterface::LANGCODE_NOT_SPECIFIED,
  ])
    ->save();
  $entities = $storage
    ->loadMultiple();
  $this
    ->assertCount(3, $entities, new FormattableMarkup('%entity_type: Three entities were created.', [
    '%entity_type' => $entity_type,
  ]));
  $entities = $storage
    ->loadMultiple([
    $translated_id,
  ]);
  $this
    ->assertCount(1, $entities, new FormattableMarkup('%entity_type: One entity correctly loaded by id.', [
    '%entity_type' => $entity_type,
  ]));
  $entities = $storage
    ->loadByProperties([
    'name' => $name,
  ]);
  $this
    ->assertCount(2, $entities, new FormattableMarkup('%entity_type: Two entities correctly loaded by name.', [
    '%entity_type' => $entity_type,
  ]));

  // @todo The default language condition should go away in favor of an
  // explicit parameter.
  $entities = $storage
    ->loadByProperties([
    'name' => $properties[$langcode]['name'][0],
    $default_langcode_key => 0,
  ]);
  $this
    ->assertCount(1, $entities, new FormattableMarkup('%entity_type: One entity correctly loaded by name translation.', [
    '%entity_type' => $entity_type,
  ]));
  $entities = $storage
    ->loadByProperties([
    $langcode_key => $default_langcode,
    'name' => $name,
  ]);
  $this
    ->assertCount(1, $entities, new FormattableMarkup('%entity_type: One entity correctly loaded by name and language.', [
    '%entity_type' => $entity_type,
  ]));
  $entities = $storage
    ->loadByProperties([
    $langcode_key => $langcode,
    'name' => $properties[$langcode]['name'][0],
  ]);
  $this
    ->assertCount(0, $entities, new FormattableMarkup('%entity_type: No entity loaded by name translation specifying the translation language.', [
    '%entity_type' => $entity_type,
  ]));
  $entities = $storage
    ->loadByProperties([
    $langcode_key => $langcode,
    'name' => $properties[$langcode]['name'][0],
    $default_langcode_key => 0,
  ]);
  $this
    ->assertCount(1, $entities, new FormattableMarkup('%entity_type: One entity loaded by name translation and language specifying to look for translations.', [
    '%entity_type' => $entity_type,
  ]));
  $entities = $storage
    ->loadByProperties([
    'user_id' => $properties[$langcode]['user_id'][0],
    $default_langcode_key => NULL,
  ]);
  $this
    ->assertCount(2, $entities, new FormattableMarkup('%entity_type: Two entities loaded by uid without caring about property translatability.', [
    '%entity_type' => $entity_type,
  ]));

  // Test property conditions and orders with multiple languages in the same
  // query.
  $query = \Drupal::entityQuery($entity_type)
    ->accessCheck(FALSE);
  $group = $query
    ->andConditionGroup()
    ->condition('user_id', $properties[$default_langcode]['user_id'][0], '=', $default_langcode)
    ->condition('name', $properties[$default_langcode]['name'][0], '=', $default_langcode);
  $result = $query
    ->condition($group)
    ->condition('name', $properties[$langcode]['name'][0], '=', $langcode)
    ->execute();
  $this
    ->assertCount(1, $result, new FormattableMarkup('%entity_type: One entity loaded by name and uid using different language meta conditions.', [
    '%entity_type' => $entity_type,
  ]));

  // Test mixed property and field conditions.
  $storage
    ->resetCache($result);
  $entity = $storage
    ->load(reset($result));
  $field_value = $this
    ->randomString();
  $entity
    ->getTranslation($langcode)
    ->set($this->fieldName, [
    [
      'value' => $field_value,
    ],
  ]);
  $entity
    ->save();
  $query = \Drupal::entityQuery($entity_type)
    ->accessCheck(FALSE);
  $default_langcode_group = $query
    ->andConditionGroup()
    ->condition('user_id', $properties[$default_langcode]['user_id'][0], '=', $default_langcode)
    ->condition('name', $properties[$default_langcode]['name'][0], '=', $default_langcode);
  $langcode_group = $query
    ->andConditionGroup()
    ->condition('name', $properties[$langcode]['name'][0], '=', $langcode)
    ->condition("{$this->fieldName}.value", $field_value, '=', $langcode);
  $result = $query
    ->condition($langcode_key, $default_langcode)
    ->condition($default_langcode_group)
    ->condition($langcode_group)
    ->execute();
  $this
    ->assertCount(1, $result, new FormattableMarkup('%entity_type: One entity loaded by name, uid and field value using different language meta conditions.', [
    '%entity_type' => $entity_type,
  ]));
}