ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilCtrlStructureReader.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21require_once __DIR__ . '/../../../../../vendor/composer/vendor/autoload.php';
22
31{
36 public const REGEX_GUI_CLASS_NAME = '/^(class\.|)([A-z0-9]*(GUI))\.php$/';
37
43 private const REGEX_PHPDOC_CALLS = '/(((?i)@ilctrl_calls)\s*({CLASS_NAME}(:\s*|\s*:\s*))\K)([A-z0-9,\s])*/';
44
49 private const REGEX_PHPDOC_CALLED_BYS = '/(((?i)@ilctrl_iscalledby)\s*({CLASS_NAME}(:\s*|\s*:\s*))\K)([A-z0-9,\s])*/';
50
57
64
70 private bool $is_executed = false;
71
77 private string $ilias_path;
78
86 {
87 $this->ilias_path = rtrim(
88 (defined('ILIAS_ABSOLUTE_PATH')) ?
89 ILIAS_ABSOLUTE_PATH : dirname(__FILE__, 6),
90 '/'
91 );
92
93 $this->cid_generator = $cid_generator;
94 $this->iterator = $iterator;
95 }
96
102 public function isExecuted(): bool
103 {
104 return $this->is_executed;
105 }
106
112 public function readStructure(): array
113 {
114 $base_classes = $structure = [];
115 foreach ($this->iterator as $class_name => $path) {
116 // skip iteration if class doesn't meet ILIAS GUI class criteria.
117 if (!$this->isGuiClass($path)) {
118 continue;
119 }
120
121 $lower_class_name = strtolower($class_name);
122 try {
123 // the classes need to be required manually, because
124 // the autoload classmap might not include the plugin
125 // classes when an update is triggered (small structure
126 // reload).
127 require_once $path;
128
129 $reflection = ($this->isNamespaced($class_name)) ?
130 new ReflectionClass("\\$class_name") :
131 new ReflectionClass($class_name)
132 ;
133
134 $structure[$lower_class_name][ilCtrlStructureInterface::KEY_CLASS_CID] = $this->cid_generator->getCid();
135 $structure[$lower_class_name][ilCtrlStructureInterface::KEY_CLASS_NAME] = $class_name;
136 $structure[$lower_class_name][ilCtrlStructureInterface::KEY_CLASS_PATH] = $this->getRelativePath($path);
137 $structure[$lower_class_name][ilCtrlStructureInterface::KEY_CLASS_CHILDREN] = $this->getChildren($reflection);
138 $structure[$lower_class_name][ilCtrlStructureInterface::KEY_CLASS_PARENTS] = $this->getParents($reflection);
139
140 // temporarily store base classes in order to filer the
141 // structure afterwards.
142 if (in_array(ilCtrlBaseClassInterface::class, $reflection->getInterfaceNames(), true)) {
143 $base_classes[] = $lower_class_name;
144 }
145 } catch (ReflectionException $e) {
146 continue;
147 }
148 }
149
150 $mapped_structure = (new ilCtrlStructureHelper($base_classes, $structure))
151 ->mapStructureReferences()
152 ->filterUnnecessaryEntries()
153 ->getStructure()
154 ;
155
156 $this->is_executed = true;
157
158 return $mapped_structure;
159 }
160
169 private function getReferencedClassesByReflection(ReflectionClass $reflection, string $regex): array
170 {
171 // abort if the class has no PHPDoc comment.
172 if (!$reflection->getDocComment()) {
173 return [];
174 }
175
176 // replace the classname placeholder with the
177 // actual one and execute the regex search.
178 $name = str_replace('\\', '\\\\', $reflection->getName());
179 $regex = str_replace('{CLASS_NAME}', $name, $regex);
180 preg_match_all($regex, $reflection->getDocComment(), $matches);
181
182 // the first array entry of $matches contains
183 // the list's of statements found.
184 if (empty($matches[0])) {
185 return [];
186 }
187
188 $referenced_classes = [];
189 foreach ($matches[0] as $class_list) {
190 // explode lists and strip all whitespaces.
191 foreach (explode(',', $class_list) as $class) {
192 $class_name = $this->stripWhitespaces($class);
193 if (!empty($class_name)) {
194 $referenced_classes[] = strtolower($class_name);
195 }
196 }
197 }
198
199 return $referenced_classes;
200 }
201
208 private function getRelativePath(string $absolute_path): string
209 {
210 // some paths might contain syntax like '../../../' etc.
211 // and realpath() resolves that in order to cut off the
212 // ilias installation path properly.
213 $absolute_path = realpath($absolute_path);
214
215 return '.' . str_replace($this->ilias_path, '', $absolute_path);
216 }
217
224 private function getChildren(ReflectionClass $reflection): array
225 {
226 return $this->getReferencedClassesByReflection($reflection, self::REGEX_PHPDOC_CALLS);
227 }
228
235 private function getParents(ReflectionClass $reflection): array
236 {
237 return $this->getReferencedClassesByReflection($reflection, self::REGEX_PHPDOC_CALLED_BYS);
238 }
239
247 private function stripWhitespaces(string $string): string
248 {
249 return (string) preg_replace('/\s+/', '', $string);
250 }
251
258 private function isGuiClass(string $path): bool
259 {
260 return (bool) preg_match(self::REGEX_GUI_CLASS_NAME, basename($path));
261 }
262
269 private function isNamespaced(string $class_name): bool
270 {
271 return (false !== strpos($class_name, '\\'));
272 }
273}
$structure
TOTAL STRUCTURE.
Class ilCtrlStructureCidGenerator.
Class ilCtrlStructureHelper.
Class ilCtrlStructureReader is responsible for reading ilCtrl's control structure.
isExecuted()
Returns whether this instance was already executed or not.
__construct(ilCtrlIteratorInterface $iterator, ilCtrlStructureCidGenerator $cid_generator)
ilCtrlStructureReader Constructor
isNamespaced(string $class_name)
Returns if the given classname is namespaced.
getReferencedClassesByReflection(ReflectionClass $reflection, string $regex)
Returns all classes referenced by an ilCtrl_Calls or ilCtrl_isCalledBy statement.
getChildren(ReflectionClass $reflection)
Helper function that returns all children references.
ilCtrlIteratorInterface $iterator
getRelativePath(string $absolute_path)
Returns a given path relative to the ILIAS absolute path.
isGuiClass(string $path)
Returns whether the given file/path matches ILIAS conventions.
readStructure()
Processes all classes within the ILIAS installation.
getParents(ReflectionClass $reflection)
Helper function that returns all parent references.
ilCtrlStructureCidGenerator $cid_generator
stripWhitespaces(string $string)
Helper function that replaces all whitespace characters from the given string.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const KEY_CLASS_CID
array key constants that are used for certain information.
$path
Definition: ltiservices.php:30