MultipleValidationWithAnd::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 8
ccs 4
cts 4
cp 1
crap 2
rs 10
1
<?php
2
3
namespace Egulias\EmailValidator\Validation;
4
5
use Egulias\EmailValidator\EmailLexer;
6
use Egulias\EmailValidator\Result\InvalidEmail;
7
use Egulias\EmailValidator\Validation\Exception\EmptyValidationList;
8
use Egulias\EmailValidator\Result\MultipleErrors;
9
use Egulias\EmailValidator\Warning\Warning;
10
11
class MultipleValidationWithAnd implements EmailValidation
12
{
13
    /**
14
     * If one of validations fails, the remaining validations will be skipped.
15
     * This means MultipleErrors will only contain a single error, the first found.
16
     */
17
    public const STOP_ON_ERROR = 0;
18
19
    /**
20
     * All of validations will be invoked even if one of them got failure.
21
     * So MultipleErrors will contain all causes.
22
     */
23
    public const ALLOW_ALL_ERRORS = 1;
24
25
    /**
26
     * @var EmailValidation[]
27
     */
28
    private $validations = [];
29
30
    /**
31
     * @var Warning[]
32
     */
33
    private $warnings = [];
34
35
    /**
36
     * @var MultipleErrors|null
37
     */
38
    private $error;
39
40
    /**
41
     * @var int
42
     */
43
    private $mode;
44
45
    /**
46
     * @param EmailValidation[] $validations The validations.
47
     * @param int               $mode        The validation mode (one of the constants).
48 9
     */
49
    public function __construct(array $validations, $mode = self::ALLOW_ALL_ERRORS)
50 9
    {
51 1
        if (count($validations) == 0) {
52
            throw new EmptyValidationList();
53
        }
54 8
55 8
        $this->validations = $validations;
56
        $this->mode = $mode;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61 8
     */
62
    public function isValid(string $email, EmailLexer $emailLexer): bool
63 8
    {
64 8
        $result = true;
65 8
        foreach ($this->validations as $validation) {
66 8
            $emailLexer->reset();
67 8
            $validationResult = $validation->isValid($email, $emailLexer);
68 8
            $result = $result && $validationResult;
69 8
            $this->warnings = array_merge($this->warnings, $validation->getWarnings());
70 6
            if (!$validationResult) {
71
                $this->processError($validation);
72
            }
73 8
74 3
            if ($this->shouldStop($result)) {
75
                break;
76
            }
77
        }
78 8
79
        return $result;
80
    }
81 6
82
    private function initErrorStorage(): void
83 6
    {
84 6
        if (null === $this->error) {
85
            $this->error = new MultipleErrors();
86
        }
87
    }
88 6
89
    private function processError(EmailValidation $validation): void
90 6
    {
91 6
        if (null !== $validation->getError()) {
92
            $this->initErrorStorage();
93 6
            /** @psalm-suppress PossiblyNullReference */
94
            $this->error->addReason($validation->getError()->reason());
95
        }
96
    }
97 8
98
    private function shouldStop(bool $result): bool
99 8
    {
100
        return !$result && $this->mode === self::STOP_ON_ERROR;
101
    }
102
103
    /**
104
     * Returns the validation errors.
105 5
     */
106
    public function getError(): ?InvalidEmail
107 5
    {
108
        return $this->error;
109
    }
110
111
    /**
112
     * @return Warning[]
113 2
     */
114
    public function getWarnings(): array
115 2
    {
116
        return $this->warnings;
117
    }
118
}
119