Skip to content

Commit

Permalink
[BUGFIX] Make it possible to reset preselected filters
Browse files Browse the repository at this point in the history
With this patch filter options with
one character length are ignored in the filtering. That makes it possible to set one charachter values as a default in the routing configuration while on the other hand reset filters if an empty value is given.
See #124 and #126
  • Loading branch information
christianbltr committed Jan 20, 2023
1 parent dddbfa6 commit add3cb9
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 21 deletions.
44 changes: 28 additions & 16 deletions Classes/Lib/Filters.php
Expand Up @@ -109,30 +109,42 @@ public function getSelectedFilterOptions($filter)
{
$selectedOptions = [];

// run through all the filter options and check if one of them
// has been selected.
// Run through all the filter options and check if one of them has been selected.
// The filter option can be selected in the frontend via piVars
// or in the backend via flexform configuration ("preselected filters").
foreach ($filter['options'] as $option) {
// Is the filter option selected in the frontend via piVars
// or in the backend via flexform configuration ("preselected filters")?
$selected = false;

if (isset($this->pObj->piVars['filter'][$filter['uid']]) && $this->pObj->piVars['filter'][$filter['uid']] == $option['tag']) {
if (
isset($this->pObj->piVars['filter'][$filter['uid']])
&& $this->pObj->piVars['filter'][$filter['uid']] == $option['tag']
) {
// one-dimensional piVar: filter option is set
$selected = true;
} elseif (is_array($this->pObj->piVars['filter'][$filter['uid']] ?? null)) { // if a this filter is set
// test pre selected filter again
if (is_array($this->pObj->preselectedFilter)
&& $this->pObj->in_multiarray($option['tag'], $this->pObj->preselectedFilter)) {
} elseif (is_array($this->pObj->piVars['filter'][$filter['uid']] ?? null)) {
// multi-dimensional piVars
if (
is_array($this->pObj->preselectedFilter)
&& $this->pObj->in_multiarray($option['tag'], $this->pObj->preselectedFilter)
) {
$selected = true;
// add preselected filter to piVars
$this->pObj->piVars['filter'][$filter['uid']][$option['uid']] = $option['tag'];
} else { // else test all other filter
$isInArray = in_array($option['tag'], $this->pObj->piVars['filter'][$filter['uid']]);
if ($isInArray) {
$selected = true;
}
} else {
// already selected via piVars?
$selected = in_array($option['tag'], $this->pObj->piVars['filter'][$filter['uid']]);
}
} elseif (!isset($this->pObj->piVars['filter'][$filter['uid']])) {
if (is_array($this->pObj->preselectedFilter)
// No piVars for this filter are set or the length of the option is one character (dummy placeholder
// for the routing configuration).
} elseif (
!isset($this->pObj->piVars['filter'][$filter['uid']])
|| (
is_string($this->pObj->piVars['filter'][$filter['uid']])
&& strlen($this->pObj->piVars['filter'][$filter['uid']]) === 1
)
) {
if (
is_array($this->pObj->preselectedFilter)
&& $this->pObj->in_multiarray($option['tag'], $this->pObj->preselectedFilter)
) {
$selected = true;
Expand Down
9 changes: 7 additions & 2 deletions Classes/Lib/Searchphrase.php
Expand Up @@ -179,8 +179,12 @@ public function buildPreselectedTagsAgainst(array &$tagsAgainst)
{
$tagChar = $this->pObj->extConf['prePostTagChar'];
foreach ($this->pObj->preselectedFilter as $key => $filterTags) {
// add it only, if no other filter options of this filter has been selected in the frontend
if (!isset($this->pObj->piVars['filter'][$key]) || empty($this->pObj->piVars['filter'][$key])) {
// Add it only, if no other filter options of this filter has been selected in the frontend.
// We ignore values with one character length here (e.g. "-"), those are coming from the routing
// configuration and are necessary for the routing but should be ignored here.
if (!isset($this->pObj->piVars['filter'][$key])
|| (is_string($this->pObj->piVars['filter'][$key]) && strlen($this->pObj->piVars['filter'][$key]) === 1)
) {
if (!isset($tagsAgainst[$key])) {
$tagsAgainst[$key] = '';
}
Expand Down Expand Up @@ -236,6 +240,7 @@ public function buildPiVarsTagsAgainst(array &$tagsAgainst)
// Don't add the tag if it is already inserted by preselected filters
if (
!empty($tag)
&& (strlen($tag) > 1)
&& strstr($tagsAgainst[$key] ?? '', $tag) === false
&& !in_array($key, self::IGNORE_FOR_TAG_BUILDING)
) {
Expand Down
12 changes: 9 additions & 3 deletions Documentation/Configuration/RoutingSpeakingUrls.rst
Expand Up @@ -43,6 +43,12 @@ Notes
or if you have huge amounts of tags and want to improve performance (the `KeSearchTagToSlugMapper` accesses the database
once for each routing parameter on every request).

* For filters of type "select" or "list" you will need to set one character
default value. That will be ignored in the filtering, but that is necessary
to differentiate if the value is coming from the routing configuration or
if the user wants to reset the filter (in that case an empty value is given).
See also https://github.com/tpwd/ke_search/issues/126

Examples
========

Expand Down Expand Up @@ -78,7 +84,7 @@ If additionally a searchword is given, this will result in
resetFilters: '0'
page: '1'
sword: ''
filter_13: ''
filter_13: '-'
requirements:
sortByField: '(score|title|customranking|sortdate)?'
sortByDir: '(asc|desc)?'
Expand Down Expand Up @@ -128,8 +134,8 @@ a "checkbox" filter, therefore each filter option has to be a configured individ
sortByDir: 'desc'
resetFilters: '0'
page: '1'
filter_13: ''
filter_14: ''
filter_13: '-'
filter_14: '-'
filter_3_267: ''
filter_3_273: ''
filter_3_278: ''
Expand Down

0 comments on commit add3cb9

Please sign in to comment.