Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 74 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
MenuService | |
0.00% |
0 / 74 |
|
0.00% |
0 / 9 |
1122 | |
0.00% |
0 / 1 |
getStructuresFilePath | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
getPerspectivesByGroup | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
getAllPerspectives | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
retrieveAllPerspectives | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
readStructure | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
buildStructures | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
156 | |||
getPerspective | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
getSection | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
flushCache | |
0.00% |
0 / 2 |
|
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) 2002-2008 (original work) Public Research Centre Henri Tudor & University of Luxembourg |
19 | * (under the project TAO & TAO2); |
20 | * 2008-2010 (update and modification) Deutsche Institut für Internationale Pädagogische Forschung |
21 | * (under the project TAO-TRANSFER); |
22 | * 2009-2012 (update and modification) Public Research Centre Henri Tudor |
23 | * (under the project TAO-SUSTAIN & TAO-DEV); |
24 | * 2014-2023 (update and modification) Open Assessment Technologies SA; |
25 | */ |
26 | |
27 | namespace oat\tao\model\menu; |
28 | |
29 | use common_ext_ExtensionsManager; |
30 | use helpers_ExtensionHelper; |
31 | use SimpleXMLElement; |
32 | |
33 | /** |
34 | * @author joel bout, <joel@taotesting.com> |
35 | */ |
36 | class MenuService |
37 | { |
38 | /** |
39 | * identifier to use to cache the structures |
40 | * |
41 | * @var string |
42 | */ |
43 | public const CACHE_KEY = 'tao_structures'; |
44 | |
45 | /** |
46 | * Use caching mechanism for the structure. |
47 | * For performances issues, cache should be enabled. |
48 | * |
49 | * @var boolean |
50 | */ |
51 | public const USE_CACHE = true; |
52 | |
53 | /** |
54 | * to stock the extension structure |
55 | * |
56 | * @access protected |
57 | * |
58 | * @var array |
59 | */ |
60 | protected static $structure = []; |
61 | |
62 | // --- OPERATIONS --- |
63 | |
64 | /** |
65 | * Load the extension structure file. |
66 | * Return the SimpleXmlElement object (don't forget to cast it) |
67 | * |
68 | * @access protected |
69 | * |
70 | * @author Jerome Bogaerts, <jerome@taotesting.com> |
71 | * |
72 | * @param string extensionId |
73 | * @param mixed $extensionId |
74 | * |
75 | * @return SimpleXMLElement |
76 | */ |
77 | public static function getStructuresFilePath($extensionId) |
78 | { |
79 | $extension = common_ext_ExtensionsManager::singleton()->getExtensionById($extensionId); |
80 | $extra = $extension->getManifest()->getExtra(); |
81 | if (isset($extra['structures'])) { |
82 | $structureFilePath = $extra['structures']; |
83 | } else { |
84 | $structureFilePath = $extension->getDir() . 'actions/structures.xml'; |
85 | } |
86 | |
87 | if (file_exists($structureFilePath)) { |
88 | return $structureFilePath; |
89 | } |
90 | return null; |
91 | } |
92 | |
93 | /** |
94 | * Get the structure content (from the structure.xml file) of each extension filtered by group. |
95 | * |
96 | * @param $groupId |
97 | * |
98 | * @return array |
99 | */ |
100 | public static function getPerspectivesByGroup($groupId) |
101 | { |
102 | $perspectives = []; |
103 | foreach (self::getAllPerspectives() as $perspective) { |
104 | if ($perspective -> getGroup() === $groupId) { |
105 | $perspectives[] = $perspective; |
106 | } |
107 | } |
108 | return $perspectives; |
109 | } |
110 | |
111 | /** |
112 | * Get the structure content (from the structure.xml file) of each extension. |
113 | * |
114 | * @return array |
115 | */ |
116 | public static function getAllPerspectives() |
117 | { |
118 | $structure = self::readStructure(); |
119 | return $structure['perspectives']; |
120 | } |
121 | |
122 | /** |
123 | * @return Perspective[] |
124 | */ |
125 | public function retrieveAllPerspectives(): array |
126 | { |
127 | return self::getAllPerspectives(); |
128 | } |
129 | |
130 | /** |
131 | * Reads the structure data. |
132 | * This method manages to cache the structure if needed. |
133 | * |
134 | * @return array() the structure data |
135 | */ |
136 | public static function readStructure() |
137 | { |
138 | if (count(self::$structure) == 0) { |
139 | if (self::USE_CACHE == false) { |
140 | //rebuild structure each time |
141 | self::$structure = self::buildStructures(); |
142 | } else { |
143 | //cache management |
144 | try { |
145 | self::$structure = \common_cache_FileCache::singleton()->get(self::CACHE_KEY); |
146 | } catch (\common_cache_NotFoundException $e) { |
147 | self::$structure = self::buildStructures(); |
148 | \common_cache_FileCache::singleton()->put(self::$structure, self::CACHE_KEY); |
149 | } |
150 | } |
151 | } |
152 | return self::$structure; |
153 | } |
154 | |
155 | /** |
156 | * Get the structure content (from the structure.xml file) of each extension. |
157 | * |
158 | * @return array |
159 | */ |
160 | protected static function buildStructures() |
161 | { |
162 | $perspectives = []; |
163 | $toAdd = []; |
164 | $sorted = helpers_ExtensionHelper::sortByDependencies( |
165 | common_ext_ExtensionsManager::singleton()->getEnabledExtensions() |
166 | ); |
167 | foreach (array_keys($sorted) as $extId) { |
168 | $file = self::getStructuresFilePath($extId); |
169 | if (!is_null($file)) { |
170 | $xmlStructures = new SimpleXMLElement($file, null, true); |
171 | $extStructures = $xmlStructures->xpath('/structures/structure'); |
172 | foreach ($extStructures as $xmlStructure) { |
173 | $perspective = Perspective::fromSimpleXMLElement($xmlStructure, $extId); |
174 | if (!isset($perspectives[$perspective->getId()])) { |
175 | $perspectives[$perspective->getId()] = $perspective; |
176 | } else { |
177 | foreach ($perspective->getChildren() as $section) { |
178 | $perspectives[$perspective->getId()]->addSection($section); |
179 | } |
180 | } |
181 | } |
182 | foreach ($xmlStructures->xpath('/structures/toolbar/toolbaraction') as $xmlStructure) { |
183 | $perspective = Perspective::fromLegacyToolbarAction($xmlStructure, $extId); |
184 | $perspectives[$perspective->getId()] = $perspective; |
185 | if (isset($xmlStructure['structure'])) { |
186 | $toAdd[$perspective->getId()] = (string)$xmlStructure['structure']; |
187 | } |
188 | } |
189 | } |
190 | } |
191 | |
192 | foreach ($toAdd as $to => $from) { |
193 | if (isset($perspectives[$from]) && isset($perspectives[$to])) { |
194 | foreach ($perspectives[$from]->getChildren() as $section) { |
195 | $perspectives[$to]->addSection($section); |
196 | } |
197 | } |
198 | } |
199 | |
200 | usort($perspectives, function ($a, $b) { |
201 | return $a->getLevel() - $b->getLevel(); |
202 | }); |
203 | |
204 | return [ |
205 | 'perspectives' => $perspectives, |
206 | ]; |
207 | } |
208 | |
209 | /** |
210 | * Get the perspective for the extension/section in parameters |
211 | * or null if not found |
212 | * |
213 | * @access public |
214 | * |
215 | * @author Jerome Bogaerts, <jerome@taotesting.com> |
216 | * |
217 | * @param string extension |
218 | * @param string perspectiveId |
219 | * @param mixed $extension |
220 | * @param mixed $perspectiveId |
221 | * |
222 | * @return Structure |
223 | */ |
224 | public static function getPerspective($extension, $perspectiveId) |
225 | { |
226 | $returnValue = null; |
227 | |
228 | foreach (self::getAllPerspectives() as $perspective) { |
229 | if ($perspective->getId() == $perspectiveId) { |
230 | $returnValue = $perspective; |
231 | break; |
232 | } |
233 | } |
234 | if (empty($returnValue)) { |
235 | \common_Logger::w('Structure ' . $perspectiveId . ' not found for extension ' . $extension); |
236 | } |
237 | |
238 | return $returnValue; |
239 | } |
240 | |
241 | /** |
242 | * Short description of method getSection |
243 | * |
244 | * @access public |
245 | * |
246 | * @author Jerome Bogaerts, <jerome@taotesting.com> |
247 | * |
248 | * @param string extension |
249 | * @param string perspectiveId |
250 | * @param string sectionId |
251 | * @param mixed $extension |
252 | * @param mixed $perspectiveId |
253 | * @param mixed $sectionId |
254 | * |
255 | * @return Section |
256 | */ |
257 | public static function getSection($extension, $perspectiveId, $sectionId) |
258 | { |
259 | $returnValue = null; |
260 | |
261 | $structure = self::getPerspective($extension, $perspectiveId); |
262 | foreach ($structure->getChildren() as $section) { |
263 | if ($section->getId() == $sectionId) { |
264 | $returnValue = $section; |
265 | break; |
266 | } |
267 | } |
268 | if (empty($returnValue)) { |
269 | \common_Logger::w('Section ' . $sectionId . ' not found found for perspective ' . $perspectiveId); |
270 | } |
271 | |
272 | return $returnValue; |
273 | } |
274 | |
275 | public static function flushCache() |
276 | { |
277 | self::$structure = []; |
278 | \common_cache_FileCache::singleton()->remove(self::CACHE_KEY); |
279 | } |
280 | } |