Passed
Push — master ( d7f029...202469 )
by Jean-Christophe
15:08
created

ValidatorsManager::validateFromCache_()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 2
dl 0
loc 11
ccs 0
cts 8
cp 0
crap 20
rs 10
c 0
b 0
f 0
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 );
0 ignored issues
show
Unused Code introduced by
The call to Ubiquity\contents\valida...r::validateFromCache_() has too many arguments starting with $excludedValidators. ( Ignorable by Annotation )

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

139
			return self::/** @scrutinizer ignore-call */ validateFromCache_ ( $instance, $cache, $excludedValidators );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
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) {
220
		$result = [ ];
221
		foreach ( $members as $accessor => $validators ) {
222
			foreach ( $validators as $validatorInstance ) {
223
				$valid = $validatorInstance->validate_ ( $instance->$accessor () );
224
				if ($valid !== true) {
225
					$result [] = $valid;
226
				}
227
			}
228
		}
229
		return $result;
230
	}
231
232
	/**
233
	 * Initializes the cache (SessionCache) for the class of instance
234
	 *
235
	 * @param object $instance
236
	 * @param string $group
237
	 */
238
	public static function initCacheInstanceValidators($instance, $group = "") {
239
		$class = get_class ( $instance );
240
		$members = self::fetch ( $class );
241
		self::initInstancesValidators ( $instance, $members, $group );
242
	}
243
244 2
	protected static function initInstancesValidators($instance, $members, $group = "") {
245 2
		$class = get_class ( $instance );
246 2
		$result = [ ];
247 2
		foreach ( $members as $member => $validators ) {
248 2
			$accessor = "get" . ucfirst ( $member );
249 2
			if (method_exists ( $instance, $accessor )) {
250 2
				foreach ( $validators as $validator ) {
251 2
					$validatorInstance = self::getValidatorInstance ( $validator ["type"] );
252 2
					if ($validatorInstance !== false) {
253 2
						$validatorInstance->setValidationParameters ( $member, $validator ["constraints"], $validator ["severity"] ?? null, $validator ["message"] ?? null);
254 2
						if ($group === "" || (isset ( $validator ["group"] ) && $validator ["group"] === $group)) {
255 2
							self::$instanceValidators [$class] [$accessor] [] = $validatorInstance;
256 2
							$result [$accessor] [] = $validatorInstance;
257
						}
258
					}
259
				}
260
			}
261
		}
262 2
		self::$cache->store ( self::getHash ( $class . $group ), $result );
263 2
	}
264
265 6
	protected static function getHash($class) {
266 6
		return hash ( "sha1", $class );
267
	}
268
269 12
	protected static function getModelCacheKey($classname) {
270 12
		return self::$key . \str_replace ( "\\", \DS, $classname );
271
	}
272
273 6
	protected static function getValidatorInstance($type) {
274 6
		if (isset ( self::$validatorTypes [$type] )) {
275 6
			$class = self::$validatorTypes [$type];
276 6
			return new $class ();
277
		} else {
278
			Logger::warn ( "validation", "Validator " . $type . " does not exists!" );
279
			return false;
280
		}
281
	}
282
}
283
284