Commit bf44ce4a authored by alexpott's avatar alexpott

Issue #2346315 by Désiré, amateescu: Fixed Translated entity references not...

Issue #2346315 by Désiré, amateescu: Fixed Translated entity references not rendered in the entity display language.
parent 51e37ae6
......@@ -69,34 +69,29 @@ public function settingsSummary() {
*/
public function viewElements(FieldItemListInterface $items) {
$view_mode = $this->getSetting('view_mode');
$elements = array();
foreach ($items as $delta => $item) {
if (!$item->access) {
// User doesn't have access to the referenced entity.
continue;
}
foreach ($this->getEntitiesToView($items) as $delta => $entity) {
// Protect ourselves from recursive rendering.
static $depth = 0;
$depth++;
if ($depth > 20) {
throw new RecursiveRenderingException(format_string('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array('@entity_type' => $item->entity->getEntityTypeId(), '@entity_id' => $item->target_id)));
throw new RecursiveRenderingException(format_string('Recursive rendering detected when rendering entity @entity_type(@entity_id). Aborting rendering.', array('@entity_type' => $entity->getEntityTypeId(), '@entity_id' => $entity->id())));
}
if (!empty($item->target_id)) {
$elements[$delta] = entity_view($item->entity, $view_mode, $item->getLangcode());
if ($entity->id()) {
$elements[$delta] = entity_view($entity, $view_mode, $entity->language()->getId());
// Add a resource attribute to set the mapping property's value to the
// entity's url. Since we don't know what the markup of the entity will
// be, we shouldn't rely on it for structured data such as RDFa.
if (!empty($item->_attributes)) {
$item->_attributes += array('resource' => $item->entity->url());
if (!empty($items[$delta]->_attributes)) {
$items[$delta]->_attributes += array('resource' => $entity->url());
}
}
else {
// This is an "auto_create" item.
$elements[$delta] = array('#markup' => $item->entity->label());
$elements[$delta] = array('#markup' => $entity->label());
}
$depth = 0;
}
......
......@@ -8,12 +8,46 @@
namespace Drupal\entity_reference\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\Core\Field\FieldItemListInterface;
/**
* Parent plugin for entity reference formatters.
*/
abstract class EntityReferenceFormatterBase extends FormatterBase {
/**
* Returns the accessible and translated entities for view.
*
* @param \Drupal\Core\Field\FieldItemListInterface $items
* The item list.
*
* @return \Drupal\Core\Entity\EntityInterface[]
* The entities to view.
*/
protected function getEntitiesToView(FieldItemListInterface $items) {
$entities = array();
$parent_entity_langcode = $items->getEntity()->language()->getId();
foreach ($items as $delta => $item) {
if ($item->originalEntity instanceof TranslatableInterface && $item->originalEntity->hasTranslation($parent_entity_langcode)) {
$entity = $item->originalEntity->getTranslation($parent_entity_langcode);
}
else {
$entity = $item->originalEntity;
}
if ($item->access || $entity->access('view')) {
$entities[$delta] = $entity;
// Mark item as accessible.
$item->access = TRUE;
}
}
return $entities;
}
/**
* {@inheritdoc}
*
......@@ -68,19 +102,12 @@ public function prepareView(array $entities_items) {
$rekey = TRUE;
continue;
}
$item->entity = $target_entities[$identifier];
if (!$item->entity->access('view')) {
continue;
}
}
else {
// This is an "auto_create" item, just leave the entity in place.
}
// Mark item as accessible.
$item->access = TRUE;
$item->originalEntity = $target_entities[$identifier];
}
// Rekey the items array if needed.
......
......@@ -30,21 +30,15 @@ class EntityReferenceIdFormatter extends EntityReferenceFormatterBase {
public function viewElements(FieldItemListInterface $items) {
$elements = array();
foreach ($items as $delta => $item) {
if (!$item->access) {
// User doesn't have access to the referenced entity.
continue;
}
if (!empty($item->entity) && !empty($item->target_id)) {
/** @var $referenced_entity \Drupal\Core\Entity\EntityInterface */
$referenced_entity = $item->entity;
foreach ($this->getEntitiesToView($items) as $delta => $entity) {
if ($entity->id()) {
$elements[$delta] = array(
'#markup' => String::checkPlain($item->target_id),
'#markup' => String::checkPlain($entity->id()),
// Create a cache tag entry for the referenced entity. In the case
// that the referenced entity is deleted, the cache for referring
// entities must be cleared.
'#cache' => array(
'tags' => $referenced_entity->getCacheTag(),
'tags' => $entity->getCacheTag(),
),
);
}
......
......@@ -62,35 +62,28 @@ public function settingsSummary() {
public function viewElements(FieldItemListInterface $items) {
$elements = array();
foreach ($items as $delta => $item) {
if (!$item->access) {
// User doesn't have access to the referenced entity.
continue;
}
/** @var $referenced_entity \Drupal\Core\Entity\EntityInterface */
if ($referenced_entity = $item->entity) {
$label = $referenced_entity->label();
// If the link is to be displayed and the entity has a uri, display a
// link.
if ($this->getSetting('link') && $uri = $referenced_entity->urlInfo()) {
$elements[$delta] = array(
'#type' => 'link',
'#title' => $label,
) + $uri->toRenderArray();
foreach ($this->getEntitiesToView($items) as $delta => $entity) {
$label = $entity->label();
// If the link is to be displayed and the entity has a uri, display a
// link.
if ($this->getSetting('link') && $uri = $entity->urlInfo()) {
$elements[$delta] = array(
'#type' => 'link',
'#title' => $label,
) + $uri->toRenderArray();
if (!empty($item->_attributes)) {
$elements[$delta]['#options'] += array('attributes' => array());
$elements[$delta]['#options']['attributes'] += $item->_attributes;
// Unset field item attributes since they have been included in the
// formatter output and shouldn't be rendered in the field template.
unset($item->_attributes);
}
}
else {
$elements[$delta] = array('#markup' => String::checkPlain($label));
if (!empty($items[$delta]->_attributes)) {
$elements[$delta]['#options'] += array('attributes' => array());
$elements[$delta]['#options']['attributes'] += $items[$delta]->_attributes;
// Unset field item attributes since they have been included in the
// formatter output and shouldn't be rendered in the field template.
unset($items[$delta]->_attributes);
}
$elements[$delta]['#cache']['tags'] = $referenced_entity->getCacheTag();
}
else {
$elements[$delta] = array('#markup' => String::checkPlain($label));
}
$elements[$delta]['#cache']['tags'] = $entity->getCacheTag();
}
return $elements;
......
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\EntityReferenceFieldTranslatedReferenceViewTest.
*/
namespace Drupal\entity_reference\Tests;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\simpletest\WebTestBase;
/**
* Tests the translation of entity reference field display on nodes.
*
* @group entity_reference
*/
class EntityReferenceFieldTranslatedReferenceViewTest extends WebTestBase {
/**
* The langcode of the source language.
*
* @var string
*/
protected $baseLangcode = 'en';
/**
* Target langcode for translation.
*
* @var string
*/
protected $translateToLangcode = 'hu';
/**
* The test entity type name.
*
* @var string
*/
protected $testEntityTypeName = 'node';
/**
* Entity type which have the entity reference field.
*
* @var \Drupal\node\Entity\NodeType
*/
protected $referrerType;
/**
* Entity type which can be referenced.
*
* @var \Drupal\node\Entity\NodeType
*/
protected $referencedType;
/**
* The referrer entity.
*
* @var \Drupal\node\Entity\Node
*/
protected $referrerEntity;
/**
* The entity to refer.
*
* @var \Drupal\node\Entity\Node
*/
protected $referencedEntityWithoutTranslation;
/**
* The entity to refer.
*
* @var \Drupal\node\Entity\Node
*/
protected $referencedEntityWithTranslation;
/**
* The machine name of the entity reference field.
*
* @var string
*/
protected $referenceFieldName = 'test_reference_field';
/**
* The label of the untranslated referenced entity, used in assertions.
*
* @var string
*/
protected $labelOfNotTranslatedReference;
/**
* The original label of the referenced entity, used in assertions.
*
* @var string
*/
protected $originalLabel;
/**
* The translated label of the referenced entity, used in assertions.
*
* @var string
*/
protected $translatedLabel;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array(
'language',
'content_translation',
'entity_reference',
'node',
);
protected function setUp() {
parent::setUp();
$this->labelOfNotTranslatedReference = $this->randomMachineName();
$this->originalLabel = $this->randomMachineName();
$this->translatedLabel = $this->randomMachineName();
$this->setUpLanguages();
$this->setUpContentTypes();
$this->enableTranslation();
$this->setUpEntityReferenceField();
$this->createContent();
}
/**
* Tests if the translated entity is displayed in an entity reference field.
*/
public function testTranslatedEntityReferenceDisplay() {
$path = $this->referrerEntity->getSystemPath();
$translation_path = $this->translateToLangcode . '/' . $path;
$this->drupalGet($path);
$this->assertText($this->labelOfNotTranslatedReference, 'The label of not translated reference is displayed.');
$this->assertText($this->originalLabel, 'The default label of translated reference is displayed.');
$this->assertNoText($this->translatedLabel, 'The translated label of translated reference is not displayed.');
$this->drupalGet($translation_path);
$this->assertText($this->labelOfNotTranslatedReference, 'The label of not translated reference is displayed.');
$this->assertNoText($this->originalLabel, 'The default label of translated reference is not displayed.');
$this->assertText($this->translatedLabel, 'The translated label of translated reference is displayed.');
}
/**
* Adds additional languages.
*/
protected function setUpLanguages() {
ConfigurableLanguage::createFromLangcode($this->translateToLangcode)->save();
}
/**
* Creates a test subject contents, with translation.
*/
protected function createContent() {
$this->referencedEntityWithTranslation = $this->createReferencedEntityWithTranslation();
$this->referencedEntityWithoutTranslation = $this->createNotTranslatedReferencedEntity();
$this->referrerEntity = $this->createReferrerEntity();
}
/**
* Enables translations where it needed.
*/
protected function enableTranslation() {
// Enable translation for the entity types and ensure the change is picked
// up.
content_translation_set_config($this->testEntityTypeName, $this->referrerType->id(), 'enabled', TRUE);
content_translation_set_config($this->testEntityTypeName, $this->referencedType->id(), 'enabled', TRUE);
drupal_static_reset();
\Drupal::entityManager()->clearCachedDefinitions();
\Drupal::service('router.builder')->rebuild();
}
/**
* Adds term reference field for the article content type.
*/
protected function setUpEntityReferenceField() {
entity_create('field_storage_config', array(
'field_name' => $this->referenceFieldName,
'entity_type' => $this->testEntityTypeName,
'type' => 'entity_reference',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
'translatable' => FALSE,
'settings' => array(
'allowed_values' => array(
array(
'target_type' => $this->testEntityTypeName,
),
),
),
))->save();
entity_create('field_config', array(
'field_name' => $this->referenceFieldName,
'bundle' => $this->referrerType->type,
'entity_type' => $this->testEntityTypeName,
))
->save();
entity_get_form_display($this->testEntityTypeName, $this->referrerType->id(), 'default')
->setComponent($this->referenceFieldName, array(
'type' => 'entity_reference_autocomplete',
))
->save();
entity_get_display($this->testEntityTypeName, $this->referrerType->id(), 'default')
->setComponent($this->referenceFieldName, array(
'type' => 'entity_reference_label',
))
->save();
}
/**
* Create content types.
*/
protected function setUpContentTypes() {
$this->referrerType = $this->drupalCreateContentType(array(
'type' => 'referrer',
'name' => 'Referrer',
));
$this->referencedType = $this->drupalCreateContentType(array(
'type' => 'referenced_page',
'name' => 'Referenced Page',
));
}
/**
* Create a referenced entity with a translation.
*/
protected function createReferencedEntityWithTranslation() {
/** @var \Drupal\node\Entity\Node $node */
$node = entity_create($this->testEntityTypeName, array(
'title' => $this->originalLabel,
'type' => $this->referencedType->id(),
'description' => array(
'value' => $this->randomMachineName(),
'format' => 'basic_html',
),
'langcode' => $this->baseLangcode,
));
$node->save();
$node->addTranslation($this->translateToLangcode, array(
'title' => $this->translatedLabel,
));
$node->save();
return $node;
}
/**
* Create the referenced entity.
*/
protected function createNotTranslatedReferencedEntity() {
/** @var \Drupal\node\Entity\Node $node */
$node = entity_create($this->testEntityTypeName, array(
'title' => $this->labelOfNotTranslatedReference,
'type' => $this->referencedType->id(),
'description' => array(
'value' => $this->randomMachineName(),
'format' => 'basic_html',
),
'langcode' => $this->baseLangcode,
));
$node->save();
return $node;
}
/**
* Create the referrer entity.
*/
protected function createReferrerEntity() {
/** @var \Drupal\node\Entity\Node $node */
$node = entity_create($this->testEntityTypeName, array(
'title' => $this->randomMachineName(),
'type' => $this->referrerType->id(),
'description' => array(
'value' => $this->randomMachineName(),
'format' => 'basic_html',
),
$this->referenceFieldName => array(
array('target_id' => $this->referencedEntityWithTranslation->id()),
array('target_id' => $this->referencedEntityWithoutTranslation->id()),
),
'langcode' => $this->baseLangcode,
));
$node->save();
$node->addTranslation($this->translateToLangcode, array());
$node->save();
return $node;
}
}
......@@ -30,14 +30,13 @@ class EntityReferenceTaxonomyTermRssFormatter extends EntityReferenceFormatterBa
*/
public function viewElements(FieldItemListInterface $items) {
$elements = array();
$entity = $items->getEntity();
foreach ($items as $item) {
foreach ($this->getEntitiesToView($items) as $delta => $entity) {
$entity->rss_elements[] = array(
'key' => 'category',
'value' => $item->entity->label(),
'value' => $entity->label(),
'attributes' => array(
'domain' => $item->target_id ? \Drupal::url('entity.taxonomy_term.canonical', ['taxonomy_term' => $item->target_id], array('absolute' => TRUE)) : '',
'domain' => $entity->id() ? \Drupal::url('entity.taxonomy_term.canonical', ['taxonomy_term' => $entity->id()], array('absolute' => TRUE)) : '',
),
);
}
......
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