Issue #2099105 by Berdir, andypost, amateescu, larowlan: Clean-up render cache when permission changes.

8.0.x
Nathaniel Catchpole 2014-01-10 11:30:55 +00:00
parent 2a839b7d01
commit 667ec43270
9 changed files with 35 additions and 28 deletions

View File

@ -37,14 +37,6 @@ class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderI
*/
protected $entityManager;
/**
* An array of view mode info for the type of entities for which this
* controller is instantiated.
*
* @var array
*/
protected $viewModesInfo;
/**
* The cache bin used to store the render cache.
*
@ -67,7 +59,6 @@ class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderI
$this->entityType = $entity_info->id();
$this->entityInfo = $entity_info;
$this->entityManager = $entity_manager;
$this->viewModesInfo = entity_get_view_modes($this->entityType);
}
/**
@ -136,10 +127,8 @@ class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderI
);
// Cache the rendered output if permitted by the view mode and global entity
// type configuration. The isset() checks below are necessary because
// 'default' is not an actual view mode.
$view_mode_is_cacheable = !isset($this->viewModesInfo[$view_mode]) || (isset($this->viewModesInfo[$view_mode]) && $this->viewModesInfo[$view_mode]['cache']);
if ($view_mode_is_cacheable && !$entity->isNew() && !isset($entity->in_preview) && $this->entityInfo->isRenderCacheable()) {
// type configuration.
if ($this->isViewModeCacheable($view_mode) && !$entity->isNew() && !isset($entity->in_preview) && $this->entityInfo->isRenderCacheable()) {
$return['#cache'] = array(
'keys' => array('entity_view', $this->entityType, $entity->id(), $view_mode),
'granularity' => DRUPAL_CACHE_PER_ROLE,
@ -265,4 +254,23 @@ class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderI
\Drupal::cache($this->cacheBin)->deleteTags(array($this->entityType . '_view' => TRUE));
}
}
/**
* Returns TRUE if the view mode is cacheable.
*
* @param string $view_mode
* Name of the view mode that should be rendered.
*
* @return bool
* TRUE if the view mode can be cached, FALSE otherwise.
*/
protected function isViewModeCacheable($view_mode) {
if ($view_mode == 'default') {
// The 'default' is not an actual view mode.
return TRUE;
}
$view_modes_info = entity_get_view_modes($this->entityType);
return !empty($view_modes_info[$view_mode]['cache']);
}
}

View File

@ -305,9 +305,6 @@ class CommentNonNodeTest extends WebTestBase {
'view test entity' => TRUE,
'skip comment approval' => FALSE,
));
// We've changed role permissions, so need to reset render cache.
// @todo Revisit after https://drupal.org/node/2099105
\Drupal::entityManager()->getViewBuilder('entity_test')->resetCache(array($this->entity));
$this->drupalGet('entity_test/' . $this->entity->id());
$this->assertPattern('@<h2[^>]*>Comments</h2>@', 'Comments were displayed.');
$this->assertLink('Log in', 0, 'Link to log in was found.');
@ -324,9 +321,6 @@ class CommentNonNodeTest extends WebTestBase {
'skip comment approval' => TRUE,
'view test entity' => TRUE,
));
// We've changed role permissions, so need to reset render cache.
// @todo Revisit after https://drupal.org/node/2099105
\Drupal::entityManager()->getViewBuilder('entity_test')->resetCache(array($this->entity));
$this->drupalGet('entity_test/' . $this->entity->id());
$this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.');
$this->assertFieldByName('subject', '', 'Subject field found.');

View File

@ -109,6 +109,10 @@ abstract class EntityDisplayModeFormBase extends EntityFormController {
* TRUE if the display mode exists, FALSE otherwise.
*/
public function exists($entity_id, array $element, array $form_state) {
// Do not allow to add internal 'default' view mode.
if ($entity_id == 'default') {
return TRUE;
}
return (bool) $this->queryFactory
->get($this->entity->entityType())
->condition('id', $element['#field_prefix'] . $entity_id)

View File

@ -14,7 +14,7 @@ use Drupal\simpletest\DrupalUnitTestBase;
*/
class FilterDefaultConfigTest extends DrupalUnitTestBase {
public static $modules = array('system', 'user', 'filter', 'filter_test');
public static $modules = array('system', 'user', 'filter', 'filter_test', 'entity');
public static function getInfo() {
return array(

View File

@ -169,7 +169,7 @@ class RdfMapping extends ConfigEntityBase implements RdfMappingInterface {
public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) {
parent::postSave($storage_controller, $update);
if (\Drupal::entityManager()->hasController($this->targetEntityType, 'render')) {
if (\Drupal::entityManager()->hasController($this->targetEntityType, 'view_builder')) {
\Drupal::entityManager()->getViewBuilder($this->targetEntityType)->resetCache();
}
}

View File

@ -19,7 +19,7 @@ class DrupalUnitTestBaseTest extends DrupalUnitTestBase {
*
* @var array
*/
public static $modules = array('entity_test');
public static $modules = array('entity', 'entity_test');
public static function getInfo() {
return array(
@ -33,14 +33,14 @@ class DrupalUnitTestBaseTest extends DrupalUnitTestBase {
* Tests expected behavior of setUp().
*/
function testSetUp() {
$module = 'entity_test';
$modules = array('entity', 'entity_test');
$table = 'entity_test';
// Verify that specified $modules have been loaded.
$this->assertTrue(function_exists('entity_test_permission'), "$module.module was loaded.");
$this->assertTrue(function_exists('entity_test_permission'), 'entity_test.module was loaded.');
// Verify that there is a fixed module list.
$this->assertIdentical(array_keys(\Drupal::moduleHandler()->getModuleList()), array($module));
$this->assertIdentical(\Drupal::moduleHandler()->getImplementations('permission'), array($module));
$this->assertIdentical(array_keys(\Drupal::moduleHandler()->getModuleList()), $modules);
$this->assertIdentical(\Drupal::moduleHandler()->getImplementations('permission'), $modules);
// Verify that no modules have been installed.
$this->assertFalse(db_table_exists($table), "'$table' database table not found.");

View File

@ -101,7 +101,6 @@ class EntityViewControllerTest extends WebTestBase {
))->save();
// Browse to the entity and verify that the attributes from both modules
// are rendered in the field item HTML markup.
\Drupal::entityManager()->getViewBuilder('entity_test')->resetCache(array($entity));
$this->drupalGet('entity_test/' . $entity->id());
$xpath = $this->xpath('//div[@data-field-item-attr="foobar" and @property="schema:text" and text()=:value]', array(':value' => $test_value));
$this->assertTrue($xpath, 'The field item attributes from both modules have been found in the rendered output of the field.');

View File

@ -141,6 +141,8 @@ class Role extends ConfigEntityBase implements RoleInterface {
parent::postSave($storage_controller, $update);
Cache::invalidateTags(array('role' => $this->id()));
// Clear render cache.
entity_render_cache_clear();
}
/**

View File

@ -23,7 +23,7 @@ class UserEntityTest extends DrupalUnitTestBase {
*
* @var array
*/
public static $modules = array('system', 'user', 'field');
public static $modules = array('system', 'user', 'field', 'entity');
public static function getInfo() {
return array(