From 64de6a69cc241d5a776fe82f692ecfd43e64540f Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Fri, 29 Mar 2024 09:50:18 +0000 Subject: [PATCH] Issue #2825860 by xurizaemon, Matroskeen, dewalt, neclimdul, joseph.olstad, ericgsmith, dpolant, hswong3i, mstrelan, aby v a, Akram Khan, Ratan Priya, robphillips, dpi, ryankavalsky, vetal4ik, jwilson3, jagermonster, Rob230, thomjjames, rajneeshb, Hygglo, CodigoVision, kndr, acbramley, Lendude, smustgrave, ExTexan, alexpott: Notice: Undefined index: value in Drupal\views\Plugin\views\filter\NumericFilter->acceptExposedInput() --- core/.phpstan-baseline.php | 5 - .../src/Functional/Views/FilterDateTest.php | 27 ++-- .../src/Plugin/views/filter/NumericFilter.php | 19 +-- .../Plugin/views/filter/NumericFilterTest.php | 118 ++++++++++++++++++ 4 files changed, 149 insertions(+), 20 deletions(-) create mode 100644 core/modules/views/tests/src/Unit/Plugin/views/filter/NumericFilterTest.php diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 927f28eff42..cd78b0334c9 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -1805,11 +1805,6 @@ $ignoreErrors[] = [ 'count' => 2, 'path' => __DIR__ . '/modules/views/src/Plugin/views/filter/NumericFilter.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Variable \\$value might not be defined\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/modules/views/src/Plugin/views/filter/NumericFilter.php', -]; $ignoreErrors[] = [ 'message' => '#^Variable \\$source might not be defined\\.$#', 'count' => 1, diff --git a/core/modules/datetime/tests/src/Functional/Views/FilterDateTest.php b/core/modules/datetime/tests/src/Functional/Views/FilterDateTest.php index 95d27dc91b1..5d5851fab5a 100644 --- a/core/modules/datetime/tests/src/Functional/Views/FilterDateTest.php +++ b/core/modules/datetime/tests/src/Functional/Views/FilterDateTest.php @@ -124,12 +124,12 @@ class FilterDateTest extends ViewTestBase { * Tests exposed grouped filters. */ public function testExposedGroupedFilters() { - // Expose the empty and not empty operators in a grouped filter. - $this->drupalGet('admin/structure/views/nojs/handler/test_filter_datetime/default/filter/' . $this->fieldName . '_value'); + $filter_identifier = $this->fieldName . '_value'; + $this->drupalGet('admin/structure/views/nojs/handler/test_filter_datetime/default/filter/' . $filter_identifier); $this->submitForm([], 'Expose filter'); $this->submitForm([], 'Grouped filters'); - // Test operators with different amount of expected values. + // Create groups with different amount of expected values. $edit = []; // No values are required. $edit['options[group_info][group_items][1][title]'] = 'empty'; @@ -162,24 +162,37 @@ class FilterDateTest extends ViewTestBase { $this->drupalGet($path); // Filter the Preview by 'empty'. - $this->getSession()->getPage()->findField($this->fieldName . '_value')->selectOption('1'); + $this->getSession()->getPage()->findField($filter_identifier)->selectOption('1'); $this->getSession()->getPage()->pressButton('Apply'); $this->assertIds([4]); // Filter the Preview by 'not empty'. - $this->getSession()->getPage()->findField($this->fieldName . '_value')->selectOption('2'); + $this->getSession()->getPage()->findField($filter_identifier)->selectOption('2'); $this->getSession()->getPage()->pressButton('Apply'); $this->assertIds([1, 2, 3]); // Filter the Preview by 'less than'. - $this->getSession()->getPage()->findField($this->fieldName . '_value')->selectOption('3'); + $this->getSession()->getPage()->findField($filter_identifier)->selectOption('3'); $this->getSession()->getPage()->pressButton('Apply'); $this->assertIds([2, 3]); // Filter the Preview by 'between'. - $this->getSession()->getPage()->findField($this->fieldName . '_value')->selectOption('4'); + $this->getSession()->getPage()->findField($filter_identifier)->selectOption('4'); $this->getSession()->getPage()->pressButton('Apply'); $this->assertIds([2]); + + // Change the identifier for grouped exposed filter. + $this->drupalGet('admin/structure/views/nojs/handler/test_filter_datetime/default/filter/' . $filter_identifier); + $filter_identifier = 'date'; + $edit['options[group_info][identifier]'] = $filter_identifier; + $this->submitForm($edit, 'Apply'); + $this->submitForm([], 'Save'); + + // Filter results again using a new filter identifier. + $this->drupalGet($path); + $this->getSession()->getPage()->findField($filter_identifier)->selectOption('2'); + $this->getSession()->getPage()->pressButton('Apply'); + $this->assertIds([1, 2, 3]); } /** diff --git a/core/modules/views/src/Plugin/views/filter/NumericFilter.php b/core/modules/views/src/Plugin/views/filter/NumericFilter.php index b87fe63dd07..3dabc8a0ec1 100644 --- a/core/modules/views/src/Plugin/views/filter/NumericFilter.php +++ b/core/modules/views/src/Plugin/views/filter/NumericFilter.php @@ -423,15 +423,18 @@ class NumericFilter extends FilterPluginBase implements FilterOperatorsInterface return TRUE; } - // rewrite the input value so that it's in the correct format so that + // Rewrite the input value so that it's in the correct format so that // the parent gets the right data. - if (!empty($this->options['expose']['identifier'])) { - $value = &$input[$this->options['expose']['identifier']]; - if (!is_array($value)) { - $value = [ - 'value' => $value, - ]; - } + $key = $this->isAGroup() ? 'group_info' : 'expose'; + if (empty($this->options[$key]['identifier'])) { + // Invalid identifier configuration. Value can't be resolved. + return FALSE; + } + $value = &$input[$this->options[$key]['identifier']]; + if (!is_array($value)) { + $value = [ + 'value' => $value, + ]; } $rc = parent::acceptExposedInput($input); diff --git a/core/modules/views/tests/src/Unit/Plugin/views/filter/NumericFilterTest.php b/core/modules/views/tests/src/Unit/Plugin/views/filter/NumericFilterTest.php new file mode 100644 index 00000000000..6752f910658 --- /dev/null +++ b/core/modules/views/tests/src/Unit/Plugin/views/filter/NumericFilterTest.php @@ -0,0 +1,118 @@ + $this->randomMachineName(), + ]; + + $plugin = new NumericFilter([], 'numeric', $plugin_definition); + $translation_stub = $this->getStringTranslationStub(); + $plugin->setStringTranslation($translation_stub); + + $view = $this->prophesize(ViewExecutable::class)->reveal(); + $display = $this->prophesize(DisplayPluginBase::class)->reveal(); + $view->display_handler = $display; + $plugin->init($view, $view->display_handler, $options); + + $this->assertSame($expected, $plugin->acceptExposedInput($value)); + } + + /** + * Data provider for testAcceptExposedInput test. + * + * @return array[] + * The test cases. + */ + public function provideAcceptExposedInput(): array { + // [$options, $value, $expected] + return [ + // Not exposed by default. Bypass parsing and return true. + 'defaults' => [[], [], TRUE], + 'exposed but not configured' => [ + [ + 'exposed' => TRUE, + 'expose' => [], + 'group_info' => [], + ], + [], + FALSE, + ], + // Exposed but not grouped. + 'exposed not grouped - missing value' => [ + [ + 'exposed' => TRUE, + 'expose' => ['identifier' => 'test_id'], + ], + [], + TRUE, + ], + 'exposed not grouped - wrong group config' => [ + [ + 'exposed' => TRUE, + 'group_info' => ['identifier' => 'test_id'], + ], + ['test_id' => ['value' => 1]], + // Wrong identifier configured. + FALSE, + ], + 'exposed not grouped' => [ + [ + 'exposed' => TRUE, + 'expose' => ['identifier' => 'test_id'], + ], + ['test_id' => ['value' => 1]], + TRUE, + ], + // Exposed and grouped. + 'exposed grouped - missing value' => [ + [ + 'exposed' => TRUE, + 'is_grouped' => TRUE, + 'group_info' => ['identifier' => 'test_id'], + ], + [], + TRUE, + ], + 'exposed grouped - wrong group config' => [ + [ + 'exposed' => TRUE, + 'is_grouped' => TRUE, + 'expose' => ['identifier' => 'test_id'], + ], + ['test_id' => ['value' => 1]], + FALSE, + ], + 'exposed grouped' => [ + [ + 'exposed' => TRUE, + 'is_grouped' => TRUE, + 'group_info' => ['identifier' => 'test_id'], + ], + ['test_id' => ['value' => 1]], + TRUE, + ], + ]; + } + +}