diff --git a/core/modules/views/src/Plugin/views/style/Table.php b/core/modules/views/src/Plugin/views/style/Table.php index b369f82c4618db3fe64d5371c7ae9c6702105167..0058bdc4f059296ee671e3287d5ef694fc85adfe 100644 --- a/core/modules/views/src/Plugin/views/style/Table.php +++ b/core/modules/views/src/Plugin/views/style/Table.php @@ -3,6 +3,7 @@ namespace Drupal\views\Plugin\views\style; use Drupal\Component\Utility\Html; +use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\wizard\WizardInterface; @@ -423,7 +424,7 @@ public function wizardSubmit(&$form, FormStateInterface $form_state, WizardInter * {@inheritdoc} */ public function getCacheMaxAge() { - return 0; + return Cache::PERMANENT; } /** diff --git a/core/modules/views/tests/fixtures/update/table-cache-max-age.php b/core/modules/views/tests/fixtures/update/table-cache-max-age.php new file mode 100644 index 0000000000000000000000000000000000000000..b6757c706e42eed956164b50130060efe3f6db3c --- /dev/null +++ b/core/modules/views/tests/fixtures/update/table-cache-max-age.php @@ -0,0 +1,19 @@ +insert('config') + ->fields([ + 'collection' => '', + 'name' => 'views.view.test_table_max_age', + 'data' => serialize(Yaml::decode(file_get_contents('core/modules/views/tests/fixtures/update/views.view.test_table_max_age.yml'))), + ]) + ->execute(); diff --git a/core/modules/views/tests/fixtures/update/views.view.test_table_max_age.yml b/core/modules/views/tests/fixtures/update/views.view.test_table_max_age.yml new file mode 100644 index 0000000000000000000000000000000000000000..deaf74d4b7a2d7ddef1faaec3dd965c160fcd523 --- /dev/null +++ b/core/modules/views/tests/fixtures/update/views.view.test_table_max_age.yml @@ -0,0 +1,185 @@ +langcode: en +status: true +dependencies: + module: + - node + - user +id: test_table_max_age +label: test-table-max-age +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: mini + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: ‹‹ + next: ›› + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + title: title + info: + title: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: '-1' + empty_table: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + title: + id: title + table: node_field_data + field: title + entity_type: node + entity_field: title + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + settings: + link_to_entity: true + plugin_id: field + relationship: none + group_type: group + admin_label: '' + exclude: 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_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: '1' + 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 + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php index 3bbe6bf97c3c965c87dc434f9bd87ad39ff8ca9d..5f1e642aa1d2e16a13a724c5c06164857b7f5370 100644 --- a/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\views\Functional\Plugin; +use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber; use Drupal\Tests\views\Functional\ViewTestBase; use Drupal\views\Entity\View; @@ -229,4 +230,18 @@ public function testGrouping() { } } + /** + * Tests the cacheability of the table display. + */ + public function testTableCacheability() { + \Drupal::service('module_installer')->uninstall(['page_cache']); + + $url = 'test-table'; + $this->drupalGet($url); + $this->assertSession()->statusCodeEquals(200); + $this->assertEquals('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); + $this->drupalGet($url); + $this->assertEquals('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); + } + } diff --git a/core/modules/views/tests/src/Functional/Update/TableDisplayCacheMaxAgeTest.php b/core/modules/views/tests/src/Functional/Update/TableDisplayCacheMaxAgeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3e40e2b76de165cc64453388de747c371cfdc53e --- /dev/null +++ b/core/modules/views/tests/src/Functional/Update/TableDisplayCacheMaxAgeTest.php @@ -0,0 +1,44 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/table-cache-max-age.php', + ]; + } + + /** + * Tests the upgrade path for cache max age with table displays. + */ + public function testViewsPostUpdateTableDisplayMaxCacheAge() { + $view = View::load('test_table_max_age'); + $data = $view->toArray(); + $this->assertSame(0, $data['display']['default']['cache_metadata']['max-age']); + + $this->runUpdates(); + + // Load and initialize our test view. + $view = View::load('test_table_max_age'); + $data = $view->toArray(); + // Check that the field is using the expected max age value. + $this->assertSame(-1, $data['display']['default']['cache_metadata']['max-age']); + } + +} diff --git a/core/modules/views/views.post_update.php b/core/modules/views/views.post_update.php index 297363dc40f5b9ba48d29761610aa23ffde68c14..b0734478b64138f9b1337b39ae26723d92e7f063 100644 --- a/core/modules/views/views.post_update.php +++ b/core/modules/views/views.post_update.php @@ -321,3 +321,28 @@ function views_post_update_filter_placeholder_text() { } } } + +/** + * Fix cache max age for table displays. + */ +function views_post_update_table_display_cache_max_age(&$sandbox = NULL) { + $storage = \Drupal::entityTypeManager()->getStorage('view'); + if (!isset($sandbox['views'])) { + $sandbox['views'] = $storage->getQuery()->accessCheck(FALSE)->execute(); + $sandbox['count'] = count($sandbox['views']); + } + + for ($i = 0; $i < 10 && count($sandbox['views']); $i++) { + $view_id = array_shift($sandbox['views']); + if ($view = $storage->load($view_id)) { + $displays = $view->get('display'); + foreach ($displays as $display_name => &$display) { + if (isset($display['display_options']['style']['type']) && $display['display_options']['style']['type'] === 'table') { + $view->save(); + } + } + } + } + + $sandbox['#finished'] = empty($sandbox['views']) ? 1 : ($sandbox['count'] - count($sandbox['views'])) / $sandbox['count']; +}