From 667ec43270e05dcd3908d4c5ddbc8cf3b31e8ee6 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Fri, 10 Jan 2014 11:30:55 +0000 Subject: [PATCH] Issue #2099105 by Berdir, andypost, amateescu, larowlan: Clean-up render cache when permission changes. --- .../Drupal/Core/Entity/EntityViewBuilder.php | 34 ++++++++++++------- .../comment/Tests/CommentNonNodeTest.php | 6 ---- .../entity/Form/EntityDisplayModeFormBase.php | 4 +++ .../filter/Tests/FilterDefaultConfigTest.php | 2 +- .../rdf/lib/Drupal/rdf/Entity/RdfMapping.php | 2 +- .../Tests/DrupalUnitTestBaseTest.php | 10 +++--- .../Tests/Entity/EntityViewControllerTest.php | 1 - .../user/lib/Drupal/user/Entity/Role.php | 2 ++ .../lib/Drupal/user/Tests/UserEntityTest.php | 2 +- 9 files changed, 35 insertions(+), 28 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index d8862243ae3..1f09b3b53f6 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -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']); + } + } diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentNonNodeTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentNonNodeTest.php index bda6e04e64e..e2b459774b5 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentNonNodeTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentNonNodeTest.php @@ -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('@]*>Comments@', '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('@]*>Comments@', 'Comments were not displayed.'); $this->assertFieldByName('subject', '', 'Subject field found.'); diff --git a/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeFormBase.php b/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeFormBase.php index 2f41ab57bbe..3da81437a5c 100644 --- a/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeFormBase.php +++ b/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeFormBase.php @@ -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) diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterDefaultConfigTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterDefaultConfigTest.php index ff930c1c552..9d8f3cacc04 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterDefaultConfigTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterDefaultConfigTest.php @@ -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( diff --git a/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php b/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php index cdb70c5a1d4..662f44d2b3d 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php +++ b/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php @@ -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(); } } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php index 79b65b5559c..0d61b308abb 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php @@ -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."); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewControllerTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewControllerTest.php index d08d45a9816..2c6a15971e1 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewControllerTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewControllerTest.php @@ -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.'); diff --git a/core/modules/user/lib/Drupal/user/Entity/Role.php b/core/modules/user/lib/Drupal/user/Entity/Role.php index 2fd26ace830..320d7f0464d 100644 --- a/core/modules/user/lib/Drupal/user/Entity/Role.php +++ b/core/modules/user/lib/Drupal/user/Entity/Role.php @@ -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(); } /** diff --git a/core/modules/user/lib/Drupal/user/Tests/UserEntityTest.php b/core/modules/user/lib/Drupal/user/Tests/UserEntityTest.php index 8532008ae6b..00fbe34c8b2 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserEntityTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserEntityTest.php @@ -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(