Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
Backend
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
9 / 9
18
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 search
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
5
 retrieve
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setQueryBuilder
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getQueryBuilder
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getRecordCollectionFactory
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getConnector
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createRecordCollection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 paramBagToArray
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3/**
4 * LibGuides backend.
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   David Maus <maus@hab.de>
26 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org
28 */
29
30namespace VuFindSearch\Backend\LibGuides;
31
32use VuFindSearch\Backend\AbstractBackend;
33use VuFindSearch\Backend\Exception\BackendException;
34use VuFindSearch\ParamBag;
35use VuFindSearch\Query\AbstractQuery;
36use VuFindSearch\Response\RecordCollectionFactoryInterface;
37use VuFindSearch\Response\RecordCollectionInterface;
38
39use function in_array;
40
41/**
42 * LibGuides backend.
43 *
44 * @category VuFind
45 * @package  Search
46 * @author   David Maus <maus@hab.de>
47 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
48 * @link     https://vufind.org
49 */
50class Backend extends AbstractBackend
51{
52    /**
53     * Connector.
54     *
55     * @var Connector
56     */
57    protected $connector;
58
59    /**
60     * Query builder.
61     *
62     * @var QueryBuilder
63     */
64    protected $queryBuilder = null;
65
66    /**
67     * Default search (performed if another search has 0 results; null to disable.
68     *
69     * @var string
70     */
71    protected $defaultSearch;
72
73    /**
74     * Constructor.
75     *
76     * @param Connector                        $connector     LibGuides connector
77     * @param RecordCollectionFactoryInterface $factory       Record collection
78     * factory (null for default)
79     * @param string                           $defaultSearch Default search query
80     *
81     * @return void
82     */
83    public function __construct(
84        Connector $connector,
85        RecordCollectionFactoryInterface $factory = null,
86        $defaultSearch = null
87    ) {
88        if (null !== $factory) {
89            $this->setRecordCollectionFactory($factory);
90        }
91        $this->connector    = $connector;
92        $this->identifier   = null;
93        $this->defaultSearch = $defaultSearch;
94    }
95
96    /**
97     * Perform a search and return record collection.
98     *
99     * @param AbstractQuery $query  Search query
100     * @param int           $offset Search offset
101     * @param int           $limit  Search limit
102     * @param ParamBag      $params Search backend parameters
103     *
104     * @return RecordCollectionInterface
105     */
106    public function search(
107        AbstractQuery $query,
108        $offset,
109        $limit,
110        ParamBag $params = null
111    ) {
112        $baseParams = $this->getQueryBuilder()->build($query);
113        if (null !== $params) {
114            $baseParams->mergeWith($params);
115        }
116        $args = $this->paramBagToArray($baseParams);
117        try {
118            $response = $this->connector->query($args, $offset, $limit);
119            // Apply default search if necessary:
120            if ($response['recordCount'] < 1 && isset($this->defaultSearch)) {
121                $args['search'] = $this->defaultSearch;
122                $response = $this->connector->query($args, $offset, $limit);
123            }
124        } catch (\Exception $e) {
125            throw new BackendException(
126                $e->getMessage(),
127                $e->getCode(),
128                $e
129            );
130        }
131
132        $collection = $this->createRecordCollection($response);
133        $this->injectSourceIdentifier($collection);
134
135        return $collection;
136    }
137
138    /**
139     * Retrieve a single document.
140     *
141     * @param string   $id     Document identifier
142     * @param ParamBag $params Search backend parameters
143     *
144     * @return RecordCollectionInterface
145     */
146    public function retrieve($id, ParamBag $params = null)
147    {
148        throw new \Exception('retrieve() not supported by LibGuides.');
149    }
150
151    /**
152     * Set the query builder.
153     *
154     * @param QueryBuilder $queryBuilder Query builder
155     *
156     * @return void
157     */
158    public function setQueryBuilder(QueryBuilder $queryBuilder)
159    {
160        $this->queryBuilder = $queryBuilder;
161    }
162
163    /**
164     * Return query builder.
165     *
166     * Lazy loads an empty QueryBuilder if none was set.
167     *
168     * @return QueryBuilder
169     */
170    public function getQueryBuilder()
171    {
172        if (!$this->queryBuilder) {
173            $this->queryBuilder = new QueryBuilder();
174        }
175        return $this->queryBuilder;
176    }
177
178    /**
179     * Return the record collection factory.
180     *
181     * Lazy loads a generic collection factory.
182     *
183     * @return RecordCollectionFactoryInterface
184     */
185    public function getRecordCollectionFactory()
186    {
187        if ($this->collectionFactory === null) {
188            $this->collectionFactory = new Response\RecordCollectionFactory();
189        }
190        return $this->collectionFactory;
191    }
192
193    /**
194     * Return the Primo connector.
195     *
196     * @return Connector
197     */
198    public function getConnector()
199    {
200        return $this->connector;
201    }
202
203    /// Internal API
204
205    /**
206     * Create record collection.
207     *
208     * @param array $records Records to process
209     *
210     * @return RecordCollectionInterface
211     */
212    protected function createRecordCollection($records)
213    {
214        return $this->getRecordCollectionFactory()->factory($records);
215    }
216
217    /**
218     * Convert a ParamBag to a query array.
219     *
220     * @param ParamBag $params ParamBag to convert
221     *
222     * @return array
223     */
224    protected function paramBagToArray(ParamBag $params)
225    {
226        $params = $params->getArrayCopy();
227
228        // Convert the options:
229        $options = [];
230
231        // Most parameters need to be flattened from array format, but a few
232        // should remain as arrays:
233        $arraySettings = [/* TODO: determine if values are needed here. */];
234        foreach ($params as $key => $param) {
235            $options[$key] = in_array($key, $arraySettings) ? $param : $param[0];
236        }
237
238        return $options;
239    }
240}