Passed
Push — master ( 2bd08b...6fd4a6 )
by Henri
01:24
created

Validator   F

Complexity

Total Complexity 62

Size/Duplication

Total Lines 224
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 107
c 4
b 0
f 0
dl 0
loc 224
rs 3.44
wmc 62

10 Methods

Rating   Name   Duplication   Size   Complexity  
A add() 0 3 1
A jsonData() 0 4 2
A existData() 0 4 2
B toJson() 0 32 7
A hasProvider() 0 4 2
F execute() 0 129 40
A includeValidations() 0 4 2
A existRole() 0 4 2
A getClass() 0 7 2
A hasRole() 0 4 2

How to fix   Complexity   

Complex Class

Complex classes like Validator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Validator, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace HnrAzevedo\Validator;
4
5
use HnrAzevedo\Validator\Rules;
6
use Exception;
7
8
Class Validator{
9
    
10
    private static array $validators = array();
11
    private static ?array $data = null;
12
13
    public static function add(object $model,callable $return): void
14
    {
15
        self::$validators[get_class($model)] = $return($Rules = new Rules($model));
16
    }
17
    
18
    private static function existData()
19
    {
20
        if(!array_key_exists('data', self::$data)){
0 ignored issues
show
Bug introduced by
It seems like self::data can also be of type null; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

20
        if(!array_key_exists('data', /** @scrutinizer ignore-type */ self::$data)){
Loading history...
21
            throw new Exception('Informações cruciais não foram recebidas.');
22
        }
23
    }
24
25
    private static function jsonData()
26
    {
27
        if(json_decode(self::$data['data']) === null){
28
            throw new Exception('O servidor recebeu as informações no formato esperado.');
29
        }
30
    }
31
32
    private static function hasProvider()
33
    {
34
        if(!array_key_exists('provider',self::$data)){
0 ignored issues
show
Bug introduced by
It seems like self::data can also be of type null; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

34
        if(!array_key_exists('provider',/** @scrutinizer ignore-type */ self::$data)){
Loading history...
35
            throw new Exception('O servidor não recebeu o ID do formulário.');
36
        }
37
    }
38
39
    private static function hasRole()
40
    {
41
        if(!array_key_exists('role',self::$data)){
0 ignored issues
show
Bug introduced by
It seems like self::data can also be of type null; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

41
        if(!array_key_exists('role',/** @scrutinizer ignore-type */ self::$data)){
Loading history...
42
            throw new Exception('O servidor não conseguiu identificar a finalidade deste formulário.');
43
        }
44
    }
45
46
    private static function includeValidations()
47
    {
48
        if( file_exists(VALIDATOR_CONFIG['path'] . ucfirst(self::$data['provider']) . '.php') ){
49
            require_once(VALIDATOR_CONFIG['path'] . ucfirst(self::$data['provider']) . '.php');
50
        }
51
    }
52
53
    private static function getClass(string $class)
54
    {
55
        if(!class_exists($class)){
56
            throw new Exception("Form ID {$class} inválido.");
57
        }
58
59
        return new $class();
60
    }
61
62
    private static function existRole($rules)
63
    {
64
        if(empty(self::$validators[get_class($rules)]->getRules(self::$data['role']))){
65
            throw new Exception('Não existe regras para validar este formulário.');
66
        }
67
    }
68
69
    public static function execute(array $datas): bool
70
    {
71
        self::$data = $datas;
72
73
		self::existData();
74
        self::jsonData();
75
        self::hasProvider();
76
        self::hasRole();
77
		            
78
        $data = (array) json_decode($datas['data']);
79
            
80
        self::includeValidations();
81
82
        $rules = self::getClass('HnrAzevedo\\Validator\\'.ucfirst(self::$data['provider']));
83
84
		self::existRole($rules);
85
86
		$validators = self::$validators[get_class($rules)]->getRules($datas['role']);
87
88
        $tests = 0;
89
            
90
		foreach ($validators as $key => $value) {
91
		    $tests = (array_key_exists('required',$value) and $value['required']===true) ? $tests+1 : $tests;
92
		}
93
94
		$testeds = 0;
95
96
		foreach ($validators as $key => $value) {
97
98
			foreach ($data as $keyy => $valuee) {
99
100
                $v = $valuee;
101
                    
102
				if(is_array($valuee)){
103
					$v = null;
104
					foreach ($valuee as $vvv) {
105
						$v .= $vvv;
106
					}
107
                }
108
                    
109
				$valuee = $v;
110
111
				if(!array_key_exists($keyy, $validators)){
112
                    throw new Exception("O campo '{$keyy}' não é esperado para está operação.");
113
                }
114
115
				if($keyy===$key){
116
117
                    $testeds++;
118
                        
119
					foreach ($value as $subkey => $subvalue) {
120
121
						switch ($subkey) {
122
							case 'minlength':
123
                                if(array_key_exists('required', $value)){
124
                                    if($value['required'] or strlen($valuee)!==0){
125
                                        if(strlen($valuee)===0){
126
                                            throw new Exception("O campo '{$key}' é obrigatório.",1);
127
                                        }
128
                                         
129
                                        if(strlen($valuee) < (int) $subvalue){
130
                                            throw new Exception("{$key} não atingiu o mínimo de caracteres esperado.",1);
131
                                        }
132
                                    }
133
                                }
134
                                break;
135
136
                            case 'type':
137
                                if(array_key_exists('required', $value)){
138
                                    if($value['required'] or strlen($valuee)!==0){
139
                                        switch ($subvalue) {
140
                                            case 'date':
141
                                                $date = explode('/', $valuee);
142
                                                if(count($date) != 3){
143
                                                    throw new Exception('Data inválida.',1);
144
                                                }
145
                                                if(!@checkdate(intval($date[1]), intval($date[0]), intval($date[2]) )){
146
                                                    throw new Exception('Data inválida.',1);
147
                                                }
148
                                                break;
149
                                        }
150
                                    }
151
                                }
152
    						    break;
153
154
							case 'maxlength':
155
                                if(array_key_exists('required', $value)){
156
                                    if($value['required'] or strlen($valuee)!==0){
157
                                        if(strlen($valuee)>(int)$subvalue){
158
                                            throw new Exception("{$key} ultrapassou o limite de caracteres permitidos.",1);
159
                                        }
160
                                    }
161
                                }
162
                                break;
163
164
							case 'regex':
165
                                if(array_key_exists('required', $value)){
166
                                    if($value['required'] or strlen($valuee)!==0){
167
                                        if(!@preg_match($subvalue,$valuee)){
168
                                            throw new Exception("{$key} inválido(a).",1);
169
                                        }
170
                                    }
171
                                }
172
                                break;
173
174
							case 'equals':
175
                                $equals = false;
176
                                foreach ($data as $ke => $sub) {
177
                                    if($ke===$subvalue){
178
                                        $equals=true;
179
                                        if($valuee !== $sub)
180
                                            throw new \Exception(ucfirst($key).' está diferente de '.ucfirst($ke),1);
181
                                    }
182
                                }
183
                                if(!$equals){
184
                                    throw new Exception("O servidor não encontrou a informação '{$subvalue}' para ser comparada a '{$key}'.",1);
185
                                }
186
                                break;
187
	    				}
188
					}
189
				}
190
			}
191
        }
192
            
193
		if($tests > $testeds){
194
            throw new Exception('Alguma informação necessária não pode ser validada.');
195
        }
196
				
197
		return true;
198
	}
199
200
    public static function toJson(array $request): string
201
    {
202
        self::$data['provider'] = $request['provider'];
203
204
        self::includeValidations();
205
206
        $rules = self::getClass('HnrAzevedo\\Validator\\'.ucfirst($request['provider']));
207
		
208
		self::existRole($rules);
209
		
210
        /* For function to validate information in javascript */
211
        $response = '{';
212
213
		foreach ( self::$validators[get_class($rules)]->getRules($request['role'])  as $field => $r) {
214
            $response .= $field.':{';
215
                
216
			foreach(array_reverse($r) as $rule => $value){
217
                $value = (gettype($value)==='string') ? '\''.$value.'\'' : $value;
218
                
219
				if(gettype($value)==='boolean'){
220
                    $value = ($value) ? 'true' : 'false';
221
                }
222
223
                $value = ($rule=='regex') ? str_replace('\\','\\\\','\''.substr($value,2,strlen($value)-4).'\'') : $value;
224
                
225
				$response .= $rule.':'.$value.',';
226
            }
227
            
228
			$response .='},';
229
        }
230
231
		return substr(str_replace(',}','}',$response),0,-1).'}';
232
	}
233
}
234