ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
ComponentDecoratorTrait.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
23 use Closure;
25 use LogicException;
27 use ReflectionType;
28 use Throwable;
30 
37 {
41  private $component_decorator;
42 
47  public function addComponentDecorator(Closure $component_decorator) : isGlobalScreenItem
48  {
49  if (!$this->checkClosure($component_decorator)) {
50  throw new LogicException('first argument and return value of closure must be type-hinted to \ILIAS\UI\Component\Component');
51  }
52  if ($this->component_decorator instanceof Closure) {
53  $existing = $this->component_decorator;
54  $this->component_decorator = static function (Component $c) use ($component_decorator, $existing) : Component {
55  $component = $existing($c);
56 
57  return $component_decorator($component);
58  };
59  } else {
60  $this->component_decorator = $component_decorator;
61  }
62 
63  return $this;
64  }
65 
69  public function getComponentDecorator() : ?Closure
70  {
71  return $this->component_decorator;
72  }
73 
74  private function checkClosure(Closure $c) : bool
75  {
76  try {
77  $r = new ReflectionFunction($c);
78  if (count($r->getParameters()) !== 1) {
79  return false;
80  }
81  $first_param_type = $r->getParameters()[0]->getType();
82  if ($first_param_type instanceof ReflectionType && $first_param_type->getName() !== Component::class) {
83  return false;
84  }
85  $return_type = $r->getReturnType();
86  if ($return_type === null) {
87  return false;
88  }
89  if ($return_type->getName() !== Component::class) {
90  return false;
91  }
92 
93  return true;
94  } catch (Throwable $i) {
95  return false;
96  }
97  }
98 }
Interface isGlobalScreenItem.
$c
Definition: cli.php:37
addComponentDecorator(Closure $component_decorator)
$i
Definition: metadata.php:24