Passed
Push — master ( 749218...64fe1c )
by Jean-Christophe
09:18
created

ValidatorsManager::start()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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