diff --git a/library/Exceptions/NestedValidationException.php b/library/Exceptions/NestedValidationException.php index e6048de6..19caaabd 100644 --- a/library/Exceptions/NestedValidationException.php +++ b/library/Exceptions/NestedValidationException.php @@ -22,19 +22,47 @@ use function implode; use function is_array; use function str_repeat; +/** + * Exception for nested validations. + * + * This exception allows to have exceptions inside itself and providers methods + * to handle them and to retrieve nested messages based on itself and its + * children. + * + * @author Alexandre Gomes Gaigalas + * @author Henrique Moody + * @author Jonathan Stewmon + * @author Wojciech Frącz + */ class NestedValidationException extends ValidationException implements IteratorAggregate { /** * @var SplObjectStorage */ - private $exceptions = []; + private $exceptions; /** + * Returns the exceptions that are children of the exception. + * + * @return SplObjectStorage|ValidationException[] + */ + public function getRelated(): SplObjectStorage + { + if (!$this->exceptions instanceof SplObjectStorage) { + $this->exceptions = new SplObjectStorage(); + } + + return $this->exceptions; + } + + /** + * Adds a child to the exception. + * * @param ValidationException $exception * * @return self */ - public function addRelated(ValidationException $exception) + public function addRelated(ValidationException $exception): self { $this->getRelated()->attach($exception); @@ -42,53 +70,25 @@ class NestedValidationException extends ValidationException implements IteratorA } /** - * @return RecursiveIteratorIterator - */ - private function getRecursiveIterator() - { - $exceptionIterator = new RecursiveExceptionIterator($this); - $recursiveIteratorIterator = new RecursiveIteratorIterator( - $exceptionIterator, - RecursiveIteratorIterator::SELF_FIRST - ); - - return $recursiveIteratorIterator; - } - - /** - * Returns weather an exception should be omitted or not. + * Adds children to the exception. * - * @param Exception $exception + * @param ValidationException[] $exceptions * - * @return bool + * @return self */ - private function isOmissible(Exception $exception): bool + public function setRelated(array $exceptions): self { - if (!$exception instanceof self) { - return false; + foreach ($exceptions as $exception) { + $this->addRelated($exception); } - if (1 !== $exception->getRelated()->count()) { - return false; - } - - $exception->getRelated()->rewind(); - $childException = $exception->getRelated()->current(); - if ($childException->getMessage() === $exception->getMessage()) { - return true; - } - - if ($exception->hasCustomTemplate()) { - return $childException->hasCustomTemplate(); - } - - return !$childException instanceof NonOmissibleException; + return $this; } /** * @return SplObjectStorage */ - public function getIterator() + public function getIterator(): SplObjectStorage { $childrenExceptions = new SplObjectStorage(); $recursiveIteratorIterator = $this->getRecursiveIterator(); @@ -123,6 +123,19 @@ class NestedValidationException extends ValidationException implements IteratorA return $childrenExceptions; } + /** + * Returns a key->value array with all the messages of the exception. + * + * In this array the "keys" are the ids of the exceptions (defined name or + * name of the rule) and the values are the message. + * + * Once templates are passed it overwrites the templates of the given + * messages. + * + * @param array $templates + * + * @return array + */ public function getMessages(array $templates = []): array { $messages = [$this->getId() => $this->renderMessage($this, $templates)]; @@ -152,9 +165,11 @@ class NestedValidationException extends ValidationException implements IteratorA } /** + * Returns a string with all the messages of the exception. + * * @return string */ - public function getFullMessage() + public function getFullMessage(): string { $messages = []; $leveler = 1; @@ -176,30 +191,35 @@ class NestedValidationException extends ValidationException implements IteratorA return implode(PHP_EOL, $messages); } - /** - * @return SplObjectStorage|ValidationException[] - */ - public function getRelated() + private function getRecursiveIterator(): RecursiveIteratorIterator { - if (!$this->exceptions instanceof SplObjectStorage) { - $this->exceptions = new SplObjectStorage(); - } - - return $this->exceptions; + return new RecursiveIteratorIterator( + new RecursiveExceptionIterator($this), + RecursiveIteratorIterator::SELF_FIRST + ); } - /** - * @param array $exceptions - * - * @return self - */ - public function setRelated(array $exceptions) + private function isOmissible(Exception $exception): bool { - foreach ($exceptions as $exception) { - $this->addRelated($exception); + if (!$exception instanceof self) { + return false; } - return $this; + if (1 !== $exception->getRelated()->count()) { + return false; + } + + $exception->getRelated()->rewind(); + $childException = $exception->getRelated()->current(); + if ($childException->getMessage() === $exception->getMessage()) { + return true; + } + + if ($exception->hasCustomTemplate()) { + return $childException->hasCustomTemplate(); + } + + return !$childException instanceof NonOmissibleException; } private function renderMessage(ValidationException $exception, array $templates): string