Problem/Motivation
After Search Api 1.25 upgrade (from 1.24), numeric and date filter values previously set via the Views UI get truncated to the first character of the number/date.
Furthermore, if the newly introduced between/not-between operators are used, they have no effect on the query, even if they appear in the View's UI.
These problem persist in -dev after #3003742: Searching with dates throw error after #1783746 has been committed.
Search API 1.25 introduces the new class SearchApiViewsHandlerFilterNumeric which (in method otion_definition()) ultimately overrides the format of the filter's 'value' option: such option was previously expected to be a string (in views_handler_filter class), but is defined as array in the new class:
...
$options['value'] = array(
'contains' => array(
'value' => array('default' => ''),
'min' => array('default' => ''),
'max' => array('default' => ''),
),
);
...
The issue is further complicated by the fact that - as noted in #3003742: Searching with dates throw error after #1783746 - the value can be also passed as a nested array: I verified that this happens when the value is extracted from a date picker in an exposed filter.
I'll go in more detail in the comments. I mark this issue as major, as it can result in malfunction of views created before 1.25 and in the filter being ignored if the between/not-between operators are used.
Proposed resolution
I think that we need to make sure that the filter's $this->value property is always in the form of the array defined in the options. This needs to be done when initializing the filter and then again when an exposed filter is applied.
In the meantime, all non-exposed date and numeric filters saved before 1.25 need to be recreated via Views' UI. For between/not-between operators, it may be possible to save them as exposed filters with default values and hide the exposed form if needed.
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | search_api-7.x-1.26_fix_export_numbers.patch | 1.33 KB | akozoriz |
| #8 | 3008849-8--numeric_views_filters_value_handling.patch | 4.97 KB | drunken monkey |
Comments
Comment #2
pamattComment #3
pamattIn this discussion, when I use the words "value" or "value of the filter" I mean the actual value to which entity fields are compared when a filter is defined in a view. When I refer to
$this->valueI mean the public property$valueof a views filter handler declared in.../search_api/contrib/search_api_views/includes/handler_filter.inc. I checked all cases with a non-exposed date/numeric filter.I count 6 cases:
In the view's UI a warning is issued:
At line 175 of the same file
$this->valueis parsedAs
$this->valueis a string in this case,$this->value[0]returns the first character of the string.$value['value']is not set at line 189 - hence the warning - and is interpreted, again, as$value[0]. In the UI, the value of the filter is truncated.Nevertheless, the filter is handled correctly by
SearchApiViewsHandlerFilter->query()at line 111 of .../search_api/contrib/search_api_views/includes/handler_filter.inc and the filter is succesfully applied to the view.The UI is handled the same way as the previous case, throws the same warning and shows the filter's value truncated to the first character.
The filter is added to the query by
SearchApiViewsHandlerFilterDate->query()with the code committed after issue #3003742: Searching with dates throw error after #1783746 has been fixed (lines 154 et seq. in .../search_api/contrib/search_api_views/includes/handler_filter_date.inc):but this doesn't correctly take into account the fact that
$this->valuecan come here as a string, so$value = $value[0]truncates the value to its first character. Most of the times this leads to a malfunctioning view: e.g. a filter for date=2018-10-24 gets passed to the query as date=2.As mentioned in #3003742: Searching with dates throw error after #1783746, there are cases in which
$this->value[0]is actually a value of an array (e.g. if the filter is exposed), and the code works fine for that.The code works.
$this->valueisIn this case
SearchApiViewsHandlerFilterNumeric->admin_summary()finds the correct value at line 189 of .../search_api/contrib/search_api_views/includes/handler_filter_numeric.inc. The filter is properly added to the query bySearchApiViewsHandlerFilter->query()at line 111 of .../search_api/contrib/search_api_views/includes/handler_filter.inc at lines 110 seq., but it must be said that this happens sort of by fortune, because i think that the loop:cannot be trusted enough to extract the correct value of the filter.
If the filter is not exposed,
$this->valueis:but
SearchApiViewsHandlerFilterNumeric->query()looks for$this->value[0]['min'], $this->value[0]['max']:and since they are not set in this case, the filter is simply ignored by the subsequent code and the view's results are unaffected by the filter.
No problem here.
$this->valueisand is what both
SearchApiViewsHandlerFilterNumeric->admin_summary()andSearchApiViewsHandlerFilterDate->query()are designed to handle.The behavior is the same as in case number 4.; SearchApiViewsHandlerFilterDate->query() is at work here and the code is slightly different, but it all boils down to the fact that a non-exposed filter is ignored in the query.
Comment #4
pamattComment #5
pamattComment #6
pamattComment #7
pamattIn this patch I propose to add a new protected method to
SearchApiViewsHandlerFilterNumericto make sure that the$valueproperty is a correctly populated array. The method is called by overriding theinit()method of the class and again in thequery()method of both this class and ofSearchApiViewsHandlerFilterDate.Comment #8
drunken monkeyThanks a lot for reporting this, and for your incredibly detailed analysis!
You’re right, we really neglected to take old views into account when making that change. Also, I wasn’t aware
isset($value[0])would beTRUEfor non-empty strings, too – you never stop to learn, I guess.Your proposed solution also looks pretty good. The patch just had a few trailing spaces, plus some coding standards problems. And one or two parts could be expressed more simply, I think – please see/test/review my attached revision!
In any case, again: thanks a lot!
Comment #9
pamattWell, thank you for all the hard work you put in the community! I completely agree with your revised patch #8. I also succesfully tested it against the 6 cases in comment #3.
Thank you again
Comment #11
drunken monkeyAwesome, thanks for reporting back!
Committed.
Thanks again!
Comment #13
amir simantov commentedJust a note: in my case the filters ARE exposed and the bug occurs, as well. Patch fixes the problem. Thanks for fixing and for committing!
Comment #14
akozoriz commentedThere is a problem with exporting Views created before 1.25.
Filters values don't export correctly, actually filter values doesn't export at all.
I've added the path with custom export method to normalize filters export.