Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Suggester
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 2
240
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getSuggestions
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
210
1<?php
2
3/**
4 * Autocomplete handler plugin manager
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  Autocomplete
25 * @author   Demian Katz <demian.katz@villanova.edu>
26 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org/wiki/development:plugins:autosuggesters Wiki
28 */
29
30namespace VuFind\Autocomplete;
31
32use Laminas\Stdlib\Parameters;
33use VuFind\Config\PluginManager as ConfigManager;
34use VuFind\Search\Options\PluginManager as OptionsManager;
35
36use function is_callable;
37use function is_object;
38
39/**
40 * Autocomplete handler plugin manager
41 *
42 * @category VuFind
43 * @package  Autocomplete
44 * @author   Demian Katz <demian.katz@villanova.edu>
45 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
46 * @link     https://vufind.org/wiki/development:plugins:autosuggesters Wiki
47 */
48class Suggester
49{
50    /**
51     * Autocomplete plugin manager.
52     *
53     * @var PluginManager
54     */
55    protected $pluginManager = null;
56
57    /**
58     * Search options plugin manager.
59     *
60     * @var OptionsManager
61     */
62    protected $optionsManager = null;
63
64    /**
65     * Configuration manager.
66     *
67     * @var ConfigManager
68     */
69    protected $configManager = null;
70
71    /**
72     * Constructor
73     *
74     * @param PluginManager  $pm Autocomplete plugin manager
75     * @param ConfigManager  $cm Config manager
76     * @param OptionsManager $om Options manager
77     */
78    public function __construct(
79        PluginManager $pm,
80        ConfigManager $cm,
81        OptionsManager $om
82    ) {
83        $this->pluginManager = $pm;
84        $this->configManager = $cm;
85        $this->optionsManager = $om;
86    }
87
88    /**
89     * This returns an array of suggestions based on current request parameters.
90     * This logic is present in the factory class so that it can be easily shared
91     * by multiple AJAX handlers.
92     *
93     * @param Parameters $request    The user request
94     * @param string     $typeParam  Request parameter containing search type
95     * @param string     $queryParam Request parameter containing query string
96     *
97     * @return array
98     */
99    public function getSuggestions($request, $typeParam = 'type', $queryParam = 'q')
100    {
101        // Process incoming parameters:
102        $type = $request->get($typeParam, '');
103        $query = $request->get($queryParam, '');
104        $searcher = $request->get('searcher', 'Solr');
105        $hiddenFilters = $request->get('hiddenFilters', []);
106
107        if (str_starts_with($type, 'VuFind:')) {
108            // If we're using a combined search box, we need to override the searcher
109            // and type settings.
110            [, $tmp] = explode(':', $type, 2);
111            [$searcher, $type] = explode('|', $tmp, 2);
112        } elseif (
113            str_starts_with($type, 'External:')
114            && str_contains($type, '/Alphabrowse')
115        ) {
116            // If includeAlphaBrowse is turned on in searchbox.ini, we should use a
117            // special prefix to allow configuration of alphabrowse-specific handlers
118            [, $tmp] = explode('?', $type, 2);
119            parse_str($tmp, $browseQuery);
120            if (!empty($browseQuery['source'])) {
121                $type = 'alphabrowse_' . $browseQuery['source'];
122            }
123        }
124
125        // get Autocomplete_Type config
126        $options = $this->optionsManager->get($searcher);
127        $config = $this->configManager->get($options->getSearchIni());
128        $types = isset($config->Autocomplete_Types) ?
129            $config->Autocomplete_Types->toArray() : [];
130
131        // Figure out which handler to use:
132        if (!empty($type) && isset($types[$type])) {
133            $module = $types[$type];
134        } elseif (isset($config->Autocomplete->default_handler)) {
135            $module = $config->Autocomplete->default_handler;
136        } else {
137            $module = false;
138        }
139
140        // Get suggestions:
141        if ($module) {
142            if (!str_contains($module, ':')) {
143                $module .= ':'; // force colon to avoid warning in explode below
144            }
145            [$name, $params] = explode(':', $module, 2);
146            $handler = $this->pluginManager->get($name);
147            $handler->setConfig($params);
148        } else {
149            $handler = null;
150        }
151
152        if (is_callable([$handler, 'addFilters'])) {
153            $handler->addFilters($hiddenFilters);
154        }
155
156        // if the handler needs the complete request, pass it on
157        if (is_callable([$handler, 'setRequest'])) {
158            $handler->setRequest($request);
159        }
160
161        return is_object($handler)
162            ? array_values($handler->getSuggestions($query)) : [];
163    }
164}