ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ComponentHelper.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
24use InvalidArgumentException;
25use Closure;
27
31trait ComponentHelper
32{
37 public function getCanonicalName(): string
38 {
39 return $this->getCanonicalNameByFullyQualifiedName();
40 }
41
45 protected function getCanonicalNameByFullyQualifiedName(): string
46 {
47 $cls = explode("\\", get_class($this));
48 $name = [];
49 $cur = array_pop($cls);
50 while ($cur !== "Component" && count($cls) > 0) {
51 $name[] = preg_replace("%([a-z])([A-Z])%", "$1 $2", $cur);
52 $cur = array_pop($cls);
53 }
54 return implode(" ", $name);
55 }
56
62 protected function checkArg(string $which, bool $check, string $message): void
63 {
64 if (!$check) {
65 throw new InvalidArgumentException("Argument '$which': $message");
66 }
67 }
68
75 protected function checkStringArg(string $which, $value): void
76 {
77 $this->checkArg($which, is_string($value), $this->wrongTypeMessage("string", $value));
78 }
79
86 protected function checkStringOrSignalArg(string $which, $value): void
87 {
88 $this->checkArg(
89 $which,
90 is_string($value) || $value instanceof Signal,
91 $this->wrongTypeMessage("string or Signal", gettype($value))
92 );
93 }
94
101 protected function checkBoolArg(string $which, $value): void
102 {
103 $this->checkArg($which, is_bool($value), $this->wrongTypeMessage("bool", $value));
104 }
105
112 protected function checkArgInstanceOf(string $which, $value, string $class): void
113 {
114 $this->checkArg($which, $value instanceof $class, $this->wrongTypeMessage($class, $value));
115 }
116
123 protected function checkArgIsElement(string $which, $value, array $array, string $name): void
124 {
125 if (!is_object($value)) {
126 $message = "expected $name, got '$value'";
127 } else {
128 $message = "expected $name, got object.";
129 }
130 $this->checkArg($which, in_array($value, $array), $message);
131 }
132
140 protected function checkArgList(string $which, array &$values, Closure $check, Closure $message): void
141 {
142 $failed_k = null;
143 $failed_v = null;
144 foreach ($values as $key => $value) {
145 $ok = $check($key, $value);
146 if (!$ok) {
147 $failed_k = $key;
148 $failed_v = $value;
149 break;
150 }
151 }
152
153 if ($failed_k !== null) {
154 $m = $message($failed_k, $failed_v);
155 } else {
156 $m = "";
157 }
158
159 $this->checkArg($which, $failed_k === null, $m);
160 }
161
169 protected function checkArgListElements(string $which, array &$values, $classes): void
170 {
171 $classes = $this->toArray($classes);
172 $this->checkArgList($which, $values, function ($_, $value) use (&$classes) {
173 foreach ($classes as $cls) {
174 if ($cls === "string" && is_string($value)) {
175 return true;
176 }
177 if ($cls === "int" && is_int($value)) {
178 return true;
179 } elseif ($value instanceof $cls) {
180 return true;
181 }
182 }
183 return false;
184 }, function ($_, $failed) use (&$classes) {
185 return $this->wrongTypeMessage(implode(", ", $classes), $failed);
186 });
187 }
188
197 protected function checkInputListElements(string $which, array $values, $classes, int $depth = 0): void
198 {
199 if (255 < $depth) {
200 throw new \LogicException('Input nesting limit of 255 exceeded.');
201 }
202
203 $classes = $this->toArray($classes);
204 foreach ($values as $value) {
205 foreach ($classes as $class) {
206 $this->checkArgInstanceOf($which, $value, $class);
207 }
208
209 if ($value instanceof \ILIAS\UI\Component\Input\Group) {
210 $this->checkInputListElements($which, $value->getInputs(), $classes, $depth + 1);
211 }
212 }
213 }
214
220 protected function toArray($value): array
221 {
222 if (is_array($value)) {
223 return $value;
224 }
225 return array($value);
226 }
227
231 protected function wrongTypeMessage(string $expected, $value): string
232 {
233 $type = gettype($value);
234 if (!is_object($value) && !is_array($value)) {
235 return "expected $expected, got $type '$value'";
236 } else {
237 if (is_object($value)) {
238 $type = get_class($value);
239 }
240 return "expected $expected, got $type";
241 }
242 }
243
244 public function reduceWith(\Closure $fn): mixed
245 {
246 $clone = clone $this;
247 $results = [];
248 foreach ($clone->getSubComponents() ?? [] as $component) {
249 $results[] = $component->reduceWith($fn);
250 }
251 return $fn($clone, $results);
252 }
253
262 protected function getSubComponents(): ?array
263 {
264 return null;
265 }
266
267}
$check
Definition: buildRTE.php:81
A component is the most general form of an entity in the UI.
Definition: Component.php:28
reduceWith(\Closure $fn)
The scheme starts at the leaves of the structure and applies the function to each leave and moves up ...
getCanonicalName()
Get the canonical name of the component.
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
$results
$message
Definition: xapiexit.php:31