PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / 5.11
Advanced Access Manager – Access Governance for WordPress v5.11
6.8.4 6.8.5 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13 6.9.14 6.9.15 6.9.16 6.9.17 6.9.18 6.9.19 6.9.2 6.9.20 6.9.21 6.9.22 6.9.23 6.9.24 6.9.25 6.9.26 6.9.27 6.9.28 6.9.29 6.9.3 6.9.30 6.9.31 6.9.32 6.9.33 6.9.34 6.9.35 6.9.36 6.9.37 6.9.38 6.9.39 6.9.4 6.9.41 6.9.42 6.9.43 6.9.44 6.9.45 6.9.46 6.9.47 6.9.48 6.9.49 6.9.5 6.9.51 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.0-alpha.6 7.0.0-alpha.7 7.0.0-beta.1 7.0.0-rc1 7.0.0-rc2 7.0.0-rc3 7.0.1 7.0.10 7.0.11 7.0.2 7.0.3 7.0.4 7.0.5 7.0.6 7.0.7 7.0.8 7.0.9 7.1.0 7.1.1 trunk 3.0 4.0 4.0.1 4.1 4.2 4.3 4.4 4.4.1 4.5 4.6 4.6.1 4.6.2 4.7 4.7.1 4.7.2 4.7.5 4.7.6 4.8 4.8.1 4.9 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.5.1 4.9.5.2 5.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1 5.1.1 5.10 5.11 5.2 5.2.1 5.2.5 5.2.6 5.2.7 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.4 5.4.1 5.4.2 5.4.3 5.4.3.1 5.4.3.2 5.5 5.5.1 5.5.2 5.6 5.6.1 5.6.1.1 5.7 5.7.1 5.7.2 5.7.3 5.8 5.8.1 5.8.2 5.8.3 5.9 5.9.1 5.9.1.1 5.9.2 5.9.2.1 5.9.3 5.9.4 5.9.5 5.9.6 5.9.6.1 5.9.6.2 5.9.6.3 5.9.7 5.9.7.1 5.9.7.2 5.9.7.3 5.9.8 5.9.8.1 5.9.9 5.9.9.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.2.0 6.2.1 6.2.2 6.3.0 6.3.1 6.3.2 6.3.3 6.4.0 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.6.0 6.6.1 6.6.2 6.6.3 6.6.4 6.7.0 6.7.1 6.7.2 6.7.3 6.7.4 6.7.5 6.7.6 6.7.7 6.7.8 6.7.9 6.8.0 6.8.1 6.8.2 6.8.3
advanced-access-manager / application / Core / Policy / Condition.php
advanced-access-manager / application / Core / Policy Last commit date
Condition.php 6 years ago Factory.php 6 years ago Manager.php 6 years ago Token.php 6 years ago Validator.php 6 years ago
Condition.php
449 lines
1 <?php
2
3 /**
4 * ======================================================================
5 * LICENSE: This file is subject to the terms and conditions defined in *
6 * file 'license.txt', which is part of this source code package. *
7 * ======================================================================
8 */
9
10 /**
11 * AAM core policy condition evaluator
12 *
13 * @package AAM
14 * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15 * @since AAM v5.8.2
16 */
17 final class AAM_Core_Policy_Condition {
18
19 /**
20 * Single instance of itself
21 *
22 * @var AAM_Core_Policy_Condition
23 *
24 * @access protected
25 * @static
26 */
27 protected static $instance = null;
28
29 /**
30 * Map between condition type and method that evaluates the
31 * group of conditions
32 *
33 * @var array
34 *
35 * @access protected
36 */
37 protected $map = array(
38 'between' => 'evaluateBetweenConditions',
39 'equals' => 'evaluateEqualsConditions',
40 'notequals' => 'evaluateNotEqualsConditions',
41 'greater' => 'evaluateGreaterConditions',
42 'less' => 'evaluateLessConditions',
43 'greaterorequals' => 'evaluateGreaterOrEqualsConditions',
44 'lessorequals' => 'evaluateLessOrEqualsConditions',
45 'in' => 'evaluateInConditions',
46 'notin' => 'evaluateNotInConditions',
47 'like' => 'evaluateLikeConditions',
48 'notlike' => 'evaluateNotLikeConditions',
49 'regex' => 'evaluateRegexConditions'
50 );
51
52 /**
53 * Constructor
54 *
55 * @return void
56 *
57 * @access protected
58 */
59 protected function __construct() {}
60
61 /**
62 * Evaluate the group of conditions based on type
63 *
64 * @param array $conditions List of conditions
65 * @param array $args Since 5.9 - Inline args for evaluation
66 *
67 * @return boolean
68 *
69 * @access public
70 */
71 public function evaluate($conditions, $args = array()) {
72 $result = true;
73
74 foreach($conditions as $type => $conditions) {
75 $type = strtolower($type);
76
77 if (isset($this->map[$type])) {
78 $callback = array($this, $this->map[$type]);
79
80 // Since v5.9.2 - if specific condition type is array, then combine
81 // them with AND operation
82 if (isset($conditions[0]) && is_array($conditions[0])) {
83 foreach($conditions as $set) {
84 $result = $result && call_user_func($callback, $set, $args);
85 }
86 } else {
87 $result = $result && call_user_func($callback, $conditions, $args);
88 }
89 } else {
90 $result = false;
91 }
92 }
93
94 return $result;
95 }
96
97 /**
98 * Evaluate group of BETWEEN conditions
99 *
100 * @param array $conditions
101 * @param array $args
102 *
103 * @return boolean
104 *
105 * @access protected
106 */
107 protected function evaluateBetweenConditions($conditions, $args) {
108 $result = false;
109
110 foreach($this->prepareConditions($conditions, $args) as $condition) {
111 // Convert the right condition into the array of array to cover more
112 // complex between conditions like [[0,8],[13,15]]
113 if (is_array($condition['right'][0])) {
114 $right = $condition['right'];
115 } else {
116 $right = array($condition['right']);
117 }
118 foreach($right as $subset) {
119 $min = (is_array($subset) ? array_shift($subset) : $subset);
120 $max = (is_array($subset) ? end($subset) : $subset);
121
122 $result = $result || ($condition['left'] >= $min && $condition['left'] <= $max);
123 }
124 }
125
126 return $result;
127 }
128
129 /**
130 * Evaluate group of EQUALS conditions
131 *
132 * The values have to be identical
133 *
134 * @param array $conditions
135 * @param array $args
136 *
137 * @return boolean
138 *
139 * @access protected
140 */
141 protected function evaluateEqualsConditions($conditions, $args) {
142 $result = false;
143
144 foreach($this->prepareConditions($conditions, $args) as $condition) {
145 $result = $result || ($condition['left'] === $condition['right']);
146 }
147
148 return $result;
149 }
150
151 /**
152 * Evaluate group of NOT EQUALs conditions
153 *
154 * @param array $conditions
155 * @param array $args
156 *
157 * @return boolean
158 *
159 * @access protected
160 */
161 protected function evaluateNotEqualsConditions($conditions, $args) {
162 return !$this->evaluateEqualsConditions($conditions, $args);
163 }
164
165 /**
166 * Evaluate group of GREATER THEN conditions
167 *
168 * @param array $conditions
169 * @param array $args
170 *
171 * @return boolean
172 *
173 * @access protected
174 */
175 protected function evaluateGreaterConditions($conditions, $args) {
176 $result = false;
177
178 foreach($this->prepareConditions($conditions, $args) as $condition) {
179 $result = $result || ($condition['left'] > $condition['right']);
180 }
181
182 return $result;
183 }
184
185 /**
186 * Evaluate group of LESS THEN conditions
187 *
188 * @param array $conditions
189 * @param array $args
190 *
191 * @return boolean
192 *
193 * @access protected
194 */
195 protected function evaluateLessConditions($conditions, $args) {
196 $result = false;
197
198 foreach($this->prepareConditions($conditions, $args) as $condition) {
199 $result = $result || ($condition['left'] < $condition['right']);
200 }
201
202 return $result;
203 }
204
205 /**
206 * Evaluate group of GREATER OR EQUALS THEN conditions
207 *
208 * @param array $conditions
209 * @param array $args
210 *
211 * @return boolean
212 *
213 * @access protected
214 */
215 protected function evaluateGreaterOrEqualsConditions($conditions, $args) {
216 $result = false;
217
218 foreach($this->prepareConditions($conditions, $args) as $condition) {
219 $result = $result || ($condition['left'] >= $condition['right']);
220 }
221
222 return $result;
223 }
224
225 /**
226 * Evaluate group of LESS OR EQUALS THEN conditions
227 *
228 * @param array $conditions
229 * @param array $args
230 *
231 * @return boolean
232 *
233 * @access protected
234 */
235 protected function evaluateLessOrEqualsConditions($conditions, $args) {
236 $result = false;
237
238 foreach($this->prepareConditions($conditions, $args) as $condition) {
239 $result = $result || ($condition['left'] <= $condition['right']);
240 }
241
242 return $result;
243 }
244
245 /**
246 * Evaluate group of IN conditions
247 *
248 * @param array $conditions
249 * @param array $args
250 *
251 * @return boolean
252 *
253 * @access protected
254 */
255 protected function evaluateInConditions($conditions, $args) {
256 $result = false;
257
258 foreach($this->prepareConditions($conditions, $args) as $condition) {
259 $result = $result || in_array($condition['left'], (array)$condition['right'], true);
260 }
261
262 return $result;
263 }
264
265 /**
266 * Evaluate group of NOT IN conditions
267 *
268 * @param array $conditions
269 * @param array $args
270 *
271 * @return boolean
272 *
273 * @access protected
274 */
275 protected function evaluateNotInConditions($conditions, $args) {
276 return !$this->evaluateInConditions($conditions, $args);
277 }
278
279 /**
280 * Evaluate group of LIKE conditions
281 *
282 * @param array $conditions
283 * @param array $args
284 *
285 * @return boolean
286 *
287 * @access protected
288 */
289 protected function evaluateLikeConditions($conditions, $args) {
290 $result = false;
291
292 foreach($this->prepareConditions($conditions, $args) as $condition) {
293 foreach((array)$condition['right'] as $el) {
294 $sub = str_replace('\*', '.*', preg_quote($el));
295 $result = $result || preg_match('@^' . $sub . '$@', $condition['left']);
296 }
297 }
298
299 return $result;
300 }
301
302 /**
303 * Evaluate group of NOT LIKE conditions
304 *
305 * @param array $conditions
306 * @param array $args
307 *
308 * @return boolean
309 *
310 * @access protected
311 */
312 protected function evaluateNotLikeConditions($conditions, $args) {
313 return !$this->evaluateLikeConditions($conditions, $args);
314 }
315
316 /**
317 * Evaluate group of REGEX conditions
318 *
319 * @param array $conditions
320 * @param array $args
321 *
322 * @return boolean
323 *
324 * @access protected
325 */
326 protected function evaluateRegexConditions($conditions, $args) {
327 $result = false;
328
329 foreach($this->prepareConditions($conditions, $args) as $condition) {
330 $result = $result || preg_match($condition['right'], $condition['left']);
331 }
332
333 return $result;
334 }
335
336 /**
337 * Prepare conditions by replacing all defined tokens
338 *
339 * @param array $conditions
340 * @param array $args
341 *
342 * @return array
343 *
344 * @access protected
345 */
346 protected function prepareConditions($conditions, $args) {
347 $result = array();
348
349 if (is_array($conditions)) {
350 foreach($conditions as $left => $right) {
351 $result[] = array(
352 'left' => $this->parseExpression($left, $args),
353 'right' => $this->parseExpression($right, $args)
354 );
355 }
356 }
357
358 return $result;
359 }
360
361 /**
362 * Parse condition and try to replace all defined tokens
363 *
364 * @param mixed $exp Part of the condition (either left or right)
365 * @param array $args Inline arguments
366 *
367 * @return mixed Prepared part of the condition or false on failure
368 *
369 * @access protected
370 */
371 protected function parseExpression($exp, $args) {
372 if (is_scalar($exp)) {
373 if (preg_match_all('/(\$\{[^}]+\})/', $exp, $match)) {
374 $exp = AAM_Core_Policy_Token::evaluate($exp, $match[1], $args);
375 }
376
377 // If there is type scaling, perform it too
378 if (preg_match('/^\(\*(string|ip|int|boolean|bool|array|null)\)(.*)/i', $exp, $scale)) {
379 $exp = $this->scaleValue($scale[2], $scale[1]);
380 }
381 } elseif (is_array($exp) || is_object($exp)) {
382 foreach($exp as &$value) {
383 $value = $this->parseExpression($value, $args);
384 }
385 } elseif (is_null($exp) === false) {
386 $exp = false;
387 }
388
389 return $exp;
390 }
391
392 /**
393 * Scale value to specific type
394 *
395 * @param mixed $value
396 * @param string $type
397 *
398 * @return mixed
399 *
400 * @access protected
401 */
402 protected function scaleValue($value, $type) {
403 switch(strtolower($type)) {
404 case 'string':
405 $value = (string)$value;
406 break;
407
408 case 'ip':
409 $value = inet_pton($value);
410 break;
411
412 case 'int':
413 $value = (int)$value;
414 break;
415
416 case 'boolean':
417 case 'bool':
418 $value = (bool)$value;
419 break;
420
421 case 'array':
422 $value = json_decode($value, true);
423 break;
424
425 case 'null':
426 $value = ($value === '' ? null : $value);
427 break;
428 }
429
430 return $value;
431 }
432
433 /**
434 * Get single instance of itself
435 *
436 * @return AAM_Core_Policy_Condition
437 *
438 * @access public
439 * @static
440 */
441 public static function getInstance() {
442 if (is_null(self::$instance)) {
443 self::$instance = new self;
444 }
445
446 return self::$instance;
447 }
448
449 }