Revert "Issue #2843565 by Berdir, swentel, yched: getViewBuilder('node')->viewMultiple() bypasses render cache"
This reverts commit 3f9882ffdc
.
8.4.x
parent
ed82b95eb3
commit
78068b63a4
|
@ -108,7 +108,16 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
|
||||
return $this->viewMultiple(array($entity), $view_mode, $langcode)[0];
|
||||
$build_list = $this->viewMultiple(array($entity), $view_mode, $langcode);
|
||||
|
||||
// The default ::buildMultiple() #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 ::buildMultiple().
|
||||
$build = $build_list[0];
|
||||
$build['#pre_render'][] = array($this, 'build');
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,6 +126,7 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
|
|||
public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
|
||||
$build_list = array(
|
||||
'#sorted' => TRUE,
|
||||
'#pre_render' => array(array($this, 'buildMultiple')),
|
||||
);
|
||||
$weight = 0;
|
||||
foreach ($entities as $key => $entity) {
|
||||
|
@ -129,7 +139,6 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
|
|||
$entityType = $this->entityTypeId;
|
||||
$this->moduleHandler()->alter(array($entityType . '_build_defaults', 'entity_build_defaults'), $build_list[$key], $entity, $view_mode);
|
||||
|
||||
$build_list[$key]['#pre_render'][] = array($this, 'build');
|
||||
$build_list[$key]['#weight'] = $weight++;
|
||||
}
|
||||
|
||||
|
@ -191,12 +200,11 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
|
|||
/**
|
||||
* Builds an entity's view; augments entity defaults.
|
||||
*
|
||||
* This method is assigned as a #pre_render callback in ::viewMultiple() for
|
||||
* each entity.
|
||||
* This function is assigned as a #pre_render callback in ::view().
|
||||
*
|
||||
* It transforms the renderable array for a single entity to a structure
|
||||
* understood by EntityViewBuilder::buildMultiple(), which is currently not
|
||||
* called directly.
|
||||
* 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 ::buildMultiple() #pre_render callback.
|
||||
*
|
||||
* @param array $build
|
||||
* A renderable array containing build information and context for an entity
|
||||
|
@ -205,8 +213,7 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
|
|||
* @return array
|
||||
* The updated renderable array.
|
||||
*
|
||||
* @see \Drupal\Core\Render\RendererInterface
|
||||
* @see \Drupal\Core\Entity\EntityViewBuilder::buildMultiple()
|
||||
* @see drupal_render()
|
||||
*/
|
||||
public function build(array $build) {
|
||||
$build_list = [$build];
|
||||
|
@ -217,17 +224,11 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
|
|||
/**
|
||||
* Builds multiple entities' views; augments entity defaults.
|
||||
*
|
||||
* This method is currently only called through EntityViewBuilder::build()
|
||||
* as the render (cache) system does not support a #pre_render callback for
|
||||
* multiple, separately cached render arrays.
|
||||
* This function is assigned as a #pre_render callback in ::viewMultiple().
|
||||
*
|
||||
* @todo Either simplify this to remove support for building multiple entities
|
||||
* at once or support a #pre_render_multiple or similar API in the render
|
||||
* system.
|
||||
*
|
||||
* By delaying the building of an entity until the #pre_render processing, the
|
||||
* processing cost of assembling an entity's renderable array is saved on
|
||||
* cache-hit requests.
|
||||
* 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.
|
||||
*
|
||||
* @param array $build_list
|
||||
* A renderable array containing build information and context for an
|
||||
|
|
|
@ -11,6 +11,13 @@ use Drupal\Core\Entity\EntityViewBuilder;
|
|||
*/
|
||||
class BlockContentViewBuilder extends EntityViewBuilder {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
|
||||
return $this->viewMultiple(array($entity), $view_mode, $langcode)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -19,9 +26,7 @@ class BlockContentViewBuilder extends EntityViewBuilder {
|
|||
// Apply the buildMultiple() #pre_render callback immediately, to make
|
||||
// bubbling of attributes and contextual links to the actual block work.
|
||||
// @see \Drupal\block\BlockViewBuilder::buildBlock()
|
||||
foreach ($entities as $key => $entity) {
|
||||
unset($build_list[$key]['#pre_render'][0]);
|
||||
}
|
||||
unset($build_list['#pre_render'][0]);
|
||||
return $this->buildMultiple($build_list);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests that hooks are invoked or not depending on render cache.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class EntityRenderCacheHookTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('entity_test_hooks', 'entity_test');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
\Drupal::service('module_installer')->uninstall(['page_cache', 'dynamic_page_cache']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that hooks are not called when entities are render cached.
|
||||
*/
|
||||
public function testHookInvocationAndRenderCache() {
|
||||
$entity = EntityTest::create(['name' => 'test entity']);
|
||||
$entity->save();
|
||||
|
||||
$this->drupalGet('test-view/' . $entity->id());
|
||||
$this->assertText('test entity');
|
||||
$this->assertText('custom hook invocation called');
|
||||
|
||||
$this->drupalGet('test-view/' . $entity->id());
|
||||
$this->assertText('test entity');
|
||||
$this->assertNoText('custom hook invocation called');
|
||||
|
||||
$this->drupalGet('test-view-multiple/' . $entity->id());
|
||||
$this->assertText('test entity');
|
||||
$this->assertNoText('custom hook invocation called');
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
type: module
|
||||
name: 'Entity test hooks module'
|
||||
core: 8.x
|
||||
package: Testing
|
||||
version: VERSION
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
||||
/**
|
||||
* Implements hook_ENTITY_TYPE_view() for entity_test.
|
||||
*/
|
||||
function entity_test_hooks_entity_test_view(array &$build, EntityTest $entity_test, EntityViewDisplayInterface $display, $view_mode) {
|
||||
drupal_set_message('custom hook invocation called');
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
test.controller_view:
|
||||
path: '/test-view/{entity_test}'
|
||||
defaults:
|
||||
_controller: 'Drupal\entity_test_hooks\Controller\ViewController::view'
|
||||
_title: 'Test view'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
test.controller_view_multiple:
|
||||
path: '/test-view-multiple/{entity_test}'
|
||||
defaults:
|
||||
_controller: 'Drupal\entity_test_hooks\Controller\ViewController::viewMultiple'
|
||||
_title: 'Test multiple'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\entity_test_hooks\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
||||
/**
|
||||
* Controller to view entities.
|
||||
*/
|
||||
class ViewController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* View an entity using \Drupal\Core\Entity\EntityViewBuilder::view()
|
||||
*
|
||||
* @param \Drupal\entity_test\Entity\EntityTest $entity_test
|
||||
* The entity to be viewed.
|
||||
*
|
||||
* @return array $build
|
||||
* The rendered entity
|
||||
*/
|
||||
public function view(EntityTest $entity_test) {
|
||||
return $this->entityTypeManager()->getViewBuilder('entity_test')->view($entity_test);
|
||||
}
|
||||
|
||||
/**
|
||||
* View an entity using \Drupal\Core\Entity\EntityViewBuilder::viewMultiple()
|
||||
*
|
||||
* @param \Drupal\entity_test\Entity\EntityTest $entity_test
|
||||
* The entity to be viewed.
|
||||
*
|
||||
* @return array $build
|
||||
* The rendered entity
|
||||
*/
|
||||
public function viewMultiple(EntityTest $entity_test) {
|
||||
return $this->entityTypeManager()->getViewBuilder('entity_test')->viewMultiple([$entity_test]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue