Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 49 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
Factory | |
0.00% |
0 / 49 |
|
0.00% |
0 / 5 |
552 | |
0.00% |
0 / 1 |
getControllers | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
getControllerDescription | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getActionDescription | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
getControllerClasses | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
156 | |||
isControllerClassNameValid | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
30 |
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) 2014 (original work) Open Assessment Technologies SA; |
19 | * |
20 | * |
21 | */ |
22 | |
23 | namespace oat\tao\model\controllerMap; |
24 | |
25 | use common_Logger; |
26 | use oat\tao\model\http\Controller; |
27 | use ReflectionClass; |
28 | use RecursiveDirectoryIterator; |
29 | use DirectoryIterator; |
30 | use RecursiveIteratorIterator; |
31 | use RegexIterator; |
32 | use RecursiveRegexIterator; |
33 | use helpers_PhpTools; |
34 | |
35 | /** |
36 | * Fectory to create the description of the controllers and |
37 | * actions from the source code |
38 | * |
39 | * @author Joel Bout <joel@taotesting.com> |
40 | */ |
41 | class Factory |
42 | { |
43 | /** |
44 | * |
45 | * @param string $extensionId |
46 | * @return ControllerDescription[] array of controller descriptions |
47 | */ |
48 | public function getControllers($extensionId) |
49 | { |
50 | |
51 | $ext = \common_ext_ExtensionsManager::singleton()->getExtensionById($extensionId); |
52 | $controllers = []; |
53 | foreach ($this->getControllerClasses($ext) as $className) { |
54 | $controllers[] = $this->getControllerDescription($className); |
55 | } |
56 | return $controllers; |
57 | } |
58 | |
59 | /** |
60 | * Get a description of the controller |
61 | * |
62 | * @param string $controllerClassName |
63 | * @return ControllerDescription |
64 | */ |
65 | public function getControllerDescription($controllerClassName) |
66 | { |
67 | $reflector = new ReflectionClass($controllerClassName); |
68 | return new ControllerDescription($reflector); |
69 | } |
70 | |
71 | /** |
72 | * Get a description of the action |
73 | * |
74 | * @param string $controllerClassName |
75 | * @param string $actionName |
76 | * @return ActionDescription |
77 | * @throws ActionNotFoundException |
78 | */ |
79 | public function getActionDescription($controllerClassName, $actionName) |
80 | { |
81 | |
82 | if (!class_exists($controllerClassName) || !method_exists($controllerClassName, $actionName)) { |
83 | throw new ActionNotFoundException('Unknown ' . $controllerClassName . '@' . $actionName); |
84 | } |
85 | |
86 | $reflector = new \ReflectionMethod($controllerClassName, $actionName); |
87 | return new ActionDescription($reflector); |
88 | } |
89 | |
90 | /** |
91 | * Helper to find all controllers |
92 | * |
93 | * @param \common_ext_Extension $extension |
94 | * @return array |
95 | * @ignore |
96 | */ |
97 | private function getControllerClasses(\common_ext_Extension $extension) |
98 | { |
99 | $returnValue = []; |
100 | |
101 | // routes |
102 | $namespaces = []; |
103 | foreach ($extension->getManifest()->getRoutes() as $mapedPath => $ns) { |
104 | if (is_string($ns)) { |
105 | $namespaces[] = trim($ns, '\\'); |
106 | } |
107 | } |
108 | if (!empty($namespaces)) { |
109 | common_Logger::t('Namespace found in routes for extension ' . $extension->getId()); |
110 | $classes = []; |
111 | $recDir = new RecursiveDirectoryIterator($extension->getDir()); |
112 | $recIt = new RecursiveIteratorIterator($recDir); |
113 | $regexIt = new RegexIterator($recIt, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); |
114 | foreach ($regexIt as $entry) { |
115 | $info = helpers_PhpTools::getClassInfo($entry[0]); |
116 | if (!empty($info['ns'])) { |
117 | $ns = trim($info['ns'], '\\'); |
118 | if (!empty($info['ns']) && in_array($ns, $namespaces)) { |
119 | $returnValue[$info['class']] = $ns . '\\' . $info['class']; |
120 | } |
121 | } |
122 | } |
123 | } |
124 | |
125 | // legacy |
126 | if ($extension->hasConstant('DIR_ACTIONS') && file_exists($extension->getConstant('DIR_ACTIONS'))) { |
127 | $dir = new DirectoryIterator($extension->getConstant('DIR_ACTIONS')); |
128 | foreach ($dir as $fileinfo) { |
129 | if (preg_match('/^class\.[^.]*\.php$/', $fileinfo->getFilename())) { |
130 | $module = substr($fileinfo->getFilename(), 6, -4); |
131 | $returnValue[$module] = $extension->getId() . '_actions_' . $module; |
132 | } |
133 | } |
134 | } |
135 | |
136 | $returnValue = array_filter($returnValue, [$this, 'isControllerClassNameValid']); |
137 | |
138 | return (array) $returnValue; |
139 | } |
140 | |
141 | /** |
142 | * Validates controller class name to: |
143 | * - exist |
144 | * - have valid base class |
145 | * - be not abstract |
146 | * |
147 | * @param string $controllerClassName |
148 | * |
149 | * @return bool |
150 | */ |
151 | private function isControllerClassNameValid($controllerClassName) |
152 | { |
153 | $returnValue = true; |
154 | |
155 | if (!class_exists($controllerClassName)) { |
156 | common_Logger::w($controllerClassName . ' not found'); |
157 | $returnValue = false; |
158 | } elseif ( |
159 | !is_subclass_of($controllerClassName, 'Module') |
160 | && !is_subclass_of($controllerClassName, Controller::class) |
161 | ) { |
162 | common_Logger::w($controllerClassName . ' is not a valid Controller.'); |
163 | $returnValue = false; |
164 | } else { |
165 | // abstract so just move along |
166 | $reflection = new \ReflectionClass($controllerClassName); |
167 | if ($reflection->isAbstract()) { |
168 | common_Logger::i($controllerClassName . ' is abstract'); |
169 | $returnValue = false; |
170 | } |
171 | } |
172 | |
173 | return $returnValue; |
174 | } |
175 | } |