core/lib/Drupal/Core/Entity/EntityViewBuilder.php | 41 +++++++--------- .../Entity/Render/DefaultLanguageRenderer.php | 55 ---------------------- .../Drupal/views/Entity/Render/RendererBase.php | 8 +--- 3 files changed, 18 insertions(+), 86 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index 1240cba..4a3ace3 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -104,7 +104,6 @@ public static function createInstance(ContainerInterface $container, EntityTypeI protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) { $build = array( '#theme' => $this->entityTypeId, - '#pre_render' => array(array($this, 'buildEntity')), "#{$this->entityTypeId}" => $entity, '#view_mode' => $view_mode, '#langcode' => $langcode, @@ -160,7 +159,15 @@ protected function alterBuild(array &$build, EntityInterface $entity, EntityView */ public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) { $buildList = $this->viewMultiple(array($entity), $view_mode, $langcode); - return $buildList[0]; + + // The default ::buildEntityMultiple() #pre_render callback won't run, + // because we extract a child element of the default renderable array. Thus + // we must assign an alternative #pre_render callback that applies the + // necessary transformations and then still calls ::buildEntityMultiple(). + $build = $buildList[0]; + $build['#pre_render'][] = array($this, 'buildEntity'); + + return $build; } /** @@ -201,16 +208,15 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la /** * Builds an entity's view; augments entity defaults. * - * This function is assigned as a #pre_render callback in - * \Drupal\Core\Entity\EntityViewBuilder::getBuildDefaults(). + * This function is assigned as a #pre_render callback in ::view(). * - * By delaying the building of an entity until the #pre_render processing in - * drupal_render(), the processing cost of assembling an entity's renderable - * array is saved on cache-hit requests. + * It transforms the renderable array for a single entity to the same + * structure as if we were rendering multiple entities, and then calls the + * default ::buildEntityMultiple() #pre_render callback. * * @param array $build - * A renderable array containing build information and context for an - * entity view. + * A renderable array containing build information and context for an entity + * view. * * @return array * The updated renderable array. @@ -229,11 +235,7 @@ public function buildEntity(array $build) { /** * Builds multiple entities' views; augments entity defaults. * - * This function is assigned as a #pre_render callback in - * \Drupal\Core\Entity\EntityViewBuilder::viewMultiple(). Each entity will - * also have a #pre_render callback in its build array for single building. - * That callback in removed for entities built in this multiple handling - * process so that any entity is only built once. + * This function is assigned as a #pre_render callback in ::viewMultiple(). * * By delaying the building of an entity until the #pre_render processing in * drupal_render(), the processing cost of assembling an entity's renderable @@ -272,17 +274,6 @@ public function buildEntityMultiple(array $build) { $displays = EntityViewDisplay::collectRenderDisplays($view_mode_entities, $view_mode); $this->buildContent($build, $view_mode_entities, $displays, $view_mode, $langcode); foreach (array_keys($view_mode_entities) as $key) { - // Remove the single item pre_render function. The renderable arrays - // were just built in the call to $this->buildContent above. Removing - // the pre_render functions prevents the renderable arrays from being - // built again when drupal_render() recurses into the child elements - // of this list of renderables. - $pre_render = $build[$key]['#pre_render'] ?: array(); - foreach ($pre_render as $index => $callable) { - if (is_array($callable) && $callable[1] === 'buildEntity') { - unset($build[$key]['#pre_render'][$index]); - } - } // Allow for alterations while building, before rendering. $entity = $build[$key][$entity_type_key]; $display = $displays[$entity->bundle()]; diff --git a/core/modules/views/lib/Drupal/views/Entity/Render/DefaultLanguageRenderer.php b/core/modules/views/lib/Drupal/views/Entity/Render/DefaultLanguageRenderer.php index 8bd9e94..18875f5 100644 --- a/core/modules/views/lib/Drupal/views/Entity/Render/DefaultLanguageRenderer.php +++ b/core/modules/views/lib/Drupal/views/Entity/Render/DefaultLanguageRenderer.php @@ -15,61 +15,6 @@ class DefaultLanguageRenderer extends RendererBase { /** - * {@inheritdoc} - */ - public function preRender(array $result) { - /** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */ - $entities = array(); - $langcodes = array(); - - /** @var \Drupal\views\ResultRow $row */ - foreach ($result as $row) { - $entity = $row->_entity; - $entity->view = $this->view; - $langcodes[] = $langcode = $this->getLangcode($row); - $entities[$entity->id()][$langcode] = $entity; - } - $count_langcodes = count(array_unique($langcodes)); - - $view_builder = $this->view->rowPlugin->entityManager->getViewBuilder($this->entityType->id()); - - if ($count_langcodes > 1) { - // Render each entity separate if we do have more than one translation. - // @todo It should be possible to use viewMultiple even if you get - // more than one language. See https://drupal.org/node/2073217. - foreach ($entities as $entity_translation) { - foreach ($entity_translation as $langcode => $entity) { - $entity = $entity->getTranslation($langcode); - $this->build[$entity->id()][$langcode] = $view_builder->view($entity, $this->view->rowPlugin->options['view_mode'], $langcode); - } - } - } - else { - $langcode = reset($langcodes); - $entity_translations = array(); - foreach ($entities as $entity_translation) { - $entity = $entity_translation[$langcode]; - $entity_translations[$entity->id()] = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity; - } - $this->build = $view_builder->viewMultiple($entity_translations, $this->view->rowPlugin->options['view_mode'], $langcode); - } - } - - /** - * {@inheritdoc} - */ - public function render(ResultRow $row) { - $entity_id = $row->_entity->id(); - $langcode = $this->getLangcode($row); - if (isset($this->build[$entity_id][$langcode])) { - return $this->build[$entity_id][$langcode]; - } - else { - return $this->build[$entity_id]; - } - } - - /** * Returns the language code associated to the given row. * * @param \Drupal\views\ResultRow $row diff --git a/core/modules/views/lib/Drupal/views/Entity/Render/RendererBase.php b/core/modules/views/lib/Drupal/views/Entity/Render/RendererBase.php index a3b211f..b3590c2 100644 --- a/core/modules/views/lib/Drupal/views/Entity/Render/RendererBase.php +++ b/core/modules/views/lib/Drupal/views/Entity/Render/RendererBase.php @@ -67,18 +67,14 @@ public function query(QueryPluginBase $query) { * The full array of results from the query. */ public function preRender(array $result) { - /** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */ - $entities = array(); + $view_builder = $this->view->rowPlugin->entityManager->getViewBuilder($this->entityType->id()); /** @var \Drupal\views\ResultRow $row */ foreach ($result as $row) { $entity = $row->_entity; $entity->view = $this->view; - $entities[$entity->id()] = $entity; + $this->build[$entity->id()] = $view_builder->view($entity, $this->view->rowPlugin->options['view_mode'], $this->getLangcode($row)); } - - $view_builder = $this->view->rowPlugin->entityManager->getViewBuilder($this->entityType->id()); - $this->build = $view_builder->viewMultiple($entities, $this->view->rowPlugin->options['view_mode']); } /**