Followup from #2576927: Grouped exposed taxonomy filter fails validation for autocomplete widget.

To reproduce:

  1. Navigate to admin/structure/views/view/frontpage
  2. Add the node type filter and expose it
  3. (Workaround known bug by clicking Cancel when you are returned to the "Add filter criteria" modal, then clicking the newly added filter to edit it and clicking the expose option again)
  4. Click the "Grouped filters" option
  5. For "Grouping 1" "label" enter "test" and tick "Article" for the "value"
  6. Click "Apply (all displays)"

Result:

Comments

mikeker created an issue. See original summary.

mikeker’s picture

Status: Active » Needs review
Issue tags: +Needs tests
StatusFileSize
new5.62 KB

First stab at fixing the wording and getting the validation right. (Now also raises an error if you set a value but do not have a title/label).

Needs tests...

mikeker’s picture

Title: Grouped filter form fails to validate with less than three group options » Improve grouped filter form and fix validation problems

Status: Needs review » Needs work

The last submitted patch, 2: 2633678-grouped-filter-validation.patch, failed testing.

geertvd’s picture

Status: Needs work » Needs review
StatusFileSize
new3.53 KB
new6.26 KB
  1. +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
    @@ -660,20 +660,35 @@ protected function buildGroupValidate($form, FormStateInterface $form_state) {
    +            assert(is_array($group['value']));
    

    We can't really assume the value is always going to be an array.

  2. +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
    @@ -660,20 +660,35 @@ protected function buildGroupValidate($form, FormStateInterface $form_state) {
    +          else {
    +            if (trim($group['value']) == '') {
    +              if ($group['title'] != '' ) {
    +                $form_state->setError($form['group_info']['group_items'][$id]['value'], $this->t('A value is required if the label for this item is defined.'));
    +              }
                 }
    +            else {
    +              $has_value = TRUE;
    +            }
    +          }
    

    By doing this, operations that don't require a value (like isEmpty) also get an error.

Fixed those issues but that caused a lot of reverts from the initial patch, didn't add any additional tests yet. Let's see if this already fixes the broken tests.

Status: Needs review » Needs work

The last submitted patch, 5: 2633678-5.patch, failed testing.

mikeker’s picture

StatusFileSize
new13.03 KB

OK, this was a bit more complicated a fix than I first thought. Starting with a tests-only patch.

mikeker’s picture

Status: Needs work » Needs review

@geertvd, Thank you for the review!

Sorry, I hadn't refreshed this page all weekend as I was working on it in bits and pieces when I had free time. I didn't see your earlier review and patch. Regardless, it looks like we were heading in the same directions with regards to handling the validation for things like "is empty" filters. I'll review your changes tomorrow and merge with mine if there are any differences. In the meantime, let me know if you think these test changes cover what's needed for basic grouped filter validation.

Status: Needs review » Needs work

The last submitted patch, 7: 2633678-tests.patch, failed testing.

mikeker’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new16.36 KB
new17.93 KB

The attached patch takes a very similar approach to what @geertvd was doing in #5 in terms of covering the empty/not-empty operator. As I mentioned in #8, I hadn't seen the earlier work when I started mine, thus the interdiff is a little messy. Sorry about that.

Would love to hear from a VDC maintainer if there are other operator types that we should include in testing/validation.

lendude’s picture

+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -658,21 +658,26 @@ protected function buildGroupValidate($form, FormStateInterface $form_state) {
-                (is_array($group['value']) && count(array_filter($group['value'], 'static::arrayFilterZero')) == 0)) {
...
-              (is_array($group['value']) && count(array_filter($group['value'], 'static::arrayFilterZero')) > 0)) {

this removes the only uses of

protected static function arrayFilterZero($var) {
    return trim($var) != '';
  }

should that method not be removed as well? Or be marked deprecated?

The fact that that method exists though, makes me think that at some point there were value arrays with 0 being a valid value. Only thing I can thing of would be a boolean filter, but that currently uses a text filter #2469553: Views filtering on boolean fields doesn't use right formatter, so even that doesn't apply.
But thats the only thing I can think of that would fail with this fix, an array where 0 is a valid value.

+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -658,21 +658,26 @@ protected function buildGroupValidate($form, FormStateInterface $form_state) {
+            if ($group['title'] == '' && $has_valid_value) {

using !empty() and empty() instead of all the =='' would make this easier to read, but that might just be me (or mean that I should really go to bed).

Manually tested this for the node type filter and fixes the issue there. Looks great otherwise.

geertvd’s picture

+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -1450,19 +1449,6 @@ public function canGroup() {
   /**
-   * Filter by no empty values, though allow to use "0".
-   *
-   * @param string $var
-   *   The variable to evaluate.
-   *
-   * @return bool
-   *   TRUE if the value is equal to an empty string, FALSE otherwise.
-   */
-  protected static function arrayFilterZero($var) {
-    return trim($var) != '';
-  }

I also think this method should be removed, it doesn't seem to be used anywhere else, the @return comment is also a bit confusing.

mikeker’s picture

From #11:

using !empty() and empty() instead of all the =='' would make this easier to read, but that might just be me

I avoided empty() only because a title could be (string) "0". I can't imagine why anyone would want to do that, but figured it was better safe than sorry... :)

From #11 and #12:

I also think this method should be removed, it doesn't seem to be used anywhere else, the @return comment is also a bit confusing.

I agree. I wasn't able to find a need for it in my manual testing. And in @geertvd's earlier patch it was removed. Sorry, fixed in this version.

mikeker’s picture

and the files...

lendude’s picture

+++ b/core/modules/views_ui/src/Tests/ExposedFormUITest.php
@@ -81,6 +95,57 @@ function testExposedAdminUi() {
+
+    // Test adding a new exposed sort criteria.
...
+    // Change the order and expose the sort.

Hmm, why are we testing setting sort criteria? Am I missing something?

mikeker’s picture

Thanks for the review, @Lendude!

Hmm, why are we testing setting sort criteria? Am I missing something?

Those tests were there originally, just moved around in this patch. I would also argue that it's within the scope of this test to verify the exposed sort options since this file is supposed to be testing the exposed form UI.

lendude’s picture

Status: Needs review » Needs work

@mikeker ah yeah missed all the - at the end there! Is all the rearranging necessary in the test file? Makes the patch much harder to read (and could be seen as unrelated changes).

+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -658,21 +658,26 @@ protected function buildGroupValidate($form, FormStateInterface $form_state) {
+              $form_state->setError($form['group_info']['group_items'][$id]['title'], $this->t('A label is required if the specified operator.'));

+++ b/core/modules/views_ui/src/Tests/ExposedFormUITest.php
@@ -33,6 +42,11 @@ protected function setUp() {
+    $this->groupFormUiErrors['missing_title_empty_operator'] = t('A label is required if the specified operator.');

the text seems to miss something at the end... is used/ is set, or change if to for?

lendude’s picture

Oh and just manually tested the empty/not empty handling of the grouped date filter and that doesn't work. So maybe that needs the special handling as well?

mikeker’s picture

Assigned: Unassigned » mikeker

@Lendude, you're right, date filters still don't work -- working on a fix.

re: moving tests around: It does make the patch harder to read, but the former state -- with all the tests in one, long method wasn't any good either. Considering this patch is adding a bunch of tests, I figured creating new methods for those tests was within the scope of this fix. At that point, it didn't make sense for some of the grouped filter tests to be in one place while others were in the new methods.

the text seems to miss something at the end... is used/ is set, or change if to for?

Gah... Thanks for catching that! ("if" should have been "for"). Will fix in the next patch.

mikeker’s picture

Status: Needs work » Needs review
StatusFileSize
new11.45 KB
new22.48 KB

The "is empty" date filter error has been opened as a followup to this issue: #2637854: Grouped date filter results in undefined index notice. There seems to be bigger problems with that so I'm moving that out of this issue in hopes that we can bring this to a close and work on the date filter separately.

This patch introduces a hasValidGroupedValue() method to FilterPluginBase. The occasional oddball filter (like datetime) can override this with specifics for their situation (in datetime's case, adding the date/offset radio button element to the value option.

It occurs to me that this could be useful outside of the grouped filter context and perhaps should be named hasValidValue instead. Thoughts?

Also this patch returns arrayFilterZero() to FilterPluginBase, but fixes it so that it functions correctly. It is needed for the case where the string "0" is entered as the value of a filter. Also adds tests for this.

The last submitted patch, 20: 2633678-14-20.interdiff.patch, failed testing.

lendude’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
    @@ -636,6 +636,39 @@ public function validateExposeForm($form, FormStateInterface $form_state) {
    +   * @param $group
    

    missing type hint

  2. +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
    @@ -636,6 +636,39 @@ public function validateExposeForm($form, FormStateInterface $form_state) {
    +   * Determines if the given group filter has a valid value.
    

    it tests a grouped filter group I'd say.

  3. +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
    @@ -655,26 +688,21 @@ protected function buildGroupValidate($form, FormStateInterface $form_state) {
    +            if ($operators[$group['operator']]['values'] == 0) {
    

    this could use some explaining

  4. +++ b/core/modules/views_ui/src/Tests/ExposedFormUITest.php
    @@ -81,6 +98,57 @@ function testExposedAdminUi() {
    +    // Check the label of the grouped exposed button
    

    missing period at the end.

  5. +++ b/core/modules/views_ui/src/Tests/ExposedFormUITest.php
    @@ -96,82 +164,96 @@ function testExposedAdminUi() {
    +  public function disabledtestGroupedFilterAdminUiErrors() {
    

    disabledtest?

Looking good! hasValidGroupedValue() is a good addition I feel. I'd say not make it more general for now, this is getting big enough as it is.

mikeker’s picture

Status: Needs work » Needs review
StatusFileSize
new4 KB
new22.27 KB

@Lendude, thanks for the review!

#1: Fixed
#2: Updated to "Determines if the given grouped filter entry has a valid value."
#3: There is a comment inside the conditional, but it was poorly worded. Fixed along with another in that block that will hopefully explain things better. Also moved the final return FALSE to the end of the method capture the odd case where $group['value'] is something other than a string or an array.
#4: Fixed.
#5: Yeah, naming things disabledtest is a great way to ensure those tests don't fail! :) Grr... leftover from when I was debugging and wanted the simpletests to run faster. Fixed.

mikeker’s picture

Added @Lendude to the commit credit. Nevermind, it looks like I can't do that on core issues...

lendude’s picture

Status: Needs review » Reviewed & tested by the community

@mikeker but thanks for trying.

Manually tested it again with the node type filter, patch does its job. Not sure if the addition of hasValidGroupedValue() is considered a API change. Since it doesn't change anything just gives you an extra option to do something more efficient (and the old method still works as always), I don't think so, but not sure.

But this now looks good to me.

dunebl’s picture

Do you think we can have this patch available for Drupal 7

mikeker’s picture

Issue tags: +Needs backport to D7

@DuneBL, I don't see why not. But it has to go into D8 first and then can be backported. Any additional manual testing on D8 would be helpful to ensure this doesn't introduce regressions.

alexpott’s picture

Version: 8.0.x-dev » 8.1.x-dev
Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/views/src/Plugin/views/filter/Date.php
    @@ -103,32 +103,23 @@ public function validateValidTime(&$form, FormStateInterface $form_state, $opera
    -  protected function buildGroupValidate($form, FormStateInterface $form_state) {
    ...
    +  protected function hasValidGroupedValue(array $group) {
    

    I think given how this is fixed I think we need a CR and this can only really be fixed in 8.1.x - any contrib/custom filters might need to make similar changes - no? It might be good to get the "should not be an error" part displayed in the issue summary fixed in 8.0.x though...

  2. +++ b/core/modules/views_ui/src/Tests/ExposedFormUITest.php
    @@ -96,82 +164,96 @@ function testExposedAdminUi() {
    +
    +  protected function assertNoGroupedFilterErrors($message = '', $group = 'Other') {
    

    Missing docblock and assert* functions should return a boolean.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dagmar’s picture

Status: Needs work » Needs review
StatusFileSize
new22.81 KB
new1.68 KB

Re-rolled. Fixed coding standards.

Status: Needs review » Needs work

The last submitted patch, 30: 2633678-30-grouped-filter-validation.patch, failed testing.

dagmar’s picture

Status: Needs work » Needs review
StatusFileSize
new1.49 KB
new22.54 KB

During the re-roll I placed arrayFilterZero() in the wrong file.

mikeker’s picture

Itty-bitty code standards fix.

And thank you for the review, @alexpott, and the re-roll, @dagmar. Sorry I let this fall off my radar.

dagmar’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC since #28 has been addressed.

I also tested this on simplytest.me and can confirm is working as expected.

mikeker’s picture

re: #28

I added a CR (https://www.drupal.org/node/2712513, unpublished) as requested.

this can only really be fixed in 8.1.x - any contrib/custom filters might need to make similar changes - no? It might be good to get the "should not be an error" part displayed in the issue summary fixed in 8.0.x though...

Contrib/custom filters will need to make a similar change only if their value is more complicated or holds multiple items (eg: date filters). It's a minor enough issue with a workaround so I feel fine putting it into 8.2.x without splitting the error portion into a separate patch.

dawehner’s picture

+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -618,6 +618,38 @@ public function validateExposeForm($form, FormStateInterface $form_state) {
+        $actual_values = count(array_filter($group['value'], 'static::arrayFilterZero'));

Oh, I wasn't aware that this is actually possible, nice!

I really like the new named function, it just makes it easier to ready.
+1 for the changes in general

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 33: 2633678-grouped-filter-validation.patch, failed testing.

mikeker’s picture

Assigned: mikeker » Unassigned
Status: Needs work » Needs review

Applies fine on 8.2.x for me... Try again, testbot!

Status: Needs review » Needs work

The last submitted patch, 33: 2633678-grouped-filter-validation.patch, failed testing.

lendude’s picture

Status: Needs work » Needs review
StatusFileSize
new22.54 KB

@mikeker no really didn't apply anymore. Reroll.

mikeker’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, @Lendude! My bad, I must've done a merge instead of applying the patch directly...

Back to RTBC as per #34 in hopes of getting this in during DrupalCon. (@Lendude, you here in NOLA? If so, ping me.)

lendude’s picture

@mikeker nope, not in NOLA unfortunately.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 40: 2633678-grouped-filter-validation_40.patch, failed testing.

mikeker’s picture

Status: Needs work » Needs review

The error in the Migration test is unrelated. Retesting.

lendude’s picture

Status: Needs review » Reviewed & tested by the community

Fails were unrelated, so back to RTBC per #34 and #41

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 40: 2633678-grouped-filter-validation_40.patch, failed testing.

lendude’s picture

Status: Needs work » Reviewed & tested by the community

Testbot hiccup, back to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 40: 2633678-grouped-filter-validation_40.patch, failed testing.

lendude’s picture

Status: Needs work » Reviewed & tested by the community

Unrelated fails, back to RTBC

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 3bf487f and pushed to 8.2.x. Thanks!

Only committed to 8.2.x because of the addition of a method to the plugin base class.

  • alexpott committed 3bf487f on 8.2.x
    Issue #2633678 by mikeker, dagmar, geertvd, Lendude: Improve grouped...
alexpott’s picture

FILE: .../core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 1550 | ERROR | [x] The closing brace for the class must have an
      |       |     empty line before it
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

Fixed that on commit.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.