PluginProbe
TablePress – Tables in WordPress made easy / 3.0.4
TablePress – Tables in WordPress made easy v3.0.4
3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 2.4.4 All 44 releases
← All changes | libraries/evalmath.class.php +241 -217 1.123.0.4 View file →
@@ -1,11 +1,12 @@
1 1 <?php
2 2 /**
3 - * EvalMath - Safely evaluate math expressions
3 + * EvalMath - Safely evaluate math expressions.
4 4 *
5 5 * Based on EvalMath by Miles Kaufmann, with modifications by Petr Skoda.
6 - * @link https://github.com/moodle/moodle/blob/4efc3d4096bc1d29e9d77f9af7194b2babfa2821/lib/evalmath/evalmath.class.php
7 6 *
7 + * @link https://github.com/moodle/moodle/blob/master/lib/evalmath/evalmath.class.php
8 + *
8 9 * @package TablePress
9 10 * @subpackage Formulas
10 11 * @author Miles Kaufmann, Petr Skoda, Tobias Bäthge
11 12 * @since 1.0.0
@@ -15,8 +16,9 @@
15 16 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
16 17
17 18 /**
18 19 * Class to safely evaluate math expressions.
20 + *
19 21 * @package TablePress
20 22 * @subpackage Formulas
21 23 * @since 1.0.0
22 24 */
@@ -24,66 +26,84 @@
24 26
25 27 /**
26 28 * Pattern used for a valid function or variable name.
27 29 *
28 - * Note, var and func names are case insensitive.
30 + * Note, variable and function names are case insensitive.
29 31 *
30 32 * @since 1.0.0
31 - * @var string
32 33 */
33 - protected static $name_pattern = '[a-z][a-z0-9_]*';
34 + protected static string $name_pattern = '[a-z][a-z0-9_]*';
34 35
35 36 /**
36 37 * Whether to suppress errors and warnings.
37 38 *
38 39 * @since 1.0.0
39 - * @var boolean
40 40 */
41 - public $suppress_errors = false;
41 + public bool $suppress_errors = false;
42 42
43 43 /**
44 44 * The last error message that was raised.
45 45 *
46 46 * @since 1.0.0
47 - * @var string
48 47 */
49 - public $last_error = '';
48 + public string $last_error = '';
50 49
51 50 /**
52 51 * Variables (including constants).
53 52 *
54 53 * @since 1.0.0
55 - * @var array
54 + * @var array<string, mixed>
56 55 */
57 - public $variables = array();
56 + public array $variables = array();
58 57
59 58 /**
60 59 * User-defined functions.
61 60 *
62 61 * @since 1.0.0
63 - * @var array
62 + * @var array<string, mixed>
64 63 */
65 - protected $functions = array();
64 + protected array $functions = array();
66 65
67 66 /**
68 67 * Constants.
69 68 *
70 69 * @since 1.0.0
71 - * @var array
70 + * @var array<string, mixed>
72 71 */
73 - protected $constants = array();
72 + protected array $constants = array();
74 73
75 74 /**
76 75 * Built-in functions.
77 76 *
78 77 * @since 1.0.0
79 - * @var array
78 + * @var string[]
80 79 */
81 - protected $builtin_functions = array(
82 - 'sin', 'sinh', 'arcsin', 'asin', 'arcsinh', 'asinh',
83 - 'cos', 'cosh', 'arccos', 'acos', 'arccosh', 'acosh',
84 - 'tan', 'tanh', 'arctan', 'atan', 'arctanh', 'atanh',
85 - 'sqrt', 'abs', 'ln', 'log10', 'exp', 'floor', 'ceil',
80 + protected array $builtin_functions = array(
81 + 'sin',
82 + 'sinh',
83 + 'arcsin',
84 + 'asin',
85 + 'arcsinh',
86 + 'asinh',
87 + 'cos',
88 + 'cosh',
89 + 'arccos',
90 + 'acos',
91 + 'arccosh',
92 + 'acosh',
93 + 'tan',
94 + 'tanh',
95 + 'arctan',
96 + 'atan',
97 + 'arctanh',
98 + 'atanh',
99 + 'sqrt',
100 + 'abs',
101 + 'ln',
102 + 'log10',
103 + 'exp',
104 + 'floor',
105 + 'ceil',
86 106 );
87 107
88 108 /**
89 109 * Emulated functions.
@@ -88,36 +108,36 @@
88 108 /**
89 109 * Emulated functions.
90 110 *
91 111 * @since 1.0.0
92 - * @var array
112 + * @var array<string, int[]>
93 113 */
94 - protected $calc_functions = array(
95 - 'average' => array( -1 ),
96 - 'mean' => array( -1 ),
97 - 'median' => array( -1 ),
98 - 'mode' => array( -1 ),
99 - 'range' => array( -1 ),
100 - 'max' => array( -1 ),
101 - 'min' => array( -1 ),
102 - 'mod' => array( 2 ),
103 - 'pi' => array( 0 ),
104 - 'power' => array( 2 ),
105 - 'log' => array( 1, 2 ),
106 - 'round' => array( 1, 2 ),
107 - 'number_format' => array( 1, 2 ),
114 + protected array $calc_functions = array(
115 + 'average' => array( -1 ),
116 + 'mean' => array( -1 ),
117 + 'median' => array( -1 ),
118 + 'mode' => array( -1 ),
119 + 'range' => array( -1 ),
120 + 'max' => array( -1 ),
121 + 'min' => array( -1 ),
122 + 'mod' => array( 2 ),
123 + 'pi' => array( 0 ),
124 + 'power' => array( 2 ),
125 + 'log' => array( 1, 2 ),
126 + 'round' => array( 1, 2 ),
127 + 'number_format' => array( 1, 2 ),
108 128 'number_format_eu' => array( 1, 2 ),
109 - 'sum' => array( -1 ),
110 - 'counta' => array ( -1 ),
111 - 'product' => array( -1 ),
112 - 'rand_int' => array( 2 ),
113 - 'rand_float' => array( 0 ),
114 - 'arctan2' => array( 2 ),
115 - 'atan2' => array( 2 ),
116 - 'if' => array( 3 ),
117 - 'not' => array( 1 ),
118 - 'and' => array( -1 ),
119 - 'or' => array( -1 ),
129 + 'sum' => array( -1 ),
130 + 'counta' => array( -1 ),
131 + 'product' => array( -1 ),
132 + 'rand_int' => array( 2 ),
133 + 'rand_float' => array( 0 ),
134 + 'arctan2' => array( 2 ),
135 + 'atan2' => array( 2 ),
136 + 'if' => array( 3 ),
137 + 'not' => array( 1 ),
138 + 'and' => array( -1 ),
139 + 'or' => array( -1 ),
120 140 );
121 141
122 142 /**
123 143 * Class constructor.
@@ -124,9 +144,9 @@
124 144 *
125 145 * @since 1.0.0
126 146 */
127 147 public function __construct() {
128 - // Sets default constants.
148 + // Set default constants.
129 149 $this->variables['pi'] = pi();
130 150 $this->variables['e'] = exp( 1 );
131 151 }
132 152
@@ -135,16 +155,16 @@
135 155 *
136 156 * @since 1.0.0
137 157 *
138 158 * @param string $expression The expression that shall be evaluated.
139 - * @return string Evaluated expression.
159 + * @return string|false Evaluated expression or false on error.
140 160 */
141 - public function evaluate( $expression ) {
161 + public function evaluate( $expression ) /* : string|false */ {
142 162 return $this->pfx( $this->nfx( $expression ) );
143 163 }
144 164
145 165 /**
146 - * Evaluate a math expression or formula, and check it for variable an function assignments.
166 + * Evaluate a math expression or formula, and check it for variable and function assignments.
147 167 *
148 168 * @since 1.0.0
149 169 *
150 170 * @param string $expression The expression that shall be evaluated.
@@ -149,9 +169,9 @@
149 169 *
150 170 * @param string $expression The expression that shall be evaluated.
151 171 * @return string|bool Evaluated expression, true on successful function assignment, or false on error.
152 172 */
153 - public function assign_and_evaluate( $expression ) {
173 + public function assign_and_evaluate( $expression ) /* : string|bool */ {
154 174 $this->last_error = '';
155 175 $expression = trim( $expression );
156 176 $expression = rtrim( $expression, ';' );
157 177
@@ -162,17 +182,17 @@
162 182 return $this->raise_error( 'cannot_assign_to_constant', $matches[1] );
163 183 }
164 184 // Evaluate the assignment.
165 185 $tmp = $this->pfx( $this->nfx( $matches[2] ) );
166 - if ( fales === $tmp ) {
186 + if ( false === $tmp ) {
167 187 return false;
168 188 }
169 - // If it could be evaluated, add it to the variable array,
189 + // If it could be evaluated, add it to the variable array, ...
170 190 $this->variables[ $matches[1] ] = $tmp;
171 - // and return the resulting value.
191 + // ... and return the resulting value.
172 192 return $tmp;
173 193
174 - // Is the expression a function assignment?
194 + // Is the expression a function assignment?
175 195 } elseif ( 1 === preg_match( '/^\s*(' . self::$name_pattern . ')\s*\(\s*(' . self::$name_pattern . '(?:\s*,\s*' . self::$name_pattern . ')*)\s*\)\s*=\s*(.+)$/', $expression, $matches ) ) {
176 196 // Get the function name.
177 197 $function_name = $matches[1];
178 198 // Make sure it isn't a built-in function -- we can't redefine those.
@@ -188,9 +208,10 @@
188 208 if ( false === $stack ) {
189 209 return false;
190 210 }
191 211 // Freeze the state of the non-argument variables.
192 - for ( $i = 0; $i < count( $stack ); $i++ ) {
212 + $stack_count = count( $stack );
213 + for ( $i = 0; $i < $stack_count; $i++ ) {
193 214 $token = $stack[ $i ];
194 215 if ( 1 === preg_match( '/^' . self::$name_pattern . '$/', $token ) && ! in_array( $token, $args, true ) ) {
195 216 if ( array_key_exists( $token, $this->variables ) ) {
196 217 $stack[ $i ] = $this->variables[ $token ];
@@ -201,9 +222,9 @@
201 222 }
202 223 $this->functions[ $function_name ] = array( 'args' => $args, 'func' => $stack );
203 224 return true;
204 225
205 - // No variable or function assignment, so straight-up evaluation.
226 + // No variable or function assignment, so straight-up evaluation.
206 227 } else {
207 228 return $this->evaluate( $expression );
208 229 }
209 230 }
@@ -212,11 +233,11 @@
212 233 * Return all user-defined variables and values.
213 234 *
214 235 * @since 1.0.0
215 236 *
216 - * @return array User-defined variables and values.
237 + * @return array<string, mixed> User-defined variables and values.
217 238 */
218 - public function variables() {
239 + public function variables(): array {
219 240 return $this->variables;
220 241 }
221 242
222 243 /**
@@ -223,11 +244,11 @@
223 244 * Return all user-defined functions with their arguments.
224 245 *
225 246 * @since 1.0.0
226 247 *
227 - * @return array User-defined functions.
248 + * @return array<int, string> User-defined functions.
228 249 */
229 - public function functions() {
250 + public function functions(): array {
230 251 $output = array();
231 252 foreach ( $this->functions as $name => $data ) {
232 253 $output[] = $name . '( ' . implode( ', ', $data['args'] ) . ' )';
233 254 }
@@ -243,27 +264,25 @@
243 264 *
244 265 * @since 1.0.0
245 266 *
246 267 * @param string $expression Math expression that shall be converted.
247 - * @return array|false Converted expression or false on error.
268 + * @return mixed[]|false Converted expression or false on error.
248 269 */
249 - protected function nfx( $expression ) {
270 + protected function nfx( $expression ) /* : mixed[]|false */ {
250 271 $index = 0;
251 - $stack = new EvalMath_Stack;
252 - $output = array(); // postfix form of expression, to be passed to pfx()
272 + $stack = new EvalMath_Stack();
273 + $output = array(); // postfix form of expression, to be passed to pfx().
253 274 $expression = trim( strtolower( $expression ) );
254 275
255 - $ops = array( '+', '-', '*', '/', '^', '_', '>', '<', '=' );
256 - // Right-associative operator?
257 - $ops_r = array( '+' => 0, '-' => 0, '*' => 0, '/' => 0, '^' => 1, '>' => 0, '<' => 0, '=' => 0 );
258 - // Operator precedence.
259 - $ops_p = array( '+' => 0, '-' => 0, '*' => 1, '/' => 1, '_' => 1, '^' => 2, '>' => 0, '<' => 0, '=' => 0 );
276 + $ops = array( '+', '-', '*', '/', '^', '_', '>', '<', '=', '%' );
277 + $ops_r = array( '+' => 0, '-' => 0, '*' => 0, '/' => 0, '^' => 1, '>' => 0, '<' => 0, '=' => 0, '%' => 0 ); // Right-associative operator?
278 + $ops_p = array( '+' => 0, '-' => 0, '*' => 1, '/' => 1, '_' => 1, '^' => 2, '>' => 0, '<' => 0, '=' => 0, '%' => 1 ); // Operator precedence.
260 279
261 280 // We use this in syntax-checking the expression and determining when a - (minus) is a negation.
262 281 $expecting_operator = false;
263 282
264 283 // Make sure the characters are all good.
265 - if ( 1 === preg_match( '/[^\w\s+*^\/()\.,-<>=]/', $expression, $matches ) ) {
284 + if ( 1 === preg_match( '/[^\%\w\s+*^\/()\.,-<>=]/', $expression, $matches ) ) {
266 285 return $this->raise_error( 'illegal_character_general', $matches[0] );
267 286 }
268 287
269 288 // Infinite Loop for the conversion.
@@ -276,34 +295,36 @@
276 295 // Is it a negation instead of a minus (in a subtraction)?
277 296 if ( '-' === $op && ! $expecting_operator ) {
278 297 // Put a negation on the stack.
279 298 $stack->push( '_' );
280 - $index++;
299 + ++$index;
281 300 } elseif ( '_' === $op ) {
282 301 // We have to explicitly deny underscores (as they mean negation), because they are legal on the stack.
283 302 return $this->raise_error( 'illegal_character_underscore' );
284 303
285 - // Are we putting an operator on the stack?
304 + // Are we putting an operator on the stack?
286 305 } elseif ( ( in_array( $op, $ops, true ) || $ex ) && $expecting_operator ) {
287 306 // Are we expecting an operator but have a number/variable/function/opening parethesis?
288 307 if ( $ex ) {
289 308 // It's an implicit multiplication.
290 309 $op = '*';
291 - $index--;
310 + --$index;
292 311 }
293 - // Heart of the algorithm:
312 + // Heart of the algorithm: .
313 + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
294 314 while ( $stack->count > 0 && ( $o2 = $stack->last() ) && in_array( $o2, $ops, true ) && ( $ops_r[ $op ] ? $ops_p[ $op ] < $ops_p[ $o2 ] : $ops_p[ $op ] <= $ops_p[ $o2 ] ) ) {
295 315 // Pop stuff off the stack into the output.
296 316 $output[] = $stack->pop();
297 317 }
298 - // Many thanks: https://en.wikipedia.org/wiki/Reverse_Polish_notation
299 - $stack->push( $op ); // finally put OUR operator onto the stack
300 - $index++;
318 + // Many thanks: https://en.wikipedia.org/wiki/Reverse_Polish_notation .
319 + $stack->push( $op ); // Finally put OUR operator onto the stack.
320 + ++$index;
301 321 $expecting_operator = false;
302 322
303 - // Ready to close a parenthesis?
323 + // Ready to close a parenthesis?
304 324 } elseif ( ')' === $op && $expecting_operator ) {
305 325 // Pop off the stack back to the last (.
326 + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
306 327 while ( '(' !== ( $o2 = $stack->pop() ) ) {
307 328 if ( is_null( $o2 ) ) {
308 329 return $this->raise_error( 'unexpected_closing_bracket' );
309 330 } else {
@@ -311,20 +332,20 @@
311 332 }
312 333 }
313 334
314 335 // Did we just close a function?
315 - if ( 1 === preg_match( '/^(' . self::$name_pattern . ')\($/', $stack->last( 2 ), $matches ) ) {
336 + if ( 1 === preg_match( '/^(' . self::$name_pattern . ')\($/', (string) $stack->last( 2 ), $matches ) ) {
316 337 // Get the function name.
317 338 $function_name = $matches[1];
318 339 // See how many arguments there were (cleverly stored on the stack, thank you).
319 340 $arg_count = $stack->pop();
320 - $fn = $stack->pop();
341 + $stack->pop(); // $fn
321 342 // Send function to output.
322 343 $output[] = array( 'function_name' => $function_name, 'arg_count' => $arg_count );
323 344 // Check the argument count, depending on what type of function we have.
324 345 if ( in_array( $function_name, $this->builtin_functions, true ) ) {
325 346 // Built-in functions.
326 - if ( $arg_count > 1 ) {
347 + if ( $arg_count > 1 ) { // @phpstan-ignore greater.alwaysFalse
327 348 $error_data = array( 'expected' => 1, 'given' => $arg_count );
328 349 return $this->raise_error( 'wrong_number_of_arguments', $error_data );
329 350 }
330 351 } elseif ( array_key_exists( $function_name, $this->calc_functions ) ) {
@@ -329,17 +350,18 @@
329 350 }
330 351 } elseif ( array_key_exists( $function_name, $this->calc_functions ) ) {
331 352 // Calc-emulation functions.
332 353 $counts = $this->calc_functions[ $function_name ];
333 - if ( in_array( -1, $counts, true ) && $arg_count > 0 ) {
354 + // @phpstan-ignore greater.alwaysFalse, booleanAnd.alwaysFalse
355 + if ( in_array( -1, $counts, true ) && $arg_count > 0 ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
334 356 // Everything is fine, we expected an indefinite number arguments and got some.
335 - } elseif ( ! in_array( $arg_count, $counts, true ) ) {
357 + } elseif ( ! in_array( $arg_count, $counts, true ) ) { // @phpstan-ignore function.impossibleType
336 358 $error_data = array( 'expected' => implode( '/', $this->calc_functions[ $function_name ] ), 'given' => $arg_count );
337 359 return $this->raise_error( 'wrong_number_of_arguments', $error_data );
338 360 }
339 361 } elseif ( array_key_exists( $function_name, $this->functions ) ) {
340 362 // User-defined functions.
341 - if ( count( $this->functions[ $function_name ]['args'] ) !== $arg_count ) {
363 + if ( count( $this->functions[ $function_name ]['args'] ) !== $arg_count ) { // @phpstan-ignore notIdentical.alwaysTrue
342 364 $error_data = array( 'expected' => count( $this->functions[ $function_name ]['args'] ), 'given' => $arg_count );
343 365 return $this->raise_error( 'wrong_number_of_arguments', $error_data );
344 366 }
345 367 } else {
@@ -346,12 +368,13 @@
346 368 // Did we somehow push a non-function on the stack? This should never happen.
347 369 return $this->raise_error( 'internal_error' );
348 370 }
349 371 }
350 - $index++;
372 + ++$index;
351 373
352 - // Did we just finish a function argument?
374 + // Did we just finish a function argument?
353 375 } elseif ( ',' === $op && $expecting_operator ) {
376 + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
354 377 while ( '(' !== ( $o2 = $stack->pop() ) ) {
355 378 if ( is_null( $o2 ) ) {
356 379 // Oops, never had a (.
357 380 return $this->raise_error( 'unexpected_comma' );
@@ -360,23 +383,23 @@
360 383 $output[] = $o2;
361 384 }
362 385 }
363 386 // Make sure there was a function.
364 - if ( 0 === preg_match( '/^(' . self::$name_pattern . ')\($/', $stack->last( 2 ), $matches ) ) {
387 + if ( 0 === preg_match( '/^(' . self::$name_pattern . ')\($/', (string) $stack->last( 2 ), $matches ) ) {
365 388 return $this->raise_error( 'unexpected_comma' );
366 389 }
367 390 // Increment the argument count.
368 - $stack->push( $stack->pop() + 1 );
391 + $stack->push( $stack->pop() + 1 ); // @phpstan-ignore binaryOp.invalid
369 392 // Put the ( back on, we'll need to pop back to it again.
370 393 $stack->push( '(' );
371 - $index++;
394 + ++$index;
372 395 $expecting_operator = false;
373 396
374 397 } elseif ( '(' === $op && ! $expecting_operator ) {
375 398 $stack->push( '(' ); // That was easy.
376 - $index++;
399 + ++$index;
377 400
378 - // Do we now have a function/variable/number?
401 + // Do we now have a function/variable/number?
379 402 } elseif ( $ex && ! $expecting_operator ) {
380 403 $expecting_operator = true;
381 404 $value = $match[1];
382 405 // May be a function, or variable with implicit multiplication against parentheses...
@@ -386,9 +409,9 @@
386 409 $stack->push( $value );
387 410 $stack->push( 1 );
388 411 $stack->push( '(' );
389 412 $expecting_operator = false;
390 - // It's a variable with implicit multiplication.
413 + // It's a variable with implicit multiplication.
391 414 } else {
392 415 $value = $matches[1];
393 416 $output[] = $value;
394 417 }
@@ -403,12 +426,12 @@
403 426 if ( '(' !== $stack->last() || 1 !== $stack->last( 2 ) ) {
404 427 return $this->raise_error( 'unexpected_closing_bracket' );
405 428 }
406 429 // Did we just close a function?
407 - if ( 1 === preg_match( '/^(' . self::$name_pattern . ')\($/', $stack->last( 3 ), $matches ) ) {
430 + if ( 1 === preg_match( '/^(' . self::$name_pattern . ')\($/', (string) $stack->last( 3 ), $matches ) ) {
408 431 $stack->pop(); // (
409 432 $stack->pop(); // 1
410 - $fn = $stack->pop();
433 + $stack->pop(); // $fn
411 434 // Get the function name.
412 435 $function_name = $matches[1];
413 436 if ( isset( $this->calc_functions[ $function_name ] ) ) {
414 437 // Custom calc-emulation function.
@@ -422,19 +445,19 @@
422 445 return $this->raise_error( 'wrong_number_of_arguments', $error_data );
423 446 }
424 447 // Send function to output.
425 448 $output[] = array( 'function_name' => $function_name, 'arg_count' => 0 );
426 - $index++;
449 + ++$index;
427 450 $expecting_operator = true;
428 451 } else {
429 452 return $this->raise_error( 'unexpected_closing_bracket' );
430 453 }
431 454
432 - // Miscellaneous error checking.
455 + // Miscellaneous error checking.
433 456 } elseif ( in_array( $op, $ops, true ) && ! $expecting_operator ) {
434 457 return $this->raise_error( 'unexpected_operator', $op );
435 458
436 - // I don't even want to know what you did to get here.
459 + // I don't even want to know what you did to get here.
437 460 } else {
438 461 return $this->raise_error( 'an_unexpected_error_occurred' );
439 462 }
440 463
@@ -448,13 +471,14 @@
448 471 }
449 472
450 473 // Step the index past whitespace (pretty much turns whitespace into implicit multiplication if no operator is there).
451 474 while ( ' ' === substr( $expression, $index, 1 ) ) {
452 - $index++;
475 + ++$index;
453 476 }
454 477 } // while ( true )
455 478
456 479 // Pop everything off the stack and push onto output.
480 + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
457 481 while ( ! is_null( $op = $stack->pop() ) ) {
458 482 if ( '(' === $op ) {
459 483 // If there are (s on the stack, ()s were unbalanced.
460 484 return $this->raise_error( 'expecting_a_closing_bracket' );
@@ -469,18 +493,18 @@
469 493 * Evaluate postfix notation.
470 494 *
471 495 * @since 1.0.0
472 496 *
473 - * @param array|false $tokens [description]
474 - * @param array $variables Optional. [description]
475 - * @return mixed [description]
497 + * @param array<int, string|mixed[]>|false $tokens [description].
498 + * @param array<string, mixed> $variables Optional. [description].
499 + * @return mixed [description].
476 500 */
477 - protected function pfx( $tokens, array $variables = array() ) {
501 + protected function pfx( $tokens, array $variables = array() ) /* : mixed */ {
478 502 if ( false === $tokens ) {
479 503 return false;
480 504 }
481 505
482 - $stack = new EvalMath_Stack;
506 + $stack = new EvalMath_Stack();
483 507
484 508 foreach ( $tokens as $token ) {
485 509 // If the token is a function, pop arguments off the stack, hand them to the function, and push the result back on.
486 510 if ( is_array( $token ) ) { // it's a function!
@@ -486,10 +510,11 @@
486 510 if ( is_array( $token ) ) { // it's a function!
487 511 $function_name = $token['function_name'];
488 512 $count = $token['arg_count'];
489 513
490 - // Built-in function.
491 514 if ( in_array( $function_name, $this->builtin_functions, true ) ) {
515 + // Built-in function.
516 +
492 517 $op1 = $stack->pop();
493 518 if ( is_null( $op1 ) ) {
494 519 return $this->raise_error( 'internal_error' );
495 520 }
@@ -499,12 +524,13 @@
499 524 if ( 'ln' === $function_name ) {
500 525 $function_name = 'log';
501 526 }
502 527 // Perfectly safe eval().
528 + // phpcs:ignore Squiz.PHP.Eval.Discouraged
503 529 eval( '$stack->push( ' . $function_name . '( $op1 ) );' );
530 + } elseif ( array_key_exists( $function_name, $this->calc_functions ) ) {
531 + // Calc-emulation function.
504 532
505 - // Calc-emulation function.
506 - } elseif ( array_key_exists( $function_name, $this->calc_functions ) ) {
507 533 // Get function arguments.
508 534 $args = array();
509 535 for ( $i = $count - 1; $i >= 0; $i-- ) {
510 536 $arg = $stack->pop();
@@ -532,11 +558,11 @@
532 558 if ( false === $result ) {
533 559 return $this->raise_error( 'internal_error' );
534 560 }
535 561 $stack->push( $result );
562 + } elseif ( array_key_exists( $function_name, $this->functions ) ) {
563 + // User-defined function.
536 564
537 - // User-defined function.
538 - } elseif ( array_key_exists( $function_name, $this->functions ) ) {
539 565 // Get function arguments.
540 566 $args = array();
541 567 for ( $i = count( $this->functions[ $function_name ]['args'] ) - 1; $i >= 0; $i-- ) {
542 568 $arg = $stack->pop();
@@ -545,14 +571,13 @@
545 571 } else {
546 572 $args[ $this->functions[ $function_name ]['args'][ $i ] ] = $arg;
547 573 }
548 574 }
549 - // yay... recursion!
575 + // Recursion.
550 576 $stack->push( $this->pfx( $this->functions[ $function_name ]['func'], $args ) );
551 577 }
552 -
553 - // If the token is a binary operator, pop two values off the stack, do the operation, and push the result back on.
554 - } elseif ( in_array( $token, array( '+', '-', '*', '/', '^', '>', '<', '=' ), true ) ) {
578 + } elseif ( in_array( $token, array( '+', '-', '*', '/', '^', '>', '<', '=', '%' ), true ) ) {
579 + // If the token is a binary operator, pop two values off the stack, do the operation, and push the result back on.
555 580 $op2 = $stack->pop();
556 581 if ( is_null( $op2 ) ) {
557 582 return $this->raise_error( 'internal_error' );
558 583 }
@@ -585,27 +610,29 @@
585 610 case '<':
586 611 $stack->push( (int) ( $op1 < $op2 ) );
587 612 break;
588 613 case '=':
614 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison,Universal.Operators.StrictComparisons.LooseEqual
589 615 $stack->push( (int) ( $op1 == $op2 ) ); // Don't use === as the variable type can differ (int/double/bool).
590 616 break;
617 + case '%':
618 + $stack->push( $op1 % $op2 );
619 + break;
591 620 }
592 -
593 - // If the token is a unary operator, pop one value off the stack, do the operation, and push it back on.
594 621 } elseif ( '_' === $token ) {
622 + // If the token is a unary operator, pop one value off the stack, do the operation, and push it back on.
595 623 $stack->push( -1 * $stack->pop() );
596 -
597 - // If the token is a number or variable, push it on the stack.
624 + } elseif ( is_numeric( $token ) ) {
625 + // If the token is a number, push it on the stack.
626 + $stack->push( $token );
627 + } elseif ( array_key_exists( $token, $this->variables ) ) {
628 + // If the token is a variable, push it on the stack.
629 + $stack->push( $this->variables[ $token ] );
630 + } elseif ( array_key_exists( $token, $variables ) ) {
631 + // If the token is a variable, push it on the stack.
632 + $stack->push( $variables[ $token ] );
598 633 } else {
599 - if ( is_numeric( $token ) ) {
600 - $stack->push( $token );
601 - } elseif ( array_key_exists( $token, $this->variables ) ) {
602 - $stack->push( $this->variables[ $token ] );
603 - } elseif ( array_key_exists( $token, $variables ) ) {
604 - $stack->push( $variables[ $token ] );
605 - } else {
606 - return $this->raise_error( 'undefined_variable', $token );
607 - }
634 + return $this->raise_error( 'undefined_variable', $token );
608 635 }
609 636 }
610 637 // When we're out of tokens, the stack should have a single element, the final result.
611 638 if ( 1 !== $stack->count ) {
@@ -618,18 +645,17 @@
618 645 * Raise an error.
619 646 *
620 647 * @since 1.0.0
621 648 *
622 - * @param string $message Error message.
623 - * @param array|string $error_data Optional. Additional error data.
624 - * @return bool False, to stop evaluation.
649 + * @param string $message Error message.
650 + * @param mixed[]|string $error_data Optional. Additional error data.
651 + * @return false False, to stop evaluation.
625 652 */
626 - protected function raise_error( $message, $error_data = null ) {
653 + protected function raise_error( $message, $error_data = null ): bool {
627 654 $this->last_error = $this->get_error_string( $message, $error_data );
628 655 return false;
629 656 }
630 657
631 -
632 658 /**
633 659 * Get a translated string for an error message.
634 660 *
635 661 * @since 1.0.0
@@ -636,13 +662,13 @@
636 662 *
637 663 * @link https://github.com/moodle/moodle/blob/13264f35057d2f37374ec3e0e8ad4070f4676bd7/lang/en/mathslib.php
638 664 * @link https://github.com/moodle/moodle/blob/8e54ce9717c19f768b95f4332f70e3180ffafc46/lib/moodlelib.php#L6323
639 665 *
640 - * @param string $identifier Identifier of the string.
641 - * @param array|string $error_data Optional. Additional error data.
666 + * @param string $identifier Identifier of the string.
667 + * @param mixed[]|string $error_data Optional. Additional error data.
642 668 * @return string Translated string.
643 669 */
644 - protected function get_error_string( $identifier, $error_data = null ) {
670 + protected function get_error_string( $identifier, $error_data = null ): string {
645 671 $strings = array();
646 672 $strings['an_unexpected_error_occurred'] = 'an unexpected error occurred';
647 673 $strings['cannot_assign_to_constant'] = 'cannot assign to constant \'{$error_data}\'';
648 674 $strings['cannot_redefine_builtin_function'] = 'cannot redefine built-in function \'{$error_data}()\'';
@@ -658,9 +684,9 @@
658 684 $strings['unexpected_comma'] = 'unexpected comma';
659 685 $strings['unexpected_operator'] = 'unexpected operator \'{$error_data}\'';
660 686 $strings['wrong_number_of_arguments'] = 'wrong number of arguments ({$error_data->given} given, {$error_data->expected} expected)';
661 687
662 - $string = $strings[ $identifier ];
688 + $a_string = $strings[ $identifier ];
663 689
664 690 if ( null !== $error_data ) {
665 691 if ( is_array( $error_data ) ) {
666 692 $search = array();
@@ -684,16 +710,16 @@
684 710 $search[] = '{$error_data->' . $key . '}';
685 711 $replace[] = (string) $value;
686 712 }
687 713 if ( $search ) {
688 - $string = str_replace( $search, $replace, $string );
714 + $a_string = str_replace( $search, $replace, $a_string );
689 715 }
690 716 } else {
691 - $string = str_replace( '{$error_data}', (string) $error_data, $string );
717 + $a_string = str_replace( '{$error_data}', (string) $error_data, $a_string );
692 718 }
693 719 }
694 720
695 - return $string;
721 + return $a_string;
696 722 }
697 723
698 724 } // class EvalMath
699 725
@@ -698,29 +724,29 @@
698 724 } // class EvalMath
699 725
700 726 /**
701 727 * Stack for the postfix/infix conversion of math expressions.
728 + *
702 729 * @package TablePress
703 730 * @subpackage Formulas
704 731 * @since 1.0.0
705 732 */
706 -class EvalMath_Stack {
733 +class EvalMath_Stack { // phpcs:ignore Generic.Files.OneObjectStructurePerFile.MultipleFound,Generic.Classes.OpeningBraceSameLine.ContentAfterBrace
707 734
708 735 /**
709 736 * The stack.
710 737 *
711 738 * @since 1.0.0
712 - * @var array
739 + * @var mixed[]
713 740 */
714 - protected $stack = array();
741 + protected array $stack = array();
715 742
716 743 /**
717 744 * Number of items on the stack.
718 745 *
719 746 * @since 1.0.0
720 - * @var int
721 747 */
722 - public $count = 0;
748 + public int $count = 0;
723 749
724 750 /**
725 751 * Push an item onto the stack.
726 752 *
@@ -727,11 +753,11 @@
727 753 * @since 1.0.0
728 754 *
729 755 * @param mixed $value The item that is pushed onto the stack.
730 756 */
731 - public function push( $value ) {
757 + public function push( $value ): void {
732 758 $this->stack[ $this->count ] = $value;
733 - $this->count++;
759 + ++$this->count;
734 760 }
735 761
736 762 /**
737 763 * Pop an item from the top of the stack.
@@ -737,13 +763,13 @@
737 763 * Pop an item from the top of the stack.
738 764 *
739 765 * @since 1.0.0
740 766 *
741 - * @return mixed The item that is popped from the stack.
767 + * @return mixed|null The item that is popped from the stack.
742 768 */
743 - public function pop() {
769 + public function pop() /* : mixed|null */ {
744 770 if ( $this->count > 0 ) {
745 - $this->count--;
771 + --$this->count;
746 772 return $this->stack[ $this->count ];
747 773 }
748 774 return null;
749 775 }
@@ -753,11 +779,11 @@
753 779 *
754 780 * @since 1.0.0
755 781 *
756 782 * @param int $n Count from the end of the stack.
757 - * @return mixed The item that is popped from the stack.
783 + * @return mixed|null The item that is popped from the stack.
758 784 */
759 - public function last( $n = 1 ) {
785 + public function last( $n = 1 ) /* : mixed|null */ {
760 786 if ( ( $this->count - $n ) >= 0 ) {
761 787 return $this->stack[ $this->count - $n ];
762 788 }
763 789 return null;
@@ -766,21 +792,21 @@
766 792 } // class EvalMath_Stack
767 793
768 794 /**
769 795 * Common math functions, prepared for usage in EvalMath.
796 + *
770 797 * @package TablePress
771 798 * @subpackage EvalMath
772 799 * @since 1.0.0
773 800 */
774 -class EvalMath_Functions {
801 +class EvalMath_Functions { // phpcs:ignore Generic.Files.OneObjectStructurePerFile.MultipleFound,Generic.Classes.OpeningBraceSameLine.ContentAfterBrace
775 802
776 803 /**
777 804 * Seed for the generation of random numbers.
778 805 *
779 806 * @since 1.0.0
780 - * @var string
781 807 */
782 - protected static $random_seed = null;
808 + protected static ?string $random_seed = null;
783 809
784 810 /**
785 811 * Choose from two values based on an if-condition.
786 812 *
@@ -787,15 +813,15 @@
787 813 * "if" is not a valid function name, which is why it's prefixed with "func_".
788 814 *
789 815 * @since 1.0.0
790 816 *
791 - * @param double|int $condition Condition.
792 - * @param double|int $then Return value if the condition is true.
793 - * @param double|int $else Return value if the condition is false.
817 + * @param double|int $condition Condition.
818 + * @param double|int $statement Return value if the condition is true.
819 + * @param double|int $alternative Return value if the condition is false.
794 820 * @return double|int Result of the if check.
795 821 */
796 - public static function func_if( $condition, $then, $else ) {
797 - return ( (bool) $condition ? $then : $else );
822 + public static function func_if( $condition, $statement, $alternative ) /* : float|int */ {
823 + return ( (bool) $condition ? $statement : $alternative );
798 824 }
799 825
800 826 /**
801 827 * Return the negation (boolean "not") of a value.
@@ -806,9 +832,9 @@
806 832 *
807 833 * @param double|int $value Value to be negated.
808 834 * @return int Negated value (0 for false, 1 for true).
809 835 */
810 - public static function func_not( $value ) {
836 + public static function func_not( $value ): int {
811 837 return (int) ! (bool) $value;
812 838 }
813 839
814 840 /**
@@ -817,12 +843,12 @@
817 843 * "and" is not a valid function name, which is why it's prefixed with "func_".
818 844 *
819 845 * @since 1.0.0
820 846 *
821 - * @param double|int $args Values for which the conjunction shall be calculated.
847 + * @param double|int ...$args Values for which the conjunction shall be calculated.
822 848 * @return int Conjunction of the passed arguments.
823 849 */
824 - public static function func_and( ...$args ) {
850 + public static function func_and( ...$args ): int {
825 851 foreach ( $args as $value ) {
826 852 if ( ! $value ) {
827 853 return 0;
828 854 }
@@ -836,12 +862,12 @@
836 862 * "or" is not a valid function name, which is why it's prefixed with "func_".
837 863 *
838 864 * @since 1.0.0
839 865 *
840 - * @param double|int $args Values for which the disjunction shall be calculated.
866 + * @param double|int ...$args Values for which the disjunction shall be calculated.
841 867 * @return int Disjunction of the passed arguments.
842 868 */
843 - public static function func_or( ...$args ) {
869 + public static function func_or( ...$args ): int {
844 870 foreach ( $args as $value ) {
845 871 if ( $value ) {
846 872 return 1;
847 873 }
@@ -855,9 +881,9 @@
855 881 * @since 1.0.0
856 882 *
857 883 * @return double Rounded value of Pi.
858 884 */
859 - public static function pi() {
885 + public static function pi(): float {
860 886 return pi();
861 887 }
862 888
863 889 /**
@@ -864,12 +890,12 @@
864 890 * Calculate the sum of the arguments.
865 891 *
866 892 * @since 1.0.0
867 893 *
868 - * @param double|int $args Values for which the sum shall be calculated.
894 + * @param double|int ...$args Values for which the sum shall be calculated.
869 895 * @return double|int Sum of the passed arguments.
870 896 */
871 - public static function sum( ...$args ) {
897 + public static function sum( ...$args ) /* : float|int */ {
872 898 return array_sum( $args );
873 899 }
874 900
875 901 /**
@@ -876,12 +902,12 @@
876 902 * Count the number of non-empty arguments.
877 903 *
878 904 * @since 1.10.0
879 905 *
880 - * @param double|int $args Values for which the number of non-empty elements shall be counted.
881 - * @return double|int Counted number of non-empty elements in the passed values.
906 + * @param double|int ...$args Values for which the number of non-empty elements shall be counted.
907 + * @return int Counted number of non-empty elements in the passed values.
882 908 */
883 - public static function counta( ...$args ) {
909 + public static function counta( ...$args ): int {
884 910 return count( array_filter( $args ) );
885 911 }
886 912
887 913 /**
@@ -888,12 +914,12 @@
888 914 * Calculate the product of the arguments.
889 915 *
890 916 * @since 1.0.0
891 917 *
892 - * @param double|int $args Values for which the product shall be calculated.
918 + * @param double|int ...$args Values for which the product shall be calculated.
893 919 * @return double|int Product of the passed arguments.
894 920 */
895 - public static function product( ...$args ) {
921 + public static function product( ...$args ) /* : float|int */ {
896 922 return array_product( $args );
897 923 }
898 924
899 925 /**
@@ -900,12 +926,12 @@
900 926 * Calculate the average/mean value of the arguments.
901 927 *
902 928 * @since 1.0.0
903 929 *
904 - * @param double|int $args Values for which the average shall be calculated.
930 + * @param double|int ...$args Values for which the average shall be calculated.
905 931 * @return double|int Average value of the passed arguments.
906 932 */
907 - public static function average( ...$args ) {
933 + public static function average( ...$args ) /* : float|int */ {
908 934 // Catch division by zero.
909 935 if ( 0 === count( $args ) ) {
910 936 return 0;
911 937 }
@@ -918,15 +944,15 @@
918 944 * For even counts of arguments, the upper median is returned.
919 945 *
920 946 * @since 1.0.0
921 947 *
922 - * @param double|int $args Values for which the median shall be calculated.
948 + * @param array<int, double|int> ...$args Values for which the median shall be calculated.
923 949 * @return double|int Median of the passed arguments.
924 950 */
925 - public static function median( ...$args ) {
951 + public static function median( array ...$args ) /* : float|int */ {
926 952 sort( $args );
927 - $middle = floor( count( $args ) / 2 ); // Upper median for even counts.
928 - return $args[ $middle ];
953 + $middle = intdiv( count( $args ), 2 ); // Upper median for even counts.
954 + return $args[ $middle ]; // @phpstan-ignore return.type
929 955 }
930 956
931 957 /**
932 958 * Calculate the mode of the arguments.
@@ -932,16 +958,15 @@
932 958 * Calculate the mode of the arguments.
933 959 *
934 960 * @since 1.0.0
935 961 *
936 - * @param double|int $args Values for which the mode shall be calculated.
962 + * @param array<int, double|int> ...$args Values for which the mode shall be calculated.
937 963 * @return double|int Mode of the passed arguments.
938 964 */
939 - public static function mode( ...$args ) {
940 - $values = array_count_values( $args );
965 + public static function mode( ...$args ) /* : float|int */ {
966 + $values = array_count_values( $args ); // @phpstan-ignore argument.type
941 967 asort( $values );
942 - end( $values );
943 - return key( $values );
968 + return array_key_last( $values ); // @phpstan-ignore return.type
944 969 }
945 970
946 971 /**
947 972 * Calculate the range of the arguments.
@@ -947,12 +972,12 @@
947 972 * Calculate the range of the arguments.
948 973 *
949 974 * @since 1.0.0
950 975 *
951 - * @param double|int $args Values for which the range shall be calculated.
976 + * @param double|int ...$args Values for which the range shall be calculated.
952 977 * @return double|int Range of the passed arguments.
953 978 */
954 - public static function range( ...$args ) {
979 + public static function range( ...$args ) /* : float|int */ {
955 980 sort( $args );
956 981 return end( $args ) - reset( $args );
957 982 }
958 983
@@ -960,13 +985,13 @@
960 985 * Find the maximum value of the arguments.
961 986 *
962 987 * @since 1.0.0
963 988 *
964 - * @param double|int $args Values for which the maximum value shall be found.
989 + * @param double|int ...$args Values for which the maximum value shall be found.
965 990 * @return double|int Maximum value of the passed arguments.
966 991 */
967 - public static function max( ...$args ) {
968 - return max( $args );
992 + public static function max( ...$args ) /* : float|int */ {
993 + return max( $args ); // @phpstan-ignore argument.type
969 994 }
970 995
971 996 /**
972 997 * Find the minimum value of the arguments.
@@ -972,13 +997,13 @@
972 997 * Find the minimum value of the arguments.
973 998 *
974 999 * @since 1.0.0
975 1000 *
976 - * @param double|int $args Values for which the minimum value shall be found.
1001 + * @param double|int ...$args Values for which the minimum value shall be found.
977 1002 * @return double|int Minimum value of the passed arguments.
978 1003 */
979 - public static function min( ...$args ) {
980 - return min( $args );
1004 + public static function min( ...$args ) /* : float|int */ {
1005 + return min( $args ); // @phpstan-ignore argument.type
981 1006 }
982 1007
983 1008 /**
984 1009 * Calculate the remainder of a division of two numbers.
@@ -986,11 +1011,11 @@
986 1011 * @since 1.0.0
987 1012 *
988 1013 * @param double|int $op1 First number (dividend).
989 1014 * @param double|int $op2 Second number (divisor).
990 - * @return double|int Remainer of the division (dividend / divisor).
1015 + * @return int Remainder of the division (dividend / divisor).
991 1016 */
992 - public static function mod( $op1, $op2 ) {
1017 + public static function mod( $op1, $op2 ): int {
993 1018 return $op1 % $op2;
994 1019 }
995 1020
996 1021 /**
@@ -1001,9 +1026,9 @@
1001 1026 * @param double|int $base Base.
1002 1027 * @param double|int $exponent Exponent.
1003 1028 * @return double|int Power base^exponent.
1004 1029 */
1005 - public static function power( $base, $exponent ) {
1030 + public static function power( $base, $exponent ) /* : float|int */ {
1006 1031 return pow( $base, $exponent );
1007 1032 }
1008 1033
1009 1034 /**
@@ -1014,9 +1039,9 @@
1014 1039 * @param double|int $number Number.
1015 1040 * @param double|int $base Optional. Base for the logarithm. Default e (for the natural logarithm).
1016 1041 * @return double Logarithm of the number to the base.
1017 1042 */
1018 - public static function log( $number, $base = M_E ) {
1043 + public static function log( $number, $base = M_E ): float {
1019 1044 return log( $number, $base );
1020 1045 }
1021 1046
1022 1047 /**
@@ -1029,9 +1054,9 @@
1029 1054 * @param double|int $op1 First number.
1030 1055 * @param double|int $op2 Second number.
1031 1056 * @return double Arc tangent of two numbers, similar to arc tangent of $op1/op$ except for the sign.
1032 1057 */
1033 - public static function atan2( $op1, $op2 ) {
1058 + public static function atan2( $op1, $op2 ): float {
1034 1059 return atan2( $op1, $op2 );
1035 1060 }
1036 1061
1037 1062 /**
@@ -1039,12 +1064,12 @@
1039 1064 *
1040 1065 * @since 1.0.0
1041 1066 *
1042 1067 * @param double|int $value Number to be rounded.
1043 - * @param double|int $decimals Optional. Number of decimals after the comma after the rounding.
1068 + * @param int $decimals Optional. Number of decimals after the comma after the rounding.
1044 1069 * @return double Rounded number.
1045 1070 */
1046 - public static function round( $value, $decimals = 0 ) {
1071 + public static function round( $value, $decimals = 0 ): float {
1047 1072 return round( $value, $decimals );
1048 1073 }
1049 1074
1050 1075 /**
@@ -1054,12 +1079,12 @@
1054 1079 *
1055 1080 * @since 1.0.0
1056 1081 *
1057 1082 * @param double|int $value Number to be rounded and formatted.
1058 - * @param double|int $decimals Optional. Number of decimals after the decimal separator after the rounding.
1059 - * @return double Formatted number.
1083 + * @param int $decimals Optional. Number of decimals after the decimal separator after the rounding.
1084 + * @return string Formatted number.
1060 1085 */
1061 - public static function number_format( $value, $decimals = 0 ) {
1086 + public static function number_format( $value, $decimals = 0 ): string {
1062 1087 return number_format( $value, $decimals, '.', ',' );
1063 1088 }
1064 1089
1065 1090 /**
@@ -1069,12 +1094,12 @@
1069 1094 *
1070 1095 * @since 1.0.0
1071 1096 *
1072 1097 * @param double|int $value Number to be rounded and formatted.
1073 - * @param double|int $decimals Optional. Number of decimals after the decimal separator after the rounding.
1074 - * @return double Formatted number.
1098 + * @param int $decimals Optional. Number of decimals after the decimal separator after the rounding.
1099 + * @return string Formatted number.
1075 1100 */
1076 - public static function number_format_eu( $value, $decimals = 0 ) {
1101 + public static function number_format_eu( $value, $decimals = 0 ): string {
1077 1102 return number_format( $value, $decimals, ',', ' ' );
1078 1103 }
1079 1104
1080 1105 /**
@@ -1081,11 +1106,11 @@
1081 1106 * Set the seed for the generation of random numbers.
1082 1107 *
1083 1108 * @since 1.0.0
1084 1109 *
1085 - * @param string The seed.
1110 + * @param string $random_seed The seed.
1086 1111 */
1087 - protected static function _set_random_seed( $random_seed ) {
1112 + protected static function _set_random_seed( $random_seed ): void {
1088 1113 self::$random_seed = $random_seed;
1089 1114 }
1090 1115
1091 1116 /**
@@ -1094,14 +1119,13 @@
1094 1119 * @since 1.0.0
1095 1120 *
1096 1121 * @return string The seed.
1097 1122 */
1098 - protected static function _get_random_seed() {
1123 + protected static function _get_random_seed(): string {
1099 1124 if ( is_null( self::$random_seed ) ) {
1100 1125 return microtime();
1101 - } else {
1102 - return self::$random_seed;
1103 1126 }
1127 + return self::$random_seed;
1104 1128 }
1105 1129
1106 1130 /**
1107 1131 * Get a random integer from a range.
@@ -1111,9 +1135,9 @@
1111 1135 * @param int $min Minimum value for the range.
1112 1136 * @param int $max Maximum value for the range.
1113 1137 * @return int Random integer from the range [$min, $max].
1114 1138 */
1115 - public static function rand_int( $min, $max ) {
1139 + public static function rand_int( $min, $max ): int {
1116 1140 // Swap min and max value if min is bigger than max.
1117 1141 if ( $min > $max ) {
1118 1142 $tmp = $max;
1119 1143 $max = $min;
@@ -1119,19 +1143,19 @@
1119 1143 $max = $min;
1120 1144 $min = $tmp;
1121 1145 unset( $tmp );
1122 1146 }
1123 - $number_characters = ceil( log( $max + 1 - $min, '16' ) );
1147 + $number_characters = (int) ceil( log( $max + 1 - $min, 16 ) );
1124 1148 $md5string = md5( self::_get_random_seed() );
1125 1149 $offset = 0;
1126 1150 do {
1127 - while ( ( $offset + $number_characters ) > strlen( $md5string ) ) {
1151 + while ( ( $offset + $number_characters ) > strlen( $md5string ) ) { // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
1128 1152 $md5string .= md5( $md5string );
1129 1153 }
1130 - $randomno = hexdec( substr( $md5string, $offset, $number_characters ) );
1154 + $random_number = (int) hexdec( substr( $md5string, $offset, $number_characters ) );
1131 1155 $offset += $number_characters;
1132 - } while ( ( $min + $randomno ) > $max );
1133 - return $min + $randomno;
1156 + } while ( ( $min + $random_number ) > $max );
1157 + return $min + $random_number;
1134 1158 }
1135 1159
1136 1160 /**
1137 1161 * Get a random double value from a range [0, 1].
@@ -1139,10 +1163,10 @@
1139 1163 * @since 1.0.0
1140 1164 *
1141 1165 * @return double Random number from the range [0, 1].
1142 1166 */
1143 - public static function rand_float() {
1167 + public static function rand_float(): float {
1144 1168 $random_values = unpack( 'v', md5( self::_get_random_seed(), true ) );
1145 - return array_shift( $random_values ) / 65536;
1169 + return array_shift( $random_values ) / 65536; // @phpstan-ignore argument.type
1146 1170 }
1147 1171
1148 1172 } // class EvalMath_Functions