Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
85.11% |
40 / 47 |
|
50.00% |
5 / 10 |
CRAP | |
0.00% |
0 / 1 |
TabManager | |
85.11% |
40 / 47 |
|
50.00% |
5 / 10 |
27.06 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
setContext | |
75.00% |
3 / 4 |
|
0.00% |
0 / 1 |
2.06 | |||
initializeCurrentContext | |
87.50% |
7 / 8 |
|
0.00% |
0 / 1 |
2.01 | |||
getConfigByClass | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
getTabServiceNames | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getBackgroundTabNames | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getExtraScripts | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultTabForRecord | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
7.14 | |||
getTabDetailsForRecord | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getTabsForRecord | |
76.92% |
10 / 13 |
|
0.00% |
0 / 1 |
7.60 |
1 | <?php |
2 | |
3 | /** |
4 | * Record tab manager |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Villanova University 2019. |
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 RecordTabs |
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:record_tabs Wiki |
28 | */ |
29 | |
30 | namespace VuFind\RecordTab; |
31 | |
32 | use VuFind\Config\PluginManager as ConfigManager; |
33 | use VuFind\RecordDriver\AbstractBase as AbstractRecordDriver; |
34 | |
35 | use function in_array; |
36 | |
37 | /** |
38 | * Record tab manager |
39 | * |
40 | * @category VuFind |
41 | * @package RecordTabs |
42 | * @author Demian Katz <demian.katz@villanova.edu> |
43 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
44 | * @link https://vufind.org/wiki/development:plugins:record_tabs Wiki |
45 | */ |
46 | class TabManager |
47 | { |
48 | /** |
49 | * Settings for different tab contexts. |
50 | * |
51 | * @var array |
52 | */ |
53 | protected $contextSettings = [ |
54 | 'record' => [ |
55 | 'configFile' => 'RecordTabs', |
56 | 'legacyConfigSection' => 'recorddriver_tabs', |
57 | ], |
58 | 'collection' => [ |
59 | 'configFile' => 'CollectionTabs', |
60 | 'legacyConfigSection' => 'recorddriver_collection_tabs', |
61 | ], |
62 | ]; |
63 | |
64 | /** |
65 | * Tab configurations |
66 | * |
67 | * @var array |
68 | */ |
69 | protected $config = []; |
70 | |
71 | /** |
72 | * Configuration plugin manager |
73 | * |
74 | * @var ConfigManager |
75 | */ |
76 | protected $configManager; |
77 | |
78 | /** |
79 | * RecordTab plugin manager |
80 | * |
81 | * @var PluginManager |
82 | */ |
83 | protected $pluginManager; |
84 | |
85 | /** |
86 | * Overall framework configuration (used for fetching configurations "the old |
87 | * way" -- can eventually be deprecated). |
88 | * |
89 | * @var array |
90 | */ |
91 | protected $legacyConfig; |
92 | |
93 | /** |
94 | * Current active context (defaults to 'record') |
95 | * |
96 | * @var string |
97 | */ |
98 | protected $context = 'record'; |
99 | |
100 | /** |
101 | * Constructor |
102 | * |
103 | * @param PluginManager $pm RecordTab plugin manager |
104 | * @param ConfigManager $cm Configuration plugin manager |
105 | * @param array $legacyConfig Overall framework configuration (only |
106 | * used for legacy config loading; optional) |
107 | */ |
108 | public function __construct( |
109 | PluginManager $pm, |
110 | ConfigManager $cm, |
111 | $legacyConfig = [] |
112 | ) { |
113 | $this->pluginManager = $pm; |
114 | $this->configManager = $cm; |
115 | $this->legacyConfig = $legacyConfig; |
116 | |
117 | // Initialize default context. |
118 | $this->initializeCurrentContext(); |
119 | } |
120 | |
121 | /** |
122 | * Set and (if necessary) initialize the context. |
123 | * |
124 | * @param string $context Context to initialize |
125 | * |
126 | * @return void |
127 | * @throws \Exception |
128 | */ |
129 | public function setContext($context) |
130 | { |
131 | if (!in_array($context, array_keys($this->contextSettings))) { |
132 | throw new \Exception("Unsupported context: $context"); |
133 | } |
134 | $this->context = $context; |
135 | $this->initializeCurrentContext(); |
136 | } |
137 | |
138 | /** |
139 | * Initialize the current context (if not already initialized). |
140 | * |
141 | * @return void |
142 | */ |
143 | protected function initializeCurrentContext() |
144 | { |
145 | if (!isset($this->config[$this->context])) { |
146 | $key = $this->contextSettings[$this->context]['legacyConfigSection'] |
147 | ?? 'recorddriver_tabs'; |
148 | $legacyConfig = $this->legacyConfig['vufind'][$key] ?? []; |
149 | $iniConfig = $this->configManager->get( |
150 | $this->contextSettings[$this->context]['configFile'] |
151 | )->toArray(); |
152 | $this->config[$this->context] = array_merge($legacyConfig, $iniConfig); |
153 | } |
154 | } |
155 | |
156 | /** |
157 | * Load the specified key from the configuration array using the best |
158 | * available match to the class of the provided driver. Return the default |
159 | * value if no match is found. |
160 | * |
161 | * @param AbstractRecordDriver $driver Record driver |
162 | * @param string $setting Key to load from configuration |
163 | * @param string $default Default to use if no setting found |
164 | * |
165 | * @return mixed |
166 | */ |
167 | protected function getConfigByClass( |
168 | AbstractRecordDriver $driver, |
169 | $setting, |
170 | $default |
171 | ) { |
172 | // Get the current record driver's class name, then start a loop |
173 | // in case we need to use a parent class' name to find the appropriate |
174 | // setting. |
175 | $className = $driver::class; |
176 | do { |
177 | if (isset($this->config[$this->context][$className][$setting])) { |
178 | return $this->config[$this->context][$className][$setting]; |
179 | } |
180 | } while ($className = get_parent_class($className)); |
181 | // No setting found... |
182 | return $default; |
183 | } |
184 | |
185 | /** |
186 | * Get an array of service names by looking up the provided record driver in |
187 | * the provided tab configuration array. |
188 | * |
189 | * @param AbstractRecordDriver $driver Record driver |
190 | * |
191 | * @return array |
192 | */ |
193 | protected function getTabServiceNames(AbstractRecordDriver $driver) |
194 | { |
195 | return $this->getConfigByClass($driver, 'tabs', []); |
196 | } |
197 | |
198 | /** |
199 | * Get an array of tabs names configured to load via AJAX in the background |
200 | * |
201 | * @param AbstractRecordDriver $driver Record driver |
202 | * |
203 | * @return array |
204 | */ |
205 | public function getBackgroundTabNames(AbstractRecordDriver $driver) |
206 | { |
207 | return $this->getConfigByClass($driver, 'backgroundLoadedTabs', []); |
208 | } |
209 | |
210 | /** |
211 | * Get an array of extra JS scripts by looking up the provided record driver in |
212 | * the provided tab configuration array. |
213 | * |
214 | * @return array |
215 | */ |
216 | public function getExtraScripts() |
217 | { |
218 | return $this->config[$this->context]['TabScripts'] ?? []; |
219 | } |
220 | |
221 | /** |
222 | * Get a default tab by looking up the provided record driver in the tab |
223 | * configuration array. |
224 | * |
225 | * @param AbstractRecordDriver $driver Record driver |
226 | * @param array $tabs Details on available tabs (returned |
227 | * from getTabsForRecord()). |
228 | * @param string $fallback Fallback to use if no tab specified |
229 | * or matched. |
230 | * |
231 | * @return string |
232 | */ |
233 | public function getDefaultTabForRecord( |
234 | AbstractRecordDriver $driver, |
235 | array $tabs, |
236 | $fallback = null |
237 | ) { |
238 | // Load default from module configuration: |
239 | $default = $this->getConfigByClass($driver, 'defaultTab', null); |
240 | |
241 | // Missing/invalid record driver configuration? Fall back to provided |
242 | // default: |
243 | if ((!$default || !isset($tabs[$default])) && isset($tabs[$fallback])) { |
244 | $default = $fallback; |
245 | } |
246 | |
247 | // Is configured tab still invalid? If so, pick first existing tab: |
248 | if ((!$default || !isset($tabs[$default])) && !empty($tabs)) { |
249 | $keys = array_keys($tabs); |
250 | $default = $keys[0]; |
251 | } |
252 | |
253 | return $default; |
254 | } |
255 | |
256 | /** |
257 | * Convenience method to load tab information, including default, in a |
258 | * single pass. Returns an associative array with 'tabs' and 'default' keys. |
259 | * |
260 | * @param AbstractRecordDriver $driver Record driver |
261 | * @param \Laminas\Http\Request $request User request (optional) |
262 | * @param string $fallback Fallback default tab to use if no |
263 | * tab specified or matched. |
264 | * |
265 | * @return array |
266 | */ |
267 | public function getTabDetailsForRecord( |
268 | AbstractRecordDriver $driver, |
269 | $request = null, |
270 | $fallback = null |
271 | ) { |
272 | $tabs = $this->getTabsForRecord($driver, $request); |
273 | $default = $this->getDefaultTabForRecord($driver, $tabs, $fallback); |
274 | return compact('tabs', 'default'); |
275 | } |
276 | |
277 | /** |
278 | * Get an array of valid tabs for the provided record driver. |
279 | * |
280 | * @param AbstractRecordDriver $driver Record driver |
281 | * @param \Laminas\Http\Request $request User request (optional) |
282 | * |
283 | * @return array service name => tab object |
284 | */ |
285 | public function getTabsForRecord( |
286 | AbstractRecordDriver $driver, |
287 | $request = null |
288 | ) { |
289 | $tabs = []; |
290 | foreach ($this->getTabServiceNames($driver) as $tabKey => $svc) { |
291 | if (!$this->pluginManager->has($svc)) { |
292 | continue; |
293 | } |
294 | $newTab = $this->pluginManager->get($svc); |
295 | if (method_exists($newTab, 'setRecordDriver')) { |
296 | $newTab->setRecordDriver($driver); |
297 | } |
298 | if ( |
299 | $request instanceof \Laminas\Http\Request |
300 | && method_exists($newTab, 'setRequest') |
301 | ) { |
302 | $newTab->setRequest($request); |
303 | } |
304 | if ($newTab->isActive()) { |
305 | $tabs[$tabKey] = $newTab; |
306 | } |
307 | } |
308 | return $tabs; |
309 | } |
310 | } |