ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilCtrlStructure.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /* Copyright (c) 2021 Thibeau Fuhrer <thf@studer-raimann.ch> Extended GPL, see docs/LICENSE */
6 
13 {
18  private const PARAM_NAME_REGEX = '/^[A-Za-z0-9_-]*$/';
19 
25  private array $temporary_parameters = [];
26 
32  private array $permanent_parameters = [];
33 
38  private array $return_targets = [];
39 
44  private array $structure;
45 
50  private array $base_classes;
51 
56  private array $security;
57 
63  private array $mapped_structure = [];
64 
71  public function __construct(
72  array $ctrl_structure,
73  array $base_classes,
74  array $security_info
75  ) {
76  $this->base_classes = $base_classes;
77  $this->security = $security_info;
78  $this->structure = $ctrl_structure;
79  }
80 
84  public function isBaseClass(string $class_name): bool
85  {
86  // baseclass must be contained within the current structure
87  // and within the current baseclass array.
88  return
89  null !== $this->getClassCidByName($class_name) &&
90  in_array($this->lowercase($class_name), $this->base_classes, true);
91  }
92 
96  public function getObjNameByCid(string $cid): ?string
97  {
98  return $this->getValueForKeyByCid(self::KEY_CLASS_NAME, $cid);
99  }
100 
104  public function getObjNameByName(string $class_name): ?string
105  {
106  return $this->getValueForKeyByName(self::KEY_CLASS_NAME, $class_name);
107  }
108 
112  public function getClassNameByCid(string $cid): ?string
113  {
114  $class_name = $this->getValueForKeyByCid(
115  self::KEY_CLASS_NAME,
116  $cid
117  );
118 
119  return (null !== $class_name) ? $this->lowercase($class_name) : null;
120  }
121 
125  public function getClassCidByName(string $class_name): ?string
126  {
127  return $this->getValueForKeyByName(self::KEY_CLASS_CID, $class_name);
128  }
129 
133  public function getRelativePathByName(string $class_name): ?string
134  {
135  return $this->getValueForKeyByName(self::KEY_CLASS_PATH, $class_name);
136  }
137 
141  public function getRelativePathByCid(string $cid): ?string
142  {
143  return $this->getValueForKeyByCid(self::KEY_CLASS_PATH, $cid);
144  }
145 
149  public function getChildrenByCid(string $cid): ?array
150  {
151  $children = $this->getValueForKeyByCid(self::KEY_CLASS_CHILDREN, $cid);
152  if (empty($children)) {
153  return null;
154  }
155 
156  return $children;
157  }
158 
162  public function getChildrenByName(string $class_name): ?array
163  {
164  $children = $this->getValueForKeyByName(self::KEY_CLASS_CHILDREN, $class_name);
165  if (empty($children)) {
166  return null;
167  }
168 
169  return $children;
170  }
171 
175  public function getParentsByCid(string $cid): ?array
176  {
177  $parents = $this->getValueForKeyByCid(self::KEY_CLASS_PARENTS, $cid);
178  if (empty($parents)) {
179  return null;
180  }
181 
182  return $parents;
183  }
184 
188  public function getParentsByName(string $class_name): ?array
189  {
190  $parents = $this->getValueForKeyByName(self::KEY_CLASS_PARENTS, $class_name);
191  if (empty($parents)) {
192  return null;
193  }
194 
195  return $parents;
196  }
197 
201  public function setPermanentParameterByClass(string $class_name, string $parameter_name): void
202  {
203  if (in_array($parameter_name, ilCtrlInterface::PROTECTED_PARAMETERS, true)) {
204  throw new ilCtrlException("Parameter '$parameter_name' must not be saved, it could mess with the control flow.");
205  }
206 
207  if (!preg_match(self::PARAM_NAME_REGEX, $parameter_name)) {
208  throw new ilCtrlException("Cannot save parameter '$parameter_name', as it contains invalid characters.");
209  }
210 
211  $this->permanent_parameters[$this->lowercase($class_name)][] = $parameter_name;
212  }
213 
217  public function removePermanentParametersByClass(string $class_name): void
218  {
219  $class_name = $this->lowercase($class_name);
220  if (isset($this->permanent_parameters[$class_name])) {
221  unset($this->permanent_parameters[$class_name]);
222  }
223  }
224 
228  public function getPermanentParametersByClass(string $class_name): ?array
229  {
230  return $this->permanent_parameters[$this->lowercase($class_name)] ?? null;
231  }
232 
236  public function setTemporaryParameterByClass(string $class_name, string $parameter_name, $value): void
237  {
238  if (!preg_match(self::PARAM_NAME_REGEX, $parameter_name)) {
239  throw new ilCtrlException("Cannot save parameter '$parameter_name', as it contains invalid characters.");
240  }
241 
242  $this->temporary_parameters[$this->lowercase($class_name)][$parameter_name] = $value;
243  }
244 
248  public function removeTemporaryParametersByClass(string $class_name): void
249  {
250  $class_name = $this->lowercase($class_name);
251  if (isset($this->temporary_parameters[$class_name])) {
252  unset($this->temporary_parameters[$class_name]);
253  }
254  }
255 
259  public function getTemporaryParametersByClass(string $class_name): ?array
260  {
261  return $this->temporary_parameters[$this->lowercase($class_name)] ?? null;
262  }
263 
267  public function removeSingleParameterByClass(string $class_name, string $parameter_name): void
268  {
269  $class_name = $this->lowercase($class_name);
270 
271  // permanent parameters are lists of parameter names
272  // mapped to the classname, therefore the index is
273  // unknown and has to be figured out.
274  if (!empty($this->permanent_parameters[$class_name])) {
275  foreach ($this->permanent_parameters[$class_name] as $index => $permanent_parameter) {
276  if ($parameter_name === $permanent_parameter) {
277  unset($this->permanent_parameters[$class_name][$index]);
278 
279  // reindex the array values.
280  $permanent_parameters = &$this->permanent_parameters[$class_name];
281  $permanent_parameters = array_values($permanent_parameters);
282  }
283  }
284  }
285 
286  // the temporary parameters are key => value pairs mapped
287  // to the classname, whereas key is the parameter name.
288  // The index is therefore known and can be unset directly.
289  if (isset($this->temporary_parameters[$class_name])) {
290  unset($this->temporary_parameters[$class_name][$parameter_name]);
291  }
292  }
293 
297  public function setReturnTargetByClass(string $class_name, string $target_url): void
298  {
299  $this->return_targets[$this->lowercase($class_name)] = $target_url;
300  }
301 
305  public function getReturnTargetByClass(string $class_name): ?string
306  {
307  return $this->return_targets[$this->lowercase($class_name)] ?? null;
308  }
309 
313  public function getUnsafeCommandsByCid(string $cid): array
314  {
315  $class_name = $this->getClassNameByCid($cid);
316  if (null !== $class_name) {
317  return $this->getUnsafeCommandsByName($class_name);
318  }
319 
320  return [];
321  }
322 
326  public function getUnsafeCommandsByName(string $class_name): array
327  {
328  return $this->security[$this->lowercase($class_name)][self::KEY_UNSAFE_COMMANDS] ?? [];
329  }
330 
334  public function getSafeCommandsByCid(string $cid): array
335  {
336  $class_name = $this->getClassNameByCid($cid);
337  if (null !== $class_name) {
338  return $this->getSafeCommandsByName($class_name);
339  }
340 
341  return [];
342  }
343 
347  public function getSafeCommandsByName(string $class_name): array
348  {
349  return $this->security[$this->lowercase($class_name)][self::KEY_SAFE_COMMANDS] ?? [];
350  }
351 
359  private function getValueForKeyByCid(string $identifier_key, string $cid)
360  {
361  if (isset($this->mapped_structure[$cid][$identifier_key])) {
362  return $this->mapped_structure[$cid][$identifier_key];
363  }
364 
365  foreach ($this->structure as $class_info) {
366  if (isset($class_info[$identifier_key]) && $class_info[self::KEY_CLASS_CID] === $cid) {
367  $this->mapped_structure[$cid] = $class_info;
368  return $class_info[$identifier_key];
369  }
370  }
371 
372  return null;
373  }
374 
382  private function getValueForKeyByName(string $identifier_key, string $class_name)
383  {
384  $class_name = $this->lowercase($class_name);
385  if (isset($this->structure[$class_name])) {
386  return $this->structure[$class_name][$identifier_key];
387  }
388 
389  return null;
390  }
391 
397  private function lowercase(string $string): string
398  {
399  return strtolower($string);
400  }
401 }
getRelativePathByCid(string $cid)
__construct(array $ctrl_structure, array $base_classes, array $security_info)
ilCtrlStructure Constructor
getPermanentParametersByClass(string $class_name)
isBaseClass(string $class_name)
setReturnTargetByClass(string $class_name, string $target_url)
Class ilCtrlStructure holds the currently read control structure.
setTemporaryParameterByClass(string $class_name, string $parameter_name, $value)
removeSingleParameterByClass(string $class_name, string $parameter_name)
$index
Definition: metadata.php:145
getParentsByName(string $class_name)
getClassNameByCid(string $cid)
getRelativePathByName(string $class_name)
getChildrenByName(string $class_name)
getValueForKeyByName(string $identifier_key, string $class_name)
Returns a stored structure value of the given key from the corresponding class mapped by name...
getUnsafeCommandsByName(string $class_name)
getReturnTargetByClass(string $class_name)
getObjNameByName(string $class_name)
removePermanentParametersByClass(string $class_name)
getParentsByCid(string $cid)
ilCtrl exceptions
lowercase(string $string)
Helper function to lowercase strings.
getObjNameByCid(string $cid)
getChildrenByCid(string $cid)
getUnsafeCommandsByCid(string $cid)
getClassCidByName(string $class_name)
setPermanentParameterByClass(string $class_name, string $parameter_name)
removeTemporaryParametersByClass(string $class_name)
getValueForKeyByCid(string $identifier_key, string $cid)
Returns a stored structure value of the given key from the corresponding class mapped by CID...
getSafeCommandsByName(string $class_name)
getSafeCommandsByCid(string $cid)
getTemporaryParametersByClass(string $class_name)