[TASK] Remove ext:dbal from installation steps
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Error / Result.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Error;
3
4 /* *
5 * This script belongs to the Extbase framework *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License as published by the *
9 * Free Software Foundation, either version 3 of the License, or (at your *
10 * option) any later version. *
11 * *
12 * This script is distributed in the hope that it will be useful, but *
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
14 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
15 * General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with the script. *
19 * If not, see http://www.gnu.org/licenses/lgpl.html *
20 * *
21 * The TYPO3 project - inspiring people to share! *
22 * */
23 /**
24 * Result object for operations dealing with objects, such as the Property Mapper or the Validators.
25 *
26 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
27 * @api
28 */
29 class Result
30 {
31 /**
32 * @var array<\TYPO3\CMS\Extbase\Error\Error>
33 */
34 protected $errors = [];
35
36 /**
37 * Caches the existence of errors
38 * @var bool
39 */
40 protected $errorsExist = false;
41
42 /**
43 * @var array<\TYPO3\CMS\Extbase\Error\Warning>
44 */
45 protected $warnings = [];
46
47 /**
48 * Caches the existence of warning
49 * @var bool
50 */
51 protected $warningsExist = false;
52
53 /**
54 * @var array<\TYPO3\CMS\Extbase\Error\Notice>
55 */
56 protected $notices = [];
57
58 /**
59 * Caches the existence of notices
60 * @var bool
61 */
62 protected $noticesExist = false;
63
64 /**
65 * The result objects for the sub properties
66 *
67 * @var array<\TYPO3\CMS\Extbase\Error\Result>
68 */
69 protected $propertyResults = [];
70
71 /**
72 * @var \TYPO3\CMS\Extbase\Error\Result
73 */
74 protected $parent = null;
75
76 /**
77 * Injects the parent result and propagates the
78 * cached error states upwards
79 *
80 * @param \TYPO3\CMS\Extbase\Error\Error $parent
81 * @return void
82 */
83 public function setParent(Result $parent)
84 {
85 if ($this->parent !== $parent) {
86 $this->parent = $parent;
87 if ($this->hasErrors()) {
88 $parent->setErrorsExist();
89 }
90 if ($this->hasWarnings()) {
91 $parent->setWarningsExist();
92 }
93 if ($this->hasNotices()) {
94 $parent->setNoticesExist();
95 }
96 }
97 }
98
99 /**
100 * Add an error to the current Result object
101 *
102 * @param \TYPO3\CMS\Extbase\Error\Error $error
103 * @return void
104 * @api
105 */
106 public function addError(\TYPO3\CMS\Extbase\Error\Error $error)
107 {
108 $this->errors[] = $error;
109 $this->setErrorsExist();
110 }
111
112 /**
113 * Add a warning to the current Result object
114 *
115 * @param \TYPO3\CMS\Extbase\Error\Warning $warning
116 * @return void
117 * @api
118 */
119 public function addWarning(\TYPO3\CMS\Extbase\Error\Warning $warning)
120 {
121 $this->warnings[] = $warning;
122 $this->setWarningsExist();
123 }
124
125 /**
126 * Add a notice to the current Result object
127 *
128 * @param \TYPO3\CMS\Extbase\Error\Notice $notice
129 * @return void
130 * @api
131 */
132 public function addNotice(\TYPO3\CMS\Extbase\Error\Notice $notice)
133 {
134 $this->notices[] = $notice;
135 $this->setNoticesExist();
136 }
137
138 /**
139 * Get all errors in the current Result object (non-recursive)
140 *
141 * @return array<\TYPO3\CMS\Extbase\Error\Error>
142 * @api
143 */
144 public function getErrors()
145 {
146 return $this->errors;
147 }
148
149 /**
150 * Get all warnings in the current Result object (non-recursive)
151 *
152 * @return array<\TYPO3\CMS\Extbase\Error\Warning>
153 * @api
154 */
155 public function getWarnings()
156 {
157 return $this->warnings;
158 }
159
160 /**
161 * Get all notices in the current Result object (non-recursive)
162 *
163 * @return array<\TYPO3\CMS\Extbase\Error\Notice>
164 * @api
165 */
166 public function getNotices()
167 {
168 return $this->notices;
169 }
170
171 /**
172 * Get the first error object of the current Result object (non-recursive)
173 *
174 * @return \TYPO3\CMS\Extbase\Error\Error
175 * @api
176 */
177 public function getFirstError()
178 {
179 reset($this->errors);
180 return current($this->errors);
181 }
182
183 /**
184 * Get the first warning object of the current Result object (non-recursive)
185 *
186 * @return \TYPO3\CMS\Extbase\Error\Warning
187 * @api
188 */
189 public function getFirstWarning()
190 {
191 reset($this->warnings);
192 return current($this->warnings);
193 }
194
195 /**
196 * Get the first notice object of the curren Result object (non-recursive)
197 *
198 * @return \TYPO3\CMS\Extbase\Error\Notice
199 * @api
200 */
201 public function getFirstNotice()
202 {
203 reset($this->notices);
204 return current($this->notices);
205 }
206
207 /**
208 * Return a Result object for the given property path. This is
209 * a fluent interface, so you will proboably use it like:
210 * $result->forProperty('foo.bar')->getErrors() -- to get all errors
211 * for property "foo.bar"
212 *
213 * @param string $propertyPath
214 * @return \TYPO3\CMS\Extbase\Error\Result
215 * @api
216 */
217 public function forProperty($propertyPath)
218 {
219 if ($propertyPath === '' || $propertyPath === null) {
220 return $this;
221 }
222 if (strpos($propertyPath, '.') !== false) {
223 return $this->recurseThroughResult(explode('.', $propertyPath));
224 }
225 if (!isset($this->propertyResults[$propertyPath])) {
226 $this->propertyResults[$propertyPath] = new Result();
227 $this->propertyResults[$propertyPath]->setParent($this);
228 }
229 return $this->propertyResults[$propertyPath];
230 }
231
232 /**
233 * Internal use only!
234 *
235 * @param array $pathSegments
236 * @return \TYPO3\CMS\Extbase\Error\Result
237 */
238 public function recurseThroughResult(array $pathSegments)
239 {
240 if (empty($pathSegments)) {
241 return $this;
242 }
243
244 $propertyName = array_shift($pathSegments);
245
246 if (!isset($this->propertyResults[$propertyName])) {
247 $this->propertyResults[$propertyName] = new Result();
248 $this->propertyResults[$propertyName]->setParent($this);
249 }
250
251 return $this->propertyResults[$propertyName]->recurseThroughResult($pathSegments);
252 }
253
254 /**
255 * Sets the error cache to TRUE and propagates the information
256 * upwards the Result-Object Tree
257 *
258 * @return void
259 */
260 protected function setErrorsExist()
261 {
262 $this->errorsExist = true;
263 if ($this->parent !== null) {
264 $this->parent->setErrorsExist();
265 }
266 }
267
268 /**
269 * Sets the warning cache to TRUE and propagates the information
270 * upwards the Result-Object Tree
271 *
272 * @return void
273 */
274 protected function setWarningsExist()
275 {
276 $this->warningsExist = true;
277 if ($this->parent !== null) {
278 $this->parent->setWarningsExist();
279 }
280 }
281
282 /**
283 * Sets the notices cache to TRUE and propagates the information
284 * upwards the Result-Object Tree
285 *
286 * @return void
287 */
288 protected function setNoticesExist()
289 {
290 $this->noticesExist = true;
291 if ($this->parent !== null) {
292 $this->parent->setNoticesExist();
293 }
294 }
295
296 /**
297 * Does the current Result object have Notices, Errors or Warnings? (Recursively)
298 *
299 * @return bool
300 */
301 public function hasMessages()
302 {
303 return $this->errorsExist || $this->noticesExist || $this->warningsExist;
304 }
305
306 /**
307 * Clears the result
308 *
309 * @return void
310 */
311 public function clear()
312 {
313 $this->errors = [];
314 $this->notices = [];
315 $this->warnings = [];
316
317 $this->warningsExist = false;
318 $this->noticesExist = false;
319 $this->errorsExist = false;
320
321 $this->propertyResults = [];
322 }
323
324 /**
325 * Internal use only!
326 *
327 * @param string $propertyName
328 * @param string $checkerMethodName
329 * @return bool
330 */
331 protected function hasProperty($propertyName, $checkerMethodName)
332 {
333 if (!empty($this->{$propertyName})) {
334 return true;
335 }
336 foreach ($this->propertyResults as $subResult) {
337 if ($subResult->{$checkerMethodName}()) {
338 return true;
339 }
340 }
341 return false;
342 }
343
344 /**
345 * Does the current Result object have Errors? (Recursively)
346 *
347 * @return bool
348 * @api
349 */
350 public function hasErrors()
351 {
352 return $this->hasProperty('errors', 'hasErrors');
353 }
354
355 /**
356 * Does the current Result object have Warnings? (Recursively)
357 *
358 * @return bool
359 * @api
360 */
361 public function hasWarnings()
362 {
363 return $this->hasProperty('warnings', 'hasWarnings');
364 }
365
366 /**
367 * Does the current Result object have Notices? (Recursively)
368 *
369 * @return bool
370 * @api
371 */
372 public function hasNotices()
373 {
374 return $this->hasProperty('notices', 'hasNotices');
375 }
376
377 /**
378 * Get a list of all Error objects recursively. The result is an array,
379 * where the key is the property path where the error occurred, and the
380 * value is a list of all errors (stored as array)
381 *
382 * @return array<\TYPO3\CMS\Extbase\Error\Error>
383 * @api
384 */
385 public function getFlattenedErrors()
386 {
387 $result = [];
388 $this->flattenTree('errors', $result, []);
389 return $result;
390 }
391
392 /**
393 * Get a list of all Warning objects recursively. The result is an array,
394 * where the key is the property path where the warning occurred, and the
395 * value is a list of all warnings (stored as array)
396 *
397 * @return array<\TYPO3\CMS\Extbase\Error\Warning>
398 * @api
399 */
400 public function getFlattenedWarnings()
401 {
402 $result = [];
403 $this->flattenTree('warnings', $result, []);
404 return $result;
405 }
406
407 /**
408 * Get a list of all Notice objects recursively. The result is an array,
409 * where the key is the property path where the notice occurred, and the
410 * value is a list of all notices (stored as array)
411 *
412 * @return array<\TYPO3\CMS\Extbase\Error\Notice>
413 * @api
414 */
415 public function getFlattenedNotices()
416 {
417 $result = [];
418 $this->flattenTree('notices', $result, []);
419 return $result;
420 }
421
422 /**
423 * Only use internally!
424 *
425 * Flatten a tree of Result objects, based on a certain property.
426 *
427 * @param string $propertyName
428 * @param array $result
429 * @param array $level
430 * @return void
431 */
432 public function flattenTree($propertyName, &$result, $level)
433 {
434 if (!empty($this->$propertyName)) {
435 $result[implode('.', $level)] = $this->$propertyName;
436 }
437 foreach ($this->propertyResults as $subPropertyName => $subResult) {
438 array_push($level, $subPropertyName);
439 $subResult->flattenTree($propertyName, $result, $level);
440 array_pop($level);
441 }
442 }
443
444 /**
445 * Merge the given Result object into this one.
446 *
447 * @param \TYPO3\CMS\Extbase\Error\Result $otherResult
448 * @return void
449 * @api
450 */
451 public function merge(Result $otherResult)
452 {
453 if ($otherResult->errorsExist) {
454 $this->mergeProperty($otherResult, 'getErrors', 'addError');
455 }
456 if ($otherResult->warningsExist) {
457 $this->mergeProperty($otherResult, 'getWarnings', 'addWarning');
458 }
459 if ($otherResult->noticesExist) {
460 $this->mergeProperty($otherResult, 'getNotices', 'addNotice');
461 }
462
463 foreach ($otherResult->getSubResults() as $subPropertyName => $subResult) {
464 /** @var $subResult Result */
465 if (array_key_exists($subPropertyName, $this->propertyResults) && $this->propertyResults[$subPropertyName]->hasMessages()) {
466 $this->forProperty($subPropertyName)->merge($subResult);
467 } else {
468 $this->propertyResults[$subPropertyName] = $subResult;
469 $subResult->setParent($this);
470 }
471 }
472 }
473
474 /**
475 * Merge a single property from the other result object.
476 *
477 * @param \TYPO3\CMS\Extbase\Error\Result $otherResult
478 * @param string $getterName
479 * @param string $adderName
480 * @return void
481 */
482 protected function mergeProperty(Result $otherResult, $getterName, $adderName)
483 {
484 foreach ($otherResult->$getterName() as $messageInOtherResult) {
485 $this->$adderName($messageInOtherResult);
486 }
487 }
488
489 /**
490 * Get a list of all sub Result objects available.
491 *
492 * @return \TYPO3\CMS\Extbase\Error\Result[]
493 */
494 public function getSubResults()
495 {
496 return $this->propertyResults;
497 }
498 }