|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Ubiquity\contents\validation; |
|
4
|
|
|
|
|
5
|
|
|
use Ubiquity\cache\CacheManager; |
|
6
|
|
|
use Ubiquity\log\Logger; |
|
7
|
|
|
use Ubiquity\contents\validation\validators\multiples\LengthValidator; |
|
8
|
|
|
use Ubiquity\contents\validation\validators\multiples\IdValidator; |
|
9
|
|
|
use Ubiquity\contents\validation\validators\basic\NotNullValidator; |
|
10
|
|
|
use Ubiquity\contents\validation\validators\basic\NotEmptyValidator; |
|
11
|
|
|
use Ubiquity\contents\validation\validators\comparison\EqualsValidator; |
|
12
|
|
|
use Ubiquity\contents\validation\validators\basic\TypeValidator; |
|
13
|
|
|
use Ubiquity\contents\validation\validators\comparison\GreaterThanValidator; |
|
14
|
|
|
use Ubiquity\contents\validation\validators\comparison\LessThanValidator; |
|
15
|
|
|
use Ubiquity\contents\validation\validators\basic\IsNullValidator; |
|
16
|
|
|
use Ubiquity\contents\validation\validators\basic\IsEmptyValidator; |
|
17
|
|
|
use Ubiquity\contents\validation\validators\basic\IsTrueValidator; |
|
18
|
|
|
use Ubiquity\contents\validation\validators\basic\IsFalseValidator; |
|
19
|
|
|
use Ubiquity\contents\validation\validators\strings\RegexValidator; |
|
20
|
|
|
use Ubiquity\contents\validation\validators\strings\EmailValidator; |
|
21
|
|
|
use Ubiquity\contents\validation\validators\strings\UrlValidator; |
|
22
|
|
|
use Ubiquity\contents\validation\validators\strings\IpValidator; |
|
23
|
|
|
use Ubiquity\contents\validation\validators\comparison\RangeValidator; |
|
24
|
|
|
use Ubiquity\contents\validation\validators\comparison\GreaterThanOrEqualValidator; |
|
25
|
|
|
use Ubiquity\contents\validation\validators\comparison\LessThanOrEqualValidator; |
|
26
|
|
|
use Ubiquity\contents\validation\validators\dates\DateValidator; |
|
27
|
|
|
use Ubiquity\contents\validation\validators\dates\DateTimeValidator; |
|
28
|
|
|
use Ubiquity\contents\validation\validators\dates\TimeValidator; |
|
29
|
|
|
use Ubiquity\contents\validation\validators\basic\IsBooleanValidator; |
|
30
|
|
|
use Ubiquity\cache\objects\SessionCache; |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* Validators manager |
|
34
|
|
|
* @author jcheron <[email protected]> |
|
35
|
|
|
* @version 1.0.0 |
|
36
|
|
|
*/ |
|
37
|
|
|
class ValidatorsManager { |
|
38
|
|
|
protected static $instanceValidators=[]; |
|
39
|
|
|
protected static $cache; |
|
40
|
|
|
|
|
41
|
|
|
public static function start(){ |
|
42
|
|
|
self::$cache=new SessionCache(); |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
public static $validatorTypes=[ |
|
46
|
|
|
"notNull"=>NotNullValidator::class, |
|
47
|
|
|
"isNull"=>IsNullValidator::class, |
|
48
|
|
|
"notEmpty"=>NotEmptyValidator::class, |
|
49
|
|
|
"isEmpty"=>IsEmptyValidator::class, |
|
50
|
|
|
"isTrue"=>IsTrueValidator::class, |
|
51
|
|
|
"isFalse"=>IsFalseValidator::class, |
|
52
|
|
|
"isBool"=>IsBooleanValidator::class, |
|
53
|
|
|
"equals"=>EqualsValidator::class, |
|
54
|
|
|
"type"=>TypeValidator::class, |
|
55
|
|
|
"greaterThan"=>GreaterThanValidator::class, |
|
56
|
|
|
"greaterThanOrEqual"=>GreaterThanOrEqualValidator::class, |
|
57
|
|
|
"lessThan"=>LessThanValidator::class, |
|
58
|
|
|
"lessThanOrEqual"=>LessThanOrEqualValidator::class, |
|
59
|
|
|
"length"=>LengthValidator::class, |
|
60
|
|
|
"id"=>IdValidator::class, |
|
61
|
|
|
"regex"=>RegexValidator::class, |
|
62
|
|
|
"email"=>EmailValidator::class, |
|
63
|
|
|
"url"=>UrlValidator::class, |
|
64
|
|
|
"ip"=>IpValidator::class, |
|
65
|
|
|
"range"=>RangeValidator::class, |
|
66
|
|
|
"date"=>DateValidator::class, |
|
67
|
|
|
"dateTime"=>DateTimeValidator::class, |
|
68
|
|
|
"time"=>TimeValidator::class |
|
69
|
|
|
|
|
70
|
|
|
]; |
|
71
|
|
|
|
|
72
|
|
|
protected static $key="contents/validators/"; |
|
73
|
|
|
|
|
74
|
|
|
/** |
|
75
|
|
|
* Registers a validator type for using with @validator annotation |
|
76
|
|
|
* @param string $type |
|
77
|
|
|
* @param string $validatorClass |
|
78
|
|
|
*/ |
|
79
|
|
|
public static function registerType($type,$validatorClass){ |
|
80
|
|
|
self::$validatorTypes[$type]=$validatorClass; |
|
81
|
|
|
} |
|
82
|
|
|
|
|
83
|
|
|
/** |
|
84
|
|
|
* Parses models and save validators in cache |
|
85
|
|
|
* to use in dev only |
|
86
|
|
|
* @param array $config |
|
87
|
|
|
*/ |
|
88
|
|
|
public static function initModelsValidators(&$config){ |
|
89
|
|
|
$models=CacheManager::getModels($config,true); |
|
90
|
|
|
foreach ($models as $model){ |
|
91
|
|
|
$parser=new ValidationModelParser(); |
|
92
|
|
|
$parser->parse($model); |
|
93
|
|
|
$validators=$parser->getValidators(); |
|
94
|
|
|
if(sizeof($validators)>0){ |
|
95
|
|
|
self::store($model, $parser->__toString()); |
|
96
|
|
|
} |
|
97
|
|
|
} |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
protected static function store($model,$validators){ |
|
101
|
|
|
CacheManager::$cache->store(self::getModelCacheKey($model), $validators); |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
protected static function fetch($model){ |
|
105
|
|
|
$key=self::getModelCacheKey($model); |
|
106
|
|
|
if(CacheManager::$cache->exists($key)){ |
|
107
|
|
|
return CacheManager::$cache->fetch($key); |
|
108
|
|
|
} |
|
109
|
|
|
return []; |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
protected static function getGroupArrayValidators(array $validators,$group){ |
|
113
|
|
|
$result=[]; |
|
114
|
|
|
foreach ($validators as $member=>$validators){ |
|
115
|
|
|
$filteredValidators=self::getGroupMemberValidators($validators, $group); |
|
116
|
|
|
if(sizeof($filteredValidators)){ |
|
117
|
|
|
$result[$member]=$filteredValidators; |
|
118
|
|
|
} |
|
119
|
|
|
} |
|
120
|
|
|
return $result; |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
protected static function getGroupMemberValidators(array $validators,$group){ |
|
124
|
|
|
$result=[]; |
|
125
|
|
|
foreach ($validators as $validator){ |
|
126
|
|
|
if(isset($validator["group"]) && $validator["group"]===$group){ |
|
127
|
|
|
$result[]=$validator; |
|
128
|
|
|
} |
|
129
|
|
|
} |
|
130
|
|
|
return $result; |
|
131
|
|
|
} |
|
132
|
|
|
|
|
133
|
|
|
private static function getCacheValidators($instance,$group=""){ |
|
134
|
|
|
if(isset(self::$cache)){ |
|
135
|
|
|
$key=self::getHash(get_class($instance).$group); |
|
136
|
|
|
if(self::$cache->exists($key)){ |
|
137
|
|
|
return self::$cache->fetch($key); |
|
138
|
|
|
} |
|
139
|
|
|
} |
|
140
|
|
|
return false; |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
/** |
|
144
|
|
|
* Validates an instance |
|
145
|
|
|
* @param object $instance |
|
146
|
|
|
* @param string $group |
|
147
|
|
|
* @return \Ubiquity\contents\validation\validators\ConstraintViolation[] |
|
148
|
|
|
*/ |
|
149
|
|
|
public static function validate($instance,$group=""){ |
|
150
|
|
|
$cache=self::getCacheValidators($instance,$group); |
|
151
|
|
|
if($cache!==false){ |
|
152
|
|
|
return self::validateFromCache_($instance,$cache); |
|
153
|
|
|
} |
|
154
|
|
|
$members=self::fetch(get_class($instance)); |
|
155
|
|
|
if($group!==""){ |
|
156
|
|
|
$members=self::getGroupArrayValidators($members, $group); |
|
157
|
|
|
} |
|
158
|
|
|
return self::validate_($instance,$members); |
|
159
|
|
|
} |
|
160
|
|
|
|
|
161
|
|
|
/** |
|
162
|
|
|
* Validates an array of objects |
|
163
|
|
|
* @param array $instances |
|
164
|
|
|
* @param string $group |
|
165
|
|
|
* @return \Ubiquity\contents\validation\validators\ConstraintViolation[] |
|
166
|
|
|
*/ |
|
167
|
|
|
public static function validateInstances($instances,$group=""){ |
|
168
|
|
|
if(sizeof($instances)>0){ |
|
169
|
|
|
$instance=reset($instances); |
|
170
|
|
|
$cache=self::getCacheValidators($instance,$group); |
|
171
|
|
|
if($cache===false){ |
|
172
|
|
|
$class=get_class($instance); |
|
173
|
|
|
$members=self::fetch($class); |
|
174
|
|
|
self::initInstancesValidators($instance, $members,$group); |
|
175
|
|
|
$cache=self::$instanceValidators[$class]; |
|
176
|
|
|
} |
|
177
|
|
|
return self::validateInstances_($instances,$cache); |
|
178
|
|
|
} |
|
179
|
|
|
return []; |
|
180
|
|
|
} |
|
181
|
|
|
|
|
182
|
|
|
public static function clearCache($model=null,$group=""){ |
|
183
|
|
|
if(isset(self::$cache)){ |
|
184
|
|
|
if(isset($model)){ |
|
185
|
|
|
$key=self::getHash($model.$group); |
|
186
|
|
|
self::$cache->remove($key); |
|
187
|
|
|
}else{ |
|
188
|
|
|
self::$cache->clear(); |
|
189
|
|
|
} |
|
190
|
|
|
} |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
View Code Duplication |
protected static function validateInstances_($instances,$members){ |
|
|
|
|
|
|
194
|
|
|
$result=[]; |
|
195
|
|
|
foreach ($instances as $instance){ |
|
196
|
|
|
foreach ($members as $accessor=>$validators){ |
|
197
|
|
|
foreach ($validators as $validator){ |
|
198
|
|
|
$valid=$validator->validate_($instance->$accessor()); |
|
199
|
|
|
if($valid!==true){ |
|
200
|
|
|
$result[]=$valid; |
|
201
|
|
|
} |
|
202
|
|
|
} |
|
203
|
|
|
} |
|
204
|
|
|
} |
|
205
|
|
|
return $result; |
|
206
|
|
|
} |
|
207
|
|
|
|
|
208
|
|
|
protected static function validate_($instance,$members){ |
|
209
|
|
|
$result=[]; |
|
210
|
|
|
foreach ($members as $member=>$validators){ |
|
211
|
|
|
$accessor="get".ucfirst($member); |
|
212
|
|
|
if(method_exists($instance, $accessor)){ |
|
213
|
|
|
foreach ($validators as $validator){ |
|
214
|
|
|
$validatorInstance=self::getValidatorInstance($validator["type"]); |
|
215
|
|
|
if($validatorInstance!==false){ |
|
216
|
|
|
$validatorInstance->setValidationParameters($member,$validator["constraints"],@$validator["severity"],@$validator["message"]); |
|
217
|
|
|
$valid=$validatorInstance->validate_($instance->$accessor()); |
|
218
|
|
|
if($valid!==true){ |
|
219
|
|
|
$result[]=$valid; |
|
220
|
|
|
} |
|
221
|
|
|
} |
|
222
|
|
|
} |
|
223
|
|
|
} |
|
224
|
|
|
} |
|
225
|
|
|
return $result; |
|
226
|
|
|
} |
|
227
|
|
|
|
|
228
|
|
View Code Duplication |
protected static function validateFromCache_($instance,$members){ |
|
|
|
|
|
|
229
|
|
|
$result=[]; |
|
230
|
|
|
foreach ($members as $accessor=>$validators){ |
|
231
|
|
|
foreach ($validators as $validatorInstance){ |
|
232
|
|
|
$valid=$validatorInstance->validate_($instance->$accessor()); |
|
233
|
|
|
if($valid!==true){ |
|
234
|
|
|
$result[]=$valid; |
|
235
|
|
|
} |
|
236
|
|
|
} |
|
237
|
|
|
} |
|
238
|
|
|
return $result; |
|
239
|
|
|
} |
|
240
|
|
|
|
|
241
|
|
|
/** |
|
242
|
|
|
* Initializes the cache (SessionCache) for the class of înstance |
|
243
|
|
|
* @param object $instance |
|
244
|
|
|
* @param string $group |
|
245
|
|
|
*/ |
|
246
|
|
|
public static function initCacheInstanceValidators($instance,$group=""){ |
|
247
|
|
|
$class=get_class($instance); |
|
248
|
|
|
$members=self::fetch($class); |
|
249
|
|
|
self::initInstancesValidators($instance, $members,$group); |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
protected static function initInstancesValidators($instance,$members,$group=""){ |
|
253
|
|
|
$class=get_class($instance); |
|
254
|
|
|
$result=[]; |
|
255
|
|
|
foreach ($members as $member=>$validators){ |
|
256
|
|
|
$accessor="get".ucfirst($member); |
|
257
|
|
|
if(method_exists($instance, $accessor)){ |
|
258
|
|
|
foreach ($validators as $validator){ |
|
259
|
|
|
$validatorInstance=self::getValidatorInstance($validator["type"]); |
|
260
|
|
|
if($validatorInstance!==false){ |
|
261
|
|
|
$validatorInstance->setValidationParameters($member,$validator["constraints"],@$validator["severity"],@$validator["message"]); |
|
262
|
|
|
if($group==="" || (isset($validator["group"]) && $validator["group"]===$group)){ |
|
263
|
|
|
self::$instanceValidators[$class][$accessor][]=$validatorInstance; |
|
264
|
|
|
$result[$accessor][]=$validatorInstance; |
|
265
|
|
|
} |
|
266
|
|
|
} |
|
267
|
|
|
} |
|
268
|
|
|
} |
|
269
|
|
|
} |
|
270
|
|
|
self::$cache->store(self::getHash($class.$group), $result); |
|
271
|
|
|
} |
|
272
|
|
|
|
|
273
|
|
|
protected static function getHash($class){ |
|
274
|
|
|
return hash("sha1", $class); |
|
275
|
|
|
} |
|
276
|
|
|
|
|
277
|
|
|
protected static function getModelCacheKey($classname){ |
|
278
|
|
|
return self::$key.\str_replace("\\", DIRECTORY_SEPARATOR, $classname); |
|
279
|
|
|
} |
|
280
|
|
|
|
|
281
|
|
|
protected static function getValidatorInstance($type){ |
|
282
|
|
|
if(isset(self::$validatorTypes[$type])){ |
|
283
|
|
|
$class=self::$validatorTypes[$type]; |
|
284
|
|
|
return new $class(); |
|
285
|
|
|
}else{ |
|
286
|
|
|
Logger::warn("validation", "Validator ".$type." does not exists!"); |
|
287
|
|
|
return false; |
|
288
|
|
|
} |
|
289
|
|
|
} |
|
290
|
|
|
} |
|
291
|
|
|
|
|
292
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.