PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / 5.9
Advanced Access Manager – Access Governance for WordPress v5.9
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 / ConfigPress / Evaluator.php
advanced-access-manager / Application / Core / ConfigPress Last commit date
Evaluator.php 7 years ago Reader.php 7 years ago
Evaluator.php
304 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 * ConfigPress section evaluator
12 *
13 * Parse configuration section and evaluate an expression. At this point it
14 * does not take in consideration the operator's precedence but you can force
15 * the order with parenthesises.
16 *
17 * @package ConfigPress
18 * @author Vasyl Martyniuk <vasyl@vasyltech.com>
19 * @copyright Copyright Vasyl Martyniuk
20 */
21 class AAM_Core_ConfigPress_Evaluator {
22
23 /**
24 * Accepted operators
25 *
26 * @var array
27 *
28 * @access private
29 */
30 private $_operators = array(
31 array('*', '/'), //the highest priority
32 array('+', '-'),
33 array('==', '!=', '===', '!==', '<', '>', '>=', '<=', '<>'),
34 array('&&', '||'),
35 array('as') //the lowest priority
36 );
37
38 /**
39 * Expression to parse
40 *
41 * @var string
42 *
43 * @access protected
44 */
45 protected $expression;
46
47 /**
48 * Parsing expression alias
49 *
50 * @var string
51 *
52 * @access protected
53 */
54 protected $alias;
55
56 /**
57 * Current expression part index
58 *
59 * @var array
60 *
61 * @access protected
62 */
63 protected $index = array(0);
64
65 /**
66 * Prepare expression evaluation
67 *
68 * @param string $expression
69 *
70 * @return void
71 */
72 public function __construct($expression) {
73 $this->alias = $expression;
74
75 $regexp = '/(===|!==|==|>=|<=|<>|<|>|\+|\-|\*|\/|&&|\|\||\(|\)|\sas\s)/';
76 $this->expression = preg_split(
77 $regexp, $expression, -1, PREG_SPLIT_DELIM_CAPTURE
78 );
79 }
80
81 /**
82 * Evaluate the expression
83 *
84 * @return mixed
85 *
86 * @access public
87 */
88 public function evaluate() {
89 $queue = array();
90
91 $index = &$this->index[count($this->index) - 1];
92
93 for ($index; $index < count($this->expression); $index++) {
94 $chunk = trim($this->expression[$index]);
95
96 if (empty($chunk)) {
97 continue; //skip empty part
98 } elseif ($chunk === '(') {
99 $this->index[] = ++$index;
100 $queue[] = $this->evaluate();
101 } elseif ($chunk === ')') {
102 array_pop($this->index);
103 $this->index[count($this->index) - 1] = ++$index;
104 break;
105 } else { //evaluate operand or operator
106 $queue[] = $this->evaluateOperand($chunk);
107 }
108 }
109
110 //compute the queue
111 return $this->computeQueue($queue);
112 }
113
114 /**
115 * Evaluate an operand
116 *
117 * @param string $operand
118 *
119 * @return mixed
120 *
121 * @access protected
122 */
123 protected function evaluateOperand($operand) {
124 if (strpos($operand, '$') === 0) { //variable
125 $operand = $this->parseVariable(substr($operand, 1));
126 } elseif (strpos($operand, '@') === 0) { //callback function
127 $operand = $this->parseCallback(substr($operand, 1));
128 }
129
130 return $operand;
131 }
132
133 /**
134 * Evaluate variable
135 *
136 * @param string $variable
137 *
138 * @return mixed
139 *
140 * @access protected
141 */
142 protected function parseVariable($variable) {
143 $value = null;
144
145 $xpath = explode('.', $variable);
146 $root = array_shift($xpath);
147
148 if (isset($GLOBALS[$root])) {
149 $value = $GLOBALS[$root];
150 foreach ($xpath as $level) {
151 if (is_array($value) && isset($value[$level])) {
152 $value = $value[$level];
153 } elseif (is_object($value) && property_exists($value, $level)) {
154 $value = $value->{$level};
155 } else {
156 break;
157 }
158 }
159 }
160
161 return $value;
162 }
163
164 /**
165 * Evaluate callback function
166 *
167 * @param string $callback
168 *
169 * @return mixed
170 */
171 protected function parseCallback($callback) {
172 $value = null;
173
174 if (is_callable($callback)) {
175 $value = call_user_func($callback);
176 }
177
178 return $value;
179 }
180
181 /**
182 * Compute parsed expression
183 *
184 * @param array $queue
185 *
186 * @return mixed
187 *
188 * @access protected
189 */
190 protected function computeQueue($queue) {
191 $value = $queue[0]; //default value
192
193 foreach ($this->_operators as $operators) {
194 $i = 0;
195 while ($i < count($queue)) {
196 if (!is_bool($queue[$i]) && in_array($queue[$i], $operators, true)) {
197 $value = $this->processOperation(
198 $queue[$i], $queue[$i - 1], $queue[$i + 1]
199 );
200 //replace just calculated value
201 array_splice($queue, --$i, 3, $value);
202 } else {
203 $i++;
204 }
205 }
206 }
207
208 return $value;
209 }
210
211 /**
212 * Process the calculation
213 *
214 * @param string $operation
215 * @param mixed $operandA
216 * @param mixed $operandB
217 *
218 * @return mixed
219 *
220 * @access protected
221 */
222 protected function processOperation($operation, $operandA, $operandB) {
223 switch ($operation) {
224 case '+':
225 $operandA += $operandB;
226 break;
227
228 case '-':
229 $operandA -= $operandB;
230 break;
231
232 case '*':
233 $operandA *= $operandB;
234 break;
235
236 case '/';
237 $operandA /= $operandB;
238 break;
239
240 case '==':
241 $operandA = ($operandA == $operandB);
242 break;
243
244 case '===':
245 $operandA = ($operandA === $operandB);
246 break;
247
248 case '!=':
249 case '<>':
250 $operandA = ($operandA != $operandB);
251 break;
252
253 case '!==':
254 $operandA = ($operandA !== $operandB);
255 break;
256
257 case '<':
258 $operandA = ($operandA < $operandB);
259 break;
260
261 case '>':
262 $operandA = ($operandA > $operandB);
263 break;
264
265 case '<=':
266 $operandA = ($operandA <= $operandB);
267 break;
268
269 case '>=':
270 $operandA = ($operandA >= $operandB);
271 break;
272
273 case '&&':
274 $operandA = ($operandA && $operandB);
275 break;
276
277 case '||':
278 $operandA = ($operandA || $operandB);
279 break;
280
281 case 'as':
282 $this->alias = $operandB;
283 break;
284
285 default:
286 $operandA = false;
287 break;
288 }
289
290 return $operandA;
291 }
292
293 /**
294 * Get section alias
295 *
296 * @return string
297 *
298 * @access public
299 */
300 public function getAlias() {
301 return $this->alias;
302 }
303
304 }