Completed
Push — master ( 10806f...3a0750 )
by Jean-Christophe
01:35
created

ValidatorsManager::getValidatorInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 1
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
31
/**
32
 * Validators manager
33
 * @author jcheron <[email protected]>
34
 * @version 1.0.0
35
 */
36
class ValidatorsManager {
37
	protected static $instanceValidators=[];
38
	public static $validatorTypes=[
39
			"notNull"=>NotNullValidator::class,
40
			"isNull"=>IsNullValidator::class,
41
			"notEmpty"=>NotEmptyValidator::class,
42
			"isEmpty"=>IsEmptyValidator::class,
43
			"isTrue"=>IsTrueValidator::class,
44
			"isFalse"=>IsFalseValidator::class,
45
			"isBool"=>IsBooleanValidator::class,
46
			"equals"=>EqualsValidator::class,
47
			"type"=>TypeValidator::class,
48
			"greaterThan"=>GreaterThanValidator::class,
49
			"greaterThanOrEqual"=>GreaterThanOrEqualValidator::class,
50
			"lessThan"=>LessThanValidator::class,
51
			"lessThanOrEqual"=>LessThanOrEqualValidator::class,
52
			"length"=>LengthValidator::class,
53
			"id"=>IdValidator::class,
54
			"regex"=>RegexValidator::class,
55
			"email"=>EmailValidator::class,
56
			"url"=>UrlValidator::class,
57
			"ip"=>IpValidator::class,
58
			"range"=>RangeValidator::class,
59
			"date"=>DateValidator::class,
60
			"dateTime"=>DateTimeValidator::class,
61
			"time"=>TimeValidator::class
62
			
63
	];
64
	
65
	protected static $key="contents/validators/";
66
	
67
	/**
68
	 * Registers a validator type for using with @validator annotation
69
	 * @param string $type
70
	 * @param string $validatorClass
71
	 */
72
	public static function registerType($type,$validatorClass){
73
		self::$validatorTypes[$type]=$validatorClass;
74
	}
75
	
76
	/**
77
	 * Parses models and save validators in cache
78
	 * to use in dev only
79
	 * @param array $config
80
	 */
81
	public static function initModelsValidators(&$config){
82
		$models=CacheManager::getModels($config,true);
83
		foreach ($models as $model){
84
			$parser=new ValidationModelParser();
85
			$parser->parse($model);
86
			$validators=$parser->getValidators();
87
			if(sizeof($validators)>0){
88
				self::store($model, $parser->__toString());
89
			}
90
		}
91
	}
92
	
93
	protected static function store($model,$validators){
94
		CacheManager::$cache->store(self::getModelCacheKey($model), $validators);
95
	}
96
	
97
	protected static function fetch($model){
98
		$key=self::getModelCacheKey($model);
99
		if(CacheManager::$cache->exists($key)){
100
			return CacheManager::$cache->fetch($key);
101
		}
102
		return [];
103
	}
104
	
105
	protected static function getGroupValidators(array $validators,$group){
106
		$result=[];
107
		foreach ($validators as $member=>$validators){
108
			$filteredValidators=self::getGroupMemberValidators($validators, $group);
109
			if(sizeof($filteredValidators)){
110
				$result[$member]=$filteredValidators;
111
			}
112
		}
113
		return $result;
114
	}
115
	
116
	protected static function getGroupMemberValidators(array $validators,$group){
117
		$result=[];
118
		foreach ($validators as $validator){
119
			if(isset($validator["group"]) && $validator["group"]===$group){
120
				$result[]=$validator;
121
			}
122
		}
123
		return $result;
124
	}
125
	
126
	/**
127
	 * Validates an instance
128
	 * @param object $instance
129
	 * @return \Ubiquity\contents\validation\validators\ConstraintViolation[]
130
	 */
131
	public static function validate($instance){
132
		return self::validate_($instance,self::fetch(get_class($instance)));
133
	}
134
	
135
	/**
136
	 * Validates an array of objects
137
	 * @param array $instances
138
	 * @return \Ubiquity\contents\validation\validators\ConstraintViolation[]
139
	 */
140
	public static function validateInstances($instances){
141
		if(sizeof($instances)>0){
142
			$instance=reset($instances);
143
			$class=get_class($instance);
144
			$members=self::fetch($class);
145
			self::initInstancesValidators($instance, $members);
146
			return self::validateInstances_($instances, self::$instanceValidators[$class]);
147
		}
148
		return [];
149
	}
150
	
151
	protected static function validateInstances_($instances,$members){
152
		$result=[];
153
		foreach ($instances as $instance){
154
			foreach ($members as $member=>$validators){
155
				$accessor="get".ucfirst($member);
156
				foreach ($validators as $validator){
157
					$valid=$validator->validate_($instance->$accessor());
158
					if($valid!==true){
159
						$result[]=$valid;
160
					}
161
				}
162
			}
163
		}
164
		return $result;
165
	}
166
	
167
	/**
168
	 * Validates an array of objects using a group of validators
169
	 * @param array $instances
170
	 * @param string $group
171
	 * @return \Ubiquity\contents\validation\validators\ConstraintViolation[]
172
	 */
173
	public static function validateInstancesGroup($instances,$group){
174
		if(sizeof($instances)>0){
175
			$instance=reset($instances);
176
			$class=get_class($instance);
177
			$members=self::fetch($class);
178
			$members=self::getGroupValidators($members, $group);
179
			self::initInstancesValidators($instance, $members);
180
			return self::validateInstances_($instances,self::$instanceValidators[$class]);
181
		}
182
		return [];
183
	}
184
	
185
	/**
186
	 * Validates an instance using a group of validators
187
	 * @param object $instance
188
	 * @param string $group
189
	 * @return \Ubiquity\contents\validation\validators\ConstraintViolation[]
190
	 */
191
	public static function validateGroup($instance,$group){
192
		$members=self::getGroupValidators(self::fetch(get_class($instance)), $group);
193
		return self::validate_($instance,$members);
194
	}
195
	
196
	protected static function validate_($instance,$members){
197
		$result=[];
198
		foreach ($members as $member=>$validators){
199
			$accessor="get".ucfirst($member);
200
			if(method_exists($instance, $accessor)){
201
				foreach ($validators as $validator){
202
					$validatorInstance=self::getValidatorInstance($validator["type"]);
203
					if($validatorInstance!==false){
204
						$validatorInstance->setValidationParameters($member,$validator["constraints"],@$validator["severity"],@$validator["message"]);
205
						$valid=$validatorInstance->validate_($instance->$accessor());
206
						if($valid!==true){
207
							$result[]=$valid;
208
						}
209
					}
210
				}
211
			}
212
		}
213
		return $result;
214
	}
215
	
216
	protected static function initInstancesValidators($instance,$members,$group=null){
217
		$class=get_class($instance);
218
		foreach ($members as $member=>$validators){
219
			$accessor="get".ucfirst($member);
220
			if(method_exists($instance, $accessor)){
221
				foreach ($validators as $validator){
222
					$validatorInstance=self::getValidatorInstance($validator["type"]);
223
					if($validatorInstance!==false){
224
						$validatorInstance->setValidationParameters($member,$validator["constraints"],@$validator["severity"],@$validator["message"]);
225
						if(!isset($group) || (isset($validator["group"]) && $validator["group"]===$group)){
226
							self::$instanceValidators[$class][$member][]=$validatorInstance;
227
						}
228
					}
229
				}
230
			}
231
		}
232
	}
233
	
234
	protected static function getModelCacheKey($classname){
235
		return self::$key.\str_replace("\\", DIRECTORY_SEPARATOR, $classname);
236
	}
237
	
238
	protected static function getValidatorInstance($type){
239
		if(isset(self::$validatorTypes[$type])){
240
			$class=self::$validatorTypes[$type];
241
			return new $class();
242
		}else{
243
			Logger::warn("validation", "Validator ".$type." does not exists!");
244
			return false;
245
		}
246
	}
247
}
248
249