Rule::processRequirements()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
4
namespace Lexuss1979\Validol;
5
6
7
use Lexuss1979\Validol\Exceptions\RequirementsConflictValidationException;
8
use Lexuss1979\Validol\Exceptions\TypeConflictValidationException;
9
use Lexuss1979\Validol\Validations\AbstractValidation;
10
use Lexuss1979\Validol\Validations\ValidationFactory;
11
12
class Rule
13
{
14
    protected $options;
15
    protected $validations;
16
    protected $errors = [];
17
    protected $value;
18
    protected $status;
19
20
    protected $validationCache = [];
21
22 159
    public function __construct($options, ValidationFactory $validationFactory)
23
    {
24 159
        $signatures = $this->getSignatures($options);
25
26 159
        foreach ($signatures as $key => $val) {
27 159
            if (is_string($key)) {
28
                /** @var AbstractValidation $validation */
29 2
                $validation = $validationFactory->get($key);
30 2
                $validation->setErrorMessage($val);
31
            } else {
32 157
                if($this->isCachedValidation($val)){
33 15
                    $validation = $this->validationCache[$val];
34
                } else {
35 156
                    $validation = $validationFactory->get($val);
36
                }
37
38
            }
39
40 159
            $this->validations[$validation->group()][] = $validation;
41
        }
42
43 159
        $this->requirementsGuard();
44 158
        $this->typeGuard();
45
46 157
    }
47
48
    /**
49
     * @param $options mixed|array|string
50
     */
51 159
    protected function getSignatures($options)
52
    {
53 159
        if (is_array($options)) {
54 19
            $signatures = [];
55 19
            foreach ($options as $key => $option) {
56 19
                $associativeArray = is_string($key);
57 19
                if ($associativeArray) {
58 2
                    $part = $this->getSignatures($key);
59 2
                    $partValidation = [];
60 2
                    foreach ($part as $item) {
61 2
                        $partValidation[$item] = $option;
62
                    }
63 2
                    $signatures = array_merge($signatures, $partValidation);
64
                } else {
65 17
                    $part = $this->getSignatures($option);
66 17
                    $signatures = array_merge($signatures, $part);
67
                }
68
69
            }
70 19
            return $signatures;
71 159
        } elseif ($options instanceof AbstractValidation){
72 15
            return [$this->addToCache($options)];
73
        }
74
75 158
        return explode(" ", $options);
76
    }
77
78 159
    protected function requirementsGuard()
79
    {
80 159
        if (count($this->requirementsValidations()) > 1) {
81 1
            throw new RequirementsConflictValidationException("Multiple requirement validations detected");
82
        }
83 158
    }
84
85 159
    protected function requirementsValidations()
86
    {
87 159
        return $this->validations[AbstractValidation::REQUIREMENTS_GROUP] ?? [];
88
    }
89
90 158
    protected function typeGuard()
91
    {
92 158
        if (count($this->typeValidations()) > 1) {
93 1
            throw new TypeConflictValidationException("Multiple type validations detected");
94
        }
95 157
    }
96
97 158
    protected function typeValidations()
98
    {
99 158
        return $this->validations[AbstractValidation::TYPE_GROUP] ?? [];
100
    }
101
102 156
    public function process(ValueObject $data)
103
    {
104 156
        $this->value = $data;
105 156
        $this->status = true;
106
107 156
        $this->processRequirements();
108 156
        $needToContinueValidate = $this->status === true && !$this->value->isNull();
109
110 156
        if ($needToContinueValidate) {
111 153
            $this->processTypes();
112 153
            $this->processCommon();
113
        }
114
115 156
        return $this->status;
116
    }
117
118 156
    protected function processRequirements()
119
    {
120 156
        $this->processValidationGroup($this->requirementsValidations());
121 156
    }
122
123 156
    protected function processValidationGroup(array $validations)
124
    {
125 156
        foreach ($validations as $validation) {
126 156
            if (!$validation->validate($this->value)) {
127 96
                $this->errors[] = $validation->error();
128 96
                $this->status = false;
129
            }
130
        }
131 156
    }
132
133 153
    protected function processTypes()
134
    {
135 153
        $this->processValidationGroup($this->typeValidations());
136 153
    }
137
138 153
    protected function processCommon()
139
    {
140 153
        $this->processValidationGroup($this->commonValidations());
141 153
    }
142
143 153
    protected function commonValidations()
144
    {
145 153
        return $this->validations[AbstractValidation::COMMON_GROUP] ?? [];
146
    }
147
148 1
    public function getValidations($group = null)
149
    {
150 1
        if (isset($group)) {
151 1
            return $this->validations[$group];
152
        }
153
        return $this->validations;
154
    }
155
156 96
    public function errors()
157
    {
158 96
        return array_unique($this->errors);
159
    }
160
161 15
    protected function addToCache(AbstractValidation $validation){
162 15
        $key = '__cache__' . sizeof($this->validationCache);
163 15
        $this->validationCache[$key] = $validation;
164 15
        return $key;
165
    }
166
167 157
    protected function isCachedValidation($name){
168 157
        return array_key_exists($name, $this->validationCache);
169
    }
170
171
}