Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 45 |
|
0.00% |
0 / 11 |
CRAP | |
0.00% |
0 / 1 |
Search | |
0.00% |
0 / 45 |
|
0.00% |
0 / 11 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
initializeFeatures | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
onPreInit | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
destroySession | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSearches | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRowById | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
getOwnedRowById | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getScheduledSearches | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSearchRowsMatchingNormalizedSearch | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
30 | |||
saveSearch | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
expirationCallback | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * Table Definition for search |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Villanova University 2010. |
9 | * Copyright (C) The National Library of Finland 2016-2017. |
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 Db_Table |
26 | * @author Demian Katz <demian.katz@villanova.edu> |
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 | |
32 | namespace VuFind\Db\Table; |
33 | |
34 | use Laminas\Db\Adapter\Adapter; |
35 | use Laminas\Db\Adapter\ParameterContainer; |
36 | use Laminas\Db\TableGateway\Feature; |
37 | use VuFind\Db\Row\RowGateway; |
38 | use VuFind\Db\Service\DbServiceAwareInterface; |
39 | use VuFind\Db\Service\DbServiceAwareTrait; |
40 | use VuFind\Db\Service\SearchServiceInterface; |
41 | use VuFind\Search\NormalizedSearch; |
42 | use VuFind\Search\SearchNormalizer; |
43 | |
44 | use function count; |
45 | use function is_object; |
46 | |
47 | /** |
48 | * Table Definition for search |
49 | * |
50 | * @category VuFind |
51 | * @package Db_Table |
52 | * @author Demian Katz <demian.katz@villanova.edu> |
53 | * @author Ere Maijala <ere.maijala@helsinki.fi> |
54 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
55 | * @link https://vufind.org Main Site |
56 | */ |
57 | class Search extends Gateway implements DbServiceAwareInterface |
58 | { |
59 | use DbServiceAwareTrait; |
60 | use ExpirationTrait; |
61 | |
62 | /** |
63 | * Constructor |
64 | * |
65 | * @param Adapter $adapter Database adapter |
66 | * @param PluginManager $tm Table manager |
67 | * @param array $cfg Laminas configuration |
68 | * @param RowGateway $rowObj Row prototype object (null for default) |
69 | * @param string $table Name of database table to interface with |
70 | */ |
71 | public function __construct( |
72 | Adapter $adapter, |
73 | PluginManager $tm, |
74 | $cfg, |
75 | ?RowGateway $rowObj = null, |
76 | $table = 'search' |
77 | ) { |
78 | parent::__construct($adapter, $tm, $cfg, $rowObj, $table); |
79 | } |
80 | |
81 | /** |
82 | * Initialize features |
83 | * |
84 | * @param array $cfg Laminas configuration |
85 | * |
86 | * @return void |
87 | */ |
88 | public function initializeFeatures($cfg) |
89 | { |
90 | // Special case for PostgreSQL inserts -- we need to provide an extra |
91 | // clue so that the database knows how to write bytea data correctly: |
92 | if ($this->adapter->getDriver()->getDatabasePlatformName() == 'Postgresql') { |
93 | if (!is_object($this->featureSet)) { |
94 | $this->featureSet = new Feature\FeatureSet(); |
95 | } |
96 | $eventFeature = new Feature\EventFeature(); |
97 | $eventFeature->getEventManager()->attach( |
98 | Feature\EventFeature::EVENT_PRE_INITIALIZE, |
99 | [$this, 'onPreInit'] |
100 | ); |
101 | $this->featureSet->addFeature($eventFeature); |
102 | } |
103 | |
104 | parent::initializeFeatures($cfg); |
105 | } |
106 | |
107 | /** |
108 | * Customize the database object to include extra metadata about the |
109 | * search_object field so that it will be written correctly. This is |
110 | * triggered only when we're interacting with PostgreSQL; MySQL works fine |
111 | * without the extra hint. |
112 | * |
113 | * @param object $event Event object |
114 | * |
115 | * @return void |
116 | */ |
117 | public function onPreInit($event) |
118 | { |
119 | $driver = $event->getTarget()->getAdapter()->getDriver(); |
120 | $statement = $driver->createStatement(); |
121 | $params = new ParameterContainer(); |
122 | $params->offsetSetErrata('search_object', ParameterContainer::TYPE_LOB); |
123 | $statement->setParameterContainer($params); |
124 | $driver->registerStatementPrototype($statement); |
125 | } |
126 | |
127 | /** |
128 | * Destroy unsaved searches belonging to the specified session/user. |
129 | * |
130 | * @param string $sid Session ID of current user. |
131 | * @param int $uid User ID of current user (optional). |
132 | * |
133 | * @return void |
134 | * |
135 | * @deprecated Use SessionServiceInterface::destroySession() |
136 | */ |
137 | public function destroySession($sid, $uid = null) |
138 | { |
139 | $this->getDbService(SearchServiceInterface::class)->destroySession($sid, $uid); |
140 | } |
141 | |
142 | /** |
143 | * Get an array of rows for the specified user. |
144 | * |
145 | * @param string $sid Session ID of current user. |
146 | * @param int $uid User ID of current user (optional). |
147 | * |
148 | * @return array Matching SearchEntry objects. |
149 | * |
150 | * @deprecated Use SessionServiceInterface::getSearches() |
151 | */ |
152 | public function getSearches($sid, $uid = null) |
153 | { |
154 | return $this->getDbService(SearchServiceInterface::class)->getSearches($sid, $uid); |
155 | } |
156 | |
157 | /** |
158 | * Get a single row matching a primary key value. |
159 | * |
160 | * @param int $id Primary key value |
161 | * @param bool $exceptionIfMissing Should we throw an exception if the row is |
162 | * missing? |
163 | * |
164 | * @throws \Exception |
165 | * @return ?\VuFind\Db\Row\Search |
166 | * |
167 | * @deprecated |
168 | */ |
169 | public function getRowById($id, $exceptionIfMissing = true) |
170 | { |
171 | $row = $this->select(['id' => $id])->current(); |
172 | if (empty($row) && $exceptionIfMissing) { |
173 | throw new \Exception('Cannot find id ' . $id); |
174 | } |
175 | return $row; |
176 | } |
177 | |
178 | /** |
179 | * Get a single row, enforcing user ownership. Returns row if found, null |
180 | * otherwise. |
181 | * |
182 | * @param int $id Primary key value |
183 | * @param string $sessId Current user session ID |
184 | * @param int $userId Current logged-in user ID (or null if none) |
185 | * |
186 | * @return ?\VuFind\Db\Row\Search |
187 | * |
188 | * @deprecated Use SessionServiceInterface::getSearchByIdAndOwner() |
189 | */ |
190 | public function getOwnedRowById($id, $sessId, $userId) |
191 | { |
192 | return $this->getDbService(SearchServiceInterface::class)->getSearchByIdAndOwner($id, $sessId, $userId); |
193 | } |
194 | |
195 | /** |
196 | * Get scheduled searches. |
197 | * |
198 | * @return array Array of VuFind\Db\Row\Search objects. |
199 | * |
200 | * @deprecated Use SessionServiceInterface::getScheduledSearches() |
201 | */ |
202 | public function getScheduledSearches() |
203 | { |
204 | return $this->getDbService(SearchServiceInterface::class)->getScheduledSearches(); |
205 | } |
206 | |
207 | /** |
208 | * Return existing search table rows matching the provided normalized search. |
209 | * |
210 | * @param NormalizedSearch $normalized Normalized search to match against |
211 | * @param string $sessionId Current session ID |
212 | * @param int|null $userId Current user ID |
213 | * @param int $limit Max rows to retrieve |
214 | * (default = no limit) |
215 | * |
216 | * @return \VuFind\Db\Row\Search[] |
217 | * |
218 | * @deprecated Use SearchNormalizer::getSearchesMatchingNormalizedSearch() |
219 | */ |
220 | public function getSearchRowsMatchingNormalizedSearch( |
221 | NormalizedSearch $normalized, |
222 | string $sessionId, |
223 | ?int $userId, |
224 | int $limit = PHP_INT_MAX |
225 | ) { |
226 | // Fetch all rows with the same CRC32 and try to match with the URL |
227 | $checksum = $normalized->getChecksum(); |
228 | $callback = function ($select) use ($checksum, $sessionId, $userId) { |
229 | $nest = $select->where |
230 | ->equalTo('checksum', $checksum) |
231 | ->and |
232 | ->nest |
233 | ->equalTo('session_id', $sessionId)->and->equalTo('saved', 0); |
234 | if (!empty($userId)) { |
235 | $nest->or->equalTo('user_id', $userId); |
236 | } |
237 | }; |
238 | $results = []; |
239 | foreach ($this->select($callback) as $match) { |
240 | $minified = $match->getSearchObjectOrThrowException(); |
241 | if ($normalized->isEquivalentToMinifiedSearch($minified)) { |
242 | $results[] = $match; |
243 | if (count($results) >= $limit) { |
244 | break; |
245 | } |
246 | } |
247 | } |
248 | return $results; |
249 | } |
250 | |
251 | /** |
252 | * Add a search into the search table (history) |
253 | * |
254 | * @param SearchNormalizer $normalizer Search manager |
255 | * @param \VuFind\Search\Base\Results $results Search to save |
256 | * @param string $sessionId Current session ID |
257 | * @param int|null $userId Current user ID |
258 | * |
259 | * @return \VuFind\Db\Row\Search |
260 | * |
261 | * @deprecated Use SearchNormalizer::saveNormalizedSearch() |
262 | */ |
263 | public function saveSearch( |
264 | SearchNormalizer $normalizer, |
265 | $results, |
266 | $sessionId, |
267 | $userId |
268 | ) { |
269 | return $normalizer->saveNormalizedSearch($results, $sessionId, $userId); |
270 | } |
271 | |
272 | /** |
273 | * Update the select statement to find records to delete. |
274 | * |
275 | * @param Select $select Select clause |
276 | * @param string $dateLimit Date threshold of an "expired" record in format |
277 | * 'Y-m-d H:i:s'. |
278 | * |
279 | * @return void |
280 | */ |
281 | protected function expirationCallback($select, $dateLimit) |
282 | { |
283 | $select->where->lessThan('created', $dateLimit)->equalTo('saved', 0); |
284 | } |
285 | } |