Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
EdsController
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 9
930
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 resultScrollerActive
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 advancedAction
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 searchAction
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAdvancedFacets
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 processAdvancedFacets
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
72
 processAdvancedExpanders
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 processPublicationDateRange
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
56
 processAdvancedSearchModes
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3/**
4 * Eds Controller
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Villanova University 2010.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 * @category VuFind
24 * @package  Controller
25 * @author   Demian Katz <demian.katz@villanova.edu>
26 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org Main Site
28 */
29
30namespace VuFind\Controller;
31
32use Laminas\ServiceManager\ServiceLocatorInterface;
33use VuFind\Solr\Utils as SolrUtils;
34
35use function in_array;
36
37/**
38 * EDS Controller
39 *
40 * @category VuFind
41 * @package  Controller
42 * @author   Demian Katz <demian.katz@villanova.edu>
43 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
44 * @link     https://vufind.org Main Site
45 */
46class EdsController extends AbstractSearch
47{
48    /**
49     * Constructor
50     *
51     * @param ServiceLocatorInterface $sm Service locator
52     */
53    public function __construct(ServiceLocatorInterface $sm)
54    {
55        $this->searchClassId = 'EDS';
56        parent::__construct($sm);
57    }
58
59    /**
60     * Is the result scroller active?
61     *
62     * @return bool
63     */
64    protected function resultScrollerActive()
65    {
66        $config = $this->serviceLocator->get(\VuFind\Config\PluginManager::class)
67            ->get('EDS');
68        return $config->Record->next_prev_navigation ?? false;
69    }
70
71    /**
72     * Handle an advanced search
73     *
74     * @return mixed
75     */
76    public function advancedAction()
77    {
78        // Standard setup from base class:
79        $view = parent::advancedAction();
80        // Set up facet information:
81        $view->limiterList = $this->processAdvancedFacets(
82            $this->getAdvancedFacets(),
83            $view->saved
84        );
85        $view->expanderList = $this->processAdvancedExpanders($view->saved);
86        $view->searchModes = $this->processAdvancedSearchModes($view->saved);
87        $view->dateRangeLimit = $this->processPublicationDateRange($view->saved);
88        return $view;
89    }
90
91    /**
92     * Search action -- call standard results action
93     *
94     * @return mixed
95     */
96    public function searchAction()
97    {
98        return $this->resultsAction();
99    }
100
101    /**
102     * Return a Search Results object containing advanced facet information. This
103     * data may come from the cache.
104     *
105     * @return array
106     */
107    protected function getAdvancedFacets()
108    {
109        // VuFind facets are what the EDS API calls limiters. Available limiters
110        // are returned with a call to the EDS API Info method and are cached.
111        // Since they are obtained from a separate call, there is no need to call
112        // search.
113
114        // Check if we have facet results stored in session. Build them if we don't.
115        // pull them from the session cache
116        $results = $this->getResultsManager()->get('EDS');
117        $params = $results->getParams();
118        $options = $params->getOptions();
119        return $options->getAdvancedLimiters();
120    }
121
122    /**
123     * Process the facets to be used as limits on the Advanced Search screen.
124     *
125     * @param array  $facetList    The advanced facet values
126     * @param object $searchObject Saved search object (false if none)
127     *
128     * @return array               Sorted facets, with selected values flagged.
129     */
130    protected function processAdvancedFacets($facetList, $searchObject = false)
131    {
132        // Process the facets, assuming they came back
133        foreach ($facetList as $facet => $list) {
134            if (isset($list['LimiterValues'])) {
135                foreach ($list['LimiterValues'] as $key => $value) {
136                    // Build the filter string for the URL:
137                    $fullFilter = $facet . ':' . $value['Value'];
138
139                    // If we haven't already found a selected facet and the current
140                    // facet has been applied to the search, we should store it as
141                    // the selected facet for the current control. Cover AND and OR
142                    // filter cases to be on the safe side; either might be used,
143                    // but we don't currently expect both at once on the same field.
144                    if ($searchObject) {
145                        $limitFilt = 'LIMIT|' . $fullFilter;
146                        $orLimitFilt = '~' . $limitFilt;
147                        if ($searchObject->getParams()->hasFilter($limitFilt)) {
148                            $facetList[$facet]['LimiterValues'][$key]['selected'] = true;
149                            // Remove the filter from the search object -- we don't
150                            // want it to show up in the "applied filters" sidebar
151                            // since it will already be accounted for by being
152                            // selected in the filter select list!
153                            $searchObject->getParams()->removeFilter($limitFilt);
154                        } elseif ($searchObject->getParams()->hasFilter($orLimitFilt)) {
155                            $facetList[$facet]['LimiterValues'][$key]['selected'] = true;
156                            $searchObject->getParams()->removeFilter($orLimitFilt);
157                        }
158                    } else {
159                        if ('y' == $facetList[$facet]['DefaultOn']) {
160                            $facetList[$facet]['selected'] = true;
161                        }
162                    }
163                }
164            }
165        }
166        return $facetList;
167    }
168
169    /**
170     * Process the expanders to be used on the Advanced Search screen.
171     *
172     * @param object $searchObject Saved search object (false if none)
173     *
174     * @return array               Sorted facets, with selected values flagged.
175     */
176    protected function processAdvancedExpanders($searchObject = false)
177    {
178        $results = $this->getResultsManager()->get('EDS');
179        $params = $results->getParams();
180        $options = $params->getOptions();
181        $availableExpanders = $options->getAvailableExpanders();
182        $defaultExpanders = $options->getDefaultExpanders();
183        // Process the expanders, assuming they came back
184        foreach ($availableExpanders as $key => $value) {
185            if ($searchObject) {
186                $expandFilt = 'EXPAND:' . $value['Value'];
187                if ($searchObject->getParams()->hasFilter($expandFilt)) {
188                    $availableExpanders[$key]['selected'] = true;
189                    // Remove the filter from the search object -- we don't want
190                    // it to show up in the "applied filters" sidebar since it
191                    // will already be accounted for by being selected in the
192                    // filter select list!
193                    $searchObject->getParams()->removeFilter($expandFilt);
194                }
195            } else {
196                if (in_array($key, $defaultExpanders)) {
197                    $availableExpanders[$key]['selected'] = true;
198                }
199            }
200        }
201        return $availableExpanders;
202    }
203
204    /**
205     * Process the publication date range limiter widget
206     *
207     * @param object $searchObject Saved search object (false if none)
208     *
209     * @return array               To and from dates
210     */
211    protected function processPublicationDateRange($searchObject = false)
212    {
213        $from = $to = '';
214        if ($searchObject) {
215            $filters = $searchObject->getParams()->getFilterList();
216            foreach ($filters as $key => $value) {
217                if ('PublicationDate' == $key) {
218                    if ($range = SolrUtils::parseRange($value[0]['value'])) {
219                        $from = $range['from'] == '*' ? '11' : $range['from'];
220                        $to = $range['to'] == '*' ? '12' : $range['to'];
221                    }
222                    $searchObject->getParams()
223                        ->removeFilter($key . ':' . $value[0]['value']);
224                    break;
225                }
226            }
227        }
228        return [$from, $to];
229    }
230
231    /**
232     * Process the search modes to be used on the Advanced Search screen.
233     *
234     * @param object $searchObject Saved search object (false if none)
235     *
236     * @return array               search modes with selected values flagged.
237     */
238    protected function processAdvancedSearchModes($searchObject = false)
239    {
240        $results = $this->getResultsManager()->get('EDS');
241        $params = $results->getParams();
242        $options = $params->getOptions();
243        $searchModes = $options->getModeOptions();
244        // Process the facets, assuming they came back
245        foreach ($searchModes as $key => $mode) {
246            if ($searchObject) {
247                $modeFilter = 'SEARCHMODE:' . $mode['Value'];
248                if ($searchObject->getParams()->hasFilter($modeFilter)) {
249                    $searchModes[$key]['selected'] = true;
250                    // Remove the filter from the search object -- we don't want
251                    // it to show up in the "applied filters" sidebar since it
252                    // will already be accounted for by being selected in the
253                    // filter select list!
254                    $searchObject->getParams()->removeFilter($modeFilter);
255                }
256            } else {
257                if ($key == $options->getDefaultMode()) {
258                    $searchModes[$key]['selected'] = true;
259                }
260            }
261        }
262
263        return $searchModes;
264    }
265}