Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 132 |
|
0.00% |
0 / 19 |
CRAP | |
0.00% |
0 / 1 |
ThemeRegistry | |
0.00% |
0 / 132 |
|
0.00% |
0 / 19 |
4032 | |
0.00% |
0 / 1 |
getExtension | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getConfigId | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setWebSource | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setDefaultTheme | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
getTheme | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
30 | |||
getDefaultTheme | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 | |||
createTarget | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
registerTheme | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
156 | |||
unregisterTheme | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
42 | |||
updatePath | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
resolveStylesheetUrl | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
resolveTemplatePath | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getResolvedBase | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
20 | |||
getAvailableThemes | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 | |||
getTemplate | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
getStylesheet | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getBaseTemplate | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
20 | |||
getBaseStylesheet | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 | |||
getServiceManager | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation; under version 2 |
7 | * of the License (non-upgradable). |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | * |
18 | * Copyright (c) 2015 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); |
19 | * |
20 | */ |
21 | |
22 | namespace oat\tao\model; |
23 | |
24 | use common_Exception; |
25 | use common_ext_ExtensionsManager; |
26 | use Exception; |
27 | use oat\oatbox\AbstractRegistry; |
28 | use oat\oatbox\service\ServiceManager; |
29 | use oat\tao\model\asset\AssetService; |
30 | use oat\tao\model\websource\WebsourceManager; |
31 | |
32 | class ThemeRegistry extends AbstractRegistry |
33 | { |
34 | public const WEBSOURCE = 'websource_'; |
35 | |
36 | /** |
37 | * |
38 | * @see \oat\oatbox\AbstractRegistry::getExtension() |
39 | */ |
40 | protected function getExtension() |
41 | { |
42 | return common_ext_ExtensionsManager::singleton()->getExtensionById('tao'); |
43 | } |
44 | |
45 | /** |
46 | * |
47 | * @see \oat\oatbox\AbstractRegistry::getConfigId() |
48 | */ |
49 | protected function getConfigId() |
50 | { |
51 | return 'themes'; |
52 | } |
53 | |
54 | |
55 | public function setWebSource($websource) |
56 | { |
57 | $this->set(ThemeRegistry::WEBSOURCE, $websource); |
58 | } |
59 | |
60 | |
61 | /** |
62 | * |
63 | * @author Lionel Lecaque, lionel@taotesting.com |
64 | * @param string $target |
65 | * @param string $themeId |
66 | * @throws common_Exception |
67 | */ |
68 | public function setDefaultTheme($target, $themeId) |
69 | { |
70 | $theme = $this->getTheme($target, $themeId); |
71 | if (!is_null($theme)) { |
72 | $array = $this->get($target); |
73 | $array['default'] = $themeId; |
74 | $this->set($target, $array); |
75 | } |
76 | } |
77 | |
78 | /** |
79 | * Get the theme array identified by its target and id |
80 | * |
81 | * @param string $target |
82 | * @param string $themeId |
83 | * @return array |
84 | * @throws common_Exception |
85 | */ |
86 | private function getTheme($target, $themeId) |
87 | { |
88 | |
89 | $returnValue = null; |
90 | if (!$this->isRegistered($target)) { |
91 | throw new common_Exception('Target ' . $target . ' does not exist'); |
92 | } else { |
93 | $array = $this->get($target); |
94 | $found = false; |
95 | foreach ($array['available'] as $theme) { |
96 | if ($theme['id'] == $themeId) { |
97 | $found = true; |
98 | $returnValue = $theme; |
99 | break; |
100 | } |
101 | } |
102 | if (!$found) { |
103 | throw new ThemeNotFoundException('Theme ' . $themeId . ' not found for target ' . $target); |
104 | } |
105 | } |
106 | return $returnValue; |
107 | } |
108 | |
109 | /** |
110 | * Get the default theme array |
111 | */ |
112 | public function getDefaultTheme($target) |
113 | { |
114 | $defaultTheme = null; |
115 | if (!$this->isRegistered($target)) { |
116 | throw new common_Exception('Target ' . $target . ' does not exist'); |
117 | } else { |
118 | $array = $this->get($target); |
119 | if (isset($array['default'])) { |
120 | $themeId = $array['default']; |
121 | try { |
122 | $defaultTheme = $this->getTheme($target, $themeId); |
123 | } catch (Exception $e) { |
124 | //not found |
125 | $defaultTheme = null; |
126 | } |
127 | } |
128 | } |
129 | return $defaultTheme; |
130 | } |
131 | |
132 | /** |
133 | * Adds a new target to the System |
134 | * |
135 | * @param string $targetId |
136 | * @param string|array $base |
137 | * @throws common_Exception |
138 | */ |
139 | public function createTarget($targetId, $base) |
140 | { |
141 | |
142 | if (!is_string($base) && !is_array($base)) { |
143 | throw new common_Exception('Invalid base format'); |
144 | } |
145 | |
146 | $array = [ |
147 | 'base' => $base, |
148 | 'available' => [] |
149 | ]; |
150 | $this->set($targetId, $array); |
151 | } |
152 | |
153 | |
154 | /** |
155 | * Adds a theme to the registry |
156 | * |
157 | * @author Lionel Lecaque, lionel@taotesting.com |
158 | * @param string $id |
159 | * @param string $name |
160 | * @param string $path |
161 | * @param array $targets |
162 | * @throws common_Exception |
163 | */ |
164 | public function registerTheme($id, $name, $path = '', $targets = [], $templates = []) |
165 | { |
166 | if (preg_match('/^[a-zA-Z0-9]*$/', $id) === 0) { |
167 | throw new common_Exception('Invalid id "' . $id . '"'); |
168 | } |
169 | if (!is_array($targets) || count($targets) === 0) { |
170 | throw new common_Exception('No targets were provided for theme ' . $id); |
171 | } |
172 | |
173 | foreach ($targets as $target) { |
174 | if (!$this->isRegistered($target)) { |
175 | throw new common_Exception('Target ' . $target . ' does not exist'); |
176 | } else { |
177 | $array = $this->get($target); |
178 | |
179 | foreach ($array['available'] as $theme) { |
180 | if ($theme['id'] == $id) { |
181 | throw new common_Exception('Theme ' . $id . ' already exists for target ' . $target); |
182 | } |
183 | } |
184 | |
185 | $theme = [ |
186 | 'id' => $id, |
187 | 'name' => $name |
188 | ]; |
189 | |
190 | //the path is optional |
191 | if ($path) { |
192 | $theme['path'] = $path; |
193 | } |
194 | |
195 | //register templates |
196 | if (is_array($templates) && count($templates) > 0) { |
197 | $theme['templates'] = []; |
198 | foreach ($templates as $templateId => $tpl) { |
199 | $theme['templates'][$templateId] = $tpl; |
200 | } |
201 | } |
202 | |
203 | $array['available'][] = $theme; |
204 | } |
205 | $this->set($target, $array); |
206 | } |
207 | } |
208 | |
209 | /** |
210 | * |
211 | * @author Joel Bout, joel@taotesting.com |
212 | * |
213 | * @param string $id |
214 | * @throws common_Exception |
215 | */ |
216 | public function unregisterTheme($id) |
217 | { |
218 | if (preg_match('/^[a-zA-Z0-9]*$/', $id) === 0) { |
219 | throw new common_Exception('Invalid id "' . $id . '"'); |
220 | } |
221 | |
222 | $isDeleted = false; |
223 | |
224 | $map = $this->getMap(); |
225 | unset($map[ThemeRegistry::WEBSOURCE]);//still ugly but looks better than 'continue' |
226 | foreach ($map as $target => $themes) { |
227 | foreach ($themes['available'] as $key => $theme) { |
228 | if ($theme['id'] == $id) { |
229 | unset($themes['available'][$key]); |
230 | $isDeleted = true; |
231 | } |
232 | } |
233 | $this->set($target, $themes); |
234 | } |
235 | |
236 | if (!$isDeleted) { |
237 | throw new ThemeNotFoundException('Theme ' . $id . ' not found for any target'); |
238 | } |
239 | } |
240 | |
241 | /** |
242 | * @param $theme |
243 | * @return mixed |
244 | */ |
245 | private function updatePath($theme) |
246 | { |
247 | |
248 | if (isset($theme['path'])) { |
249 | if (strpos($theme['path'], ThemeRegistry::WEBSOURCE) === 0) { |
250 | $websource = WebsourceManager::singleton()->getWebsource($this->get(ThemeRegistry::WEBSOURCE)); |
251 | $webUrl = $websource->getAccessUrl(substr($theme['path'], strlen(ThemeRegistry::WEBSOURCE))); |
252 | $theme['path'] = $webUrl; |
253 | } else { |
254 | $assetService = $this->getServiceManager()->get(AssetService::SERVICE_ID); |
255 | $theme['path'] = $assetService->getAsset($theme['path']); |
256 | } |
257 | } |
258 | |
259 | return $theme; |
260 | } |
261 | |
262 | /** |
263 | * Get the resolved absolute URL for a stylesheet |
264 | * |
265 | * @param string $path |
266 | * @return string |
267 | */ |
268 | private function resolveStylesheetUrl($path) |
269 | { |
270 | $websource = WebsourceManager::singleton()->getWebsource($this->get(ThemeRegistry::WEBSOURCE)); |
271 | if (strpos($path, ThemeRegistry::WEBSOURCE) === 0) { |
272 | return $websource->getAccessUrl(substr($path, strlen(ThemeRegistry::WEBSOURCE))); |
273 | } else { |
274 | $assetService = $this->getServiceManager()->get(AssetService::SERVICE_ID); |
275 | return $assetService->getAsset($path); |
276 | } |
277 | } |
278 | |
279 | /** |
280 | * Resolve the template absolute path |
281 | * |
282 | * @todo make it support templates as data |
283 | * @param string $tpl |
284 | * @return string |
285 | */ |
286 | private function resolveTemplatePath($tpl) |
287 | { |
288 | return ROOT_PATH . $tpl; |
289 | } |
290 | |
291 | /** |
292 | * Resolve the path and url defined in target "base" |
293 | * |
294 | * @param string $target |
295 | * @return mixed |
296 | * @throws common_Exception |
297 | */ |
298 | private function getResolvedBase($target) |
299 | { |
300 | |
301 | $base = null; |
302 | $array = $this->get($target); |
303 | |
304 | if (is_string($array['base'])) { |
305 | $assetService = $this->getServiceManager()->get(AssetService::SERVICE_ID); |
306 | $base = $assetService->getAsset($array['base']); |
307 | } elseif (is_array($array['base'])) { |
308 | $base = [ |
309 | 'css' => $this->resolveStylesheetUrl($array['base']['css']), |
310 | 'templates' => [] |
311 | ]; |
312 | |
313 | foreach ($array['base']['templates'] as $id => $path) { |
314 | $base['templates'][$id] = $this->resolveTemplatePath($path); |
315 | } |
316 | } else { |
317 | throw new common_Exception('invalid type for theme base'); |
318 | } |
319 | |
320 | return $base; |
321 | } |
322 | |
323 | /** |
324 | * Get list of available theme |
325 | * The available themes have their URL and paths resolved |
326 | * |
327 | * @author Lionel Lecaque, lionel@taotesting.com |
328 | */ |
329 | public function getAvailableThemes() |
330 | { |
331 | |
332 | $returnValue = []; |
333 | foreach ($this->getMap() as $target => $value) { |
334 | //ugly |
335 | if ($target == ThemeRegistry::WEBSOURCE) { |
336 | continue; |
337 | } |
338 | //retrieve all other value |
339 | $returnValue[$target] = $value; |
340 | |
341 | // adapt path for all theme |
342 | $returnValue[$target]['available'] = []; |
343 | foreach ($value['available'] as $theme) { |
344 | $returnValue[$target]['available'][] = $this->updatePath($theme); |
345 | } |
346 | |
347 | $returnValue[$target]['base'] = $this->getResolvedBase($target); |
348 | } |
349 | return $returnValue; |
350 | } |
351 | |
352 | /** |
353 | * Get the absolute path to a theme template |
354 | * |
355 | * @deprecated use theme\ThemeService instead |
356 | * @param string $target |
357 | * @param string $themeId |
358 | * @param string $templateId |
359 | * @return string |
360 | */ |
361 | public function getTemplate($target, $themeId, $templateId) |
362 | { |
363 | $theme = $this->getTheme($target, $themeId); |
364 | if (isset($theme['templates']) && isset($theme['templates'][$templateId])) { |
365 | return $this->resolveTemplatePath($theme['templates'][$templateId]); |
366 | } |
367 | return null; |
368 | } |
369 | |
370 | /** |
371 | * Get the abosolute url to a stylesheet |
372 | * |
373 | * @deprecated use theme\ThemeService instead |
374 | * @param string $target |
375 | * @param string $themeId |
376 | * @return string |
377 | */ |
378 | public function getStylesheet($target, $themeId) |
379 | { |
380 | $theme = $this->getTheme($target, $themeId); |
381 | if (isset($theme['path'])) { |
382 | return $this->resolveStylesheetUrl($theme['path']); |
383 | } |
384 | return null;//not found |
385 | } |
386 | |
387 | /** |
388 | * Get the asbolute path to the base template |
389 | * |
390 | * @deprecated use theme\ThemeService instead |
391 | * @param string $target |
392 | * @param string $templateId |
393 | * @return string |
394 | */ |
395 | public function getBaseTemplate($target, $templateId) |
396 | { |
397 | $base = $this->getResolvedBase($target); |
398 | if (is_array($base) && isset($base['templates']) && isset($base['templates'][$templateId])) { |
399 | return $base['templates'][$templateId]; |
400 | } |
401 | return null; |
402 | } |
403 | |
404 | /** |
405 | * Get the absolute url to the base css |
406 | * |
407 | * @deprecated use theme\ThemeService instead |
408 | * @param string $target |
409 | * @return string |
410 | */ |
411 | public function getBaseStylesheet($target) |
412 | { |
413 | $base = $this->getResolvedBase($target); |
414 | if (is_string($base)) { |
415 | return $base; |
416 | } elseif (is_array($base) && isset($base['css'])) { |
417 | return $base['css']; |
418 | } |
419 | return null; |
420 | } |
421 | |
422 | public function getServiceManager() |
423 | { |
424 | return ServiceManager::getServiceManager(); |
425 | } |
426 | } |