Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
61.54% |
16 / 26 |
|
64.29% |
18 / 28 |
|
28.57% |
6 / 21 |
|
83.33% |
5 / 6 |
CRAP | |
0.00% |
0 / 1 |
| ValidationErrors | |
61.54% |
16 / 26 |
|
64.29% |
18 / 28 |
|
28.57% |
6 / 21 |
|
83.33% |
5 / 6 |
85.43 | |
0.00% |
0 / 1 |
| add | |
100.00% |
3 / 3 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| hasErrors | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getErrors | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| addValidationError | |
100.00% |
6 / 6 |
|
100.00% |
4 / 4 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| merge | |
100.00% |
5 / 5 |
|
100.00% |
9 / 9 |
|
0.00% |
0 / 8 |
|
100.00% |
1 / 1 |
4 | |||
| __toString | |
0.00% |
0 / 10 |
|
0.00% |
0 / 10 |
|
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\Shared\Domain\Validation; |
| 4 | |
| 5 | use stdClass; |
| 6 | use Symfony\Component\Validator\Constraints\Valid; |
| 7 | |
| 8 | /** |
| 9 | * A collection of validation errors |
| 10 | * @see ValidationError |
| 11 | * |
| 12 | * @author Wilhelm Zwertvaegher |
| 13 | * |
| 14 | */ |
| 15 | class ValidationErrors |
| 16 | { |
| 17 | /** |
| 18 | * A list of errors, with a field as key |
| 19 | * The values are a list of ValidationError with an ErrorCode as key and a built ValidationError as value |
| 20 | * @var array<string, array<string, ValidationError>> $errors |
| 21 | * |
| 22 | */ |
| 23 | private array $errors = []; |
| 24 | |
| 25 | public function add(ValidationError $error): void |
| 26 | { |
| 27 | if (!isset($this->errors[$error->field()])) { |
| 28 | $this->errors[$error->field()] = []; |
| 29 | } |
| 30 | $this->addValidationError($error); |
| 31 | } |
| 32 | |
| 33 | public function hasErrors(): bool |
| 34 | { |
| 35 | return count($this->errors) > 0; |
| 36 | } |
| 37 | |
| 38 | /** |
| 39 | * @return array<string, array<string, ValidationError>> |
| 40 | */ |
| 41 | public function getErrors(): array |
| 42 | { |
| 43 | return $this->errors; |
| 44 | } |
| 45 | |
| 46 | private function addValidationError(ValidationError $error): void |
| 47 | { |
| 48 | // merge the ValidationError to keep details if provided |
| 49 | $lookupField = $error->field(); |
| 50 | $lookupCode = $error->code()->getCode(); |
| 51 | |
| 52 | if (isset($this->errors[$lookupField][$lookupCode])) { |
| 53 | $this->errors[$lookupField][$lookupCode]->merge($error); |
| 54 | } else { |
| 55 | // we create a new ValidationError to prevent original $error to be modified |
| 56 | // if it is merged with other ValidationError in the future |
| 57 | $addedError = new ValidationError($error->field(), $error->code(), $error->details()); |
| 58 | $this->errors[$lookupField][$lookupCode] = $addedError; |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | |
| 75 | public function __toString(): string |
| 76 | { |
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |
| 93 | } |
Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 81 | foreach ($errors as $code => $error) { |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 83 | foreach ($error->details() as $key => $message) { |
| 83 | foreach ($error->details() as $key => $message) { |
| 83 | foreach ($error->details() as $key => $message) { |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 81 | foreach ($errors as $code => $error) { |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 83 | foreach ($error->details() as $key => $message) { |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 81 | foreach ($errors as $code => $error) { |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |
| 25 | public function add(ValidationError $error): void |
| 26 | { |
| 27 | if (!isset($this->errors[$error->field()])) { |
| 28 | $this->errors[$error->field()] = []; |
| 29 | } |
| 30 | $this->addValidationError($error); |
| 30 | $this->addValidationError($error); |
| 31 | } |
| 25 | public function add(ValidationError $error): void |
| 26 | { |
| 27 | if (!isset($this->errors[$error->field()])) { |
| 30 | $this->addValidationError($error); |
| 31 | } |
| 46 | private function addValidationError(ValidationError $error): void |
| 47 | { |
| 48 | // merge the ValidationError to keep details if provided |
| 49 | $lookupField = $error->field(); |
| 50 | $lookupCode = $error->code()->getCode(); |
| 51 | |
| 52 | if (isset($this->errors[$lookupField][$lookupCode])) { |
| 52 | if (isset($this->errors[$lookupField][$lookupCode])) { |
| 53 | $this->errors[$lookupField][$lookupCode]->merge($error); |
| 60 | } |
| 46 | private function addValidationError(ValidationError $error): void |
| 47 | { |
| 48 | // merge the ValidationError to keep details if provided |
| 49 | $lookupField = $error->field(); |
| 50 | $lookupCode = $error->code()->getCode(); |
| 51 | |
| 52 | if (isset($this->errors[$lookupField][$lookupCode])) { |
| 57 | $addedError = new ValidationError($error->field(), $error->code(), $error->details()); |
| 58 | $this->errors[$lookupField][$lookupCode] = $addedError; |
| 59 | } |
| 60 | } |
| 60 | } |
| 43 | return $this->errors; |
| 44 | } |
| 35 | return count($this->errors) > 0; |
| 36 | } |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 68 | foreach ($errors as $error) { |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 3 | namespace App\Shared\Domain\Validation; |
| 4 | |
| 5 | use stdClass; |
| 6 | use Symfony\Component\Validator\Constraints\Valid; |
| 7 | |
| 8 | /** |
| 9 | * A collection of validation errors |
| 10 | * @see ValidationError |
| 11 | * |
| 12 | * @author Wilhelm Zwertvaegher |
| 13 | * |
| 14 | */ |
| 15 | class ValidationErrors |
| 16 | { |
| 17 | /** |
| 18 | * A list of errors, with a field as key |
| 19 | * The values are a list of ValidationError with an ErrorCode as key and a built ValidationError as value |
| 20 | * @var array<string, array<string, ValidationError>> $errors |
| 21 | * |
| 22 | */ |
| 23 | private array $errors = []; |
| 24 | |
| 25 | public function add(ValidationError $error): void |
| 26 | { |
| 27 | if (!isset($this->errors[$error->field()])) { |
| 28 | $this->errors[$error->field()] = []; |
| 29 | } |
| 30 | $this->addValidationError($error); |
| 31 | } |
| 32 | |
| 33 | public function hasErrors(): bool |
| 34 | { |
| 35 | return count($this->errors) > 0; |
| 36 | } |
| 37 | |
| 38 | /** |
| 39 | * @return array<string, array<string, ValidationError>> |
| 40 | */ |
| 41 | public function getErrors(): array |
| 42 | { |
| 43 | return $this->errors; |
| 44 | } |
| 45 | |
| 46 | private function addValidationError(ValidationError $error): void |
| 47 | { |
| 48 | // merge the ValidationError to keep details if provided |
| 49 | $lookupField = $error->field(); |
| 50 | $lookupCode = $error->code()->getCode(); |
| 51 | |
| 52 | if (isset($this->errors[$lookupField][$lookupCode])) { |
| 53 | $this->errors[$lookupField][$lookupCode]->merge($error); |
| 54 | } else { |
| 55 | // we create a new ValidationError to prevent original $error to be modified |
| 56 | // if it is merged with other ValidationError in the future |
| 57 | $addedError = new ValidationError($error->field(), $error->code(), $error->details()); |
| 58 | $this->errors[$lookupField][$lookupCode] = $addedError; |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | public function merge(ValidationErrors $validationErrors): void |
| 63 | { |
| 64 | foreach ($validationErrors->getErrors() as $field => $errors) { |
| 65 | if (!isset($this->errors[$field])) { |
| 66 | $this->errors[$field] = []; |
| 67 | } |
| 68 | foreach ($errors as $error) { |
| 69 | $this->addValidationError($error); |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | |
| 75 | public function __toString(): string |
| 76 | { |
| 77 | $result = 'ValidationErrors{errors='; |
| 78 | foreach ($this->errors as $field => $errors) { |
| 79 | $result .= '{field='.$field.', details={'; |
| 80 | |
| 81 | foreach ($errors as $code => $error) { |
| 82 | $result .= '{code:'.$code.', details:{'; |
| 83 | foreach ($error->details() as $key => $message) { |
| 84 | $result .= '{key:'.$key.', message:{'.$message.'}}'; |
| 85 | } |
| 86 | $result .= '}'; |
| 87 | } |
| 88 | $result .= '}'; |
| 89 | } |
| 90 | |
| 91 | return $result; |
| 92 | } |