Summary

If there is an exposed image field with an exposed operator, the NULL and NOT NULL operators do not work correctly. Both options return all results. This bug was not present in Views 3.22.

Steps to reproduce

  1. Start a new instance on simplytest.me with Views 3.23 installed.
  2. Create an article with an image
  3. Create an article without an image
  4. Enable Views UI module
  5. Create a view with an exposed filter on the image fid, exposing the operator
  6. Use the exposed view form to select the NULL and NOT NULL operators
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

pianomansam created an issue. See original summary.

pianomansam’s picture

Issue summary: View changes

Here is a gist of the exported view I created in the steps to reproduce on simplytest.me

https://gist.github.com/pianomansam/3d2edd7b7aba48f766e6a425ad2cf73d

pianomansam’s picture

Issue summary: View changes

One clue I've discovered is that if you set the value of the exposed filter, it works properly. In the above example, enter a value like "1" and submit it. You'll then have this in the URL:

field_image_fid%5Bvalue%5D=1

Then if you change the operator to NULL or NOT NULL, this value sticks around and the filter works properly.

FeyP’s picture

Thanks for taking the time to file this issue and for providing steps to reproduce and a views export as well. This is indeed a new regression introduced in 7.x-3.23. The last good revision is 0f6e47b1. The first bad revision is 50fe583e, so this regression has been introduced in #477984: CCK field is empty/not empty filter doesn't work when exposed.

Relevant part of the commit that introduced the regression:

      // Various ways to check for the absence of non-required input.
      if (empty($this->options['expose']['required'])) {
-        if (($this->operator == 'empty' || $this->operator == 'not empty') && $value === '') {
-          $value = ' ';
+        if ($this->operator == 'empty' || $this->operator == 'not empty') {
+          $value = is_array($value) ? $value['value'] : $value;
+          $this->operator = ($this->operator == 'empty' && empty($value)) || ($this->operator == 'not empty' && !empty($value)) ? 'not empty' : 'empty';
        }

Previously in the accept_exposed_input() method of the parent filter, the value was reset to a single space, if the operator was either empty or not empty and the value was empty. This code has been removed so the exposed input is rejected as invalid and the filter is not applied.

I guess the problem is, that the commit in question added a boolean filter to the exposed form, which allows users to select between "Yes", "No" and "Any" for either the "empty" or "not empty" operations. Unfortunately, the select is only rendered in the exposed_form() method of the parent filter, if the operator is initially configured to either "empty" or "not empty", but not if the operator is exposed and initially set to another operator like in your example view. Since the numeric filter doesn't provide any value for "empty" or "not empty" itself and the parent handler expects a non empty value (= user selected "Yes", apply operator) or an empty value (= user selected "No", apply opposite of operator) as exposed input and treats anything else as "user selected "Any", skip filter", it doesn't work anymore.

As soon as you set a value, it is not empty and thus treated as "user selected yes, apply operator" and the filter starts to work, so this explains your observation in #03.

Until this is fixed, you should be able to work around this using grouped filters as it seems that they are not affected.

FeyP’s picture

Component: Miscellaneous » exposed filters
Status: Active » Needs review
FileSize
8.48 KB
9.37 KB

Attached is a patch against 7.x-3.x-dev.

I fixed this by forcing a positive value in the accept_exposed_input() method of the filter, if the operator is exposed and the user selected either "empty" or "not empty", so that the parent method will accept the value. A better fix might be to change the exposed_form() method in the parent class to give the user a "Yes", "No", "Any" choice in this case as well, but that would probably require more testing and would also be a little bit more risky, so I didn't implement this for now.

To confirm that the fix works and doesn't break any existing functionality, I implemented tests for all operators when they are exposed. The rest of the exposed filters seem to be covered by the test relatively well. When writing the tests, I noticed that the "not between" operator is inclusive. I didn't expect that and I asked a colleague and she didn't expect it either, but this is probably implemented this way to mimic the inclusiveness of the BETWEEN operator in SQL, so I left it alone. Also, I would have expected the test data with the NULL value to be in the result sets for != value, not between value and value and value does not match not regular expression, but it seems that they are not. Again, I didn't change anything here either.

I think it would really make sense to check whether other filters extending the parent class are also affected by this, but I don't have time to do it right now. Maybe later, we'll see.

The last submitted patch, 5: views-n3057975-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

DamienMcKenna’s picture

@pianomansam: Would you mind testing the patch in #5 to confirm it resolves the problem for you? Thanks.

DamienMcKenna’s picture

pianomansam’s picture

@DamienMcKenna I can confirm patch in #5 works when applied to 7.x-3.23

pianomansam’s picture

Status: Needs review » Reviewed & tested by the community
mfuggle’s picture

I am experiencing this problem but my issue has nothing to do with 'images'.
I am filtering a CivICRM Group and a number of grouped filters. Two of the grouped filters contain a selection 'Is Empty (NULL)'. Selecting this entry in the exposed drop down filter returns all rows of data. The same happens with 'Is Not Empty (NOT NULL)', i.e. all rows are returned.
Regards
Martin Fuggle

FeyP’s picture

I am experiencing this problem but my issue has nothing to do with 'images'.

This issue is in the numeric filter handler. If you are filtering on a field, that uses or extends this type of filter handler, you may be affected by this issue. Does the patch fix it for you?

If the patch doesn't fix your issue, it might be a similar, but ultimately different problem. In that case I suggest you create a new issue with steps to reproduce and attach an export of a view that demonstrates the problem. This might be your original view or, preferably, a reduced test case view. Reference this issue as a related issue and also post a comment about the new issue here, so that we can look into it. Thank you.

luke.stewart’s picture

We've tested the patch from #5 for the problem raised in #11 and our initial findings is that also addresses this case.
> I am filtering a CivICRM Group and a number of grouped filters.

Thanks heaps for your work.

luke.stewart’s picture

Just a further update - looks like this still has some problems we'll do some further testing to try and identify the cause.

pianomansam’s picture

@luke.stewart any update on investigating problems? Otherwise, this patch is still working fine for me.

  • DamienMcKenna committed 56a2a7d on 7.x-3.x authored by FeyP
    Issue #3057975 by FeyP, pianomansam: Broken NULL and NOT NULL operator...
DamienMcKenna’s picture

Status: Reviewed & tested by the community » Fixed

Committed. Thank you.

Status: Fixed » Closed (fixed)

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