summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2016-02-01 16:35:16 (GMT)
committerAlex Pott2016-02-01 16:35:16 (GMT)
commit130f8c1ab9902b4862568ca3e4b0b1d62b8db002 (patch)
treeafaea5171b818f84cbeb0d80e8f2a232eaeb4f0e
parent7ab932fbee604e1ac97f86268dbb6d95cbdce900 (diff)
Issue #2633308 by dawehner, mparker17, Wim Leers, Fabianx: Views cache contexts are lost (and thus do not bubble) when rendering a view's block display
-rw-r--r--core/modules/user/config/schema/user.views.schema.yml4
-rw-r--r--core/modules/views/src/Plugin/views/display/DisplayPluginBase.php8
-rw-r--r--core/modules/views/src/Tests/Plugin/CacheWebTest.php11
-rw-r--r--core/modules/views/src/Tests/RenderCacheWebTest.php80
-rw-r--r--core/modules/views/tests/modules/views_test_config/test_views/views.view.node_id_argument.yml215
5 files changed, 312 insertions, 6 deletions
diff --git a/core/modules/user/config/schema/user.views.schema.yml b/core/modules/user/config/schema/user.views.schema.yml
index d74140f..ed0eb28 100644
--- a/core/modules/user/config/schema/user.views.schema.yml
+++ b/core/modules/user/config/schema/user.views.schema.yml
@@ -56,10 +56,6 @@ views.argument_default.current_user:
type: boolean
label: 'User ID from logged in user'
-views.argument_default.node:
- type: boolean
- label: 'Content ID from URL'
-
views_field_user:
type: views_field
mapping:
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index d54a055..1d18ee1 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -2335,13 +2335,17 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
'#cache_properties' => ['#view_id', '#view_display_show_admin_links', '#view_display_plugin_id'],
];
+ // When something passes $cache = FALSE, they're asking us not to create our
+ // own render cache for it. However, we still need to include certain pieces
+ // of cacheability metadata (e.g.: cache contexts), so they can bubble up.
+ // Thus, we add the cacheability metadata first, then modify / remove the
+ // cache keys depending on the $cache argument.
+ $this->applyDisplayCachablityMetadata($this->view->element);
if ($cache) {
$this->view->element['#cache'] += ['keys' => []];
// Places like \Drupal\views\ViewExecutable::setCurrentPage() set up an
// additional cache context.
$this->view->element['#cache']['keys'] = array_merge(['views', 'display', $this->view->element['#name'], $this->view->element['#display_id']], $this->view->element['#cache']['keys']);
-
- $this->applyDisplayCachablityMetadata($this->view->element);
}
else {
// Remove the cache keys, to ensure render caching is not triggered. We
diff --git a/core/modules/views/src/Tests/Plugin/CacheWebTest.php b/core/modules/views/src/Tests/Plugin/CacheWebTest.php
index 85194e2..de8f932 100644
--- a/core/modules/views/src/Tests/Plugin/CacheWebTest.php
+++ b/core/modules/views/src/Tests/Plugin/CacheWebTest.php
@@ -84,4 +84,15 @@ class CacheWebTest extends PluginTestBase {
$this->assertCacheTags($cache_tags);
}
+ /**
+ * Tests that a display without caching still contains the cache metadata.
+ */
+ public function testDisplayWithoutCacheStillBubblesMetadata() {
+ $view = Views::getView('test_display');
+
+ $uncached_block = $view->buildRenderable('block_1', [], FALSE);
+ $cached_block = $view->buildRenderable('block_1', [], TRUE);
+ $this->assertEqual($uncached_block['#cache']['contexts'], $cached_block['#cache']['contexts'], 'Cache contexts are the same when you render the view cached and uncached.');
+ }
+
}
diff --git a/core/modules/views/src/Tests/RenderCacheWebTest.php b/core/modules/views/src/Tests/RenderCacheWebTest.php
new file mode 100644
index 0000000..b63a2fd
--- /dev/null
+++ b/core/modules/views/src/Tests/RenderCacheWebTest.php
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\RenderCacheWebTest.
+ */
+
+namespace Drupal\views\Tests;
+
+use Drupal\node\Entity\Node;
+
+/**
+ * Tests render caching of blocks provided by views.
+ *
+ * @group views
+ */
+class RenderCacheWebTest extends ViewTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['node', 'block'];
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $testViews = ['node_id_argument'];
+
+ /**
+ * The created nodes.
+ *
+ * @var \Drupal\node\NodeInterface[]
+ */
+ protected $nodes;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
+
+ $node_type = $this->drupalCreateContentType(['type' => 'test_type']);
+ $node = Node::create([
+ 'title' => 'test title 1',
+ 'type' => $node_type->id(),
+ ]);
+ $node->save();
+ $this->nodes[] = $node;
+
+ $node = Node::create([
+ 'title' => 'test title 2',
+ 'type' => $node_type->id(),
+ ]);
+ $node->save();
+ $this->nodes[] = $node;
+
+ $this->placeBlock('views_block:node_id_argument-block_1', ['region' => 'header']);
+ }
+
+ /**
+ * Tests rendering caching of a views block with arguments.
+ */
+ public function testEmptyView() {
+ $this->drupalGet('<front>');
+ $this->assertEqual([], $this->cssSelect('div.region-header div.views-field-title'));
+
+ $this->drupalGet($this->nodes[0]->toUrl());
+ $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+ $this->assertEqual('test title 1', $result);
+
+ $this->drupalGet($this->nodes[1]->toUrl());
+ $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+ $this->assertEqual('test title 2', $result);
+
+ $this->drupalGet($this->nodes[0]->toUrl());
+ $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+ $this->assertEqual('test title 1', $result);
+ }
+
+}
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.node_id_argument.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.node_id_argument.yml
new file mode 100644
index 0000000..746b56b
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.node_id_argument.yml
@@ -0,0 +1,215 @@
+langcode: en
+status: true
+dependencies:
+ module:
+ - node
+ - user
+id: node_id_argument
+label: node_id_argument
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+ default:
+ display_plugin: default
+ id: default
+ display_title: Master
+ position: 0
+ display_options:
+ access:
+ type: perm
+ options:
+ perm: 'access content'
+ cache:
+ type: tag
+ options: { }
+ query:
+ type: views_query
+ options:
+ disable_sql_rewrite: false
+ distinct: false
+ replica: false
+ query_comment: ''
+ query_tags: { }
+ exposed_form:
+ type: basic
+ options:
+ submit_button: Apply
+ reset_button: false
+ reset_button_label: Reset
+ exposed_sorts_label: 'Sort by'
+ expose_sort_order: true
+ sort_asc_label: Asc
+ sort_desc_label: Desc
+ pager:
+ type: some
+ options:
+ items_per_page: 5
+ offset: 0
+ style:
+ type: default
+ row:
+ type: fields
+ fields:
+ title:
+ id: title
+ table: node_field_data
+ field: title
+ settings:
+ link_to_entity: false
+ plugin_id: field
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: ''
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ click_sort_column: value
+ type: string
+ group_column: value
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ filters:
+ status:
+ value: true
+ table: node_field_data
+ field: status
+ plugin_id: boolean
+ entity_type: node
+ entity_field: status
+ id: status
+ expose:
+ operator: ''
+ group: 1
+ sorts:
+ created:
+ id: created
+ table: node_field_data
+ field: created
+ order: DESC
+ entity_type: node
+ entity_field: created
+ plugin_id: date
+ relationship: none
+ group_type: group
+ admin_label: ''
+ exposed: false
+ expose:
+ label: ''
+ granularity: second
+ title: node_id_argument
+ header: { }
+ footer: { }
+ empty: { }
+ relationships: { }
+ arguments:
+ nid:
+ id: nid
+ table: node_field_data
+ field: nid
+ relationship: none
+ group_type: group
+ admin_label: ''
+ default_action: default
+ exception:
+ value: all
+ title_enable: false
+ title: All
+ title_enable: false
+ title: ''
+ default_argument_type: node
+ default_argument_options: { }
+ default_argument_skip_url: false
+ summary_options:
+ base_path: ''
+ count: true
+ items_per_page: 25
+ override: false
+ summary:
+ sort_order: asc
+ number_of_records: 0
+ format: default_summary
+ specify_validation: false
+ validate:
+ type: none
+ fail: 'not found'
+ validate_options: { }
+ break_phrase: false
+ not: false
+ entity_type: node
+ entity_field: nid
+ plugin_id: node_nid
+ display_extenders: { }
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url
+ - 'user.node_grants:view'
+ - user.permissions
+ tags: { }
+ block_1:
+ display_plugin: block
+ id: block_1
+ display_title: Block
+ position: 1
+ display_options:
+ display_extenders: { }
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url
+ - 'user.node_grants:view'
+ - user.permissions
+ tags: { }