diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Primo/Backend.php b/module/VuFindSearch/src/VuFindSearch/Backend/Primo/Backend.php index 818b785f880803c13d5723778f129d2364bc886e..42f0464bd3841d7f57efe506c0689eb81cb1edc5 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/Primo/Backend.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/Primo/Backend.php @@ -28,6 +28,8 @@ */ namespace VuFindSearch\Backend\Primo; +use VuFindSearch\Feature\RetrieveBatchInterface; + use VuFindSearch\Query\AbstractQuery; use VuFindSearch\ParamBag; @@ -47,7 +49,7 @@ use VuFindSearch\Backend\Exception\BackendException; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link http://vufind.org */ -class Backend extends AbstractBackend +class Backend extends AbstractBackend implements RetrieveBatchInterface { /** * Connector. @@ -146,6 +148,49 @@ class Backend extends AbstractBackend return $collection; } + /** + * Retrieve a batch of documents. + * + * @param array $ids Array of document identifiers + * @param ParamBag $params Search backend parameters + * + * @return RecordCollectionInterface + */ + public function retrieveBatch($ids, ParamBag $params = null) + { + // Load 100 records at a time; this is a good number to avoid memory + // problems while still covering a lot of ground. + $pageSize = 100; + + // Retrieve records a page at a time: + $results = false; + while (count($ids) > 0) { + $currentPage = array_splice($ids, 0, $pageSize, []); + + try { + $response = $this->connector->getRecords( + $currentPage, $this->connector->getInstitutionCode() + ); + } catch (\Exception $e) { + throw new BackendException( + $e->getMessage(), + $e->getCode(), + $e + ); + } + $next = $this->createRecordCollection($response); + if (!$results) { + $results = $next; + } else { + foreach ($next->getRecords() as $record) { + $results->add($record); + } + } + } + $this->injectSourceIdentifier($results); + return $results; + } + /** * Set the query builder. * diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Primo/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/Primo/Connector.php index 67db8328a5b7f5e493db3ee1f524365cae3ffd29..71a51d7a089b14e9133baa0ee720c0f63803c166 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/Primo/Connector.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/Primo/Connector.php @@ -604,7 +604,8 @@ class Connector implements \Zend\Log\LoggerAwareInterface // Query String Parameters if (isset($recordId)) { $qs = []; - $qs[] = "query=rid,exact,\"$recordId\""; + $qs[] = 'query=rid,exact,"' . urlencode(addcslashes($recordId, '"')) + . '"'; $qs[] = "institution=$inst_code"; $qs[] = "onCampus=true"; $qs[] = "indx=1"; @@ -620,6 +621,42 @@ class Connector implements \Zend\Log\LoggerAwareInterface return $result; } + /** + * Retrieves multiple documents specified by the ID. + * + * @param array $recordIds The documents to retrieve from the Primo API + * @param string $inst_code Institution code (optional) + * + * @throws \Exception + * @return string The requested resource + */ + public function getRecords($recordIds, $inst_code = null) + { + // Callback function for formatting IDs: + $formatIds = function ($i) { + return '"' . addcslashes($i, '"') . '"'; + }; + + // Query String Parameters + if ($recordIds) { + $qs = []; + $recordIds = array_map($formatIds, $recordIds); + $qs[] = 'query=rid,contains,' . urlencode(implode(' OR ', $recordIds)); + $qs[] = "institution=$inst_code"; + $qs[] = "onCampus=true"; + $qs[] = "indx=1"; + $qs[] = "bulkSize=" . count($recordIds); + $qs[] = "loc=adaptor,primo_central_multiple_fe"; + + // Send Request + $result = $this->call(implode('&', $qs)); + } else { + throw new \Exception('Primo API does not accept a null query'); + } + + return $result; + } + /** * Get the institution code based on user IP. If user is coming from * off campus return