From 2f6097898a5c057d11be9b6d55d67af535cf1539 Mon Sep 17 00:00:00 2001 From: Oliver Goldschmidt <o.goldschmidt@tuhh.de> Date: Tue, 21 Apr 2015 09:32:59 -0400 Subject: [PATCH] prepares default filters to work with complex expressions - currently only works for Solr; Summon implementation probably possible with some variation. --- config/vufind/searches.ini | 4 +++ .../VuFind/src/VuFind/Search/Base/Params.php | 26 +++++++++++++++++++ .../VuFind/src/VuFind/Search/Solr/Params.php | 7 +++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/config/vufind/searches.ini b/config/vufind/searches.ini index 9c0922189e3..3b99fce01db 100644 --- a/config/vufind/searches.ini +++ b/config/vufind/searches.ini @@ -77,11 +77,15 @@ retain_filters_by_default = true ; this setting to have no default filters applied. These differ from hidden ; filters because they are visible in the UI and may be removed by the user. ; +; You can use complex filters (for example with boolean operators inside). +; In order to do that, just set the filter into parentheses (as in the third sample line). +; ; NOTE: If you are setting a default filter on a field that is used for OR ; facets (see the orFacets setting in facets.ini), be sure to prefix the field ; name with a tilde (~)... e.g. "~format:Book" ;default_filters[] = "format:Book" ;default_filters[] = "institution:MyInstitution" +;default_filters[] = "(format:Book AND institution:MyInstitution)" [Cache] ; This controls whether the parsed searchspecs.yaml file will be stored to diff --git a/module/VuFind/src/VuFind/Search/Base/Params.php b/module/VuFind/src/VuFind/Search/Base/Params.php index eec7e04b08c..97b7c72cb97 100644 --- a/module/VuFind/src/VuFind/Search/Base/Params.php +++ b/module/VuFind/src/VuFind/Search/Base/Params.php @@ -844,6 +844,13 @@ class Params implements ServiceLocatorAwareInterface */ public function parseFilter($filter) { + // Special case: complex filters cannot be split into field/value + // since they have multiple parts (e.g. field1:a OR field2:b). Use + // a fake "#" field to collect these types of filters. + if ($this->isAdvancedFilter($filter) == true) { + return ['#', $filter]; + } + // Split the string and assign the parts to $field and $value $temp = explode(':', $filter, 2); $field = array_shift($temp); @@ -901,6 +908,25 @@ class Params implements ServiceLocatorAwareInterface } } + /** + * Detects if a filter is advanced (true) or simple (false). An advanced + * filter is currently defined as one surrounded by parentheses, while a + * simple filter is of the form field:value. Advanced filters are used to + * express more complex queries, such as combining multiple values from + * multiple fields using boolean operators. + * + * @param string $filter A filter string + * + * @return bool + */ + public function isAdvancedFilter($filter) + { + if (substr($filter, 0, 1) == '(') { + return true; + } + return false; + } + /** * Remove a filter from the list. * diff --git a/module/VuFind/src/VuFind/Search/Solr/Params.php b/module/VuFind/src/VuFind/Search/Solr/Params.php index 4d586f2ab2e..b85c7950a25 100644 --- a/module/VuFind/src/VuFind/Search/Solr/Params.php +++ b/module/VuFind/src/VuFind/Search/Solr/Params.php @@ -108,10 +108,13 @@ class Params extends \VuFind\Search\Base\Params $field = substr($field, 1); } foreach ($filter as $value) { - // Special case -- allow trailing wildcards and ranges: - if (substr($value, -1) == '*' + // Special case -- complex filter, that should be taken as-is: + if ($field == '#') { + $q = $value; + } else if (substr($value, -1) == '*' || preg_match('/\[[^\]]+\s+TO\s+[^\]]+\]/', $value) ) { + // Special case -- allow trailing wildcards and ranges $q = $field . ':' . $value; } else { $q = $field . ':"' . addcslashes($value, '"\\') . '"'; -- GitLab