Issue #2099105 by Berdir, andypost, amateescu, larowlan: Clean-up render cache when permission changes.
parent
2a839b7d01
commit
667ec43270
|
@ -37,14 +37,6 @@ class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderI
|
||||||
*/
|
*/
|
||||||
protected $entityManager;
|
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.
|
* The cache bin used to store the render cache.
|
||||||
*
|
*
|
||||||
|
@ -67,7 +59,6 @@ class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderI
|
||||||
$this->entityType = $entity_info->id();
|
$this->entityType = $entity_info->id();
|
||||||
$this->entityInfo = $entity_info;
|
$this->entityInfo = $entity_info;
|
||||||
$this->entityManager = $entity_manager;
|
$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
|
// Cache the rendered output if permitted by the view mode and global entity
|
||||||
// type configuration. The isset() checks below are necessary because
|
// type configuration.
|
||||||
// 'default' is not an actual view mode.
|
if ($this->isViewModeCacheable($view_mode) && !$entity->isNew() && !isset($entity->in_preview) && $this->entityInfo->isRenderCacheable()) {
|
||||||
$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()) {
|
|
||||||
$return['#cache'] = array(
|
$return['#cache'] = array(
|
||||||
'keys' => array('entity_view', $this->entityType, $entity->id(), $view_mode),
|
'keys' => array('entity_view', $this->entityType, $entity->id(), $view_mode),
|
||||||
'granularity' => DRUPAL_CACHE_PER_ROLE,
|
'granularity' => DRUPAL_CACHE_PER_ROLE,
|
||||||
|
@ -265,4 +254,23 @@ class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderI
|
||||||
\Drupal::cache($this->cacheBin)->deleteTags(array($this->entityType . '_view' => TRUE));
|
\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']);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,9 +305,6 @@ class CommentNonNodeTest extends WebTestBase {
|
||||||
'view test entity' => TRUE,
|
'view test entity' => TRUE,
|
||||||
'skip comment approval' => FALSE,
|
'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->drupalGet('entity_test/' . $this->entity->id());
|
||||||
$this->assertPattern('@<h2[^>]*>Comments</h2>@', 'Comments were displayed.');
|
$this->assertPattern('@<h2[^>]*>Comments</h2>@', 'Comments were displayed.');
|
||||||
$this->assertLink('Log in', 0, 'Link to log in was found.');
|
$this->assertLink('Log in', 0, 'Link to log in was found.');
|
||||||
|
@ -324,9 +321,6 @@ class CommentNonNodeTest extends WebTestBase {
|
||||||
'skip comment approval' => TRUE,
|
'skip comment approval' => TRUE,
|
||||||
'view test entity' => 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->drupalGet('entity_test/' . $this->entity->id());
|
||||||
$this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.');
|
$this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.');
|
||||||
$this->assertFieldByName('subject', '', 'Subject field found.');
|
$this->assertFieldByName('subject', '', 'Subject field found.');
|
||||||
|
|
|
@ -109,6 +109,10 @@ abstract class EntityDisplayModeFormBase extends EntityFormController {
|
||||||
* TRUE if the display mode exists, FALSE otherwise.
|
* TRUE if the display mode exists, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
public function exists($entity_id, array $element, array $form_state) {
|
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
|
return (bool) $this->queryFactory
|
||||||
->get($this->entity->entityType())
|
->get($this->entity->entityType())
|
||||||
->condition('id', $element['#field_prefix'] . $entity_id)
|
->condition('id', $element['#field_prefix'] . $entity_id)
|
||||||
|
|
|
@ -14,7 +14,7 @@ use Drupal\simpletest\DrupalUnitTestBase;
|
||||||
*/
|
*/
|
||||||
class FilterDefaultConfigTest extends 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() {
|
public static function getInfo() {
|
||||||
return array(
|
return array(
|
||||||
|
|
|
@ -169,7 +169,7 @@ class RdfMapping extends ConfigEntityBase implements RdfMappingInterface {
|
||||||
public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) {
|
public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) {
|
||||||
parent::postSave($storage_controller, $update);
|
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();
|
\Drupal::entityManager()->getViewBuilder($this->targetEntityType)->resetCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ class DrupalUnitTestBaseTest extends DrupalUnitTestBase {
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $modules = array('entity_test');
|
public static $modules = array('entity', 'entity_test');
|
||||||
|
|
||||||
public static function getInfo() {
|
public static function getInfo() {
|
||||||
return array(
|
return array(
|
||||||
|
@ -33,14 +33,14 @@ class DrupalUnitTestBaseTest extends DrupalUnitTestBase {
|
||||||
* Tests expected behavior of setUp().
|
* Tests expected behavior of setUp().
|
||||||
*/
|
*/
|
||||||
function testSetUp() {
|
function testSetUp() {
|
||||||
$module = 'entity_test';
|
$modules = array('entity', 'entity_test');
|
||||||
$table = 'entity_test';
|
$table = 'entity_test';
|
||||||
|
|
||||||
// Verify that specified $modules have been loaded.
|
// 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.
|
// Verify that there is a fixed module list.
|
||||||
$this->assertIdentical(array_keys(\Drupal::moduleHandler()->getModuleList()), array($module));
|
$this->assertIdentical(array_keys(\Drupal::moduleHandler()->getModuleList()), $modules);
|
||||||
$this->assertIdentical(\Drupal::moduleHandler()->getImplementations('permission'), array($module));
|
$this->assertIdentical(\Drupal::moduleHandler()->getImplementations('permission'), $modules);
|
||||||
|
|
||||||
// Verify that no modules have been installed.
|
// Verify that no modules have been installed.
|
||||||
$this->assertFalse(db_table_exists($table), "'$table' database table not found.");
|
$this->assertFalse(db_table_exists($table), "'$table' database table not found.");
|
||||||
|
|
|
@ -101,7 +101,6 @@ class EntityViewControllerTest extends WebTestBase {
|
||||||
))->save();
|
))->save();
|
||||||
// Browse to the entity and verify that the attributes from both modules
|
// Browse to the entity and verify that the attributes from both modules
|
||||||
// are rendered in the field item HTML markup.
|
// are rendered in the field item HTML markup.
|
||||||
\Drupal::entityManager()->getViewBuilder('entity_test')->resetCache(array($entity));
|
|
||||||
$this->drupalGet('entity_test/' . $entity->id());
|
$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));
|
$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.');
|
$this->assertTrue($xpath, 'The field item attributes from both modules have been found in the rendered output of the field.');
|
||||||
|
|
|
@ -141,6 +141,8 @@ class Role extends ConfigEntityBase implements RoleInterface {
|
||||||
parent::postSave($storage_controller, $update);
|
parent::postSave($storage_controller, $update);
|
||||||
|
|
||||||
Cache::invalidateTags(array('role' => $this->id()));
|
Cache::invalidateTags(array('role' => $this->id()));
|
||||||
|
// Clear render cache.
|
||||||
|
entity_render_cache_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,7 +23,7 @@ class UserEntityTest extends DrupalUnitTestBase {
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $modules = array('system', 'user', 'field');
|
public static $modules = array('system', 'user', 'field', 'entity');
|
||||||
|
|
||||||
public static function getInfo() {
|
public static function getInfo() {
|
||||||
return array(
|
return array(
|
||||||
|
|
Loading…
Reference in New Issue