Issue #2374019 by yched, jibran, amateescu: Cleanup the use of custom item properties in EntityReferenceFormatterBase

8.0.x
Alex Pott 2015-02-02 10:47:25 +00:00
parent 9eb96615da
commit 6d75fd574c
5 changed files with 51 additions and 31 deletions

View File

@ -30,26 +30,19 @@ abstract class EntityReferenceFormatterBase extends FormatterBase {
$parent_entity_langcode = $items->getEntity()->language()->getId();
foreach ($items as $delta => $item) {
// The "originalEntity" property is assigned in self::prepareView() and
// its absence means that the referenced entity was neither found in the
// persistent storage nor is it a new entity (e.g. from "autocreate").
if (!isset($item->originalEntity)) {
$item->access = FALSE;
continue;
}
// Ignore items where no entity could be loaded in prepareView().
if (!empty($item->_loaded)) {
$entity = $item->entity;
if ($item->originalEntity instanceof TranslatableInterface && $item->originalEntity->hasTranslation($parent_entity_langcode)) {
$entity = $item->originalEntity->getTranslation($parent_entity_langcode);
}
else {
$entity = $item->originalEntity;
}
// Set the entity in the correct language for display.
if ($entity instanceof TranslatableInterface && $entity->hasTranslation($parent_entity_langcode)) {
$entity = $entity->getTranslation($parent_entity_langcode);
}
if ($item->access || $entity->access('view')) {
$entities[$delta] = $entity;
// Mark item as accessible.
$item->access = TRUE;
// Check entity access.
if ($entity->access('view')) {
$entities[$delta] = $entity;
}
}
}
@ -60,7 +53,7 @@ abstract class EntityReferenceFormatterBase extends FormatterBase {
* {@inheritdoc}
*
* Loads the entities referenced in that field across all the entities being
* viewed, and places them in a custom item property for getEntitiesToView().
* viewed.
*/
public function prepareView(array $entities_items) {
// Load the existing (non-autocreate) entities. For performance, we want to
@ -71,6 +64,11 @@ abstract class EntityReferenceFormatterBase extends FormatterBase {
$ids = array();
foreach ($entities_items as $items) {
foreach ($items as $item) {
// To avoid trying to reload non-existent entities in
// getEntitiesToView(), explicitly mark the items where $item->entity
// contains a valid entity ready for display. All items are initialized
// at FALSE.
$item->_loaded = FALSE;
if ($item->target_id !== NULL) {
$ids[] = $item->target_id;
}
@ -81,15 +79,16 @@ abstract class EntityReferenceFormatterBase extends FormatterBase {
$target_entities = \Drupal::entityManager()->getStorage($target_type)->loadMultiple($ids);
}
// For each item, place the referenced entity where getEntitiesToView()
// reads it.
// For each item, pre-populate the loaded entity in $item->entity, and set
// the 'loaded' flag.
foreach ($entities_items as $items) {
foreach ($items as $item) {
if (isset($target_entities[$item->target_id])) {
$item->originalEntity = $target_entities[$item->target_id];
$item->entity = $target_entities[$item->target_id];
$item->_loaded = TRUE;
}
elseif ($item->hasNewEntity()) {
$item->originalEntity = $item->entity;
$item->_loaded = TRUE;
}
}
}

View File

@ -12,6 +12,7 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\filter\Entity\FilterFormat;
use Drupal\system\Tests\Entity\EntityUnitTestBase;
use Drupal\user\Entity\Role;
/**
* Tests the formatters functionality.
@ -66,6 +67,12 @@ class EntityReferenceFormatterTest extends EntityUnitTestBase {
protected function setUp() {
parent::setUp();
// Grant the 'view test entity' permission.
$this->installConfig(array('user'));
Role::load(DRUPAL_ANONYMOUS_RID)
->grantPermission('view test entity')
->save();
// The label formatter rendering generates links, so build the router.
$this->installSchema('system', 'router');
$this->container->get('router.builder')->rebuild();
@ -118,6 +125,11 @@ class EntityReferenceFormatterTest extends EntityUnitTestBase {
* Assert unaccessible items don't change the data of the fields.
*/
public function testAccess() {
// Revoke the 'view test entity' permission for this test.
Role::load(DRUPAL_ANONYMOUS_RID)
->revokePermission('view test entity')
->save();
$field_name = $this->fieldName;
$referencing_entity = entity_create($this->entityType, array('name' => $this->randomMachineName()));
@ -265,8 +277,7 @@ class EntityReferenceFormatterTest extends EntityUnitTestBase {
$delta = 0;
foreach ($referenced_entities as $referenced_entity) {
$referencing_entity->{$this->fieldName}[$delta]->entity = $referenced_entity;
$referencing_entity->{$this->fieldName}[$delta++]->access = TRUE;
$referencing_entity->{$this->fieldName}[$delta++]->entity = $referenced_entity;
}
// Build the renderable array for the entity reference field.

View File

@ -6,9 +6,7 @@
namespace Drupal\rdf\Tests\Field;
use Drupal\rdf\Tests\Field\FieldRdfaTestBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Language\Language;
use Drupal\user\Entity\Role;
/**
* Tests the RDFa output of the entity reference field formatter.
@ -53,6 +51,12 @@ class EntityReferenceRdfaTest extends FieldRdfaTestBase {
$this->installEntitySchema('entity_test_rev');
// Give anonymous users permission to view test entities.
$this->installConfig(array('user'));
Role::load(DRUPAL_ANONYMOUS_RID)
->grantPermission('view test entity')
->save();
entity_reference_create_field($this->entityType, $this->bundle, $this->fieldName, 'Field test', $this->entityType);
// Add the mapping.
@ -69,7 +73,6 @@ class EntityReferenceRdfaTest extends FieldRdfaTestBase {
$this->entity = entity_create($this->entityType, array('name' => $this->randomMachineName()));
$this->entity->save();
$this->entity->{$this->fieldName}->entity = $this->targetEntity;
$this->entity->{$this->fieldName}->access = TRUE;
$this->uri = $this->getAbsoluteUri($this->entity);
}

View File

@ -7,6 +7,8 @@
namespace Drupal\system\Tests\Entity;
use Drupal\user\Entity\Role;
/**
* Tests the entity view builder.
*
@ -26,7 +28,12 @@ class EntityViewBuilderTest extends EntityUnitTestBase {
*/
protected function setUp() {
parent::setUp();
$this->installConfig(array('entity_test'));
$this->installConfig(array('user', 'entity_test'));
// Give anonymous users permission to view test entities.
Role::load(DRUPAL_ANONYMOUS_RID)
->grantPermission('view test entity')
->save();
}
/**
@ -113,7 +120,6 @@ class EntityViewBuilderTest extends EntityUnitTestBase {
// Create another entity that references the first one.
$entity_test = $this->createTestEntity('entity_test');
$entity_test->reference_field->entity = $entity_test_reference;
$entity_test->reference_field->access = TRUE;
$entity_test->save();
// Get a fully built entity view render array.

View File

@ -14,6 +14,7 @@ namespace Drupal\entity_test\Entity;
* id = "entity_test_label",
* label = @Translation("Entity Test label"),
* handlers = {
* "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder"
* },
* base_table = "entity_test",