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     * Fields that the EDS API will always filter multiple values using OR, not AND.
52     *
53     * @var array
54     */
55    protected $forcedOrFields = [
56        'ContentProvider',
57        'SourceType',
58    ];
59
60    /**
61     * Settings for the date facet only
62     *
63     * @var array
64     */
65    protected $dateFacetSettings = [];
66
67    /**
68     * Additional filters to display as side facets
69     *
70     * @var array
71     */
72    protected $extraFilterList = [];
73
74    /**
75     * Config sections to search for facet labels if no override configuration
76     * is set.
77     *
78     * @var array
79     */
80    protected $defaultFacetLabelSections
81        = ['FacetsTop', 'Facets'];
82
83    /**
84     * Config sections to search for checkbox facet labels if no override
85     * configuration is set.
86     *
87     * @var array
88     */
89    protected $defaultFacetLabelCheckboxSections = ['CheckboxFacets'];
90
91    /**
92     * Facet settings
93     *
94     * @var array
95     */
96    protected $fullFacetSettings = [];
97
98    /**
99     * A flag indicating whether limiters and expanders have been added to the
100     * checkbox facets. Used to defer adding them (and accessing the API) until
101     * necessary.
102     *
103     * @var bool
104     */
105    protected $checkboxFacetsAugmented = false;
106
107    /**
108     * Default query adapter class (override to use EDS version)
109     *
110     * @var string
111     */
112    protected $queryAdapterClass = QueryAdapter::class;
113
114    /**
115     * Constructor
116     *
117     * @param \VuFind\Search\Base\Options  $options      Options to use
118     * @param \VuFind\Config\PluginManager $configLoader Config loader
119     */
120    public function __construct($options, \VuFind\Config\PluginManager $configLoader)
121    {
122        parent::__construct($options, $configLoader);
123    }
124
125    /**
126     * Pull the search parameters
127     *
128     * @param \Laminas\Stdlib\Parameters $request Parameter object representing user
129     * request.
130     *
131     * @return void
132     */
133    public function initFromRequest($request)
134    {
135        parent::initFromRequest($request);
136
137        //make sure that the searchmode parameter is set
138        $searchmode = $request->get('searchmode');
139        if (isset($searchmode)) {
140            $this->getOptions()->setSearchMode($searchmode);
141        } else {
142            //get default search mode and set as a hidden filter
143            $defaultSearchMode = $this->getOptions()->getDefaultMode();
144            $this->getOptions()->setSearchMode($defaultSearchMode);
145        }
146    }
147
148    /**
149     * Create search backend parameters for advanced features.
150     *
151     * @return ParamBag
152     */
153    public function getBackendParameters()
154    {
155        $backendParams = new ParamBag();
156
157        $options = $this->getOptions();
158
159        // The "relevance" sort option is a VuFind reserved word; we need to make
160        // this null in order to achieve the desired effect with EDS:
161        $sort = $this->getSort();
162        $finalSort = ($sort == 'relevance') ? null : $sort;
163        $backendParams->set('sort', $finalSort);
164
165        if ($options->highlightEnabled()) {
166            $backendParams->set('highlight', true);
167        }
168
169        $view = $this->getEdsView();
170        $backendParams->set('view', $view);
171
172        $mode = $options->getSearchMode();
173        if (isset($mode)) {
174            $backendParams->set('searchMode', $mode);
175        }
176
177        $this->createBackendFilterParameters($backendParams);
178
179        return $backendParams;
180    }
181
182    /**
183     * Return the value for which search view we use
184     *
185     * @return string
186     */
187    public function getEdsView()
188    {
189        $viewArr = explode('|', $this->view ?? '');
190        return (1 < count($viewArr)) ? $viewArr[1] : $this->options->getEdsView();
191    }
192
193    /**
194     * Add a field to facet on.
195     *
196     * @param string $newField Field name
197     * @param string $newAlias Optional on-screen display label
198     * @param bool   $ored     Should we treat this as an ORed facet?
199     *
200     * @return void
201     */
202    public function addFacet($newField, $newAlias = null, $ored = false)
203    {
204        // Save the full field name (which may include extra parameters);
205        // we'll need these to do the proper search using the EDS class:
206        if (strstr($newField, 'PublicationDate')) {
207            // Special case -- we don't need to send this to the EDS API,
208            // but we do need to set a flag so VuFind knows to display the
209            // date facet control.
210            $this->dateFacetSettings[] = 'PublicationDate';
211        } else {
212            $this->fullFacetSettings[] = $newField;
213        }
214
215        // Field name may have parameters attached -- remove them:
216        $parts = explode(',', $newField);
217        parent::addFacet($parts[0], $newAlias, $ored);
218    }
219
220    /**
221     * Get the full facet settings stored by addFacet -- these may include extra
222     * parameters needed by the search results class.
223     *
224     * @return array
225     */
226    public function getFullFacetSettings()
227    {
228        return $this->fullFacetSettings;
229    }
230
231    /**
232     * Get a user-friendly string to describe the provided facet field.
233     *
234     * @param string $field   Facet field name.
235     * @param string $value   Facet value.
236     * @param string $default Default field name (null for default behavior).
237     *
238     * @return string         Human-readable description of field.
239     */
240    public function getFacetLabel($field, $value = null, $default = null)
241    {
242        // Also store Limiter/Search Mode IDs/Values in the config file
243        if (str_starts_with($field, 'LIMIT|')) {
244            $facetId = substr($field, 6);
245        } elseif (str_starts_with($field, 'SEARCHMODE|')) {
246            $facetId = substr($field, 11);
247        } else {
248            $facetId = $field;
249        }
250        return parent::getFacetLabel($facetId, $value, $default ?: $facetId);
251    }
252
253    /**
254     * Get the date facet settings stored by addFacet.
255     *
256     * @return array
257     */
258    public function getDateFacetSettings()
259    {
260        return $this->dateFacetSettings;
261    }
262
263    /**
264     * Populate common limiters as checkbox facets
265     *
266     * @param Options $options Options
267     *
268     * @return void
269     */
270    public function addLimitersAsCheckboxFacets(Options $options)
271    {
272        $ssLimiters = $options->getSearchScreenLimiters();
273        foreach ($ssLimiters as $ssLimiter) {
274            $this->addCheckboxFacet(
275                $ssLimiter['selectedvalue'],
276                $ssLimiter['description'],
277                true
278            );
279        }
280    }
281
282    /**
283     * Populate expanders as checkbox facets
284     *
285     * @param Options $options Options
286     *
287     * @return void
288     */
289    public function addExpandersAsCheckboxFacets(Options $options)
290    {
291        $availableExpanders = $options->getSearchScreenExpanders();
292        foreach ($availableExpanders as $expander) {
293            $this->addCheckboxFacet(
294                $expander['selectedvalue'],
295                $expander['description'],
296                true
297            );
298        }
299    }
300
301    /**
302     * Basic 'getter' for list of available view options.
303     *
304     * @return array
305     */
306    public function getViewList()
307    {
308        $list = [];
309        foreach ($this->getOptions()->getViewOptions() as $key => $value) {
310            $list[$key] = [
311                'desc' => $value,
312                'selected' => ($key == $this->getView() . '|' . $this->getEdsView()),
313            ];
314        }
315        return $list;
316    }
317
318    /**
319     * Override for build a string for onscreen display showing the
320     *   query used in the search. It will include field level operators instead
321     *   of group operators (Since EDS only uses one group.)
322     *
323     * @return string user friendly version of 'query'
324     */
325    public function getDisplayQuery()
326    {
327        // Set up callbacks:
328        $translate = [$this, 'translate'];
329        $showField = [$this->getOptions(), 'getHumanReadableFieldName'];
330
331        // Build display query:
332        return $this->getQueryAdapter()->display($this->getQuery(), $translate, $showField);
333    }
334
335    /**
336     * Return checkbox facets without any processing
337     *
338     * @return array
339     */
340    protected function getRawCheckboxFacets(): array
341    {
342        $this->augmentCheckboxFacets();
343        return parent::getRawCheckboxFacets();
344    }
345
346    /**
347     * Augment checkbox facets with limiters and expanders retrieved from the API
348     * info
349     *
350     * @return void
351     */
352    protected function augmentCheckboxFacets(): void
353    {
354        if (!$this->checkboxFacetsAugmented) {
355            $this->addLimitersAsCheckboxFacets($this->getOptions());
356            $this->addExpandersAsCheckboxFacets($this->getOptions());
357            $this->checkboxFacetsAugmented = true;
358        }
359    }
360}