Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
66.28% |
114 / 172 |
|
23.94% |
17 / 71 |
CRAP | |
0.00% |
0 / 1 |
ComposedDriver | |
66.28% |
114 / 172 |
|
23.94% |
17 / 71 |
408.53 | |
0.00% |
0 / 1 |
init | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
cancelHolds | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
cancelILLRequests | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
cancelStorageRetrievalRequests | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
changePassword | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
checkILLRequestIsValid | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
checkRequestIsValid | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
checkStorageRetrievalRequestIsValid | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
findReserves | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAccountBlocks | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getCancelHoldDetails | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getCancelHoldLink | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getCancelILLRequestDetails | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getCancelStorageRetrievalRequestDetails | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getConfig | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getConsortialHoldings | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
getCourses | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultPickUpLocation | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDepartments | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFunds | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getHoldDefaultRequiredDate | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getHolding | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
getHoldLink | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getILLPickupLibraries | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getILLPickupLocations | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getInstructors | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMyFines | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMyHolds | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMyILLRequests | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMyProfile | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMyStorageRetrievalRequests | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMyTransactionHistory | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMyTransactions | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getNewItems | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getOfflineMode | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getPickUpLocations | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getProxiedUsers | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getPurchaseHistory | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRenewDetails | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRequestBlocks | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRequestGroups | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getStatus | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getStatuses | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getSuppressedAuthorityRecords | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSuppressedRecords | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getUrlsForRecord | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
hasHoldings | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
loginIsHidden | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
patronLogin | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
placeHold | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
placeILLRequest | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
placeStorageRetrievalRequest | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
purgeTransactionHistory | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
renewMyItems | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
renewMyItemsLink | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
supportsMethod | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
updateHolds | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getLoginDrivers | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultLoginDriver | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultRequestGroup | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
__call | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
callDriverMethod | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getMainDriverNameForMethod | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
defaultCall | |
75.00% |
3 / 4 |
|
0.00% |
0 / 1 |
2.06 | |||
mergeSingleArrayResults | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
combineArraysOfAssociativeArrays | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
2 | |||
combineMultipleArraysOfAssociativeArrays | |
100.00% |
32 / 32 |
|
100.00% |
1 / 1 |
4 | |||
extractResultSubfields | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
mergeInSubfields | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
mergeAssociativeArrays | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
6 | |||
extractKey | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | /** |
4 | * Composed Driver. |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Hebis Verbundzentrale 2023. |
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 ILSdrivers |
25 | * @author Thomas Wagener <wagener@hebis.uni-frankfurt.de> |
26 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
27 | * @link https://vufind.org/wiki/development:plugins:ils_drivers Wiki |
28 | */ |
29 | |
30 | namespace VuFind\ILS\Driver; |
31 | |
32 | use VuFind\Date\DateException; |
33 | use VuFind\Exception\ILS as ILSException; |
34 | |
35 | use function call_user_func_array; |
36 | use function count; |
37 | use function func_get_args; |
38 | use function in_array; |
39 | |
40 | /** |
41 | * Composed Driver. |
42 | * |
43 | * ILS Driver for VuFind to use multiple drivers for different tasks and |
44 | * combine their results. |
45 | * |
46 | * @category VuFind |
47 | * @package ILSdrivers |
48 | * @author Thomas Wagener <wagener@hebis.uni-frankfurt.de> |
49 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
50 | * @link https://vufind.org/wiki/development:plugins:ils_drivers Wiki |
51 | */ |
52 | class ComposedDriver extends AbstractMultiDriver |
53 | { |
54 | /** |
55 | * Name of the main driver |
56 | * |
57 | * @var string |
58 | */ |
59 | protected $mainDriver; |
60 | |
61 | /** |
62 | * Initialize the driver. |
63 | * |
64 | * Validate configuration and perform all resource-intensive tasks needed to |
65 | * make the driver active. |
66 | * |
67 | * @throws ILSException |
68 | * @return void |
69 | */ |
70 | public function init() |
71 | { |
72 | parent::init(); |
73 | if (!($this->mainDriver = $this->config['General']['main_driver'] ?? false)) { |
74 | throw new ILSException('Main driver needs to be set.'); |
75 | } |
76 | } |
77 | |
78 | /** |
79 | * Cancel Holds |
80 | * |
81 | * Attempts to Cancel a hold or recall on a particular item. The |
82 | * data in $cancelDetails['details'] is determined by getCancelHoldDetails(). |
83 | * |
84 | * @param array $cancelDetails An array of item and patron data |
85 | * |
86 | * @return array An array of data on each request including |
87 | * whether or not it was successful and a system message (if available) |
88 | */ |
89 | public function cancelHolds($cancelDetails) |
90 | { |
91 | return $this->defaultCall('cancelHolds', func_get_args()); |
92 | } |
93 | |
94 | /** |
95 | * Cancel ILL Requests |
96 | * |
97 | * Attempts to Cancel an ILL request on a particular item. The |
98 | * data in $cancelDetails['details'] is determined by |
99 | * getCancelILLRequestDetails(). |
100 | * |
101 | * @param array $cancelDetails An array of item and patron data |
102 | * |
103 | * @return array An array of data on each request including |
104 | * whether or not it was successful and a system message (if available) |
105 | */ |
106 | public function cancelILLRequests($cancelDetails) |
107 | { |
108 | return $this->defaultCall('cancelILLRequests', func_get_args()); |
109 | } |
110 | |
111 | /** |
112 | * Cancel Call Slips |
113 | * |
114 | * Attempts to Cancel a call slip on a particular item. The |
115 | * data in $cancelDetails['details'] is determined by |
116 | * getCancelStorageRetrievalRequestDetails(). |
117 | * |
118 | * @param array $cancelDetails An array of item and patron data |
119 | * |
120 | * @return array An array of data on each request including |
121 | * whether or not it was successful and a system message (if available) |
122 | */ |
123 | public function cancelStorageRetrievalRequests($cancelDetails) |
124 | { |
125 | return $this->defaultCall('cancelStorageRetrievalRequests', func_get_args()); |
126 | } |
127 | |
128 | /** |
129 | * Change Password |
130 | * |
131 | * Attempts to change patron password (PIN code) |
132 | * |
133 | * @param array $details An array of patron id and old and new password |
134 | * |
135 | * @return mixed An array of data on the request including |
136 | * whether or not it was successful and a system message (if available) |
137 | */ |
138 | public function changePassword($details) |
139 | { |
140 | return $this->defaultCall('changePassword', func_get_args()); |
141 | } |
142 | |
143 | /** |
144 | * Check whether an ILL request is valid |
145 | * |
146 | * This is responsible for determining if an item is requestable |
147 | * |
148 | * @param string $id The Bib ID |
149 | * @param array $data An Array of item data |
150 | * @param array $patron An array of patron data |
151 | * |
152 | * @return mixed An array of data on the request including |
153 | * whether or not it is valid and a status message. Alternatively a boolean |
154 | * true if request is valid, false if not. |
155 | */ |
156 | public function checkILLRequestIsValid($id, $data, $patron) |
157 | { |
158 | return $this->defaultCall('checkILLRequestIsValid', func_get_args()); |
159 | } |
160 | |
161 | /** |
162 | * Check whether a hold or recall request is valid |
163 | * |
164 | * This is responsible for determining if an item is requestable |
165 | * |
166 | * @param string $id The Bib ID |
167 | * @param array $data An Array of item data |
168 | * @param array $patron An array of patron data |
169 | * |
170 | * @return mixed An array of data on the request including |
171 | * whether or not it is valid and a status message. Alternatively a boolean |
172 | * true if request is valid, false if not. |
173 | */ |
174 | public function checkRequestIsValid($id, $data, $patron) |
175 | { |
176 | return $this->defaultCall('checkRequestIsValid', func_get_args()); |
177 | } |
178 | |
179 | /** |
180 | * Check whether a storage retrieval request is valid |
181 | * |
182 | * This is responsible for determining if an item is requestable |
183 | * |
184 | * @param string $id The Bib ID |
185 | * @param array $data An Array of item data |
186 | * @param array $patron An array of patron data |
187 | * |
188 | * @return mixed An array of data on the request including |
189 | * whether or not it is valid and a status message. Alternatively a boolean |
190 | * true if request is valid, false if not. |
191 | */ |
192 | public function checkStorageRetrievalRequestIsValid($id, $data, $patron) |
193 | { |
194 | return $this->defaultCall('checkStorageRetrievalRequestIsValid', func_get_args()); |
195 | } |
196 | |
197 | /** |
198 | * Find Reserves |
199 | * |
200 | * Obtain information on course reserves. |
201 | * |
202 | * @param string $course ID from getCourses (empty string to match all) |
203 | * @param string $inst ID from getInstructors (empty string to match all) |
204 | * @param string $dept ID from getDepartments (empty string to match all) |
205 | * |
206 | * @return mixed An array of associative arrays representing reserve items |
207 | */ |
208 | public function findReserves($course, $inst, $dept) |
209 | { |
210 | return $this->defaultCall('findReserves', func_get_args()); |
211 | } |
212 | |
213 | /** |
214 | * Check whether the patron has any blocks on their account. |
215 | * |
216 | * @param array $patron Patron data from patronLogin(). |
217 | * |
218 | * @return mixed A boolean false if no blocks are in place and an array |
219 | * of block reasons if blocks are in place |
220 | */ |
221 | public function getAccountBlocks($patron) |
222 | { |
223 | return $this->defaultCall('getAccountBlocks', func_get_args()); |
224 | } |
225 | |
226 | /** |
227 | * Get Cancel Hold Details |
228 | * |
229 | * In order to cancel a hold, the ILS requires some information on the hold. |
230 | * This function returns the required information, which is then submitted |
231 | * as form data in Hold.php. This value is then extracted by the CancelHolds |
232 | * function. |
233 | * |
234 | * @param array $hold A single hold array from getMyHolds |
235 | * @param array $patron Patron information from patronLogin |
236 | * |
237 | * @return string Data for use in a form field |
238 | */ |
239 | public function getCancelHoldDetails($hold, $patron = []) |
240 | { |
241 | return $this->defaultCall('getCancelHoldDetails', func_get_args()); |
242 | } |
243 | |
244 | /** |
245 | * Get Cancel Hold Link |
246 | * |
247 | * @param array $holdDetails Hold Details |
248 | * @param array $patron Patron |
249 | * |
250 | * @return string URL to native OPAC |
251 | */ |
252 | public function getCancelHoldLink($holdDetails, $patron) |
253 | { |
254 | return $this->defaultCall('getCancelHoldLink', func_get_args()); |
255 | } |
256 | |
257 | /** |
258 | * Get Cancel ILL Request Details |
259 | * |
260 | * In order to cancel an ILL request, the ILS requires some information on the |
261 | * request. This function returns the required information, which is then |
262 | * submitted as form data. This value is then extracted by the CancelILLRequests |
263 | * function. |
264 | * |
265 | * @param array $details An array of item data |
266 | * |
267 | * @return string Data for use in a form field |
268 | */ |
269 | public function getCancelILLRequestDetails($details) |
270 | { |
271 | return $this->defaultCall('getCancelILLRequestDetails', func_get_args()); |
272 | } |
273 | |
274 | /** |
275 | * Get Cancel Call Slip Details |
276 | * |
277 | * In order to cancel a call slip, the ILS requires some information on it. |
278 | * This function returns the required information, which is then submitted |
279 | * as form data. This value is then extracted by the |
280 | * CancelStorageRetrievalRequests function. |
281 | * |
282 | * @param array $details An array of item data |
283 | * |
284 | * @return string Data for use in a form field |
285 | */ |
286 | public function getCancelStorageRetrievalRequestDetails($details) |
287 | { |
288 | return $this->defaultCall('getCancelStorageRetrievalRequestDetails', func_get_args()); |
289 | } |
290 | |
291 | /** |
292 | * Function which specifies renew, hold and cancel settings. |
293 | * |
294 | * @param string $function The name of the feature to be checked |
295 | * @param array $params Optional feature-specific parameters (array) |
296 | * |
297 | * @return array An array with key-value pairs. |
298 | */ |
299 | public function getConfig($function, $params = null) |
300 | { |
301 | return $this->defaultCall('getConfig', func_get_args()); |
302 | } |
303 | |
304 | /** |
305 | * Get Consortial Holdings |
306 | * |
307 | * This is responsible for retrieving the holding information of a certain |
308 | * consortial record. |
309 | * |
310 | * @param string $id The record id to retrieve the holdings for |
311 | * @param array $patron Patron data |
312 | * @param array $ids The (consortial) source records for the record id |
313 | * |
314 | * @return array On success, an associative array with the following |
315 | * keys: id, availability (boolean), status, location, reserve, callnumber, |
316 | * duedate, number, barcode. |
317 | * @throws ILSException |
318 | * @throws DateException |
319 | */ |
320 | public function getConsortialHoldings($id, $patron, $ids) |
321 | { |
322 | return $this->combineArraysOfAssociativeArrays( |
323 | 'getConsortialHoldings', |
324 | func_get_args(), |
325 | ['holdings', 'electronic_holdings'] |
326 | ); |
327 | } |
328 | |
329 | /** |
330 | * Get Courses |
331 | * |
332 | * Obtain a list of courses for use in limiting the reserves list. |
333 | * |
334 | * @return array An associative array with key = ID, value = name. |
335 | */ |
336 | public function getCourses() |
337 | { |
338 | return $this->defaultCall('getCourses', func_get_args()); |
339 | } |
340 | |
341 | /** |
342 | * Get Default Pick Up Location |
343 | * |
344 | * Returns the default pick up location |
345 | * |
346 | * @param array $patron Patron information returned by the patronLogin |
347 | * method. |
348 | * @param array $holdDetails Optional array, only passed in when getting a list |
349 | * in the context of placing a hold; contains most of the same values passed to |
350 | * placeHold, minus the patron data. May be used to limit the pickup options |
351 | * or may be ignored. |
352 | * |
353 | * @return string A location ID |
354 | */ |
355 | public function getDefaultPickUpLocation($patron = false, $holdDetails = null) |
356 | { |
357 | return $this->defaultCall('getDefaultPickUpLocation', func_get_args()); |
358 | } |
359 | |
360 | /** |
361 | * Get Departments |
362 | * |
363 | * Obtain a list of departments for use in limiting the reserves list. |
364 | * |
365 | * @return array An associative array with key = dept. ID, value = dept. name. |
366 | */ |
367 | public function getDepartments() |
368 | { |
369 | return $this->defaultCall('getDepartments', func_get_args()); |
370 | } |
371 | |
372 | /** |
373 | * Get Funds |
374 | * |
375 | * Return a list of funds which may be used to limit the getNewItems list. |
376 | * |
377 | * @throws ILSException |
378 | * @return array An associative array with key = fund ID, value = fund name. |
379 | */ |
380 | public function getFunds() |
381 | { |
382 | return $this->defaultCall('getFunds', func_get_args()); |
383 | } |
384 | |
385 | /** |
386 | * Get Default "Hold Required By" Date (as Unix timestamp) or null if unsupported |
387 | * |
388 | * @param array $patron Patron information returned by the patronLogin method. |
389 | * @param array $holdInfo Contains most of the same values passed to |
390 | * placeHold, minus the patron data. |
391 | * |
392 | * @return int|null |
393 | */ |
394 | public function getHoldDefaultRequiredDate($patron, $holdInfo) |
395 | { |
396 | return $this->defaultCall('getHoldDefaultRequiredDate', func_get_args()); |
397 | } |
398 | |
399 | /** |
400 | * Get Holding |
401 | * |
402 | * This is responsible for retrieving the holding information of a certain |
403 | * record. |
404 | * |
405 | * @param string $id The record id to retrieve the holdings for |
406 | * @param array $patron Patron data |
407 | * @param array $options Extra options (not currently used) |
408 | * |
409 | * @return array On success, an associative array with the following |
410 | * keys: id, availability (boolean), status, location, reserve, callnumber, |
411 | * duedate, number, barcode. |
412 | * |
413 | * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
414 | */ |
415 | public function getHolding($id, array $patron = null, array $options = []) |
416 | { |
417 | return $this->combineArraysOfAssociativeArrays( |
418 | 'getHolding', |
419 | func_get_args(), |
420 | ['holdings', 'electronic_holdings'] |
421 | ); |
422 | } |
423 | |
424 | /** |
425 | * Get Hold Link |
426 | * |
427 | * The goal for this method is to return a URL to a "place hold" web page on |
428 | * the ILS OPAC. This is used for ILSs that do not support an API or method |
429 | * to place Holds. |
430 | * |
431 | * @param string $id The id of the bib record |
432 | * @param array $details Item details from getHoldings return array |
433 | * |
434 | * @return string URL to ILS's OPAC's place hold screen. |
435 | */ |
436 | public function getHoldLink($id, $details) |
437 | { |
438 | return $this->defaultCall('getHoldLink', func_get_args()); |
439 | } |
440 | |
441 | /** |
442 | * Get ILL Pickup Libraries |
443 | * |
444 | * This is responsible for getting information on the possible pickup libraries |
445 | * |
446 | * @param string $id Record ID |
447 | * @param array $patron Patron |
448 | * |
449 | * @return bool|array False if request not allowed, or an array of associative |
450 | * arrays with libraries. |
451 | */ |
452 | public function getILLPickupLibraries($id, $patron) |
453 | { |
454 | return $this->defaultCall('getILLPickupLibraries', func_get_args()); |
455 | } |
456 | |
457 | /** |
458 | * Get ILL Pickup Locations |
459 | * |
460 | * This is responsible for getting a list of possible pickup locations for a |
461 | * library |
462 | * |
463 | * @param string $id Record ID |
464 | * @param string $pickupLib Pickup library ID |
465 | * @param array $patron Patron |
466 | * |
467 | * @return bool|array False if request not allowed, or an array of |
468 | * locations. |
469 | */ |
470 | public function getILLPickupLocations($id, $pickupLib, $patron) |
471 | { |
472 | return $this->defaultCall('getILLPickupLocations', func_get_args()); |
473 | } |
474 | |
475 | /** |
476 | * Get Instructors |
477 | * |
478 | * Obtain a list of instructors for use in limiting the reserves list. |
479 | * |
480 | * @return array An associative array with key = ID, value = name. |
481 | */ |
482 | public function getInstructors() |
483 | { |
484 | return $this->defaultCall('getInstructors', func_get_args()); |
485 | } |
486 | |
487 | /** |
488 | * Get Patron Fines |
489 | * |
490 | * This is responsible for retrieving all fines by a specific patron. |
491 | * |
492 | * @param array $patron The patron array from patronLogin |
493 | * |
494 | * @return mixed Array of the patron's fines on success. |
495 | */ |
496 | public function getMyFines($patron) |
497 | { |
498 | return $this->combineArraysOfAssociativeArrays('getMyFines', func_get_args()); |
499 | } |
500 | |
501 | /** |
502 | * Get Patron Holds |
503 | * |
504 | * This is responsible for retrieving all holds by a specific patron. |
505 | * |
506 | * @param array $patron The patron array from patronLogin |
507 | * |
508 | * @return mixed Array of the patron's holds |
509 | */ |
510 | public function getMyHolds($patron) |
511 | { |
512 | return $this->combineArraysOfAssociativeArrays('getMyHolds', func_get_args()); |
513 | } |
514 | |
515 | /** |
516 | * Get Patron ILL Requests |
517 | * |
518 | * This is responsible for retrieving all ILL Requests by a specific patron. |
519 | * |
520 | * @param array $patron The patron array from patronLogin |
521 | * |
522 | * @return mixed Array of the patron's ILL requests |
523 | */ |
524 | public function getMyILLRequests($patron) |
525 | { |
526 | return $this->combineArraysOfAssociativeArrays('getMyILLRequests', func_get_args()); |
527 | } |
528 | |
529 | /** |
530 | * Get Patron Profile |
531 | * |
532 | * This is responsible for retrieving the profile for a specific patron. |
533 | * |
534 | * @param array $patron The patron array |
535 | * |
536 | * @return mixed Array of the patron's profile data |
537 | */ |
538 | public function getMyProfile($patron) |
539 | { |
540 | return $this->mergeSingleArrayResults('getMyProfile', func_get_args()); |
541 | } |
542 | |
543 | /** |
544 | * Get Patron Call Slips |
545 | * |
546 | * This is responsible for retrieving all call slips by a specific patron. |
547 | * |
548 | * @param array $patron The patron array from patronLogin |
549 | * |
550 | * @return mixed Array of the patron's holds |
551 | */ |
552 | public function getMyStorageRetrievalRequests($patron) |
553 | { |
554 | return $this->combineArraysOfAssociativeArrays('getMyStorageRetrievalRequests', func_get_args()); |
555 | } |
556 | |
557 | /** |
558 | * Get Patron Loan History |
559 | * |
560 | * @param array $user The patron array from patronLogin |
561 | * @param array $params Parameters |
562 | * |
563 | * @throws DateException |
564 | * @throws ILSException |
565 | * @return array Array of the patron's historic loans on success. |
566 | */ |
567 | public function getMyTransactionHistory($user, $params = null) |
568 | { |
569 | return $this->combineArraysOfAssociativeArrays('getMyTransactionHistory', func_get_args()); |
570 | } |
571 | |
572 | /** |
573 | * Get Patron Transactions |
574 | * |
575 | * This is responsible for retrieving all transactions (i.e. checked out items) |
576 | * by a specific patron. |
577 | * |
578 | * @param array $patron The patron array from patronLogin |
579 | * |
580 | * @return mixed Array of the patron's transactions on success. |
581 | */ |
582 | public function getMyTransactions($patron) |
583 | { |
584 | return $this->combineArraysOfAssociativeArrays('getMyTransactions', func_get_args(), ['records']); |
585 | } |
586 | |
587 | /** |
588 | * Get New Items |
589 | * |
590 | * Retrieve the IDs of items recently added to the catalog. |
591 | * |
592 | * @param int $page Page number of results to retrieve (counting starts at 1) |
593 | * @param int $limit The size of each page of results to retrieve |
594 | * @param int $daysOld The maximum age of records to retrieve in days (max. 30) |
595 | * @param int $fundId optional fund ID to use for limiting results (use a value |
596 | * returned by getFunds, or exclude for no limit); note that "fund" may be a |
597 | * misnomer - if funds are not an appropriate way to limit your new item |
598 | * results, you can return a different set of values from getFunds. The |
599 | * important thing is that this parameter supports an ID returned by getFunds, |
600 | * whatever that may mean. |
601 | * |
602 | * @return array Associative array with 'count' and 'results' keys |
603 | */ |
604 | public function getNewItems($page, $limit, $daysOld, $fundId = null) |
605 | { |
606 | return $this->defaultCall('getNewItems', func_get_args()); |
607 | } |
608 | |
609 | /** |
610 | * Get Offline Mode |
611 | * |
612 | * This is responsible for returning the offline mode |
613 | * |
614 | * @return string "ils-offline" for systems where the main ILS is offline, |
615 | * "ils-none" for systems which do not use an ILS |
616 | */ |
617 | public function getOfflineMode() |
618 | { |
619 | return $this->defaultCall('getOfflineMode', func_get_args()); |
620 | } |
621 | |
622 | /** |
623 | * Get Pick Up Locations |
624 | * |
625 | * This is responsible get a list of valid library locations for holds / recall |
626 | * retrieval |
627 | * |
628 | * @param array $patron Patron information returned by the patronLogin |
629 | * method. |
630 | * @param array $holdDetails Optional array, only passed in when getting a list |
631 | * in the context of placing or editing a hold. When placing a hold, it contains |
632 | * most of the same values passed to placeHold, minus the patron data. When |
633 | * editing a hold it contains all the hold information returned by getMyHolds. |
634 | * May be used to limit the pickup options or may be ignored. The driver must |
635 | * not add new options to the return array based on this data or other areas of |
636 | * VuFind may behave incorrectly. |
637 | * |
638 | * @return array An array of associative arrays with locationID and |
639 | * locationDisplay keys |
640 | */ |
641 | public function getPickUpLocations($patron = false, $holdDetails = null) |
642 | { |
643 | return $this->defaultCall('getPickUpLocations', func_get_args()); |
644 | } |
645 | |
646 | /** |
647 | * Get list of users for whom the provided patron is a proxy. |
648 | * |
649 | * @param array $patron The patron array with username and password |
650 | * |
651 | * @return array |
652 | */ |
653 | public function getProxiedUsers($patron) |
654 | { |
655 | return $this->defaultCall('getProxiedUsers', func_get_args()); |
656 | } |
657 | |
658 | /** |
659 | * Get Purchase History |
660 | * |
661 | * This is responsible for retrieving the acquisitions history data for the |
662 | * specific record (usually recently received issues of a serial). |
663 | * |
664 | * @param string $id The record id to retrieve the info for |
665 | * |
666 | * @throws ILSException |
667 | * @return array An array with the acquisitions data on success. |
668 | */ |
669 | public function getPurchaseHistory($id) |
670 | { |
671 | return $this->combineArraysOfAssociativeArrays('getPurchaseHistory', func_get_args()); |
672 | } |
673 | |
674 | /** |
675 | * Get Renew Details |
676 | * |
677 | * In order to renew an item, the ILS requires information on the item and |
678 | * patron. This function returns the information as a string which is then used |
679 | * as submitted form data in checkedOut.php. This value is then extracted by |
680 | * the RenewMyItems function. |
681 | * |
682 | * @param array $checkoutDetails An array of item data |
683 | * |
684 | * @return string Data for use in a form field |
685 | */ |
686 | public function getRenewDetails($checkoutDetails) |
687 | { |
688 | return $this->defaultCall('getRenewDetails', func_get_args()); |
689 | } |
690 | |
691 | /** |
692 | * Check whether the patron is blocked from placing requests (holds/ILL/SRR). |
693 | * |
694 | * @param array $patron Patron data from patronLogin(). |
695 | * |
696 | * @return mixed A boolean false if no blocks are in place and an array |
697 | * of block reasons if blocks are in place |
698 | */ |
699 | public function getRequestBlocks($patron) |
700 | { |
701 | return $this->defaultCall('getRequestBlocks', func_get_args()); |
702 | } |
703 | |
704 | /** |
705 | * Get request groups |
706 | * |
707 | * @param int $id BIB ID |
708 | * @param array $patron Patron information returned by the patronLogin |
709 | * method. |
710 | * @param array $holdDetails Optional array, only passed in when getting a list |
711 | * in the context of placing a hold; contains most of the same values passed to |
712 | * placeHold, minus the patron data. May be used to limit the request group |
713 | * options or may be ignored. |
714 | * |
715 | * @return array An array of associative arrays with requestGroupId and |
716 | * name keys |
717 | */ |
718 | public function getRequestGroups($id, $patron, $holdDetails = null) |
719 | { |
720 | return $this->defaultCall('getRequestGroups', func_get_args()); |
721 | } |
722 | |
723 | /** |
724 | * Get Status |
725 | * |
726 | * This is responsible for retrieving the status information of a certain |
727 | * record. |
728 | * |
729 | * @param string $id The record id to retrieve the holdings for |
730 | * |
731 | * @throws ILSException |
732 | * @return mixed On success, an associative array with the following keys: |
733 | * id, availability (boolean), status, location, reserve, callnumber. |
734 | */ |
735 | public function getStatus($id) |
736 | { |
737 | return $this->combineArraysOfAssociativeArrays('getStatus', [$id]); |
738 | } |
739 | |
740 | /** |
741 | * Get Statuses |
742 | * |
743 | * This is responsible for retrieving the status information for a |
744 | * collection of records. |
745 | * |
746 | * @param array $ids The array of record ids to retrieve the status for |
747 | * |
748 | * @throws ILSException |
749 | * @return array An array of getStatus() return values on success. |
750 | */ |
751 | public function getStatuses($ids) |
752 | { |
753 | return $this->combineMultipleArraysOfAssociativeArrays('getStatuses', [$ids], 'id'); |
754 | } |
755 | |
756 | /** |
757 | * Get suppressed authority records |
758 | * |
759 | * @return array ID numbers of suppressed authority records in the system. |
760 | */ |
761 | public function getSuppressedAuthorityRecords() |
762 | { |
763 | return $this->defaultCall('getSuppressedAuthorityRecords', func_get_args()); |
764 | } |
765 | |
766 | /** |
767 | * Get suppressed records. |
768 | * |
769 | * @throws ILSException |
770 | * @return array ID numbers of suppressed records in the system. |
771 | */ |
772 | public function getSuppressedRecords() |
773 | { |
774 | return $this->defaultCall('getSuppressedRecords', func_get_args()); |
775 | } |
776 | |
777 | /** |
778 | * Provide an array of URL data (in the same format returned by the record |
779 | * driver's getURLs method) for the specified bibliographic record. |
780 | * |
781 | * @param string $id Bibliographic record ID |
782 | * |
783 | * @return array |
784 | */ |
785 | public function getUrlsForRecord($id) |
786 | { |
787 | return $this->defaultCall('getUrlsForRecord', func_get_args()); |
788 | } |
789 | |
790 | /** |
791 | * Has Holdings |
792 | * |
793 | * This is responsible for determining if holdings exist for a particular |
794 | * bibliographic id |
795 | * |
796 | * @param string $id The record id to retrieve the holdings for |
797 | * |
798 | * @return bool True if holdings exist, False if they do not |
799 | * |
800 | * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
801 | */ |
802 | public function hasHoldings($id) |
803 | { |
804 | return $this->defaultCall('hasHoldings', func_get_args()); |
805 | } |
806 | |
807 | /** |
808 | * Get Hidden Login Mode |
809 | * |
810 | * This is responsible for indicating whether login should be hidden. |
811 | * |
812 | * @return bool true if the login should be hidden, false if not |
813 | */ |
814 | public function loginIsHidden() |
815 | { |
816 | return $this->defaultCall('loginIsHidden', func_get_args()); |
817 | } |
818 | |
819 | /** |
820 | * Patron Login |
821 | * |
822 | * This is responsible for authenticating a patron against the catalog. |
823 | * |
824 | * @param string $username The patron barcode |
825 | * @param string $password The patron password |
826 | * |
827 | * @throws ILSException |
828 | * @return mixed Associative array of patron info on successful login, |
829 | * null on unsuccessful login. |
830 | */ |
831 | public function patronLogin($username, $password) |
832 | { |
833 | return $this->defaultCall('patronLogin', func_get_args()); |
834 | } |
835 | |
836 | /** |
837 | * Place Hold |
838 | * |
839 | * Attempts to place a hold or recall on a particular item and returns |
840 | * an array with result details |
841 | * |
842 | * @param array $holdDetails An array of item and patron data |
843 | * |
844 | * @return mixed An array of data on the request including |
845 | * whether or not it was successful and a system message (if available) |
846 | */ |
847 | public function placeHold($holdDetails) |
848 | { |
849 | return $this->defaultCall('placeHold', func_get_args()); |
850 | } |
851 | |
852 | /** |
853 | * Place ILL Request |
854 | * |
855 | * Attempts to place an ILL request on a particular item and returns |
856 | * an array with result details (or throws an exception on failure of support |
857 | * classes) |
858 | * |
859 | * @param array $details An array of item and patron data |
860 | * |
861 | * @return mixed An array of data on the request including |
862 | * whether or not it was successful and a system message (if available) |
863 | */ |
864 | public function placeILLRequest($details) |
865 | { |
866 | return $this->defaultCall('placeILLRequest', func_get_args()); |
867 | } |
868 | |
869 | /** |
870 | * Place Storage Retrieval Request |
871 | * |
872 | * Attempts to place a storage retrieval request on a particular item and returns |
873 | * an array with result details |
874 | * |
875 | * @param array $details An array of item and patron data |
876 | * |
877 | * @return mixed An array of data on the request including |
878 | * whether or not it was successful and a system message (if available) |
879 | */ |
880 | public function placeStorageRetrievalRequest($details) |
881 | { |
882 | return $this->defaultCall('placeStorageRetrievalRequest', func_get_args()); |
883 | } |
884 | |
885 | /** |
886 | * Purge Patron Transaction History |
887 | * |
888 | * @param array $patron The patron array from patronLogin |
889 | * @param ?array $ids IDs to purge, or null for all |
890 | * |
891 | * @throws ILSException |
892 | * @return array Associative array of the results |
893 | */ |
894 | public function purgeTransactionHistory(array $patron, ?array $ids) |
895 | { |
896 | return $this->defaultCall('purgeTransactionHistory', func_get_args()); |
897 | } |
898 | |
899 | /** |
900 | * Renew My Items |
901 | * |
902 | * Function for attempting to renew a patron's items. The data in |
903 | * $renewDetails['details'] is determined by getRenewDetails(). |
904 | * |
905 | * @param array $renewDetails An array of data required for renewing items |
906 | * including the Patron ID and an array of renewal IDS |
907 | * |
908 | * @return array An array of renewal information keyed by item ID |
909 | */ |
910 | public function renewMyItems($renewDetails) |
911 | { |
912 | return $this->defaultCall('renewMyItems', func_get_args()); |
913 | } |
914 | |
915 | /** |
916 | * Renew My Items Link |
917 | * |
918 | * @param array $checkedOutDetails Checked Out Details |
919 | * |
920 | * @return string Url to a native OPAC |
921 | */ |
922 | public function renewMyItemsLink($checkedOutDetails) |
923 | { |
924 | return $this->defaultCall('renewMyItemsLink', func_get_args()); |
925 | } |
926 | |
927 | /** |
928 | * Helper method to determine whether or not a certain method can be |
929 | * called on this driver. Required method for any smart drivers. |
930 | * |
931 | * @param string $method The name of the called method. |
932 | * @param array $params Array of passed parameters. |
933 | * |
934 | * @return bool True if the method can be called with the given parameters, |
935 | * false otherwise. |
936 | */ |
937 | public function supportsMethod($method, $params) |
938 | { |
939 | $driverName = $this->config[$method]['main_driver'] ?? $this->mainDriver; |
940 | $driver = $this->getDriver($driverName); |
941 | return $driver && $this->driverSupportsMethod($driver, $method, $params); |
942 | } |
943 | |
944 | /** |
945 | * Update holds |
946 | * |
947 | * This is responsible for changing the status of hold requests |
948 | * |
949 | * @param array $holdsDetails The details identifying the holds |
950 | * @param array $fields An associative array of fields to be updated |
951 | * @param array $patron Patron array |
952 | * |
953 | * @return array Associative array of the results |
954 | */ |
955 | public function updateHolds($holdsDetails, $fields, $patron) |
956 | { |
957 | return $this->defaultCall('updateHolds', func_get_args()); |
958 | } |
959 | |
960 | /** |
961 | * Get available login targets (drivers enabled for login) |
962 | * |
963 | * @return string[] Source ID's |
964 | */ |
965 | public function getLoginDrivers() |
966 | { |
967 | return [$this->mainDriver]; |
968 | } |
969 | |
970 | /** |
971 | * Get default login driver |
972 | * |
973 | * @return string Default login driver or empty string |
974 | */ |
975 | public function getDefaultLoginDriver() |
976 | { |
977 | return $this->mainDriver; |
978 | } |
979 | |
980 | /** |
981 | * Get Default Request Group |
982 | * |
983 | * Returns the default request group |
984 | * |
985 | * @param array $patron Patron information returned by the patronLogin |
986 | * method. |
987 | * @param array $holdDetails Optional array, only passed in when getting a list |
988 | * in the context of placing a hold; contains most of the same values passed to |
989 | * placeHold, minus the patron data. May be used to limit the request group |
990 | * options or may be ignored. |
991 | * |
992 | * @return string A location ID |
993 | */ |
994 | public function getDefaultRequestGroup($patron, $holdDetails = null) |
995 | { |
996 | return $this->defaultCall('getDefaultRequestGroup', func_get_args()); |
997 | } |
998 | |
999 | /** |
1000 | * Default method -- pass along calls to the driver if a source can be determined |
1001 | * and a driver is available. Throws ILSException otherwise. |
1002 | * |
1003 | * @param string $methodName The name of the called method |
1004 | * @param array $params Array of passed parameters |
1005 | * |
1006 | * @throws ILSException |
1007 | * @return mixed Varies by method |
1008 | */ |
1009 | public function __call($methodName, $params) |
1010 | { |
1011 | return $this->defaultCall($methodName, $params); |
1012 | } |
1013 | |
1014 | /** |
1015 | * Calling a function of a driver |
1016 | * |
1017 | * @param string $driverName Name of the driver on which the method is called |
1018 | * @param string $method Name of the method |
1019 | * @param array $params Parameters |
1020 | * |
1021 | * @return mixed |
1022 | */ |
1023 | protected function callDriverMethod($driverName, $method, $params) |
1024 | { |
1025 | $driver = $this->getDriver($driverName); |
1026 | return call_user_func_array([$driver, $method], $params); |
1027 | } |
1028 | |
1029 | /** |
1030 | * Determines which driver should be used for the specified method |
1031 | * |
1032 | * @param $method string name of the method |
1033 | * |
1034 | * @return string |
1035 | */ |
1036 | protected function getMainDriverNameForMethod($method) |
1037 | { |
1038 | $driverName = $this->config[$method]['main_driver'] ?? $this->mainDriver; |
1039 | return $driverName; |
1040 | } |
1041 | |
1042 | /** |
1043 | * Simply calls the method for the specified main driver |
1044 | * |
1045 | * @param string $methodName Name of the method to be called |
1046 | * @param array $params Arguments for the method call |
1047 | * |
1048 | * @return mixed |
1049 | */ |
1050 | protected function defaultCall($methodName, $params) |
1051 | { |
1052 | if ($this->supportsMethod($methodName, $params)) { |
1053 | $driverName = $this->getMainDriverNameForMethod($methodName); |
1054 | return $this->callDriverMethod($driverName, $methodName, $params); |
1055 | } |
1056 | throw new ILSException('Method "' . $methodName . '" is not supported.'); |
1057 | } |
1058 | |
1059 | /** |
1060 | * Used for methods that return associative arrays. Calls the method for the main and support drivers and merges |
1061 | * the results. Only uses the specified support fields of the support drivers. |
1062 | * |
1063 | * @param string $methodName Name of the method to be called |
1064 | * @param array $params Arguments for the method call |
1065 | * |
1066 | * @return array |
1067 | */ |
1068 | protected function mergeSingleArrayResults($methodName, $params) |
1069 | { |
1070 | $methodConfig = $this->config[$methodName] ?? []; |
1071 | |
1072 | // get main results |
1073 | $mainDriverName = $this->getMainDriverNameForMethod($methodName); |
1074 | $mainResult = $this->callDriverMethod($mainDriverName, $methodName, $params); |
1075 | |
1076 | $supportConfig = $methodConfig['support_drivers'] ?? []; |
1077 | $supportDriverNames = array_keys($supportConfig) ?? []; |
1078 | |
1079 | // get support results |
1080 | $supportResults = array_map(function ($driverName) use ($methodName, $params, $supportConfig) { |
1081 | $supportKeys = explode(',', $supportConfig[$driverName] ?? ''); |
1082 | return array_intersect_key( |
1083 | $this->callDriverMethod($driverName, $methodName, $params), |
1084 | array_flip($supportKeys) |
1085 | ); |
1086 | }, $supportDriverNames); |
1087 | |
1088 | // merge results |
1089 | return array_merge($mainResult, ...$supportResults); |
1090 | } |
1091 | |
1092 | /** |
1093 | * Used for methods where the result is a list of items. Calls the method for |
1094 | * the main driver and all support drivers. Then adds specified fields of the |
1095 | * support drivers to the main driver's result. |
1096 | * |
1097 | * @param $methodName string Name of the method to be called |
1098 | * @param $params array Arguments for the method call |
1099 | * @param $optionalResultSubfields array Keys of possible result subfields |
1100 | * |
1101 | * @return mixed |
1102 | */ |
1103 | protected function combineArraysOfAssociativeArrays($methodName, $params, $optionalResultSubfields = []) |
1104 | { |
1105 | $methodConfig = $this->config[$methodName] ?? []; |
1106 | |
1107 | // get main results |
1108 | $mainDriverName = $this->getMainDriverNameForMethod($methodName); |
1109 | $mainResult = $this->callDriverMethod($mainDriverName, $methodName, $params); |
1110 | |
1111 | if (!empty($mergeKeys = $methodConfig['merge_keys'] ?? [])) { |
1112 | $supportConfig = $methodConfig['support_drivers'] ?? []; |
1113 | $supportDriverNames = array_keys($supportConfig) ?? []; |
1114 | |
1115 | // get support results |
1116 | $supportResult = array_map( |
1117 | function ($driverName) use ( |
1118 | $params, |
1119 | $mergeKeys, |
1120 | $methodName, |
1121 | $supportConfig, |
1122 | $optionalResultSubfields |
1123 | ) { |
1124 | $result = $this->callDriverMethod($driverName, $methodName, $params); |
1125 | $result = $this->extractResultSubfields($result, $optionalResultSubfields); |
1126 | $mergeKey = $mergeKeys[$driverName]; |
1127 | // extract support keys |
1128 | $supportEntry = array_map( |
1129 | function ($fullEntry) use ($mergeKey, $supportConfig, $driverName) { |
1130 | $usedKeys = array_merge([$mergeKey], explode(',', $supportConfig[$driverName])); |
1131 | return array_intersect_key($fullEntry, array_flip($usedKeys)); |
1132 | }, |
1133 | $result |
1134 | ); |
1135 | return $this->extractKey($supportEntry, $mergeKey); |
1136 | }, |
1137 | array_combine($supportDriverNames, $supportDriverNames) |
1138 | ); |
1139 | |
1140 | // merge results |
1141 | $mainResult = $this->mergeInSubfields($mainResult, $supportResult, $mergeKeys, $optionalResultSubfields); |
1142 | } |
1143 | return $mainResult; |
1144 | } |
1145 | |
1146 | /** |
1147 | * Used for methods where the result is a list of lists of items. Calls the method for |
1148 | * the main driver and all support drivers. Then adds specified fields of the |
1149 | * support drivers to the main driver's result. |
1150 | * |
1151 | * @param $methodName string Name of the method to be called |
1152 | * @param $params array Arguments for the method |
1153 | * @param $baseMergeKey string Key to match arrays on the first level |
1154 | * @param $optionalResultSubfields array Keys of possible result subfields |
1155 | * |
1156 | * @return mixed |
1157 | */ |
1158 | protected function combineMultipleArraysOfAssociativeArrays( |
1159 | $methodName, |
1160 | $params, |
1161 | $baseMergeKey, |
1162 | $optionalResultSubfields = [] |
1163 | ) { |
1164 | $methodConfig = $this->config[$methodName] ?? []; |
1165 | |
1166 | // get main results |
1167 | $mainDriverName = $this->getMainDriverNameForMethod($methodName); |
1168 | $mainResult = $this->callDriverMethod($mainDriverName, $methodName, $params); |
1169 | $subMergeKeys = $methodConfig['merge_keys'] ?? []; |
1170 | |
1171 | if (!empty($subMergeKeys)) { |
1172 | $supportConfig = $methodConfig['support_drivers'] ?? []; |
1173 | $supportDriverNames = array_keys($supportConfig) ?? []; |
1174 | |
1175 | // get support results |
1176 | $supportResults = array_map( |
1177 | function ($driverName) use ( |
1178 | $params, |
1179 | $baseMergeKey, |
1180 | $subMergeKeys, |
1181 | $methodName, |
1182 | $supportConfig, |
1183 | $optionalResultSubfields |
1184 | ) { |
1185 | $results = $this->callDriverMethod($driverName, $methodName, $params); |
1186 | return array_map( |
1187 | function ($result) use ( |
1188 | $baseMergeKey, |
1189 | $subMergeKeys, |
1190 | $supportConfig, |
1191 | $driverName, |
1192 | $optionalResultSubfields |
1193 | ) { |
1194 | $result = $this->extractResultSubfields($result, $optionalResultSubfields); |
1195 | $subMergeKey = $subMergeKeys[$driverName]; |
1196 | // extract support keys |
1197 | $supportEntry = array_map( |
1198 | function ($fullEntry) use ($subMergeKey, $supportConfig, $driverName, $baseMergeKey) { |
1199 | $usedKeys = array_merge( |
1200 | [$baseMergeKey, $subMergeKey], |
1201 | explode(',', $supportConfig[$driverName]) |
1202 | ); |
1203 | return array_intersect_key($fullEntry, array_flip($usedKeys)); |
1204 | }, |
1205 | $result |
1206 | ); |
1207 | return $this->extractKey($supportEntry, $subMergeKey); |
1208 | }, |
1209 | $results |
1210 | ); |
1211 | }, |
1212 | array_combine($supportDriverNames, $supportDriverNames) |
1213 | ); |
1214 | |
1215 | // merge all single results |
1216 | $res = []; |
1217 | for ($i = 0; $i < count($mainResult); $i++) { |
1218 | if ($baseMergeValue = $mainResult[$i][0][$baseMergeKey] ?? false) { |
1219 | $supportResult = array_map(function ($supportResult) use ($baseMergeKey, $baseMergeValue) { |
1220 | return current(array_filter( |
1221 | $supportResult, |
1222 | function ($entry) use ($baseMergeKey, $baseMergeValue) { |
1223 | return ($entry[array_keys($entry)[0]][$baseMergeKey] ?? null) === $baseMergeValue; |
1224 | } |
1225 | )); |
1226 | }, $supportResults); |
1227 | $res[] = $this->mergeInSubfields( |
1228 | $mainResult[$i], |
1229 | $supportResult, |
1230 | $subMergeKeys, |
1231 | $optionalResultSubfields |
1232 | ); |
1233 | } |
1234 | } |
1235 | $mainResult = $res; |
1236 | } |
1237 | return $mainResult; |
1238 | } |
1239 | |
1240 | /** |
1241 | * Extracts results from support drivers where the result can be split into named subfields. |
1242 | * |
1243 | * @param $result array Result of a support driver |
1244 | * @param $optionalResultSubfields array Keys of possible result subfields |
1245 | * |
1246 | * @return array |
1247 | */ |
1248 | protected function extractResultSubfields($result, $optionalResultSubfields) |
1249 | { |
1250 | $includesSubfields = false; |
1251 | foreach ($optionalResultSubfields as $subfield) { |
1252 | $includesSubfields |= in_array($subfield, array_keys($result)); |
1253 | } |
1254 | if ($includesSubfields) { |
1255 | $tmpResult = []; |
1256 | foreach ($optionalResultSubfields as $key) { |
1257 | $tmpResult = array_merge($tmpResult, $result[$key] ?? []); |
1258 | } |
1259 | $result = $tmpResult; |
1260 | } |
1261 | return $result; |
1262 | } |
1263 | |
1264 | /** |
1265 | * Merges results where the result can be split into named subfields. |
1266 | * |
1267 | * @param $mainResult array Result of the main driver |
1268 | * @param $supportResults array Result of a support driver |
1269 | * @param $mergeKeys array Merge keys |
1270 | * @param $optionalResultSubfields array Keys of possible result subfields |
1271 | * |
1272 | * @return array |
1273 | */ |
1274 | protected function mergeInSubfields($mainResult, $supportResults, $mergeKeys, $optionalResultSubfields) |
1275 | { |
1276 | $includesSubfields = false; |
1277 | foreach ($optionalResultSubfields as $subfield) { |
1278 | $includesSubfields |= in_array($subfield, array_keys($mainResult)); |
1279 | } |
1280 | if ($includesSubfields) { |
1281 | foreach ($optionalResultSubfields as $key) { |
1282 | $mainResult[$key] = $this->mergeAssociativeArrays($mainResult[$key], $supportResults, $mergeKeys); |
1283 | } |
1284 | } else { |
1285 | $mainResult = $this->mergeAssociativeArrays($mainResult, $supportResults, $mergeKeys); |
1286 | } |
1287 | return $mainResult; |
1288 | } |
1289 | |
1290 | /** |
1291 | * Merges results of the main and the support drivers on the specified key |
1292 | * |
1293 | * @param array $mainResult Result of main driver |
1294 | * @param array $supportResults Results of support drivers |
1295 | * @param array $mergeKeys Key on which the results are merged |
1296 | * |
1297 | * @return array |
1298 | */ |
1299 | protected function mergeAssociativeArrays($mainResult, $supportResults, $mergeKeys) |
1300 | { |
1301 | $res = []; |
1302 | foreach ($mainResult as $mainEntry) { |
1303 | foreach ($supportResults as $driverName => $supportResult) { |
1304 | $mergeKey = $mergeKeys[$driverName] ?? null; |
1305 | if ($mergeKey !== null && $mainEntry[$mergeKey]) { |
1306 | // merge entries that match on $mergeKey |
1307 | $supportEntry = $supportResult[$mainEntry[$mergeKey]] ?? []; |
1308 | if (!empty($supportEntry)) { |
1309 | $mainEntry = array_merge($supportEntry, $mainEntry); |
1310 | } |
1311 | } |
1312 | } |
1313 | $res[] = $mainEntry; |
1314 | } |
1315 | return $res; |
1316 | } |
1317 | |
1318 | /** |
1319 | * Takes an array of item as input and creates an associative |
1320 | * array using specified fields of the items as key |
1321 | * |
1322 | * @param array $data Array of items |
1323 | * @param string $key Items field to be used as key |
1324 | * |
1325 | * @return array |
1326 | */ |
1327 | protected function extractKey($data, $key) |
1328 | { |
1329 | $res = []; |
1330 | foreach ($data as $entry) { |
1331 | if (!empty($entry[$key])) { |
1332 | $res[$entry[$key]] = $entry; |
1333 | } |
1334 | } |
1335 | return $res; |
1336 | } |
1337 | } |