diff --git a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php index f8d03e12b72c161945bf60633198685c5fc0a73b..c0fcde77ea3698f3dd42eb2873a482ef4be84186 100644 --- a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php @@ -46,6 +46,23 @@ */ abstract class FilterPluginBase extends HandlerBase implements CacheableDependencyInterface { + /** + * A list of restricted identifiers. + * + * This list contains strings that could cause clashes with other site + * operations when used as a filter identifier. + * + * @var array + */ + const RESTRICTED_IDENTIFIERS = [ + 'value', + 'q', + 'destination', + '_format', + '_wrapper_format', + 'token', + ]; + /** * The value. * @@ -660,7 +677,8 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) { '#default_value' => $this->options['expose']['identifier'], '#title' => $this->t('Filter identifier'), '#size' => 40, - '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), + '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed. @reserved_identifiers are reserved words and cannot be used.', + ['@reserved_identifiers' => '"' . implode('", "', self::RESTRICTED_IDENTIFIERS) . '"']), ]; } @@ -771,7 +789,7 @@ protected function validateIdentifier($identifier, FormStateInterface $form_stat if (empty($identifier)) { $error = $this->t('The identifier is required if the filter is exposed.'); } - elseif ($identifier == 'value') { + elseif (in_array($identifier, self::RESTRICTED_IDENTIFIERS)) { $error = $this->t('This identifier is not allowed.'); } elseif (preg_match('/[^a-zA-Z0-9_~\.\-]+/', $identifier)) { @@ -1029,7 +1047,8 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form '#default_value' => $identifier, '#title' => $this->t('Filter identifier'), '#size' => 40, - '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), + '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed. @reserved_identifiers are reserved words and cannot be used.', + ['@reserved_identifiers' => '"' . implode('", "', self::RESTRICTED_IDENTIFIERS) . '"']), ]; $form['group_info']['label'] = [ '#type' => 'textfield', @@ -1083,7 +1102,8 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form '#default_value' => $identifier, '#title' => $this->t('Filter identifier'), '#size' => 40, - '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), + '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed. @reserved_identifiers are reserved words and cannot be used.', + ['@reserved_identifiers' => '"' . implode('", "', self::RESTRICTED_IDENTIFIERS) . '"']), ]; $form['group_info']['label'] = [ '#type' => 'textfield', diff --git a/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php index 4f6dd5b8446013c37ed51fc8ad3b59193b418987..99bfb6baabf5c8538e8e0eeb26d96441d9dbfe3b 100644 --- a/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php @@ -9,6 +9,7 @@ use Drupal\views\ViewExecutable; use Drupal\views\Views; use Drupal\views\Entity\View; +use Drupal\views\Plugin\views\filter\FilterPluginBase; /** * Tests exposed forms functionality. @@ -161,6 +162,37 @@ public function testExposedIdentifier() { 'page_1' => ['This identifier has illegal characters.'], ]; $this->assertEquals($expected, $errors); + + foreach (FilterPluginBase::RESTRICTED_IDENTIFIERS as $restricted_identifier) { + $view = Views::getView('test_exposed_form_buttons'); + $view->setDisplay(); + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'type' => [ + 'exposed' => TRUE, + 'field' => 'type', + 'id' => 'type', + 'table' => 'node_field_data', + 'plugin_id' => 'in_operator', + 'entity_type' => 'node', + 'entity_field' => 'type', + 'expose' => [ + 'identifier' => $restricted_identifier, + 'label' => 'Content: Type', + 'operator_id' => 'type_op', + 'reduce' => FALSE, + 'description' => 'Exposed overridden description', + ], + ], + ]); + $this->executeView($view); + + $errors = $view->validate(); + $expected = [ + 'default' => ['This identifier is not allowed.'], + 'page_1' => ['This identifier is not allowed.'], + ]; + $this->assertEquals($expected, $errors); + } } /**