diff --git a/config/vufind/searches.ini b/config/vufind/searches.ini index 9c0922189e30b939ac70bb5b766e6a30e8fe5ede..3b99fce01db471b6d8de2eb43ff7e84e0fa38659 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 eec7e04b08c7591e85b3884f04ff141f37bcf806..97b7c72cb97ced8f832b4d10fe11ca56dc449079 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 4d586f2ab2ed925fc2af0d019efb9bf185781d64..b85c7950a2597e4fd79f0a61ea091bd651d90904 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, '"\\') . '"';