summaryrefslogtreecommitdiffstatshomepage
path: root/core/modules/views
diff options
context:
space:
mode:
Diffstat (limited to 'core/modules/views')
-rw-r--r--core/modules/views/config/schema/views.data_types.schema.yml23
-rw-r--r--core/modules/views/config/schema/views.pager.schema.yml2
-rw-r--r--core/modules/views/js/ajax_view.js2
-rw-r--r--core/modules/views/src/Entity/View.php2
-rw-r--r--core/modules/views/src/Form/ViewsExposedForm.php1
-rw-r--r--core/modules/views/src/Plugin/views/argument/DayDate.php4
-rw-r--r--core/modules/views/src/Plugin/views/argument/MonthDate.php4
-rw-r--r--core/modules/views/src/Plugin/views/argument/YearMonthDate.php4
-rw-r--r--core/modules/views/src/Plugin/views/display/DisplayPluginBase.php7
-rw-r--r--core/modules/views/src/Plugin/views/pager/Full.php4
-rw-r--r--core/modules/views/src/Plugin/views/pager/Mini.php3
-rw-r--r--core/modules/views/src/Plugin/views/pager/PagerPluginBase.php8
-rw-r--r--core/modules/views/src/Plugin/views/style/StylePluginBase.php6
-rw-r--r--core/modules/views/src/ViewExecutable.php12
-rw-r--r--core/modules/views/tests/modules/views_test_config/test_views/views.view.test_third_party_uninstall.yml37
-rw-r--r--core/modules/views/tests/modules/views_test_data/test_views/views.view.test_content_access_filter.yml247
-rw-r--r--core/modules/views/tests/modules/views_third_party_settings_test/config/schema/views_third_party_settings_test.schema.yml7
-rw-r--r--core/modules/views/tests/modules/views_third_party_settings_test/views_third_party_settings_test.info.yml8
-rw-r--r--core/modules/views/tests/src/Functional/GlossaryTest.php1
-rw-r--r--core/modules/views/tests/src/Functional/Plugin/AccessTest.php35
-rw-r--r--core/modules/views/tests/src/Functional/Plugin/DisplayTest.php13
-rw-r--r--core/modules/views/tests/src/Kernel/Handler/ArgumentSummaryTest.php34
-rw-r--r--core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php5
-rw-r--r--core/modules/views/tests/src/Kernel/ThirdPartyUninstallTest.php55
-rw-r--r--core/modules/views/views.theme.inc14
25 files changed, 493 insertions, 45 deletions
diff --git a/core/modules/views/config/schema/views.data_types.schema.yml b/core/modules/views/config/schema/views.data_types.schema.yml
index 0e011d73dc15..31c6b2f6479e 100644
--- a/core/modules/views/config/schema/views.data_types.schema.yml
+++ b/core/modules/views/config/schema/views.data_types.schema.yml
@@ -633,29 +633,33 @@ views_pager:
offset:
type: integer
label: 'Offset'
+ constraints:
+ PositiveOrZero: []
pagination_heading_level:
+ # Validating against a string, but the list is populated by a protected
+ # property of the plugin. This could be a callback in the future.
type: string
label: 'Pager header element'
items_per_page:
type: integer
label: 'Items per page'
+ constraints:
+ PositiveOrZero: []
views_pager_sql:
type: views_pager
label: 'SQL pager'
mapping:
- items_per_page:
- type: integer
- label: 'Items per page'
- pagination_heading_level:
- type: string
- label: 'Pager header element'
total_pages:
type: integer
label: 'Number of pages'
+ constraints:
+ PositiveOrZero: []
id:
type: integer
label: 'Pager ID'
+ constraints:
+ PositiveOrZero: []
tags:
type: mapping
label: 'Pager link labels'
@@ -669,6 +673,8 @@ views_pager_sql:
quantity:
type: integer
label: 'Number of pager links visible'
+ constraints:
+ PositiveOrZero: []
expose:
type: mapping
label: 'Exposed options'
@@ -682,6 +688,11 @@ views_pager_sql:
items_per_page_options:
type: string
label: 'Exposed items per page options'
+ constraints:
+ # Comma separated list of integers, with optional space in between.
+ Regex:
+ pattern: '/^(\d+)(,\s*\d+)*$/'
+ message: 'Per page should be a valid list of integers.'
items_per_page_options_all:
type: boolean
label: 'Include all items option'
diff --git a/core/modules/views/config/schema/views.pager.schema.yml b/core/modules/views/config/schema/views.pager.schema.yml
index eb360227e029..072dbc5b87e0 100644
--- a/core/modules/views/config/schema/views.pager.schema.yml
+++ b/core/modules/views/config/schema/views.pager.schema.yml
@@ -33,3 +33,5 @@ views.pager.full:
quantity:
type: integer
label: 'Number of pager links visible'
+ constraints:
+ PositiveOrZero: []
diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js
index dd3da9b83507..8e646697d83e 100644
--- a/core/modules/views/js/ajax_view.js
+++ b/core/modules/views/js/ajax_view.js
@@ -83,7 +83,7 @@
if (queryString !== '') {
// If there is a '?' in ajaxPath, clean URL are on and & should be
// used to add parameters.
- queryString = (/\?/.test(ajaxPath) ? '&' : '?') + queryString;
+ queryString = (ajaxPath.includes('?') ? '&' : '?') + queryString;
}
}
diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php
index cd1b2a0a42e1..f6bb32cec877 100644
--- a/core/modules/views/src/Entity/View.php
+++ b/core/modules/views/src/Entity/View.php
@@ -481,7 +481,7 @@ class View extends ConfigEntityBase implements ViewEntityInterface {
* {@inheritdoc}
*/
public function onDependencyRemoval(array $dependencies) {
- $changed = FALSE;
+ $changed = parent::onDependencyRemoval($dependencies);
// Don't intervene if the views module is removed.
if (isset($dependencies['module']) && in_array('views', $dependencies['module'])) {
diff --git a/core/modules/views/src/Form/ViewsExposedForm.php b/core/modules/views/src/Form/ViewsExposedForm.php
index d68b1dd5363c..9f90160ff55f 100644
--- a/core/modules/views/src/Form/ViewsExposedForm.php
+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -196,7 +196,6 @@ class ViewsExposedForm extends FormBase implements WorkspaceSafeFormInterface {
$view->exposed_data = $values;
$view->exposed_raw_input = [];
- $exclude = ['submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', 'reset'];
/** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
$exposed_form_plugin = $view->display_handler->getPlugin('exposed_form');
$exposed_form_plugin->exposedFormSubmit($form, $form_state, $exclude);
diff --git a/core/modules/views/src/Plugin/views/argument/DayDate.php b/core/modules/views/src/Plugin/views/argument/DayDate.php
index 884355a72a4b..a4a94da06998 100644
--- a/core/modules/views/src/Plugin/views/argument/DayDate.php
+++ b/core/modules/views/src/Plugin/views/argument/DayDate.php
@@ -29,7 +29,7 @@ class DayDate extends Date {
$day = str_pad($data->{$this->name_alias}, 2, '0', STR_PAD_LEFT);
// strtotime() respects server timezone, so we need to set the time fixed
// as utc time
- return $this->dateFormatter->format(strtotime("2005" . "05" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+ return $this->dateFormatter->format(strtotime("200505" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
}
/**
@@ -37,7 +37,7 @@ class DayDate extends Date {
*/
public function title() {
$day = str_pad($this->argument, 2, '0', STR_PAD_LEFT);
- return $this->dateFormatter->format(strtotime("2005" . "05" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+ return $this->dateFormatter->format(strtotime("200505" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
}
/**
diff --git a/core/modules/views/src/Plugin/views/argument/MonthDate.php b/core/modules/views/src/Plugin/views/argument/MonthDate.php
index cec2159c9a3d..a24f23f120d9 100644
--- a/core/modules/views/src/Plugin/views/argument/MonthDate.php
+++ b/core/modules/views/src/Plugin/views/argument/MonthDate.php
@@ -28,7 +28,7 @@ class MonthDate extends Date {
public function summaryName($data) {
$month = str_pad($data->{$this->name_alias}, 2, '0', STR_PAD_LEFT);
try {
- return $this->dateFormatter->format(strtotime("2005" . $month . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+ return $this->dateFormatter->format(strtotime("2005" . $month . "15 00:00:00 UTC"), 'custom', $this->format, 'UTC');
}
catch (\InvalidArgumentException) {
return parent::summaryName($data);
@@ -41,7 +41,7 @@ class MonthDate extends Date {
public function title() {
$month = str_pad($this->argument, 2, '0', STR_PAD_LEFT);
try {
- return $this->dateFormatter->format(strtotime("2005" . $month . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+ return $this->dateFormatter->format(strtotime("2005" . $month . "15 00:00:00 UTC"), 'custom', $this->format, 'UTC');
}
catch (\InvalidArgumentException) {
return parent::title();
diff --git a/core/modules/views/src/Plugin/views/argument/YearMonthDate.php b/core/modules/views/src/Plugin/views/argument/YearMonthDate.php
index 16410ad25564..b82071f6d6ae 100644
--- a/core/modules/views/src/Plugin/views/argument/YearMonthDate.php
+++ b/core/modules/views/src/Plugin/views/argument/YearMonthDate.php
@@ -27,14 +27,14 @@ class YearMonthDate extends Date {
*/
public function summaryName($data) {
$created = $data->{$this->name_alias};
- return $this->dateFormatter->format(strtotime($created . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+ return $this->dateFormatter->format(strtotime($created . "15 00:00:00 UTC"), 'custom', $this->format, 'UTC');
}
/**
* {@inheritdoc}
*/
public function title() {
- return $this->dateFormatter->format(strtotime($this->argument . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
+ return $this->dateFormatter->format(strtotime($this->argument . "15 00:00:00 UTC"), 'custom', $this->format, 'UTC');
}
}
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index fc4a983f9299..d3adc61de5ab 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -2117,13 +2117,18 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
$hasMoreRecords = !empty($this->view->pager) && $this->view->pager->hasMoreRecords();
if ($this->isMoreEnabled() && ($this->useMoreAlways() || $hasMoreRecords)) {
$url = $this->getMoreUrl();
+ $access = $url->access(return_as_object: TRUE);
- return [
+ $more_link = [
'#type' => 'more_link',
'#url' => $url,
'#title' => $this->useMoreText(),
'#view' => $this->view,
+ '#access' => $access->isAllowed(),
];
+ $accessCacheability = CacheableMetadata::createFromObject($access);
+ $accessCacheability->applyTo($more_link);
+ return $more_link;
}
}
diff --git a/core/modules/views/src/Plugin/views/pager/Full.php b/core/modules/views/src/Plugin/views/pager/Full.php
index 0176fc6e7f90..ed8f7d7566a2 100644
--- a/core/modules/views/src/Plugin/views/pager/Full.php
+++ b/core/modules/views/src/Plugin/views/pager/Full.php
@@ -79,8 +79,8 @@ class Full extends SqlBase {
* {@inheritdoc}
*/
public function render($input) {
- // The 0, 1, 3, 4 indexes are correct. See the template_preprocess_pager()
- // documentation.
+ // The 0, 1, 3, 4 indexes are correct. See the
+ // \Drupal\Core\Pager\PagerPreprocess::preprocessPager() documentation.
$tags = [
0 => $this->options['tags']['first'],
1 => $this->options['tags']['previous'],
diff --git a/core/modules/views/src/Plugin/views/pager/Mini.php b/core/modules/views/src/Plugin/views/pager/Mini.php
index 0f95f7a0d2f6..e17aa7fabdd7 100644
--- a/core/modules/views/src/Plugin/views/pager/Mini.php
+++ b/core/modules/views/src/Plugin/views/pager/Mini.php
@@ -90,7 +90,8 @@ class Mini extends SqlBase {
* {@inheritdoc}
*/
public function render($input) {
- // The 1, 3 indexes are correct, see template_preprocess_pager().
+ // The 1, 3 indexes are correct, see
+ // \Drupal\Core\Pager\PagerPreprocess::preprocessPager().
$tags = [
1 => $this->options['tags']['previous'],
3 => $this->options['tags']['next'],
diff --git a/core/modules/views/src/Plugin/views/pager/PagerPluginBase.php b/core/modules/views/src/Plugin/views/pager/PagerPluginBase.php
index 3356d703c93d..5796488746cc 100644
--- a/core/modules/views/src/Plugin/views/pager/PagerPluginBase.php
+++ b/core/modules/views/src/Plugin/views/pager/PagerPluginBase.php
@@ -29,14 +29,18 @@ abstract class PagerPluginBase extends PluginBase {
/**
* The current page.
+ *
+ * @phpcs:ignore Drupal.Commenting.VariableComment.MissingVar
*/
- // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName, Drupal.Commenting.VariableComment.Missing
+ // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName
public $current_page = NULL;
/**
* The total number of lines.
+ *
+ * @phpcs:ignore Drupal.Commenting.VariableComment.MissingVar
*/
- // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName, Drupal.Commenting.VariableComment.Missing
+ // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName
public $total_items = 0;
/**
diff --git a/core/modules/views/src/Plugin/views/style/StylePluginBase.php b/core/modules/views/src/Plugin/views/style/StylePluginBase.php
index 3f555cfec9fd..ca8df3ba8fef 100644
--- a/core/modules/views/src/Plugin/views/style/StylePluginBase.php
+++ b/core/modules/views/src/Plugin/views/style/StylePluginBase.php
@@ -85,12 +85,12 @@ abstract class StylePluginBase extends PluginBase {
/**
* Stores the rendered field values, keyed by the row index and field name.
*
+ * @var array|null
+ *
* @see \Drupal\views\Plugin\views\style\StylePluginBase::renderFields()
* @see \Drupal\views\Plugin\views\style\StylePluginBase::getField()
- *
- * @var array|null
*/
- // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName, Drupal.Commenting.VariableComment.Missing
+ // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName
protected $rendered_fields;
/**
diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php
index 4867ba48f9a6..407260ed285d 100644
--- a/core/modules/views/src/ViewExecutable.php
+++ b/core/modules/views/src/ViewExecutable.php
@@ -400,21 +400,21 @@ class ViewExecutable {
/**
* Force the query to calculate the total number of results.
*
- * @todo Move to the query.
- *
* @var bool
+ *
+ * @todo Move to the query.
*/
- // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName, Drupal.Commenting.VariableComment.Missing
+ // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName
public $get_total_rows;
/**
* Indicates if the sorts have been built.
*
- * @todo Group with other static properties.
- *
* @var bool
+ *
+ * @todo Group with other static properties.
*/
- // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName, Drupal.Commenting.VariableComment.Missing
+ // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName
public $build_sort;
/**
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_third_party_uninstall.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_third_party_uninstall.yml
new file mode 100644
index 000000000000..eb59548f17f5
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_third_party_uninstall.yml
@@ -0,0 +1,37 @@
+langcode: en
+status: true
+dependencies:
+ module:
+ - node
+ - views_third_party_settings_test
+third_party_settings:
+ views_third_party_settings_test:
+ example_setting: true
+id: test_third_party_uninstall
+label: test_third_party_uninstall
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+display:
+ default:
+ display_options:
+ access:
+ type: none
+ cache:
+ type: tag
+ exposed_form:
+ type: basic
+ pager:
+ type: full
+ query:
+ type: views_query
+ style:
+ type: default
+ row:
+ type: fields
+ display_plugin: default
+ display_title: Defaults
+ id: default
+ position: 0
diff --git a/core/modules/views/tests/modules/views_test_data/test_views/views.view.test_content_access_filter.yml b/core/modules/views/tests/modules/views_test_data/test_views/views.view.test_content_access_filter.yml
new file mode 100644
index 000000000000..8680489c2b6e
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_data/test_views/views.view.test_content_access_filter.yml
@@ -0,0 +1,247 @@
+status: true
+dependencies:
+ config:
+ - core.entity_view_mode.node.teaser
+ module:
+ - node
+ - user
+id: test_content_access_filter
+label: 'Test Content Access Filter'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+display:
+ default:
+ display_plugin: default
+ id: default
+ display_title: Default
+ 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: default
+ row:
+ type: 'entity:node'
+ options:
+ view_mode: teaser
+ 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:
+ nid:
+ id: nid
+ table: node_access
+ field: nid
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: '='
+ value: ''
+ group: 1
+ exposed: false
+ expose:
+ operator_id: ''
+ label: ''
+ description: ''
+ use_operator: false
+ operator: ''
+ operator_limit_selection: false
+ operator_list: { }
+ identifier: ''
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ plugin_id: node_access
+ status:
+ id: status
+ table: node_field_data
+ field: status
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: '='
+ value: '1'
+ group: 1
+ exposed: false
+ expose:
+ operator_id: ''
+ label: ''
+ description: ''
+ use_operator: false
+ operator: ''
+ operator_limit_selection: false
+ operator_list: { }
+ identifier: ''
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ entity_type: node
+ entity_field: status
+ plugin_id: boolean
+ 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: ''
+ field_identifier: ''
+ granularity: second
+ title: 'Test Content Access Filter'
+ header: { }
+ footer: { }
+ empty: { }
+ relationships: { }
+ arguments: { }
+ display_extenders: { }
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url.query_args
+ - 'user.node_grants:view'
+ - user.permissions
+ tags: { }
+ page_1:
+ display_plugin: page
+ id: page_1
+ display_title: Page
+ position: 1
+ display_options:
+ display_extenders: { }
+ path: test-content-access-filter
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url.query_args
+ - 'user.node_grants:view'
+ - user.permissions
+ tags: { }
diff --git a/core/modules/views/tests/modules/views_third_party_settings_test/config/schema/views_third_party_settings_test.schema.yml b/core/modules/views/tests/modules/views_third_party_settings_test/config/schema/views_third_party_settings_test.schema.yml
new file mode 100644
index 000000000000..0bdeeed705ab
--- /dev/null
+++ b/core/modules/views/tests/modules/views_third_party_settings_test/config/schema/views_third_party_settings_test.schema.yml
@@ -0,0 +1,7 @@
+views.view.*.third_party.views_third_party_settings_test:
+ type: config_entity
+ label: "Example settings"
+ mapping:
+ example_setting:
+ type: boolean
+ label: "Example setting"
diff --git a/core/modules/views/tests/modules/views_third_party_settings_test/views_third_party_settings_test.info.yml b/core/modules/views/tests/modules/views_third_party_settings_test/views_third_party_settings_test.info.yml
new file mode 100644
index 000000000000..be9752795657
--- /dev/null
+++ b/core/modules/views/tests/modules/views_third_party_settings_test/views_third_party_settings_test.info.yml
@@ -0,0 +1,8 @@
+name: 'Third Party Settings Test'
+type: module
+description: 'A dummy module that third party settings tests can depend on'
+package: Testing
+version: VERSION
+dependencies:
+ - drupal:node
+ - drupal:views
diff --git a/core/modules/views/tests/src/Functional/GlossaryTest.php b/core/modules/views/tests/src/Functional/GlossaryTest.php
index 292f91767715..25c08d5f1590 100644
--- a/core/modules/views/tests/src/Functional/GlossaryTest.php
+++ b/core/modules/views/tests/src/Functional/GlossaryTest.php
@@ -83,7 +83,6 @@ class GlossaryTest extends ViewTestBase {
'url',
'user.node_grants:view',
'user.permissions',
- 'route',
],
[
'config:views.view.glossary',
diff --git a/core/modules/views/tests/src/Functional/Plugin/AccessTest.php b/core/modules/views/tests/src/Functional/Plugin/AccessTest.php
index df420cf879fa..92874dd8b417 100644
--- a/core/modules/views/tests/src/Functional/Plugin/AccessTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/AccessTest.php
@@ -22,7 +22,12 @@ class AccessTest extends ViewTestBase {
*
* @var array
*/
- public static $testViews = ['test_access_none', 'test_access_static', 'test_access_dynamic'];
+ public static $testViews = [
+ 'test_access_none',
+ 'test_access_static',
+ 'test_access_dynamic',
+ 'test_content_access_filter',
+ ];
/**
* {@inheritdoc}
@@ -113,4 +118,32 @@ class AccessTest extends ViewTestBase {
$this->assertSession()->statusCodeEquals(200);
}
+ /**
+ * Tests that node_access table is joined when hook_node_grants() is implemented.
+ */
+ public function testContentAccessFilter(): void {
+ $view = Views::getView('test_content_access_filter');
+ $view->setDisplay('page_1');
+
+ $view->initQuery();
+ $view->execute();
+ /** @var \Drupal\Core\Database\Query\Select $main_query */
+ $main_query = $view->build_info['query'];
+ $tables = array_keys($main_query->getTables());
+ $this->assertNotContains('node_access', $tables);
+
+ // Enable node access test module to ensure that table is present again.
+ \Drupal::service('module_installer')->install(['node_access_test']);
+ node_access_rebuild();
+
+ $view = Views::getView('test_content_access_filter');
+ $view->setDisplay('page_1');
+ $view->initQuery();
+ $view->execute();
+ /** @var \Drupal\Core\Database\Query\Select $main_query */
+ $main_query = $view->build_info['query'];
+ $tables = array_keys($main_query->getTables());
+ $this->assertContains('node_access', $tables);
+ }
+
}
diff --git a/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
index 8af887d1ef1b..5aecbea3e366 100644
--- a/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Drupal\Tests\views\Functional\Plugin;
-use Drupal\Component\Render\FormattableMarkup;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Views;
@@ -317,6 +316,14 @@ class DisplayTest extends ViewTestBase {
$output = $view->preview();
$output = (string) $renderer->renderRoot($output);
$this->assertStringContainsString('/node?date=22&foo=bar#22', $output, 'The read more link with href "/node?date=22&foo=bar#22" was found.');
+
+ // Test more link isn't rendered if user doesn't have permission to the
+ // more link URL.
+ $view->display_handler->setOption('link_url', 'admin/content');
+ $this->executeView($view);
+ $output = $view->preview();
+ $output = (string) $renderer->renderRoot($output);
+ $this->assertStringNotContainsString('/admin/content', $output, 'The read more link with href "/admin/content" was not found.');
}
/**
@@ -389,8 +396,8 @@ class DisplayTest extends ViewTestBase {
$errors = $view->validate();
// Check that the error messages are shown.
$this->assertCount(2, $errors['default'], 'Error messages found for required relationship');
- $this->assertEquals(new FormattableMarkup('The %relationship_name relationship used in %handler_type %handler is not present in the %display_name display.', ['%relationship_name' => 'uid', '%handler_type' => 'field', '%handler' => 'User: Last login', '%display_name' => 'Default']), $errors['default'][0]);
- $this->assertEquals(new FormattableMarkup('The %relationship_name relationship used in %handler_type %handler is not present in the %display_name display.', ['%relationship_name' => 'uid', '%handler_type' => 'field', '%handler' => 'User: Created', '%display_name' => 'Default']), $errors['default'][1]);
+ $this->assertEquals("The uid relationship used in field User: Last login is not present in the Default display.", $errors['default'][0]);
+ $this->assertEquals("The uid relationship used in field User: Created is not present in the Default display.", $errors['default'][1]);
}
/**
diff --git a/core/modules/views/tests/src/Kernel/Handler/ArgumentSummaryTest.php b/core/modules/views/tests/src/Kernel/Handler/ArgumentSummaryTest.php
index 03488125064a..e19f1414615f 100644
--- a/core/modules/views/tests/src/Kernel/Handler/ArgumentSummaryTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/ArgumentSummaryTest.php
@@ -150,4 +150,38 @@ class ArgumentSummaryTest extends ViewsKernelTestBase {
$this->assertStringContainsString($tags[1]->label() . ' (2)', $output);
}
+ /**
+ * Tests that the active link is set correctly.
+ */
+ public function testActiveLink(): void {
+ require_once $this->root . '/core/modules/views/views.theme.inc';
+
+ // We need at least one node.
+ Node::create([
+ 'type' => $this->nodeType->id(),
+ 'title' => $this->randomMachineName(),
+ ])->save();
+
+ $view = Views::getView('test_argument_summary');
+ $view->execute();
+ $view->build();
+ $variables = [
+ 'view' => $view,
+ 'rows' => $view->result,
+ ];
+
+ template_preprocess_views_view_summary_unformatted($variables);
+ $this->assertFalse($variables['rows'][0]->active);
+
+ template_preprocess_views_view_summary($variables);
+ $this->assertFalse($variables['rows'][0]->active);
+
+ // Checks that the row with the current path is active.
+ \Drupal::service('path.current')->setPath('/test-argument-summary');
+ template_preprocess_views_view_summary_unformatted($variables);
+ $this->assertTrue($variables['rows'][0]->active);
+ template_preprocess_views_view_summary($variables);
+ $this->assertTrue($variables['rows'][0]->active);
+ }
+
}
diff --git a/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
index 97d670634b3f..14f90fd0c33a 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
@@ -137,12 +137,13 @@ class ExposedFormRenderTest extends ViewsKernelTestBase {
$view->save();
$this->executeView($view);
+ // The "type" filter should be excluded from the raw input because its
+ // value is "All".
$expected = [
- 'type' => 'All',
'type_with_default_value' => 'article',
'multiple_types_with_default_value' => ['article' => 'article'],
];
- $this->assertSame($view->exposed_raw_input, $expected);
+ $this->assertSame($expected, $view->exposed_raw_input);
}
}
diff --git a/core/modules/views/tests/src/Kernel/ThirdPartyUninstallTest.php b/core/modules/views/tests/src/Kernel/ThirdPartyUninstallTest.php
new file mode 100644
index 000000000000..0f3d3eb5291a
--- /dev/null
+++ b/core/modules/views/tests/src/Kernel/ThirdPartyUninstallTest.php
@@ -0,0 +1,55 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\views\Kernel;
+
+use Drupal\views\Entity\View;
+
+/**
+ * Tests proper removal of third-party settings from views.
+ *
+ * @group views
+ */
+class ThirdPartyUninstallTest extends ViewsKernelTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ protected static $modules = ['node', 'views_third_party_settings_test'];
+
+ /**
+ * Views used by this test.
+ *
+ * @var array
+ */
+ public static $testViews = ['test_third_party_uninstall'];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp($import_test_views = TRUE): void {
+ parent::setUp($import_test_views);
+
+ $this->installEntitySchema('user');
+ $this->installSchema('user', ['users_data']);
+ }
+
+ /**
+ * Tests removing third-party settings when a provider module is uninstalled.
+ */
+ public function testThirdPartyUninstall(): void {
+ $view = View::load('test_third_party_uninstall');
+ $this->assertNotEmpty($view);
+ $this->assertContains('views_third_party_settings_test', $view->getDependencies()['module']);
+ $this->assertTrue($view->getThirdPartySetting('views_third_party_settings_test', 'example_setting'));
+
+ \Drupal::service('module_installer')->uninstall(['views_third_party_settings_test']);
+
+ $view = View::load('test_third_party_uninstall');
+ $this->assertNotEmpty($view);
+ $this->assertNotContains('views_third_party_settings_test', $view->getDependencies()['module']);
+ $this->assertNull($view->getThirdPartySetting('views_third_party_settings_test', 'example_setting'));
+ }
+
+}
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 10c29c5dbf30..04c5de5a535f 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -253,15 +253,12 @@ function template_preprocess_views_view_summary(&$variables): void {
$url_options['query'] = $view->exposed_raw_input;
}
+ $currentPath = \Drupal::service('path.current')->getPath();
$active_urls = [
// Force system path.
- Url::fromRoute('<current>', [], ['alias' => TRUE])->toString(),
- // Force system path.
- Url::fromRouteMatch(\Drupal::routeMatch())->setOption('alias', TRUE)->toString(),
- // Could be an alias.
- Url::fromRoute('<current>')->toString(),
+ Url::fromUserInput($currentPath, ['alias' => TRUE])->toString(),
// Could be an alias.
- Url::fromRouteMatch(\Drupal::routeMatch())->toString(),
+ Url::fromUserInput($currentPath)->toString(),
];
$active_urls = array_combine($active_urls, $active_urls);
@@ -342,11 +339,12 @@ function template_preprocess_views_view_summary_unformatted(&$variables): void {
}
$count = 0;
+ $currentPath = \Drupal::service('path.current')->getPath();
$active_urls = [
// Force system path.
- Url::fromRoute('<current>', [], ['alias' => TRUE])->toString(),
+ Url::fromUserInput($currentPath, ['alias' => TRUE])->toString(),
// Could be an alias.
- Url::fromRoute('<current>')->toString(),
+ Url::fromUserInput($currentPath)->toString(),
];
$active_urls = array_combine($active_urls, $active_urls);