diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index 28991e5..cf7cfe5 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -87,15 +87,30 @@ public static function createInstance(ContainerInterface $container, EntityTypeI * {@inheritdoc} */ public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) { - // Let the formatters prepare the field values. $entities_by_bundle = array(); foreach ($entities as $id => $entity) { // Remove previously built content, if exists. $entity->content = array( '#view_mode' => $view_mode, ); + // Initialize the field item attributes for the fields being displayed. + // The entity can include fields that are not displayed, and the display + // can include components that are not fields, so we want to act on the + // intersection. However, the entity can have many more fields than are + // displayed, so we avoid the cost of calling $entity->getProperties() + // by iterating the intersection as follows. + foreach ($displays[$entity->bundle()]->getComponents() as $name => $options) { + if ($entity->hasField($name)) { + foreach ($entity->get($name) as $item) { + $item->_attributes = array(); + } + } + } + // Group the entities by bundle. $entities_by_bundle[$entity->bundle()][$id] = $entity; } + + // Let the formatters prepare the field values. foreach ($entities_by_bundle as $bundle => $bundle_entities) { $displays[$bundle]->prepareFields($bundle_entities); } diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php index 0d026f2..003aea3 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php @@ -15,9 +15,9 @@ /** * Build the structured $content property on the entity. * - * @param array $entities + * @param \Drupal\Core\Entity\EntityInterface[] $entities * The entities, implementing EntityInterface, whose content is being built. - * @param array $displays + * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface[] $displays * The array of entity_display objects holding the display options * configured for the entity components, keyed by bundle name. * @param string $view_mode diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php index 47ba000..364f0a0 100644 --- a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php @@ -72,30 +72,23 @@ public function getRenderer($field_name) { return $formatter; } + /** * {@inheritdoc} */ public function prepareFields(array $entities) { - if ($entities) { - // For each field in the bundle, group items across all entities and - // pass them to the formatter's prepareView() method. - $field_definitions = current($entities)->getPropertyDefinitions(); - foreach ($field_definitions as $field_name => $definition) { - if ($formatter = $this->getRenderer($field_name)) { - $entities_items = array(); - foreach ($entities as $id => $entity) { - $items = $entity->get($field_name); - $items->filterEmptyValues(); - - // Initialize the field item attributes for the fields set to be displayed. - foreach ($items as $item) { - $item->_attributes = array(); - } - $entities_items[$id] = $items; - } - - $formatter->prepareView($entities_items); + // For each field that is displayed, group items across all entities and + // pass them to the formatter's prepareView() method. + foreach ($this->getFieldDefinitions() as $field_name => $definition) { + if ($formatter = $this->getRenderer($field_name)) { + $entities_items = array(); + foreach ($entities as $id => $entity) { + $items = $entity->get($field_name); + $items->filterEmptyValues(); + $entities_items[$id] = $items; } + + $formatter->prepareView($entities_items); } } } @@ -105,7 +98,7 @@ public function prepareFields(array $entities) { */ public function attachFields(EntityInterface $entity) { $build = array(); - foreach ($entity->getPropertyDefinitions() as $field_name => $definition) { + foreach ($this->getFieldDefinitions() as $field_name => $definition) { if ($formatter = $this->getRenderer($field_name)) { $items = $entity->get($field_name); $items->filterEmptyValues();