Unverified Commit 94493f36 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2955392 by bnjmnm, dhirendra.mishra, dagmar, Berdir, alexpott, Regnoy,...

Issue #2955392 by bnjmnm, dhirendra.mishra, dagmar, Berdir, alexpott, Regnoy, scotself, johndevman, babis.p, shaal, Anybody, Steven Buteneers, thomas.frobieter, Diego_Mow, YahyaAlHamad, mdupont, msankhala: EntityViewBuilder::viewField() does not respect entity current language when used with an entity reference field

(cherry picked from commit 1e04ea32)
parent e6b64adc
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -456,7 +456,15 @@ protected function isViewModeCacheable($view_mode) {
   * {@inheritdoc}
   */
  public function viewField(FieldItemListInterface $items, $display_options = []) {
    /** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
    $entity = $items->getEntity();
    // If the field is not translatable and the entity is, then the field item
    // list always points to the default translation of the entity. Attempt to
    // fetch it in the current content language.
    if (!$items->getFieldDefinition()->isTranslatable() && $entity->isTranslatable()) {
      $entity = $this->entityRepository->getTranslationFromContext($entity);
    }

    $field_name = $items->getFieldDefinition()->getName();
    $display = $this->getSingleFieldDisplay($entity, $field_name, $display_options);

+106 −0
Original line number Diff line number Diff line
@@ -5,6 +5,11 @@
use Drupal\Core\Entity\EntityViewBuilder;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\Entity\EntityViewMode;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
@@ -197,6 +202,107 @@ public function testEntityViewBuilderWeight() {
    $this->assertEqual($view['label']['#weight'], 20, 'The weight of a display component is respected.');
  }

  /**
   * Tests EntityViewBuilder::viewField() language awareness.
   */
  public function testViewField() {
    // Allow access to view translations as well.
    Role::load(RoleInterface::ANONYMOUS_ID)
      ->grantPermission('view test entity translations')
      ->save();
    $this->enableModules([
      'language',
      'content_translation',
    ]);
    $this->installEntitySchema('entity_test_mul');
    $en = ConfigurableLanguage::create(['id' => 'en']);
    $en->save();
    $es = ConfigurableLanguage::create(['id' => 'es']);
    $es->save();
    $this->container->get('content_translation.manager')->setEnabled('entity_test_mul', 'entity_test_mul', TRUE);

    $this->createEntityReferenceField('entity_test_mul', 'entity_test_mul', 'reference_field', 'Reference', 'entity_test_mul');

    // Make the entity reference field non-translatable to confirm it still
    // renders the correct language when displayed as an entity reference.
    $field = FieldConfig::loadByName('entity_test_mul', 'entity_test_mul', 'reference_field');
    $field->set('translatable', FALSE)->save();

    // Create fields and displays for the test entity.
    FieldStorageConfig::create([
      'field_name' => 'text',
      'entity_type' => 'entity_test_mul',
      'type' => 'string',
    ])->save();

    FieldConfig::create([
      'field_name' => 'text',
      'entity_type' => 'entity_test_mul',
      'bundle' => 'entity_test_mul',
      'label' => 'Translated text',
      'translatable' => TRUE,
    ])->save();

    EntityViewMode::create([
      'id' => 'entity_test_mul.full',
      'targetEntityType' => 'entity_test_mul',
      'status' => FALSE,
      'enabled' => TRUE,
      'label' => 'Full',
    ])->save();

    $display = EntityViewDisplay::create([
      'targetEntityType' => 'entity_test_mul',
      'bundle' => 'entity_test_mul',
      'mode' => 'full',
      'label' => 'My view mode',
      'status' => TRUE,
    ])
      ->setComponent('reference_field', [
        'type' => 'entity_reference_entity_view',
        'settings' => [
          'view_mode' => 'full',
        ],
      ])
      ->setComponent('text', [
        'type' => 'string',
        'region' => 'content',
      ]);
    $display->save();

    // Create the entity that will be displayed in the entity reference field
    // of the main entity.
    $referenced_entity = $this->createTestEntity('entity_test_mul');
    $referenced_entity->addTranslation('es', $referenced_entity->getTranslation('en')->toArray());
    $referenced_entity->set('text', 'Text in English');
    $referenced_entity->getTranslation('es')->text = 'Text in Spanish';

    // The entity that will reference $referenced_entity.
    $main_entity = $this->createTestEntity('entity_test_mul');
    $main_entity->addTranslation('es', $main_entity->getTranslation('en')->toArray());
    $main_entity->set('reference_field', $referenced_entity);

    $view_builder = $this->container->get('entity_type.manager')->getViewBuilder('entity_test_mul');
    $renderer = $this->container->get('renderer');

    // Build the view for the reference field and render in English - the site
    // default. Confirm the reference field shows the content of the English
    // translation.
    $reference_field = $main_entity->get('reference_field');
    $reference_field_array_english = $view_builder->viewField($reference_field, 'full');
    $rendered_reference_field_english = $renderer->renderRoot($reference_field_array_english);
    $this->assertContains('Text in English', (string) $rendered_reference_field_english);

    // Change the default language to Spanish and render the reference
    // field again. It should display the contents of the Spanish translation.
    \Drupal::service('language.default')->set($es);
    \Drupal::languageManager()->reset();
    \Drupal::languageManager()->getCurrentLanguage();
    $reference_field_array_spanish = $view_builder->viewField($reference_field, 'full');
    $rendered_reference_field_spanish = $renderer->renderRoot($reference_field_array_spanish);
    $this->assertContains('Text in Spanish', (string) $rendered_reference_field_spanish);
  }

  /**
   * Creates an entity for testing.
   *