Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
16.98% covered (danger)
16.98%
9 / 53
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
OpenLibrarySubjects
16.98% covered (danger)
16.98%
9 / 53
0.00% covered (danger)
0.00%
0 / 5
476.59
0.00% covered (danger)
0.00%
0 / 1
 setConfig
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
132
 init
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 process
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
 getPublishedDates
56.25% covered (warning)
56.25%
9 / 16
0.00% covered (danger)
0.00%
0 / 1
18.37
 getResult
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * OpenLibrarySubjects Recommendations Module
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  Recommendations
25 * @author   Demian Katz <demian.katz@villanova.edu>
26 * @author   Eoghan Ó Carragáin <eoghan.ocarragain@gmail.com>
27 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
28 * @link     https://vufind.org/wiki/development:plugins:recommendation_modules Wiki
29 */
30
31namespace VuFind\Recommend;
32
33use VuFind\Connection\OpenLibrary;
34use VuFind\Solr\Utils as SolrUtils;
35
36use function intval;
37use function is_object;
38
39/**
40 * OpenLibrarySubjects Recommendations Module
41 *
42 * This class provides recommendations by doing a search of the catalog; useful
43 * for displaying catalog recommendations in other modules (i.e. Summon, Web, etc.)
44 *
45 * @category VuFind
46 * @package  Recommendations
47 * @author   Demian Katz <demian.katz@villanova.edu>
48 * @author   Eoghan Ó Carragáin <eoghan.ocarragain@gmail.com>
49 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
50 * @link     https://vufind.org/wiki/development:plugins:recommendation_modules Wiki
51 */
52class OpenLibrarySubjects implements
53    RecommendInterface,
54    \VuFindHttp\HttpServiceAwareInterface
55{
56    use \VuFindHttp\HttpServiceAwareTrait;
57
58    /**
59     * Parameter to use for search terms
60     *
61     * @var string
62     */
63    protected $requestParam;
64
65    /**
66     * Search limit
67     *
68     * @var int
69     */
70    protected $limit;
71
72    /**
73     * Field to use for date filtering
74     *
75     * @var string
76     */
77    protected $pubFilter;
78
79    /**
80     * Date filter to apply
81     *
82     * @var string
83     */
84    protected $publishedIn = '';
85
86    /**
87     * Subject to search for
88     *
89     * @var string
90     */
91    protected $subject;
92
93    /**
94     * Subject types to use
95     *
96     * @var array
97     */
98    protected $subjectTypes;
99
100    /**
101     * Result of search (false if none)
102     *
103     * @var array|bool
104     */
105    protected $result = false;
106
107    /**
108     * Store the configuration of the recommendation module.
109     *
110     * @param string $settings Settings from searches.ini.
111     *
112     * @return void
113     */
114    public function setConfig($settings)
115    {
116        // Parse out parameters:
117        $params = explode(':', $settings);
118        $this->requestParam = empty($params[0]) ? 'lookfor' : $params[0];
119        $this->limit = isset($params[1]) && is_numeric($params[1]) && $params[1] > 0
120            ? intval($params[1]) : 5;
121        $this->pubFilter = (!isset($params[2]) || empty($params[2])) ?
122            'publishDate' : $params[2];
123        if (strtolower(trim($this->pubFilter)) == 'false') {
124            $this->pubFilter = false;
125        }
126
127        if (isset($params[3])) {
128            $this->subjectTypes = explode(',', $params[3]);
129        } else {
130            $this->subjectTypes = ['topic'];
131        }
132
133        // A 4th parameter is not specified in searches.ini, if it exists
134        //     it has been passed in by an AJAX call and carries the
135        //     publication date range in the form YYYY-YYYY
136        if (isset($params[4]) && strstr($params[4], '-') != false) {
137            $this->publishedIn = $params[4];
138        }
139    }
140
141    /**
142     * Called before the Search Results object performs its main search
143     * (specifically, in response to \VuFind\Search\SearchRunner::EVENT_CONFIGURED).
144     * This method is responsible for setting search parameters needed by the
145     * recommendation module and for reading any existing search parameters that may
146     * be needed.
147     *
148     * @param \VuFind\Search\Base\Params $params  Search parameter object
149     * @param \Laminas\Stdlib\Parameters $request Parameter object representing user
150     * request.
151     *
152     * @return void
153     */
154    public function init($params, $request)
155    {
156        // Get and normalise $requestParam
157        $this->subject = $request->get($this->requestParam);
158
159        // Set up the published date range if it has not already been provided:
160        if (empty($this->publishedIn) && $this->pubFilter) {
161            $this->publishedIn = $this->getPublishedDates(
162                $this->pubFilter,
163                $params,
164                $request
165            );
166        }
167    }
168
169    /**
170     * Called after the Search Results object has performed its main search. This
171     * may be used to extract necessary information from the Search Results object
172     * or to perform completely unrelated processing.
173     *
174     * @param \VuFind\Search\Base\Results $results Search results object
175     *
176     * @return void
177     */
178    public function process($results)
179    {
180        // Only proceed if we have a request parameter value
181        if (!empty($this->subject)) {
182            $ol = new OpenLibrary($this->httpService->createClient());
183            $result = $ol->getSubjects(
184                $this->subject,
185                $this->publishedIn,
186                $this->subjectTypes,
187                true,
188                false,
189                $this->limit,
190                null,
191                true
192            );
193
194            if (!empty($result)) {
195                $this->result = [
196                    'worksArray' => $result, 'subject' => $this->subject,
197                ];
198            }
199        }
200    }
201
202    /**
203     * Support function to get publication date range. Return string in the form
204     * "YYYY-YYYY"
205     *
206     * @param string                     $field   Name of filter field to check for
207     * date limits
208     * @param \VuFind\Search\Params\Base $params  Search parameter object
209     * @param \Laminas\Stdlib\Parameters $request Parameter object representing user
210     *                                            request.
211     *
212     * @return string
213     */
214    protected function getPublishedDates($field, $params, $request)
215    {
216        $range = null;
217        // Try to extract range details from request parameters or SearchObject:
218        $from = $request->get($field . 'from');
219        $to = $request->get($field . 'to');
220        if (null !== $from && null !== $to) {
221            $range = ['from' => $from, 'to' => $to];
222        } elseif (is_object($params)) {
223            $currentFilters = $params->getRawFilters();
224            if (isset($currentFilters[$field][0])) {
225                $range = SolrUtils::parseRange($currentFilters[$field][0]);
226            }
227        }
228
229        // Normalize range if we found one:
230        if (isset($range)) {
231            if (empty($range['from']) || $range['from'] == '*') {
232                $range['from'] = 0;
233            }
234            if (empty($range['to']) || $range['to'] == '*') {
235                $range['to'] = date('Y') + 1;
236            }
237            return $range['from'] . '-' . $range['to'];
238        }
239
240        // No range found?  Return empty string:
241        return '';
242    }
243
244    /**
245     * Get the results of the subject query -- false if none, otherwise an array
246     * with 'worksArray' and 'subject' keys.
247     *
248     * @return bool|array
249     */
250    public function getResult()
251    {
252        return $this->result;
253    }
254}