Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
61.54% covered (warning)
61.54%
16 / 26
64.29% covered (warning)
64.29%
18 / 28
28.57% covered (danger)
28.57%
6 / 21
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ValidationErrors
61.54% covered (warning)
61.54%
16 / 26
64.29% covered (warning)
64.29%
18 / 28
28.57% covered (danger)
28.57%
6 / 21
83.33% covered (warning)
83.33%
5 / 6
85.43
0.00% covered (danger)
0.00%
0 / 1
 add
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 hasErrors
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getErrors
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addValidationError
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 merge
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
9 / 9
0.00% covered (danger)
0.00%
0 / 8
100.00% covered (success)
100.00%
1 / 1
4
 __toString
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace App\Shared\Domain\Validation;
4
5use stdClass;
6use Symfony\Component\Validator\Constraints\Valid;
7
8/**
9 * A collection of validation errors
10 * @see ValidationError
11 *
12 * @author Wilhelm Zwertvaegher
13 *
14 */
15class 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}

Branches

Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once. Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

ValidationErrors->__toString
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) {
81            foreach ($errors as $code => $error) {
82                $result .= '{code:'.$code.', details:{';
83                foreach ($error->details() as $key => $message) {
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) {
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    }
ValidationErrors->add
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    }
ValidationErrors->addValidationError
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);
57            $addedError = new ValidationError($error->field(), $error->code(), $error->details());
58            $this->errors[$lookupField][$lookupCode] = $addedError;
59        }
60    }
60    }
ValidationErrors->getErrors
43        return $this->errors;
44    }
ValidationErrors->hasErrors
35        return count($this->errors) > 0;
36    }
ValidationErrors->merge
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);
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) {
65            if (!isset($this->errors[$field])) {
66                $this->errors[$field] = [];
67            }
68            foreach ($errors as $error) {
69                $this->addValidationError($error);
70            }
71        }
72    }
{main}
3namespace App\Shared\Domain\Validation;
4
5use stdClass;
6use Symfony\Component\Validator\Constraints\Valid;
7
8/**
9 * A collection of validation errors
10 * @see ValidationError
11 *
12 * @author Wilhelm Zwertvaegher
13 *
14 */
15class 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    }