Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
75.76% covered (warning)
75.76%
50 / 66
42.86% covered (danger)
42.86%
6 / 14
CRAP
0.00% covered (danger)
0.00%
0 / 1
Params
75.76% covered (warning)
75.76%
50 / 66
42.86% covered (danger)
42.86%
6 / 14
37.39
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 initFromRequest
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
2.02
 getBackendParameters
92.86% covered (success)
92.86%
13 / 14
0.00% covered (danger)
0.00%
0 / 1
4.01
 getEdsView
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 addFacet
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
2.03
 getFullFacetSettings
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getFacetLabel
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
4.07
 getDateFacetSettings
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addLimitersAsCheckboxFacets
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 addExpandersAsCheckboxFacets
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getViewList
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 getDisplayQuery
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getRawCheckboxFacets
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 augmentCheckboxFacets
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3/**
4 * EDS API Params
5 *
6 * PHP version 8
7 *
8 * Copyright (C) EBSCO Industries 2013
9 * Copyright (C) The National Library of Finland 2022
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2,
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 *
24 * @category VuFind
25 * @package  EBSCO
26 * @author   Michelle Milton <mmilton@epnet.com>
27 * @author   Ere Maijala <ere.maijala@helsinki.fi>
28 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
29 * @link     https://vufind.org Main Page
30 */
31
32namespace VuFind\Search\EDS;
33
34use VuFindSearch\ParamBag;
35
36use function count;
37
38/**
39 * EDS API Params
40 *
41 * @category VuFind
42 * @package  EBSCO
43 * @author   Michelle Milton <mmilton@epnet.com>
44 * @author   Ere Maijala <ere.maijala@helsinki.fi>
45 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
46 * @link     https://vufind.org Main Page
47 */
48class Params extends AbstractEDSParams
49{
50    /**
51     * Settings for the date facet only
52     *
53     * @var array
54     */
55    protected $dateFacetSettings = [];
56
57    /**
58     * Additional filters to display as side facets
59     *
60     * @var array
61     */
62    protected $extraFilterList = [];
63
64    /**
65     * Config sections to search for facet labels if no override configuration
66     * is set.
67     *
68     * @var array
69     */
70    protected $defaultFacetLabelSections
71        = ['FacetsTop', 'Facets'];
72
73    /**
74     * Config sections to search for checkbox facet labels if no override
75     * configuration is set.
76     *
77     * @var array
78     */
79    protected $defaultFacetLabelCheckboxSections = ['CheckboxFacets'];
80
81    /**
82     * Facet settings
83     *
84     * @var array
85     */
86    protected $fullFacetSettings = [];
87
88    /**
89     * A flag indicating whether limiters and expanders have been added to the
90     * checkbox facets. Used to defer adding them (and accessing the API) until
91     * necessary.
92     *
93     * @var bool
94     */
95    protected $checkboxFacetsAugmented = false;
96
97    /**
98     * Default query adapter class (override to use EDS version)
99     *
100     * @var string
101     */
102    protected $queryAdapterClass = QueryAdapter::class;
103
104    /**
105     * Constructor
106     *
107     * @param \VuFind\Search\Base\Options  $options      Options to use
108     * @param \VuFind\Config\PluginManager $configLoader Config loader
109     */
110    public function __construct($options, \VuFind\Config\PluginManager $configLoader)
111    {
112        parent::__construct($options, $configLoader);
113    }
114
115    /**
116     * Pull the search parameters
117     *
118     * @param \Laminas\Stdlib\Parameters $request Parameter object representing user
119     * request.
120     *
121     * @return void
122     */
123    public function initFromRequest($request)
124    {
125        parent::initFromRequest($request);
126
127        //make sure that the searchmode parameter is set
128        $searchmode = $request->get('searchmode');
129        if (isset($searchmode)) {
130            $this->getOptions()->setSearchMode($searchmode);
131        } else {
132            //get default search mode and set as a hidden filter
133            $defaultSearchMode = $this->getOptions()->getDefaultMode();
134            $this->getOptions()->setSearchMode($defaultSearchMode);
135        }
136    }
137
138    /**
139     * Create search backend parameters for advanced features.
140     *
141     * @return ParamBag
142     */
143    public function getBackendParameters()
144    {
145        $backendParams = new ParamBag();
146
147        $options = $this->getOptions();
148
149        // The "relevance" sort option is a VuFind reserved word; we need to make
150        // this null in order to achieve the desired effect with EDS:
151        $sort = $this->getSort();
152        $finalSort = ($sort == 'relevance') ? null : $sort;
153        $backendParams->set('sort', $finalSort);
154
155        if ($options->highlightEnabled()) {
156            $backendParams->set('highlight', true);
157        }
158
159        $view = $this->getEdsView();
160        $backendParams->set('view', $view);
161
162        $mode = $options->getSearchMode();
163        if (isset($mode)) {
164            $backendParams->set('searchMode', $mode);
165        }
166
167        $this->createBackendFilterParameters($backendParams);
168
169        return $backendParams;
170    }
171
172    /**
173     * Return the value for which search view we use
174     *
175     * @return string
176     */
177    public function getEdsView()
178    {
179        $viewArr = explode('|', $this->view ?? '');
180        return (1 < count($viewArr)) ? $viewArr[1] : $this->options->getEdsView();
181    }
182
183    /**
184     * Add a field to facet on.
185     *
186     * @param string $newField Field name
187     * @param string $newAlias Optional on-screen display label
188     * @param bool   $ored     Should we treat this as an ORed facet?
189     *
190     * @return void
191     */
192    public function addFacet($newField, $newAlias = null, $ored = false)
193    {
194        // Save the full field name (which may include extra parameters);
195        // we'll need these to do the proper search using the EDS class:
196        if (strstr($newField, 'PublicationDate')) {
197            // Special case -- we don't need to send this to the EDS API,
198            // but we do need to set a flag so VuFind knows to display the
199            // date facet control.
200            $this->dateFacetSettings[] = 'PublicationDate';
201        } else {
202            $this->fullFacetSettings[] = $newField;
203        }
204
205        // Field name may have parameters attached -- remove them:
206        $parts = explode(',', $newField);
207        parent::addFacet($parts[0], $newAlias, $ored);
208    }
209
210    /**
211     * Get the full facet settings stored by addFacet -- these may include extra
212     * parameters needed by the search results class.
213     *
214     * @return array
215     */
216    public function getFullFacetSettings()
217    {
218        return $this->fullFacetSettings;
219    }
220
221    /**
222     * Get a user-friendly string to describe the provided facet field.
223     *
224     * @param string $field   Facet field name.
225     * @param string $value   Facet value.
226     * @param string $default Default field name (null for default behavior).
227     *
228     * @return string         Human-readable description of field.
229     */
230    public function getFacetLabel($field, $value = null, $default = null)
231    {
232        // Also store Limiter/Search Mode IDs/Values in the config file
233        if (str_starts_with($field, 'LIMIT|')) {
234            $facetId = substr($field, 6);
235        } elseif (str_starts_with($field, 'SEARCHMODE|')) {
236            $facetId = substr($field, 11);
237        } else {
238            $facetId = $field;
239        }
240        return parent::getFacetLabel($facetId, $value, $default ?: $facetId);
241    }
242
243    /**
244     * Get the date facet settings stored by addFacet.
245     *
246     * @return array
247     */
248    public function getDateFacetSettings()
249    {
250        return $this->dateFacetSettings;
251    }
252
253    /**
254     * Populate common limiters as checkbox facets
255     *
256     * @param Options $options Options
257     *
258     * @return void
259     */
260    public function addLimitersAsCheckboxFacets(Options $options)
261    {
262        $ssLimiters = $options->getSearchScreenLimiters();
263        foreach ($ssLimiters as $ssLimiter) {
264            $this->addCheckboxFacet(
265                $ssLimiter['selectedvalue'],
266                $ssLimiter['description'],
267                true
268            );
269        }
270    }
271
272    /**
273     * Populate expanders as checkbox facets
274     *
275     * @param Options $options Options
276     *
277     * @return void
278     */
279    public function addExpandersAsCheckboxFacets(Options $options)
280    {
281        $availableExpanders = $options->getSearchScreenExpanders();
282        foreach ($availableExpanders as $expander) {
283            $this->addCheckboxFacet(
284                $expander['selectedvalue'],
285                $expander['description'],
286                true
287            );
288        }
289    }
290
291    /**
292     * Basic 'getter' for list of available view options.
293     *
294     * @return array
295     */
296    public function getViewList()
297    {
298        $list = [];
299        foreach ($this->getOptions()->getViewOptions() as $key => $value) {
300            $list[$key] = [
301                'desc' => $value,
302                'selected' => ($key == $this->getView() . '|' . $this->getEdsView()),
303            ];
304        }
305        return $list;
306    }
307
308    /**
309     * Override for build a string for onscreen display showing the
310     *   query used in the search. It will include field level operators instead
311     *   of group operators (Since EDS only uses one group.)
312     *
313     * @return string user friendly version of 'query'
314     */
315    public function getDisplayQuery()
316    {
317        // Set up callbacks:
318        $translate = [$this, 'translate'];
319        $showField = [$this->getOptions(), 'getHumanReadableFieldName'];
320
321        // Build display query:
322        return $this->getQueryAdapter()->display($this->getQuery(), $translate, $showField);
323    }
324
325    /**
326     * Return checkbox facets without any processing
327     *
328     * @return array
329     */
330    protected function getRawCheckboxFacets(): array
331    {
332        $this->augmentCheckboxFacets();
333        return parent::getRawCheckboxFacets();
334    }
335
336    /**
337     * Augment checkbox facets with limiters and expanders retrieved from the API
338     * info
339     *
340     * @return void
341     */
342    protected function augmentCheckboxFacets(): void
343    {
344        if (!$this->checkboxFacetsAugmented) {
345            $this->addLimitersAsCheckboxFacets($this->getOptions());
346            $this->addExpandersAsCheckboxFacets($this->getOptions());
347            $this->checkboxFacetsAugmented = true;
348        }
349    }
350}