Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 37 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
SearchRunner | |
0.00% |
0 / 37 |
|
0.00% |
0 / 4 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
run | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
42 | |||
setEventManager | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getEventManager | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | /** |
4 | * VuFind Search Runner |
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 Search |
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 Page |
28 | */ |
29 | |
30 | namespace VuFind\Search; |
31 | |
32 | use Laminas\EventManager\EventManager; |
33 | use Laminas\EventManager\EventManagerInterface; |
34 | use Laminas\Stdlib\Parameters; |
35 | use VuFind\Search\Results\PluginManager as ResultsManager; |
36 | use VuFind\Search\Solr\AbstractErrorListener as ErrorListener; |
37 | |
38 | use function is_array; |
39 | use function is_callable; |
40 | |
41 | /** |
42 | * VuFind Search Runner |
43 | * |
44 | * @category VuFind |
45 | * @package Search |
46 | * @author Demian Katz <demian.katz@villanova.edu> |
47 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
48 | * @link https://vufind.org Main Page |
49 | */ |
50 | class SearchRunner |
51 | { |
52 | /** |
53 | * Event identifiers. |
54 | * |
55 | * @var string |
56 | */ |
57 | public const EVENT_CONFIGURED = 'configured'; |
58 | public const EVENT_COMPLETE = 'complete'; |
59 | |
60 | /** |
61 | * Event manager. |
62 | * |
63 | * @var EventManager |
64 | */ |
65 | protected $events = null; |
66 | |
67 | /** |
68 | * Search results object manager. |
69 | * |
70 | * @var ResultsManager |
71 | */ |
72 | protected $resultsManager; |
73 | |
74 | /** |
75 | * Counter of how many searches we have run (for differentiating listeners). |
76 | * |
77 | * @var int |
78 | */ |
79 | protected $searchId = 0; |
80 | |
81 | /** |
82 | * Constructor |
83 | * |
84 | * @param ResultsManager $resultsManager Results manager |
85 | * @param EventManager $events Event manager (optional) |
86 | */ |
87 | public function __construct( |
88 | ResultsManager $resultsManager, |
89 | EventManager $events = null |
90 | ) { |
91 | $this->resultsManager = $resultsManager; |
92 | if (null !== $events) { |
93 | $this->setEventManager($events); |
94 | } |
95 | } |
96 | |
97 | /** |
98 | * Run the search. |
99 | * |
100 | * @param array|Parameters $rawRequest Incoming parameters for search |
101 | * @param string $searchClassId Type of search to perform |
102 | * @param mixed $setupCallback Optional callback for setting up params |
103 | * and attaching listeners; if provided, will be passed three parameters: |
104 | * this object, the search parameters object, and a unique identifier for |
105 | * the current running search. |
106 | * @param string $lastView Last valid view parameter loaded |
107 | * from a previous search (optional; used for view persistence). |
108 | * |
109 | * @return \VuFind\Search\Base\Results |
110 | * |
111 | * @throws \VuFindSearch\Backend\Exception\BackendException |
112 | */ |
113 | public function run( |
114 | $rawRequest, |
115 | $searchClassId = 'Solr', |
116 | $setupCallback = null, |
117 | $lastView = null |
118 | ) { |
119 | // Increment the ID counter, then save the current value to a variable; |
120 | // since events within this run could theoretically trigger additional |
121 | // runs of the SearchRunner, we can't rely on the property value past |
122 | // this point! |
123 | $this->searchId++; |
124 | $runningSearchId = $this->searchId; |
125 | |
126 | // Format the request object: |
127 | $request = $rawRequest instanceof Parameters |
128 | ? $rawRequest |
129 | : new Parameters(is_array($rawRequest) ? $rawRequest : []); |
130 | |
131 | // Set up the search: |
132 | $results = $this->resultsManager->get($searchClassId); |
133 | $params = $results->getParams(); |
134 | $params->setLastView($lastView); |
135 | $params->initFromRequest($request); |
136 | |
137 | if (is_callable($setupCallback)) { |
138 | $setupCallback($this, $params, $runningSearchId); |
139 | } |
140 | |
141 | // Trigger the "configuration done" event. |
142 | $this->getEventManager()->trigger( |
143 | self::EVENT_CONFIGURED, |
144 | $this, |
145 | compact('params', 'request', 'runningSearchId') |
146 | ); |
147 | |
148 | // Attempt to perform the search; if there is a problem, inspect any Solr |
149 | // exceptions to see if we should communicate to the user about them. |
150 | try { |
151 | // Explicitly execute search within controller -- this allows us to |
152 | // catch exceptions more reliably: |
153 | $results->performAndProcessSearch(); |
154 | } catch (\VuFindSearch\Backend\Exception\BackendException $e) { |
155 | if ($e->hasTag(ErrorListener::TAG_PARSER_ERROR)) { |
156 | // We need to create and process an "empty results" object to |
157 | // ensure that recommendation modules and templates behave |
158 | // properly when displaying the error message. |
159 | $results = $this->resultsManager->get('EmptySet'); |
160 | $results->setParams($params); |
161 | $results->performAndProcessSearch(); |
162 | } else { |
163 | throw $e; |
164 | } |
165 | } |
166 | |
167 | // Trigger the "search completed" event. |
168 | $this->getEventManager()->trigger( |
169 | self::EVENT_COMPLETE, |
170 | $this, |
171 | compact('results', 'runningSearchId') |
172 | ); |
173 | |
174 | return $results; |
175 | } |
176 | |
177 | /** |
178 | * Set EventManager instance. |
179 | * |
180 | * @param EventManagerInterface $events Event manager |
181 | * |
182 | * @return void |
183 | */ |
184 | public function setEventManager(EventManagerInterface $events) |
185 | { |
186 | $events->setIdentifiers([__CLASS__]); |
187 | $this->events = $events; |
188 | } |
189 | |
190 | /** |
191 | * Return EventManager instance. |
192 | * |
193 | * Lazy loads a new EventManager if none was set. |
194 | * |
195 | * @return EventManagerInterface |
196 | */ |
197 | public function getEventManager() |
198 | { |
199 | if (!$this->events) { |
200 | $this->setEventManager(new EventManager()); |
201 | } |
202 | return $this->events; |
203 | } |
204 | } |