diff --git a/core/includes/common.inc b/core/includes/common.inc
index 4668a90..fe1c9d9 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -5478,7 +5478,7 @@ function drupal_render_cache_set(&$markup, $elements) {
}
$bin = isset($elements['#cache']['bin']) ? $elements['#cache']['bin'] : 'cache';
$expire = isset($elements['#cache']['expire']) ? $elements['#cache']['expire'] : CacheBackendInterface::CACHE_PERMANENT;
- $tags = isset($elements['#cache']['tags']) ? $elements['#cache']['tags'] : array();
+ $tags = drupal_render_collect_cache_tags($elements, TRUE);
cache($bin)->set($cid, $data, $expire, $tags);
}
@@ -5526,6 +5526,57 @@ function drupal_render_collect_attached($elements, $return = FALSE) {
}
/**
+ * Collects cache tags for an element and its children into a single array.
+ *
+ * When caching elements, it is necessary to collect all cache tags into a
+ * single array, from both the element itself and all child elements. This
+ * allows items to be invalidated based on all tags attached to the content
+ * they're constituted from.
+ *
+ * @param array $elements
+ * The element to collect cache tags from.
+ * @param bool $return
+ * Whether to return the attached elements and reset the internal static.
+ *
+ * @return array
+ * The cache tags array for this element and its descendants.
+ */
+function drupal_render_collect_cache_tags($elements, $return = FALSE) {
+ $tags = &drupal_static(__FUNCTION__, array());
+
+ // Collect all cache tags for this element.
+ if (isset($elements['#cache']['tags'])) {
+ foreach ($elements['#cache']['tags'] as $namespace => $values) {
+ if (is_array($values)) {
+ foreach ($values as $value) {
+ if (!isset($tags[$namespace][$value])) {
+ $tags[$namespace][$value] = $value;
+ }
+ }
+ }
+ else {
+ if (!isset($tags[$namespace])) {
+ $tags[$namespace] = $values;
+ }
+ }
+ }
+ }
+ if ($children = element_children($elements)) {
+ foreach ($children as $child) {
+ drupal_render_collect_cache_tags($elements[$child]);
+ }
+ }
+
+ // If this was the first call to the function, return all attached elements
+ // and reset the static cache.
+ if ($return) {
+ $return = $tags;
+ $tags = array();
+ return $return;
+ }
+}
+
+/**
* Prepares an element for caching based on a query.
*
* This smart caching strategy saves Drupal from querying and rendering to HTML
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 53d8bcf..32c9da1 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -46,6 +46,18 @@ function entity_info_cache_clear() {
}
/**
+ * Clears the entity render cache for all entity types.
+ */
+function entity_render_cache_clear() {
+ $entity_manager = Drupal::entityManager();
+ foreach ($entity_manager->getDefinitions() as $entity_type => $info) {
+ if ($entity_manager->hasController($entity_type, 'render')) {
+ $entity_manager->getRenderController($entity_type)->resetCache();
+ }
+ }
+}
+
+/**
* Returns the entity bundle info.
*
* @param string|null $entity_type
@@ -579,14 +591,19 @@ function entity_render_controller($entity_type) {
* @param string $langcode
* (optional) For which language the entity should be rendered, defaults to
* the current content language.
+ * @param bool $reset
+ * (optional) Whether to reset the render cache for the requested entity.
+ * Defaults to FALSE.
*
* @return array
* A render array for the entity.
*/
-function entity_view(EntityInterface $entity, $view_mode, $langcode = NULL) {
- return Drupal::entityManager()
- ->getRenderController($entity->entityType())
- ->view($entity, $view_mode, $langcode);
+function entity_view(EntityInterface $entity, $view_mode, $langcode = NULL, $reset = FALSE) {
+ $render_controller = Drupal::entityManager()->getRenderController($entity->entityType());
+ if ($reset) {
+ $render_controller->resetCache(array($entity));
+ }
+ return $render_controller->view($entity, $view_mode, $langcode);
}
/**
@@ -599,15 +616,20 @@ function entity_view(EntityInterface $entity, $view_mode, $langcode = NULL) {
* @param string $langcode
* (optional) For which language the entity should be rendered, defaults to
* the current content language.
+ * @param bool $reset
+ * (optional) Whether to reset the render cache for the requested entities.
+ * Defaults to FALSE.
*
* @return array
* A render array for the entities, indexed by the same keys as the
* entities array passed in $entities.
*/
-function entity_view_multiple(array $entities, $view_mode, $langcode = NULL) {
- return Drupal::entityManager()
- ->getRenderController(reset($entities)->entityType())
- ->viewMultiple($entities, $view_mode, $langcode);
+function entity_view_multiple(array $entities, $view_mode, $langcode = NULL, $reset = FALSE) {
+ $render_controller = Drupal::entityManager()->getRenderController(reset($entities)->entityType());
+ if ($reset) {
+ $render_controller->resetCache($entities);
+ }
+ return $render_controller->viewMultiple($entities, $view_mode, $langcode);
}
/**
diff --git a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
index 30c8252..cd0b139 100644
--- a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php
@@ -138,6 +138,14 @@ class EntityType extends Plugin {
public $static_cache = TRUE;
/**
+ * Boolean indicating whether the rendered output of entities should be
+ * cached.
+ *
+ * @var bool (optional)
+ */
+ public $render_cache = TRUE;
+
+ /**
* Boolean indicating whether entities of this type have multilingual support.
*
* At an entity level, this indicates language support and at a bundle level
diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php
index 6bb91e1..03a3cfe 100644
--- a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php
+++ b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php
@@ -538,6 +538,7 @@ public function save(EntityInterface $entity) {
$this->saveRevision($entity);
}
$this->resetCache(array($entity->id()));
+
$this->postSave($entity, TRUE);
$this->invokeHook('update', $entity);
}
diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
index 9b7020a..2a0f42e 100644
--- a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
+++ b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
@@ -305,6 +305,7 @@ public function save(EntityInterface $entity) {
$this->savePropertyData($entity);
}
$this->resetCache(array($entity->id()));
+
$this->postSave($entity, TRUE);
$this->invokeHook('update', $entity);
}
diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php
index 98d4a3d..5eeb08a 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormController.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormController.php
@@ -263,7 +263,13 @@ public function submit(array $form, array &$form_state) {
* A reference to a keyed array containing the current state of the form.
*/
public function save(array $form, array &$form_state) {
- // @todo Perform common save operations.
+ // Clear the render cache.
+ try {
+ \Drupal::entityManager()->getRenderController($this->entity->entityType())->resetCache(array($this->entity));
+ }
+ catch (\Exception $e) {
+ // Nothing to do if the entity type doesn't have a render controller.
+ }
}
/**
diff --git a/core/lib/Drupal/Core/Entity/EntityRenderController.php b/core/lib/Drupal/Core/Entity/EntityRenderController.php
index 53457aa..ee5aa65 100644
--- a/core/lib/Drupal/Core/Entity/EntityRenderController.php
+++ b/core/lib/Drupal/Core/Entity/EntityRenderController.php
@@ -20,8 +20,37 @@ class EntityRenderController implements EntityRenderControllerInterface {
*/
protected $entityType;
+ /**
+ * The entity info array.
+ *
+ * @var array
+ *
+ * @see entity_get_info()
+ */
+ protected $entityInfo;
+
+ /**
+ * 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.
+ *
+ * @todo Defaults to 'cache' for now, until http://drupal.org/node/1194136 is
+ * fixed.
+ *
+ * @var string
+ */
+ protected $cacheBin = 'cache';
+
public function __construct($entity_type) {
$this->entityType = $entity_type;
+ $this->entityInfo = entity_get_info($entity_type);
+ $this->viewModesInfo = entity_get_view_modes($entity_type);
}
/**
@@ -60,6 +89,21 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco
'#view_mode' => $view_mode,
'#langcode' => $langcode,
);
+
+ // Cache the rendered output if permitted by the view mode settings.
+ $view_mode_is_cacheable = !isset($this->viewModesInfo[$view_mode]) || (isset($this->viewModesInfo[$view_mode]) && $this->viewModesInfo[$view_mode]['cache']);
+ if (!isset($entity->in_preview) && $this->entityInfo['render_cache'] && $view_mode_is_cacheable) {
+ $return['#cache'] = array(
+ 'keys' => array('entity_view', $this->entityType ,$entity->id(), $view_mode),
+ 'granularity' => DRUPAL_CACHE_PER_ROLE,
+ 'bin' => $this->cacheBin,
+ 'tags' => array(
+ $this->entityType . '_view' => TRUE,
+ $this->entityType => array($entity->id()),
+ ),
+ );
+ }
+
return $return;
}
@@ -162,4 +206,35 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
return $build;
}
+
+ /**
+ * Implements \Drupal\Core\Entity\EntityRenderControllerInterface::resetCache().
+ */
+ public function resetCache(array $entities = NULL) {
+ if (isset($entities)) {
+ $tags = array();
+ foreach ($entities as $entity) {
+ $tags[$this->entityType][$entity->id()] = $entity->id();
+
+ // @todo Remove when all entities are converted to EntityNG.
+ if ($entity->getPropertyDefinitions() === NULL) {
+ continue;
+ }
+
+ // Add all the referenced entity types and IDs to the tags that will be
+ // cleared.
+ foreach ($entity->getPropertyDefinitions() as $name => $definition) {
+ if ($definition['type'] == 'entity_reference_field' && $field_values = $entity->get($name)->getValue()) {
+ foreach ($field_values as $value) {
+ $tags[$definition['settings']['target_type']][$value['target_id']] = $value['target_id'];
+ }
+ }
+ }
+ }
+ \Drupal::cache($this->cacheBin)->deleteTags($tags);
+ }
+ else {
+ \Drupal::cache($this->cacheBin)->deleteTags(array($this->entityType . '_view' => TRUE));
+ }
+ }
}
diff --git a/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
index 03ba014..88e1461 100644
--- a/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
@@ -75,4 +75,12 @@ public function view(EntityInterface $entity, $view_mode = 'full', $langcode = N
* be available for loading.
*/
public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL);
+
+ /**
+ * Resets the entity render cache.
+ *
+ * @param array|null $entities
+ * (optional) If specified, the cache is reset for the given entities only.
+ */
+ public function resetCache(array $entities = NULL);
}
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php b/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php
index 459a99b..50adbb9 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php
@@ -111,6 +111,8 @@ public function validate(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$feed = $this->entity;
$insert = (bool) $feed->id();
if (!empty($form_state['values']['category'])) {
diff --git a/core/modules/block/custom_block/config/entity.view_mode.custom_block.full.yml b/core/modules/block/custom_block/config/entity.view_mode.custom_block.full.yml
index ebacec5..6c2a3d1 100644
--- a/core/modules/block/custom_block/config/entity.view_mode.custom_block.full.yml
+++ b/core/modules/block/custom_block/config/entity.view_mode.custom_block.full.yml
@@ -1,4 +1,5 @@
id: custom_block.full
label: Full
status: '0'
+cache: '1'
targetEntityType: custom_block
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
index 1a09dbf..b548634 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
@@ -159,6 +159,8 @@ public function submit(array $form, array &$form_state) {
* Overrides \Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$block = $this->entity;
$insert = empty($block->id->value);
$block->save();
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php
index 6e5de33..bb9159a 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php
@@ -87,6 +87,8 @@ public function form(array $form, array &$form_state) {
* Overrides \Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$block_type = $this->entity;
$status = $block_type->save();
diff --git a/core/modules/block/lib/Drupal/block/BlockRenderController.php b/core/modules/block/lib/Drupal/block/BlockRenderController.php
index 12fff82..deaeb94 100644
--- a/core/modules/block/lib/Drupal/block/BlockRenderController.php
+++ b/core/modules/block/lib/Drupal/block/BlockRenderController.php
@@ -44,4 +44,10 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
return $build;
}
+ /**
+ * Implements \Drupal\Core\Entity\EntityRenderControllerInterface::resetCache().
+ */
+ public function resetCache(array $entities = NULL) {
+ // @todo Move block render caching logic to this controller?
+ }
}
diff --git a/core/modules/book/config/entity.view_mode.node.print.yml b/core/modules/book/config/entity.view_mode.node.print.yml
index fe45f50..6f7333f 100644
--- a/core/modules/book/config/entity.view_mode.node.print.yml
+++ b/core/modules/book/config/entity.view_mode.node.print.yml
@@ -1,4 +1,5 @@
id: node.print
label: Print
status: '0'
+cache: '1'
targetEntityType: node
diff --git a/core/modules/comment/comment.admin.inc b/core/modules/comment/comment.admin.inc
index 488c2f9..cf29b50 100644
--- a/core/modules/comment/comment.admin.inc
+++ b/core/modules/comment/comment.admin.inc
@@ -203,6 +203,7 @@ function comment_admin_overview_submit($form, &$form_state) {
}
drupal_set_message(t('The update has been performed.'));
$form_state['redirect'] = 'admin/content/comment';
+ Drupal::entityManager()->getRenderController('comment')->resetCache(array($comment));
cache_invalidate_tags(array('content' => TRUE));
}
@@ -250,8 +251,15 @@ function comment_multiple_delete_confirm($form, &$form_state) {
*/
function comment_multiple_delete_confirm_submit($form, &$form_state) {
if ($form_state['values']['confirm']) {
- comment_delete_multiple(array_keys($form_state['values']['comments']));
+ $entity_manager = \Drupal::entityManager();
+
+ $controller = $entity_manager->getStorageController('comment');
+ $entities = $controller->load(array_keys($form_state['values']['comments']));
+ $controller->delete($entities);
+
+ $entity_manager->getRenderController('comment')->resetCache($entities);
cache_invalidate_tags(array('content' => TRUE));
+
$count = count($form_state['values']['comments']);
watchdog('content', 'Deleted @count comments.', array('@count' => $count));
drupal_set_message(format_plural($count, 'Deleted 1 comment.', 'Deleted @count comments.'));
@@ -307,6 +315,7 @@ function comment_confirm_delete_submit($form, &$form_state) {
drupal_set_message(t('The comment and all its replies have been deleted.'));
watchdog('content', 'Deleted comment @cid and its replies.', array('@cid' => $comment->id()));
// Clear the cache so an anonymous user sees that his comment was deleted.
+ Drupal::entityManager()->getRenderController('comment')->resetCache(array($comment));
cache_invalidate_tags(array('content' => TRUE));
$form_state['redirect'] = "node/{$comment->nid->target_id}";
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 717a25b..bf334e9 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1920,6 +1920,7 @@ function comment_unpublish_by_keyword_action_submit($form, $form_state) {
*/
function comment_save_action(Comment $comment) {
comment_save($comment);
+ Drupal::entityManager()->getRenderController('comment')->resetCache(array($comment));
cache_invalidate_tags(array('content' => TRUE));
watchdog('action', 'Saved comment %title', array('%title' => $comment->subject->value));
}
diff --git a/core/modules/comment/comment.pages.inc b/core/modules/comment/comment.pages.inc
index 5e1b190..371da22 100644
--- a/core/modules/comment/comment.pages.inc
+++ b/core/modules/comment/comment.pages.inc
@@ -80,6 +80,7 @@ function comment_reply(EntityInterface $node, $pid = NULL) {
// This is the case where the comment is in response to a node. Display the node.
elseif (user_access('access content')) {
$build['comment_node'] = node_view($node);
+ unset($build['comment_node']['#cache']);
}
// Should we show the reply box?
@@ -118,6 +119,7 @@ function comment_approve(Comment $comment) {
$comment->status->value = COMMENT_PUBLISHED;
$comment->save();
+ Drupal::entityManager()->getRenderController('comment')->resetCache(array($comment));
drupal_set_message(t('Comment approved.'));
drupal_goto('node/' . $comment->nid->target_id);
diff --git a/core/modules/comment/config/entity.view_mode.comment.full.yml b/core/modules/comment/config/entity.view_mode.comment.full.yml
index e48fbd7..abfc646 100644
--- a/core/modules/comment/config/entity.view_mode.comment.full.yml
+++ b/core/modules/comment/config/entity.view_mode.comment.full.yml
@@ -1,4 +1,5 @@
id: comment.full
label: Full comment
status: '0'
+cache: '1'
targetEntityType: comment
diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
index 179410c..a2fecc6 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
@@ -309,6 +309,8 @@ public function preview(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$node = node_load($form_state['values']['nid']);
$comment = $this->entity;
diff --git a/core/modules/comment/lib/Drupal/comment/CommentRenderController.php b/core/modules/comment/lib/Drupal/comment/CommentRenderController.php
index dab8dc4..0e1ce5e 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentRenderController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentRenderController.php
@@ -79,9 +79,10 @@ protected function alterBuild(array &$build, EntityInterface $comment, EntityDis
$is_threaded = isset($comment->divs)
&& variable_get('comment_default_mode_' . $comment->bundle(), COMMENT_MODE_THREADED) == COMMENT_MODE_THREADED;
- // Add 'new' anchor if needed.
+ // Add 'new' anchor and disable render cache if needed.
if (!empty($comment->first_new)) {
$prefix .= "\n";
+ unset($build['#cache']);
}
// Add indentation div or close open divs as needed.
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentAnonymousTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentAnonymousTest.php
index 86f778a..b983cc7 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentAnonymousTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentAnonymousTest.php
@@ -146,6 +146,8 @@ function testAnonymous() {
'post comments' => FALSE,
'skip comment approval' => FALSE,
));
+ \Drupal::entityManager()->getRenderController('node')->resetCache();
+ \Drupal::entityManager()->getRenderController('comment')->resetCache();
$this->drupalGet('node/' . $this->node->nid);
$this->assertPattern('@
]*>Comments
@', 'Comments were displayed.');
$this->assertLink('Log in', 1, 'Link to log in was found.');
@@ -156,6 +158,8 @@ function testAnonymous() {
'post comments' => TRUE,
'skip comment approval' => TRUE,
));
+ \Drupal::entityManager()->getRenderController('node')->resetCache();
+ \Drupal::entityManager()->getRenderController('comment')->resetCache();
$this->drupalGet('node/' . $this->node->nid);
$this->assertNoPattern('@]*>Comments
@', 'Comments were not displayed.');
$this->assertFieldByName('subject', '', 'Subject field found.');
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
index 5585650..7f74c3e 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
@@ -207,6 +207,9 @@ function setEnvironment(array $info) {
// Update current environment.
$current = $info;
+ // Clear the render cache.
+ entity_render_cache_clear();
+
return $info;
}
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
index fe4a11c..aff941d 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
@@ -267,6 +267,7 @@ function setCommentsPerPage($number) {
*/
function setCommentSettings($name, $value, $message) {
variable_set($name . '_article', $value);
+ \Drupal::entityManager()->getRenderController('comment')->resetCache();
// Display status message.
$this->pass($message);
}
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestFormController.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestFormController.php
index efba401..1c3894f 100644
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestFormController.php
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestFormController.php
@@ -64,6 +64,8 @@ public function form(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$entity = $this->entity;
$status = $entity->save();
diff --git a/core/modules/contact/lib/Drupal/contact/CategoryFormController.php b/core/modules/contact/lib/Drupal/contact/CategoryFormController.php
index 8febed8..ee95b57 100644
--- a/core/modules/contact/lib/Drupal/contact/CategoryFormController.php
+++ b/core/modules/contact/lib/Drupal/contact/CategoryFormController.php
@@ -94,6 +94,8 @@ public function validate(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$category = $this->entity;
$status = $category->save();
diff --git a/core/modules/contact/lib/Drupal/contact/MessageFormController.php b/core/modules/contact/lib/Drupal/contact/MessageFormController.php
index 6f73d96..a754711 100644
--- a/core/modules/contact/lib/Drupal/contact/MessageFormController.php
+++ b/core/modules/contact/lib/Drupal/contact/MessageFormController.php
@@ -137,6 +137,8 @@ public function preview(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
global $user;
$language_interface = language(LANGUAGE_TYPE_INTERFACE);
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
index 461a240..014636c 100644
--- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php
@@ -120,7 +120,17 @@ public function save() {
if (empty($this->id)) {
$this->id = $this->id();
}
- return parent::save();
+ $return = parent::save();
+
+ // Reset the render cache for the target entity type.
+ try {
+ \Drupal::entityManager()->getRenderController($this->targetEntityType)->resetCache();
+ }
+ catch (\Exception $e) {
+ // Nothing to do if the entity type doesn't have a render controller.
+ }
+
+ return $return;
}
/**
diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityViewMode.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityViewMode.php
index c2c54dd..a29bb82 100644
--- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityViewMode.php
+++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityViewMode.php
@@ -91,4 +91,11 @@ class EntityViewMode extends ConfigEntityBase implements EntityViewModeInterface
*/
public $status = FALSE;
+ /**
+ * Whether or not the rendered output of this view mode is cached by default.
+ *
+ * @var bool
+ */
+ public $cache = TRUE;
+
}
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
index 6b316ae..445cd11 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
@@ -106,6 +106,14 @@ public function view(EntityInterface $entity, $langcode, array $items) {
'#formatter' => $this->getPluginId(),
);
+ // Gather cache tags from reference fields.
+ foreach ($items as $item) {
+ if (isset($item['entity'])) {
+ $info['#cache']['tags'][$item['entity']->entityType()][] = $item['entity']->id();
+ $info['#cache']['tags'][$item['entity']->entityType() . '_view'] = TRUE;
+ }
+ }
+
$addition[$field['field_name']] = array_merge($info, $elements);
}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/TestEntityFormController.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/TestEntityFormController.php
index d5a4508..7d48c0d 100644
--- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/TestEntityFormController.php
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/TestEntityFormController.php
@@ -37,6 +37,8 @@ public function form(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$entity = $this->entity;
$is_new = $entity->isNew();
$entity->save();
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
index c1a490d..8c56588 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -496,6 +496,9 @@ public function submitForm(array &$form, array &$form_state) {
field_bundle_settings($this->entity_type, $this->bundle, $bundle_settings);
}
+ // Clear the render cache for this entity type.
+ \Drupal::entityManager()->getRenderController($this->entity_type)->resetCache();
+
drupal_set_message(t('Your settings have been saved.'));
}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
index 51dc8b1..1518ca1 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
@@ -280,7 +280,7 @@ function assertNodeViewTextHelper(EntityInterface $node, $view_mode, $text, $mes
// Render a cloned node, so that we do not alter the original.
$clone = clone $node;
- $element = node_view($clone, $view_mode);
+ $element = entity_view($clone, $view_mode, NULL, TRUE);
$output = drupal_render($element);
$this->verbose(t('Rendered node - view mode: @view_mode', array('@view_mode' => $view_mode)) . '
'. $output);
diff --git a/core/modules/file/config/entity.view_mode.file.full.yml b/core/modules/file/config/entity.view_mode.file.full.yml
index 60808f9..4d4ed1f 100644
--- a/core/modules/file/config/entity.view_mode.file.full.yml
+++ b/core/modules/file/config/entity.view_mode.file.full.yml
@@ -1,4 +1,5 @@
id: file.full
label: File default
status: '0'
+cache: '1'
targetEntityType: file
diff --git a/core/modules/filter/filter.admin.inc b/core/modules/filter/filter.admin.inc
index aa3018c..6430687 100644
--- a/core/modules/filter/filter.admin.inc
+++ b/core/modules/filter/filter.admin.inc
@@ -358,5 +358,6 @@ function filter_admin_format_form_submit($form, &$form_state) {
break;
}
+ entity_render_cache_clear();
$form_state['redirect'] = 'admin/config/content/formats';
}
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index c30c686..fb8e716 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -229,6 +229,7 @@ function testImageFieldDefaultImage() {
$this->drupalPost("admin/structure/types/manage/article/fields/node.article.$field_name/field", $edit, t('Save field settings'));
// Clear field info cache so the new default image is detected.
field_info_cache_clear();
+ \Drupal::entityManager()->getRenderController('node')->resetCache(array($node));
$field = field_info_field($field_name);
$image = file_load($field['settings']['default_image'][0]);
$this->assertTrue($image->status == FILE_STATUS_PERMANENT, 'The default image status is permanent.');
diff --git a/core/modules/menu/lib/Drupal/menu/MenuFormController.php b/core/modules/menu/lib/Drupal/menu/MenuFormController.php
index 4eeab27..7aeac04 100644
--- a/core/modules/menu/lib/Drupal/menu/MenuFormController.php
+++ b/core/modules/menu/lib/Drupal/menu/MenuFormController.php
@@ -83,6 +83,8 @@ protected function actions(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$menu = $this->entity;
$system_menus = menu_list_system_menus();
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
index 79bd8de..09e978d 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
@@ -202,8 +202,9 @@ public function submit(array $form, array &$form_state) {
* Overrides EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
- $menu_link = $this->entity;
+ parent::save($form, $form_state);
+ $menu_link = $this->entity;
$saved = $menu_link->save();
if ($saved) {
diff --git a/core/modules/node/config/entity.view_mode.node.full.yml b/core/modules/node/config/entity.view_mode.node.full.yml
index af6d938..e4d8bd0 100644
--- a/core/modules/node/config/entity.view_mode.node.full.yml
+++ b/core/modules/node/config/entity.view_mode.node.full.yml
@@ -1,4 +1,5 @@
id: node.full
label: Full content
status: '0'
+cache: '1'
targetEntityType: node
diff --git a/core/modules/node/config/entity.view_mode.node.rss.yml b/core/modules/node/config/entity.view_mode.node.rss.yml
index 984b05f..0dbf7c1 100644
--- a/core/modules/node/config/entity.view_mode.node.rss.yml
+++ b/core/modules/node/config/entity.view_mode.node.rss.yml
@@ -1,4 +1,5 @@
id: node.rss
label: RSS
status: '0'
+cache: '1'
targetEntityType: node
diff --git a/core/modules/node/config/entity.view_mode.node.teaser.yml b/core/modules/node/config/entity.view_mode.node.teaser.yml
index 2089b94..636de15 100644
--- a/core/modules/node/config/entity.view_mode.node.teaser.yml
+++ b/core/modules/node/config/entity.view_mode.node.teaser.yml
@@ -1,4 +1,5 @@
id: node.teaser
label: Teaser
status: '1'
+cache: '1'
targetEntityType: node
diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php
index 5145a57..a6d6042 100644
--- a/core/modules/node/lib/Drupal/node/NodeFormController.php
+++ b/core/modules/node/lib/Drupal/node/NodeFormController.php
@@ -427,6 +427,8 @@ public function unpublish(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$node = $this->entity;
$insert = empty($node->nid);
$node->save();
diff --git a/core/modules/node/lib/Drupal/node/NodeRenderController.php b/core/modules/node/lib/Drupal/node/NodeRenderController.php
index 6a6608a..5973fbd 100644
--- a/core/modules/node/lib/Drupal/node/NodeRenderController.php
+++ b/core/modules/node/lib/Drupal/node/NodeRenderController.php
@@ -91,6 +91,10 @@ protected function alterBuild(array &$build, EntityInterface $entity, EntityDisp
if (!empty($entity->nid)) {
$build['#contextual_links']['node'] = array('node', array($entity->nid));
}
+
+ // The node 'submitted' info is not rendered in a standard way (renderable
+ // array) so we have to add a cache tag manually.
+ $build['#cache']['tags']['user'][] = $entity->uid;
}
}
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php
index 46244b8..dba9816 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php
@@ -139,6 +139,7 @@ function testRevisions() {
$new_node_revision->setNewRevision();
$new_node_revision->isDefaultRevision = FALSE;
node_save($new_node_revision);
+ \Drupal::entityManager()->getRenderController('node')->resetCache(array($node));
$this->drupalGet("node/$node->nid");
$this->assertNoText($new_body, 'Revision body text is not present on default version of node.');
diff --git a/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php b/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php
index 6a28f7f..7a0373c 100644
--- a/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php
@@ -136,6 +136,7 @@ public function testRowPlugin() {
// Test with links disabled.
$view->rowPlugin->options['links'] = FALSE;
+ \Drupal::entityManager()->getRenderController('node')->resetCache();
$output = $view->preview();
$output = drupal_render($output);
$this->drupalSetContent($output);
@@ -145,6 +146,7 @@ public function testRowPlugin() {
// Test with links enabled.
$view->rowPlugin->options['links'] = TRUE;
+ \Drupal::entityManager()->getRenderController('node')->resetCache();
$output = $view->preview();
$output = drupal_render($output);
$this->drupalSetContent($output);
@@ -154,6 +156,7 @@ public function testRowPlugin() {
// Test with comments enabled.
$view->rowPlugin->options['comments'] = TRUE;
+ \Drupal::entityManager()->getRenderController('node')->resetCache();
$output = $view->preview();
$output = drupal_render($output);
foreach ($this->nodes as $node) {
@@ -164,6 +167,7 @@ public function testRowPlugin() {
// Test with comments disabled.
$view->rowPlugin->options['comments'] = FALSE;
+ \Drupal::entityManager()->getRenderController('node')->resetCache();
$output = $view->preview();
$output = drupal_render($output);
foreach ($this->nodes as $node) {
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index ae25bb1..4c91efe 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1039,16 +1039,18 @@ function node_revision_delete($revision_id) {
* @see node_menu()
*/
function node_show(EntityInterface $node, $message = FALSE) {
+ // For markup consistency with other pages, use node_view_multiple() rather than node_view().
+ $nodes = array('nodes' => node_view_multiple(array($node->id() => $node), 'full'));
+
if ($message) {
drupal_set_title(t('Revision of %title from %date', array('%title' => $node->label(), '%date' => format_date($node->revision_timestamp))), PASS_THROUGH);
+ // Don't use the render cache when a revision is displayed.
+ unset($nodes['nodes'][$node->id()]['#cache']);
}
- // For markup consistency with other pages, use node_view_multiple() rather than node_view().
- $nodes = array('nodes' => node_view_multiple(array($node->nid => $node), 'full'));
-
// Update the history table, stating that this user viewed this node.
if (module_exists('history')) {
- history_write($node->nid);
+ history_write($node->id());
}
return $nodes;
@@ -2208,7 +2210,7 @@ function _node_index_node(EntityInterface $node) {
foreach ($languages as $language) {
// Render the node.
- $build = node_view($node, 'search_index', $language->langcode);
+ $build = entity_view($node, 'search_index', $language->langcode, TRUE);
unset($build['#theme']);
$node->rendered = drupal_render($build);
diff --git a/core/modules/picture/lib/Drupal/picture/PictureMappingFormController.php b/core/modules/picture/lib/Drupal/picture/PictureMappingFormController.php
index 4b93dc5..55f969b 100644
--- a/core/modules/picture/lib/Drupal/picture/PictureMappingFormController.php
+++ b/core/modules/picture/lib/Drupal/picture/PictureMappingFormController.php
@@ -134,6 +134,8 @@ public function validate(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$picture_mapping = $this->entity;
$picture_mapping->save();
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
index dbdba31..6a67605 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
@@ -285,6 +285,7 @@ function saveComment($nid, $uid, $contact = NULL, $pid = 0) {
$comment = entity_create('comment', $values);
$comment->save();
+ \Drupal::entityManager()->getRenderController('comment')->resetCache(array($comment));
return $comment;
}
}
diff --git a/core/modules/search/config/entity.view_mode.node.search_index.yml b/core/modules/search/config/entity.view_mode.node.search_index.yml
index ed22c30..e12156d 100644
--- a/core/modules/search/config/entity.view_mode.node.search_index.yml
+++ b/core/modules/search/config/entity.view_mode.node.search_index.yml
@@ -1,4 +1,5 @@
id: node.search_index
label: Search index
status: '0'
+cache: '1'
targetEntityType: node
diff --git a/core/modules/search/config/entity.view_mode.node.search_result.yml b/core/modules/search/config/entity.view_mode.node.search_result.yml
index 1608657..776ada9 100644
--- a/core/modules/search/config/entity.view_mode.node.search_result.yml
+++ b/core/modules/search/config/entity.view_mode.node.search_result.yml
@@ -1,4 +1,5 @@
id: node.search_result
label: Search result
status: '0'
+cache: '1'
targetEntityType: node
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php
index 1e25679..0eed29e 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php
@@ -73,6 +73,8 @@ public function validate(array $form, array &$form_state) {
* Overrides \Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$entity = $this->entity;
$is_new = !$entity->getOriginalID();
$entity->save();
diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module
index 9d0c19e..4b867e6 100644
--- a/core/modules/statistics/statistics.module
+++ b/core/modules/statistics/statistics.module
@@ -73,6 +73,17 @@ function statistics_node_view(EntityInterface $node, EntityDisplay $display, $vi
}
/**
+ * Implements hook_node_view_alter().
+ */
+function statistics_node_view_alter(&$build, EntityInterface $node, EntityDisplay $display) {
+ // If statistics were added to the node render array, we can't use the render
+ // cache.
+ if (isset($build['links']['statistics'])) {
+ unset($build['#cache']);
+ }
+}
+
+/**
* Implements hook_menu().
*/
function statistics_menu() {
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/DateTimeTest.php b/core/modules/system/lib/Drupal/system/Tests/System/DateTimeTest.php
index c867581..f2afd30 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/DateTimeTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/DateTimeTest.php
@@ -65,6 +65,7 @@ function testTimeZoneHandling() {
// Set time zone to Los Angeles time.
$config->set('default', 'America/Los_Angeles')->save();
+ \Drupal::entityManager()->getRenderController('node')->resetCache(array($node1, $node2));
// Confirm date format and time zone.
$this->drupalGet("node/$node1->nid");
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index d344d37..f101504 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -2327,6 +2327,7 @@ function system_date_format_localize_reset_form($form, &$form_state, $langcode)
function system_date_format_localize_reset_form_submit($form, &$form_state) {
config('locale.config.' . $form['langcode']['#value'] . '.system.date')
->delete();
+ entity_render_cache_clear();
$form_state['redirect'] = 'admin/config/regional/date-time/locale';
}
diff --git a/core/modules/system/tests/modules/entity_test/config/entity.view_mode.entity_test_render.full.yml b/core/modules/system/tests/modules/entity_test/config/entity.view_mode.entity_test_render.full.yml
index 8902bc3..4ce40f1 100644
--- a/core/modules/system/tests/modules/entity_test/config/entity.view_mode.entity_test_render.full.yml
+++ b/core/modules/system/tests/modules/entity_test/config/entity.view_mode.entity_test_render.full.yml
@@ -1,4 +1,5 @@
id: entity_test_render.full
label: Full
status: '0'
+cache: '1'
targetEntityType: entity_test_render
diff --git a/core/modules/system/tests/modules/entity_test/config/entity.view_mode.entity_test_render.test.yml b/core/modules/system/tests/modules/entity_test/config/entity.view_mode.entity_test_render.test.yml
index a0d108b..310bceb 100644
--- a/core/modules/system/tests/modules/entity_test/config/entity.view_mode.entity_test_render.test.yml
+++ b/core/modules/system/tests/modules/entity_test/config/entity.view_mode.entity_test_render.test.yml
@@ -1,4 +1,5 @@
id: entity_test_render.test
label: Test
status: '0'
+cache: '1'
targetEntityType: entity_test_render
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php
index acea3a1..f1431df 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php
@@ -57,6 +57,8 @@ public function form(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$entity = $this->entity;
$is_new = $entity->isNew();
$entity->save();
diff --git a/core/modules/taxonomy/config/entity.view_mode.taxonomy_term.full.yml b/core/modules/taxonomy/config/entity.view_mode.taxonomy_term.full.yml
index 100547e..2666012 100644
--- a/core/modules/taxonomy/config/entity.view_mode.taxonomy_term.full.yml
+++ b/core/modules/taxonomy/config/entity.view_mode.taxonomy_term.full.yml
@@ -1,4 +1,5 @@
id: taxonomy_term.full
label: Taxonomy term page
status: '0'
+cache: '1'
targetEntityType: taxonomy_term
diff --git a/core/modules/taxonomy/config/entity.view_mode.taxonomy_vocabulary.full.yml b/core/modules/taxonomy/config/entity.view_mode.taxonomy_vocabulary.full.yml
index bb47091..8961a6f 100644
--- a/core/modules/taxonomy/config/entity.view_mode.taxonomy_vocabulary.full.yml
+++ b/core/modules/taxonomy/config/entity.view_mode.taxonomy_vocabulary.full.yml
@@ -1,4 +1,5 @@
id: vocabulary.full
label: Taxonomy vocabulary
status: '0'
+cache: '1'
targetEntityType: taxonomy_vocabulary
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
index 24d252b..bc9e8f1 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
@@ -154,6 +154,8 @@ public function buildEntity(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$term = $this->entity;
switch ($term->save()) {
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index b9b1108..c175964 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -333,6 +333,7 @@ function testTermInterface() {
// Check that it does NOT show a description when description is blank.
$term->description = '';
$term->save();
+ \Drupal::entityManager()->getRenderController('taxonomy_term')->resetCache(array($term));
$this->drupalGet('taxonomy/term/' . $term->id());
$this->assertNoPattern('|class="taxonomy-term-description"|', 'Term page did not display the term description when description was blank.');
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
index 96e8697..eab308d 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
@@ -144,6 +144,8 @@ public function submit(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$vocabulary = $this->entity;
// Prevent leading and trailing spaces in vocabulary names.
diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc
index 0703071..8a73c87 100644
--- a/core/modules/taxonomy/taxonomy.admin.inc
+++ b/core/modules/taxonomy/taxonomy.admin.inc
@@ -513,13 +513,15 @@ function taxonomy_term_confirm_delete($form, &$form_state, Term $term) {
* @see taxonomy_term_confirm_delete()
*/
function taxonomy_term_confirm_delete_submit($form, &$form_state) {
- entity_delete_multiple('taxonomy_term', array($form_state['values']['tid']));
+ $entity = taxonomy_term_load($form_state['values']['tid']);
+ $entity->delete();
taxonomy_check_vocabulary_hierarchy($form_state['taxonomy']['vocabulary'], $form_state['values']);
drupal_set_message(t('Deleted term %name.', array('%name' => $form_state['values']['name'])));
watchdog('taxonomy', 'Deleted term %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE);
if (!isset($_GET['destination'])) {
$form_state['redirect'] = 'admin/structure/taxonomy';
}
+ Drupal::entityManager()->getRenderController('taxonomy_term')->resetCache(array($entity));
cache_invalidate_tags(array('content' => TRUE));
return;
}
diff --git a/core/modules/user/config/entity.view_mode.user.compact.yml b/core/modules/user/config/entity.view_mode.user.compact.yml
index c27265b..c211e99 100644
--- a/core/modules/user/config/entity.view_mode.user.compact.yml
+++ b/core/modules/user/config/entity.view_mode.user.compact.yml
@@ -1,4 +1,5 @@
id: user.compact
label: Compact
status: '1'
+cache: '1'
targetEntityType: user
diff --git a/core/modules/user/config/entity.view_mode.user.full.yml b/core/modules/user/config/entity.view_mode.user.full.yml
index ac1ca20..343e909 100644
--- a/core/modules/user/config/entity.view_mode.user.full.yml
+++ b/core/modules/user/config/entity.view_mode.user.full.yml
@@ -1,4 +1,5 @@
id: user.full
label: User account
status: '0'
+cache: '1'
targetEntityType: user
diff --git a/core/modules/user/lib/Drupal/user/ProfileFormController.php b/core/modules/user/lib/Drupal/user/ProfileFormController.php
index 484a4af..8e72e76 100644
--- a/core/modules/user/lib/Drupal/user/ProfileFormController.php
+++ b/core/modules/user/lib/Drupal/user/ProfileFormController.php
@@ -41,6 +41,8 @@ public function submit(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$account = $this->entity;
$account->save();
$form_state['values']['uid'] = $account->id();
diff --git a/core/modules/user/lib/Drupal/user/RegisterFormController.php b/core/modules/user/lib/Drupal/user/RegisterFormController.php
index ceecd65..3c0bdbd 100644
--- a/core/modules/user/lib/Drupal/user/RegisterFormController.php
+++ b/core/modules/user/lib/Drupal/user/RegisterFormController.php
@@ -93,6 +93,8 @@ public function submit(array $form, array &$form_state) {
* Overrides Drupal\Core\Entity\EntityFormController::submit().
*/
public function save(array $form, array &$form_state) {
+ parent::save($form, $form_state);
+
$account = $this->entity;
$pass = $account->pass;
$admin = $form_state['values']['administer_users'];
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPictureTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPictureTest.php
index 1cd12bc..3a84f48 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserPictureTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserPictureTest.php
@@ -120,6 +120,8 @@ function testPictureOnNodeComment() {
->set('features.node_user_picture', FALSE)
->set('features.comment_user_picture', FALSE)
->save();
+ \Drupal::entityManager()->getStorageController('node')->resetCache(array($node));
+ \Drupal::entityManager()->getStorageController('comment')->resetCache();
$this->drupalGet('node/' . $node->nid);
$this->assertNoRaw(file_uri_target($file->uri), 'User picture not found on node and comment.');
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index 9946ae2..12347fd 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -383,8 +383,9 @@ function user_admin_permissions_submit($form, &$form_state) {
drupal_set_message(t('The changes have been saved.'));
- // Clear the cached pages and blocks.
+ // Clear cached pages, blocks and rendered entities.
cache_invalidate_tags(array('content' => TRUE));
+ entity_render_cache_clear();
}
/**