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 +161 -164 1.143.0.4 View file →
@@ -2,8 +2,9 @@
2 2 /**
3 3 * EvalMath - Safely evaluate math expressions.
4 4 *
5 5 * Based on EvalMath by Miles Kaufmann, with modifications by Petr Skoda.
6 + *
6 7 * @link https://github.com/moodle/moodle/blob/master/lib/evalmath/evalmath.class.php
7 8 *
8 9 * @package TablePress
9 10 * @subpackage Formulas
@@ -28,59 +29,56 @@
28 29 *
29 30 * Note, variable and function names are case insensitive.
30 31 *
31 32 * @since 1.0.0
32 - * @var string
33 33 */
34 - protected static $name_pattern = '[a-z][a-z0-9_]*';
34 + protected static string $name_pattern = '[a-z][a-z0-9_]*';
35 35
36 36 /**
37 37 * Whether to suppress errors and warnings.
38 38 *
39 39 * @since 1.0.0
40 - * @var boolean
41 40 */
42 - public $suppress_errors = false;
41 + public bool $suppress_errors = false;
43 42
44 43 /**
45 44 * The last error message that was raised.
46 45 *
47 46 * @since 1.0.0
48 - * @var string
49 47 */
50 - public $last_error = '';
48 + public string $last_error = '';
51 49
52 50 /**
53 51 * Variables (including constants).
54 52 *
55 53 * @since 1.0.0
56 - * @var array
54 + * @var array<string, mixed>
57 55 */
58 - public $variables = array();
56 + public array $variables = array();
59 57
60 58 /**
61 59 * User-defined functions.
62 60 *
63 61 * @since 1.0.0
64 - * @var array
62 + * @var array<string, mixed>
65 63 */
66 - protected $functions = array();
64 + protected array $functions = array();
67 65
68 66 /**
69 67 * Constants.
70 68 *
71 69 * @since 1.0.0
72 - * @var array
70 + * @var array<string, mixed>
73 71 */
74 - protected $constants = array();
72 + protected array $constants = array();
75 73
76 74 /**
77 75 * Built-in functions.
78 76 *
79 77 * @since 1.0.0
80 - * @var array
78 + * @var string[]
81 79 */
82 - protected $builtin_functions = array(
80 + protected array $builtin_functions = array(
83 81 'sin',
84 82 'sinh',
85 83 'arcsin',
86 84 'asin',
@@ -110,11 +108,11 @@
110 108 /**
111 109 * Emulated functions.
112 110 *
113 111 * @since 1.0.0
114 - * @var array
112 + * @var array<string, int[]>
115 113 */
116 - protected $calc_functions = array(
114 + protected array $calc_functions = array(
117 115 'average' => array( -1 ),
118 116 'mean' => array( -1 ),
119 117 'median' => array( -1 ),
120 118 'mode' => array( -1 ),
@@ -159,9 +157,9 @@
159 157 *
160 158 * @param string $expression The expression that shall be evaluated.
161 159 * @return string|false Evaluated expression or false on error.
162 160 */
163 - public function evaluate( $expression ) {
161 + public function evaluate( $expression ) /* : string|false */ {
164 162 return $this->pfx( $this->nfx( $expression ) );
165 163 }
166 164
167 165 /**
@@ -171,9 +169,9 @@
171 169 *
172 170 * @param string $expression The expression that shall be evaluated.
173 171 * @return string|bool Evaluated expression, true on successful function assignment, or false on error.
174 172 */
175 - public function assign_and_evaluate( $expression ) {
173 + public function assign_and_evaluate( $expression ) /* : string|bool */ {
176 174 $this->last_error = '';
177 175 $expression = trim( $expression );
178 176 $expression = rtrim( $expression, ';' );
179 177
@@ -187,11 +185,11 @@
187 185 $tmp = $this->pfx( $this->nfx( $matches[2] ) );
188 186 if ( false === $tmp ) {
189 187 return false;
190 188 }
191 - // If it could be evaluated, add it to the variable array,
189 + // If it could be evaluated, add it to the variable array, ...
192 190 $this->variables[ $matches[1] ] = $tmp;
193 - // and return the resulting value.
191 + // ... and return the resulting value.
194 192 return $tmp;
195 193
196 194 // Is the expression a function assignment?
197 195 } elseif ( 1 === preg_match( '/^\s*(' . self::$name_pattern . ')\s*\(\s*(' . self::$name_pattern . '(?:\s*,\s*' . self::$name_pattern . ')*)\s*\)\s*=\s*(.+)$/', $expression, $matches ) ) {
@@ -235,11 +233,11 @@
235 233 * Return all user-defined variables and values.
236 234 *
237 235 * @since 1.0.0
238 236 *
239 - * @return array User-defined variables and values.
237 + * @return array<string, mixed> User-defined variables and values.
240 238 */
241 - public function variables() {
239 + public function variables(): array {
242 240 return $this->variables;
243 241 }
244 242
245 243 /**
@@ -246,11 +244,11 @@
246 244 * Return all user-defined functions with their arguments.
247 245 *
248 246 * @since 1.0.0
249 247 *
250 - * @return array User-defined functions.
248 + * @return array<int, string> User-defined functions.
251 249 */
252 - public function functions() {
250 + public function functions(): array {
253 251 $output = array();
254 252 foreach ( $this->functions as $name => $data ) {
255 253 $output[] = $name . '( ' . implode( ', ', $data['args'] ) . ' )';
256 254 }
@@ -266,25 +264,25 @@
266 264 *
267 265 * @since 1.0.0
268 266 *
269 267 * @param string $expression Math expression that shall be converted.
270 - * @return array|false Converted expression or false on error.
268 + * @return mixed[]|false Converted expression or false on error.
271 269 */
272 - protected function nfx( $expression ) {
270 + protected function nfx( $expression ) /* : mixed[]|false */ {
273 271 $index = 0;
274 - $stack = new EvalMath_Stack;
272 + $stack = new EvalMath_Stack();
275 273 $output = array(); // postfix form of expression, to be passed to pfx().
276 274 $expression = trim( strtolower( $expression ) );
277 275
278 - $ops = array( '+', '-', '*', '/', '^', '_', '>', '<', '=' );
279 - $ops_r = array( '+' => 0, '-' => 0, '*' => 0, '/' => 0, '^' => 1, '>' => 0, '<' => 0, '=' => 0 ); // Right-associative operator?
280 - $ops_p = array( '+' => 0, '-' => 0, '*' => 1, '/' => 1, '_' => 1, '^' => 2, '>' => 0, '<' => 0, '=' => 0 ); // Operator precedence.
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.
281 279
282 280 // We use this in syntax-checking the expression and determining when a - (minus) is a negation.
283 281 $expecting_operator = false;
284 282
285 283 // Make sure the characters are all good.
286 - if ( 1 === preg_match( '/[^\w\s+*^\/()\.,-<>=]/', $expression, $matches ) ) {
284 + if ( 1 === preg_match( '/[^\%\w\s+*^\/()\.,-<>=]/', $expression, $matches ) ) {
287 285 return $this->raise_error( 'illegal_character_general', $matches[0] );
288 286 }
289 287
290 288 // Infinite Loop for the conversion.
@@ -297,9 +295,9 @@
297 295 // Is it a negation instead of a minus (in a subtraction)?
298 296 if ( '-' === $op && ! $expecting_operator ) {
299 297 // Put a negation on the stack.
300 298 $stack->push( '_' );
301 - $index++;
299 + ++$index;
302 300 } elseif ( '_' === $op ) {
303 301 // We have to explicitly deny underscores (as they mean negation), because they are legal on the stack.
304 302 return $this->raise_error( 'illegal_character_underscore' );
305 303
@@ -308,25 +306,25 @@
308 306 // Are we expecting an operator but have a number/variable/function/opening parethesis?
309 307 if ( $ex ) {
310 308 // It's an implicit multiplication.
311 309 $op = '*';
312 - $index--;
310 + --$index;
313 311 }
314 - // Heart of the algorithm:
315 - // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
312 + // Heart of the algorithm: .
313 + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
316 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 ] ) ) {
317 315 // Pop stuff off the stack into the output.
318 316 $output[] = $stack->pop();
319 317 }
320 - // Many thanks: https://en.wikipedia.org/wiki/Reverse_Polish_notation
321 - $stack->push( $op ); // finally put OUR operator onto the stack
322 - $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;
323 321 $expecting_operator = false;
324 322
325 323 // Ready to close a parenthesis?
326 324 } elseif ( ')' === $op && $expecting_operator ) {
327 325 // Pop off the stack back to the last (.
328 - // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
326 + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
329 327 while ( '(' !== ( $o2 = $stack->pop() ) ) {
330 328 if ( is_null( $o2 ) ) {
331 329 return $this->raise_error( 'unexpected_closing_bracket' );
332 330 } else {
@@ -334,9 +332,9 @@
334 332 }
335 333 }
336 334
337 335 // Did we just close a function?
338 - if ( 1 === preg_match( '/^(' . self::$name_pattern . ')\($/', $stack->last( 2 ), $matches ) ) {
336 + if ( 1 === preg_match( '/^(' . self::$name_pattern . ')\($/', (string) $stack->last( 2 ), $matches ) ) {
339 337 // Get the function name.
340 338 $function_name = $matches[1];
341 339 // See how many arguments there were (cleverly stored on the stack, thank you).
342 340 $arg_count = $stack->pop();
@@ -345,9 +343,9 @@
345 343 $output[] = array( 'function_name' => $function_name, 'arg_count' => $arg_count );
346 344 // Check the argument count, depending on what type of function we have.
347 345 if ( in_array( $function_name, $this->builtin_functions, true ) ) {
348 346 // Built-in functions.
349 - if ( $arg_count > 1 ) {
347 + if ( $arg_count > 1 ) { // @phpstan-ignore greater.alwaysFalse
350 348 $error_data = array( 'expected' => 1, 'given' => $arg_count );
351 349 return $this->raise_error( 'wrong_number_of_arguments', $error_data );
352 350 }
353 351 } elseif ( array_key_exists( $function_name, $this->calc_functions ) ) {
@@ -352,17 +350,18 @@
352 350 }
353 351 } elseif ( array_key_exists( $function_name, $this->calc_functions ) ) {
354 352 // Calc-emulation functions.
355 353 $counts = $this->calc_functions[ $function_name ];
356 - 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
357 356 // Everything is fine, we expected an indefinite number arguments and got some.
358 - } elseif ( ! in_array( $arg_count, $counts, true ) ) {
357 + } elseif ( ! in_array( $arg_count, $counts, true ) ) { // @phpstan-ignore function.impossibleType
359 358 $error_data = array( 'expected' => implode( '/', $this->calc_functions[ $function_name ] ), 'given' => $arg_count );
360 359 return $this->raise_error( 'wrong_number_of_arguments', $error_data );
361 360 }
362 361 } elseif ( array_key_exists( $function_name, $this->functions ) ) {
363 362 // User-defined functions.
364 - if ( count( $this->functions[ $function_name ]['args'] ) !== $arg_count ) {
363 + if ( count( $this->functions[ $function_name ]['args'] ) !== $arg_count ) { // @phpstan-ignore notIdentical.alwaysTrue
365 364 $error_data = array( 'expected' => count( $this->functions[ $function_name ]['args'] ), 'given' => $arg_count );
366 365 return $this->raise_error( 'wrong_number_of_arguments', $error_data );
367 366 }
368 367 } else {
@@ -369,13 +368,13 @@
369 368 // Did we somehow push a non-function on the stack? This should never happen.
370 369 return $this->raise_error( 'internal_error' );
371 370 }
372 371 }
373 - $index++;
372 + ++$index;
374 373
375 374 // Did we just finish a function argument?
376 375 } elseif ( ',' === $op && $expecting_operator ) {
377 - // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
376 + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
378 377 while ( '(' !== ( $o2 = $stack->pop() ) ) {
379 378 if ( is_null( $o2 ) ) {
380 379 // Oops, never had a (.
381 380 return $this->raise_error( 'unexpected_comma' );
@@ -384,21 +383,21 @@
384 383 $output[] = $o2;
385 384 }
386 385 }
387 386 // Make sure there was a function.
388 - if ( 0 === preg_match( '/^(' . self::$name_pattern . ')\($/', $stack->last( 2 ), $matches ) ) {
387 + if ( 0 === preg_match( '/^(' . self::$name_pattern . ')\($/', (string) $stack->last( 2 ), $matches ) ) {
389 388 return $this->raise_error( 'unexpected_comma' );
390 389 }
391 390 // Increment the argument count.
392 - $stack->push( $stack->pop() + 1 );
391 + $stack->push( $stack->pop() + 1 ); // @phpstan-ignore binaryOp.invalid
393 392 // Put the ( back on, we'll need to pop back to it again.
394 393 $stack->push( '(' );
395 - $index++;
394 + ++$index;
396 395 $expecting_operator = false;
397 396
398 397 } elseif ( '(' === $op && ! $expecting_operator ) {
399 398 $stack->push( '(' ); // That was easy.
400 - $index++;
399 + ++$index;
401 400
402 401 // Do we now have a function/variable/number?
403 402 } elseif ( $ex && ! $expecting_operator ) {
404 403 $expecting_operator = true;
@@ -427,9 +426,9 @@
427 426 if ( '(' !== $stack->last() || 1 !== $stack->last( 2 ) ) {
428 427 return $this->raise_error( 'unexpected_closing_bracket' );
429 428 }
430 429 // Did we just close a function?
431 - if ( 1 === preg_match( '/^(' . self::$name_pattern . ')\($/', $stack->last( 3 ), $matches ) ) {
430 + if ( 1 === preg_match( '/^(' . self::$name_pattern . ')\($/', (string) $stack->last( 3 ), $matches ) ) {
432 431 $stack->pop(); // (
433 432 $stack->pop(); // 1
434 433 $stack->pop(); // $fn
435 434 // Get the function name.
@@ -446,9 +445,9 @@
446 445 return $this->raise_error( 'wrong_number_of_arguments', $error_data );
447 446 }
448 447 // Send function to output.
449 448 $output[] = array( 'function_name' => $function_name, 'arg_count' => 0 );
450 - $index++;
449 + ++$index;
451 450 $expecting_operator = true;
452 451 } else {
453 452 return $this->raise_error( 'unexpected_closing_bracket' );
454 453 }
@@ -472,14 +471,14 @@
472 471 }
473 472
474 473 // Step the index past whitespace (pretty much turns whitespace into implicit multiplication if no operator is there).
475 474 while ( ' ' === substr( $expression, $index, 1 ) ) {
476 - $index++;
475 + ++$index;
477 476 }
478 477 } // while ( true )
479 478
480 479 // Pop everything off the stack and push onto output.
481 - // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
480 + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
482 481 while ( ! is_null( $op = $stack->pop() ) ) {
483 482 if ( '(' === $op ) {
484 483 // If there are (s on the stack, ()s were unbalanced.
485 484 return $this->raise_error( 'expecting_a_closing_bracket' );
@@ -494,18 +493,18 @@
494 493 * Evaluate postfix notation.
495 494 *
496 495 * @since 1.0.0
497 496 *
498 - * @param array|false $tokens [description]
499 - * @param array $variables Optional. [description]
500 - * @return mixed [description]
497 + * @param array<int, string|mixed[]>|false $tokens [description].
498 + * @param array<string, mixed> $variables Optional. [description].
499 + * @return mixed [description].
501 500 */
502 - protected function pfx( $tokens, array $variables = array() ) {
501 + protected function pfx( $tokens, array $variables = array() ) /* : mixed */ {
503 502 if ( false === $tokens ) {
504 503 return false;
505 504 }
506 505
507 - $stack = new EvalMath_Stack;
506 + $stack = new EvalMath_Stack();
508 507
509 508 foreach ( $tokens as $token ) {
510 509 // If the token is a function, pop arguments off the stack, hand them to the function, and push the result back on.
511 510 if ( is_array( $token ) ) { // it's a function!
@@ -511,10 +510,11 @@
511 510 if ( is_array( $token ) ) { // it's a function!
512 511 $function_name = $token['function_name'];
513 512 $count = $token['arg_count'];
514 513
515 - // Built-in function.
516 514 if ( in_array( $function_name, $this->builtin_functions, true ) ) {
515 + // Built-in function.
516 +
517 517 $op1 = $stack->pop();
518 518 if ( is_null( $op1 ) ) {
519 519 return $this->raise_error( 'internal_error' );
520 520 }
@@ -526,11 +526,11 @@
526 526 }
527 527 // Perfectly safe eval().
528 528 // phpcs:ignore Squiz.PHP.Eval.Discouraged
529 529 eval( '$stack->push( ' . $function_name . '( $op1 ) );' );
530 + } elseif ( array_key_exists( $function_name, $this->calc_functions ) ) {
531 + // Calc-emulation function.
530 532
531 - // Calc-emulation function.
532 - } elseif ( array_key_exists( $function_name, $this->calc_functions ) ) {
533 533 // Get function arguments.
534 534 $args = array();
535 535 for ( $i = $count - 1; $i >= 0; $i-- ) {
536 536 $arg = $stack->pop();
@@ -558,11 +558,11 @@
558 558 if ( false === $result ) {
559 559 return $this->raise_error( 'internal_error' );
560 560 }
561 561 $stack->push( $result );
562 + } elseif ( array_key_exists( $function_name, $this->functions ) ) {
563 + // User-defined function.
562 564
563 - // User-defined function.
564 - } elseif ( array_key_exists( $function_name, $this->functions ) ) {
565 565 // Get function arguments.
566 566 $args = array();
567 567 for ( $i = count( $this->functions[ $function_name ]['args'] ) - 1; $i >= 0; $i-- ) {
568 568 $arg = $stack->pop();
@@ -571,14 +571,13 @@
571 571 } else {
572 572 $args[ $this->functions[ $function_name ]['args'][ $i ] ] = $arg;
573 573 }
574 574 }
575 - // yay... recursion!
575 + // Recursion.
576 576 $stack->push( $this->pfx( $this->functions[ $function_name ]['func'], $args ) );
577 577 }
578 -
578 + } elseif ( in_array( $token, array( '+', '-', '*', '/', '^', '>', '<', '=', '%' ), true ) ) {
579 579 // If the token is a binary operator, pop two values off the stack, do the operation, and push the result back on.
580 - } elseif ( in_array( $token, array( '+', '-', '*', '/', '^', '>', '<', '=' ), true ) ) {
581 580 $op2 = $stack->pop();
582 581 if ( is_null( $op2 ) ) {
583 582 return $this->raise_error( 'internal_error' );
584 583 }
@@ -611,28 +610,29 @@
611 610 case '<':
612 611 $stack->push( (int) ( $op1 < $op2 ) );
613 612 break;
614 613 case '=':
615 - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
614 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison,Universal.Operators.StrictComparisons.LooseEqual
616 615 $stack->push( (int) ( $op1 == $op2 ) ); // Don't use === as the variable type can differ (int/double/bool).
617 616 break;
617 + case '%':
618 + $stack->push( $op1 % $op2 );
619 + break;
618 620 }
619 -
621 + } elseif ( '_' === $token ) {
620 622 // If the token is a unary operator, pop one value off the stack, do the operation, and push it back on.
621 - } elseif ( '_' === $token ) {
622 623 $stack->push( -1 * $stack->pop() );
623 -
624 - // 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 ] );
625 633 } else {
626 - if ( is_numeric( $token ) ) {
627 - $stack->push( $token );
628 - } elseif ( array_key_exists( $token, $this->variables ) ) {
629 - $stack->push( $this->variables[ $token ] );
630 - } elseif ( array_key_exists( $token, $variables ) ) {
631 - $stack->push( $variables[ $token ] );
632 - } else {
633 - return $this->raise_error( 'undefined_variable', $token );
634 - }
634 + return $this->raise_error( 'undefined_variable', $token );
635 635 }
636 636 }
637 637 // When we're out of tokens, the stack should have a single element, the final result.
638 638 if ( 1 !== $stack->count ) {
@@ -645,18 +645,17 @@
645 645 * Raise an error.
646 646 *
647 647 * @since 1.0.0
648 648 *
649 - * @param string $message Error message.
650 - * @param array|string $error_data Optional. Additional error data.
651 - * @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.
652 652 */
653 - protected function raise_error( $message, $error_data = null ) {
653 + protected function raise_error( $message, $error_data = null ): bool {
654 654 $this->last_error = $this->get_error_string( $message, $error_data );
655 655 return false;
656 656 }
657 657
658 -
659 658 /**
660 659 * Get a translated string for an error message.
661 660 *
662 661 * @since 1.0.0
@@ -663,13 +662,13 @@
663 662 *
664 663 * @link https://github.com/moodle/moodle/blob/13264f35057d2f37374ec3e0e8ad4070f4676bd7/lang/en/mathslib.php
665 664 * @link https://github.com/moodle/moodle/blob/8e54ce9717c19f768b95f4332f70e3180ffafc46/lib/moodlelib.php#L6323
666 665 *
667 - * @param string $identifier Identifier of the string.
668 - * @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.
669 668 * @return string Translated string.
670 669 */
671 - protected function get_error_string( $identifier, $error_data = null ) {
670 + protected function get_error_string( $identifier, $error_data = null ): string {
672 671 $strings = array();
673 672 $strings['an_unexpected_error_occurred'] = 'an unexpected error occurred';
674 673 $strings['cannot_assign_to_constant'] = 'cannot assign to constant \'{$error_data}\'';
675 674 $strings['cannot_redefine_builtin_function'] = 'cannot redefine built-in function \'{$error_data}()\'';
@@ -685,9 +684,9 @@
685 684 $strings['unexpected_comma'] = 'unexpected comma';
686 685 $strings['unexpected_operator'] = 'unexpected operator \'{$error_data}\'';
687 686 $strings['wrong_number_of_arguments'] = 'wrong number of arguments ({$error_data->given} given, {$error_data->expected} expected)';
688 687
689 - $string = $strings[ $identifier ];
688 + $a_string = $strings[ $identifier ];
690 689
691 690 if ( null !== $error_data ) {
692 691 if ( is_array( $error_data ) ) {
693 692 $search = array();
@@ -711,16 +710,16 @@
711 710 $search[] = '{$error_data->' . $key . '}';
712 711 $replace[] = (string) $value;
713 712 }
714 713 if ( $search ) {
715 - $string = str_replace( $search, $replace, $string );
714 + $a_string = str_replace( $search, $replace, $a_string );
716 715 }
717 716 } else {
718 - $string = str_replace( '{$error_data}', (string) $error_data, $string );
717 + $a_string = str_replace( '{$error_data}', (string) $error_data, $a_string );
719 718 }
720 719 }
721 720
722 - return $string;
721 + return $a_string;
723 722 }
724 723
725 724 } // class EvalMath
726 725
@@ -725,29 +724,29 @@
725 724 } // class EvalMath
726 725
727 726 /**
728 727 * Stack for the postfix/infix conversion of math expressions.
728 + *
729 729 * @package TablePress
730 730 * @subpackage Formulas
731 731 * @since 1.0.0
732 732 */
733 -class EvalMath_Stack {
733 +class EvalMath_Stack { // phpcs:ignore Generic.Files.OneObjectStructurePerFile.MultipleFound,Generic.Classes.OpeningBraceSameLine.ContentAfterBrace
734 734
735 735 /**
736 736 * The stack.
737 737 *
738 738 * @since 1.0.0
739 - * @var array
739 + * @var mixed[]
740 740 */
741 - protected $stack = array();
741 + protected array $stack = array();
742 742
743 743 /**
744 744 * Number of items on the stack.
745 745 *
746 746 * @since 1.0.0
747 - * @var int
748 747 */
749 - public $count = 0;
748 + public int $count = 0;
750 749
751 750 /**
752 751 * Push an item onto the stack.
753 752 *
@@ -754,11 +753,11 @@
754 753 * @since 1.0.0
755 754 *
756 755 * @param mixed $value The item that is pushed onto the stack.
757 756 */
758 - public function push( $value ) {
757 + public function push( $value ): void {
759 758 $this->stack[ $this->count ] = $value;
760 - $this->count++;
759 + ++$this->count;
761 760 }
762 761
763 762 /**
764 763 * Pop an item from the top of the stack.
@@ -764,13 +763,13 @@
764 763 * Pop an item from the top of the stack.
765 764 *
766 765 * @since 1.0.0
767 766 *
768 - * @return mixed The item that is popped from the stack.
767 + * @return mixed|null The item that is popped from the stack.
769 768 */
770 - public function pop() {
769 + public function pop() /* : mixed|null */ {
771 770 if ( $this->count > 0 ) {
772 - $this->count--;
771 + --$this->count;
773 772 return $this->stack[ $this->count ];
774 773 }
775 774 return null;
776 775 }
@@ -780,11 +779,11 @@
780 779 *
781 780 * @since 1.0.0
782 781 *
783 782 * @param int $n Count from the end of the stack.
784 - * @return mixed The item that is popped from the stack.
783 + * @return mixed|null The item that is popped from the stack.
785 784 */
786 - public function last( $n = 1 ) {
785 + public function last( $n = 1 ) /* : mixed|null */ {
787 786 if ( ( $this->count - $n ) >= 0 ) {
788 787 return $this->stack[ $this->count - $n ];
789 788 }
790 789 return null;
@@ -793,21 +792,21 @@
793 792 } // class EvalMath_Stack
794 793
795 794 /**
796 795 * Common math functions, prepared for usage in EvalMath.
796 + *
797 797 * @package TablePress
798 798 * @subpackage EvalMath
799 799 * @since 1.0.0
800 800 */
801 -class EvalMath_Functions {
801 +class EvalMath_Functions { // phpcs:ignore Generic.Files.OneObjectStructurePerFile.MultipleFound,Generic.Classes.OpeningBraceSameLine.ContentAfterBrace
802 802
803 803 /**
804 804 * Seed for the generation of random numbers.
805 805 *
806 806 * @since 1.0.0
807 - * @var string
808 807 */
809 - protected static $random_seed = null;
808 + protected static ?string $random_seed = null;
810 809
811 810 /**
812 811 * Choose from two values based on an if-condition.
813 812 *
@@ -814,15 +813,15 @@
814 813 * "if" is not a valid function name, which is why it's prefixed with "func_".
815 814 *
816 815 * @since 1.0.0
817 816 *
818 - * @param double|int $condition Condition.
819 - * @param double|int $then Return value if the condition is true.
820 - * @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.
821 820 * @return double|int Result of the if check.
822 821 */
823 - public static function func_if( $condition, $then, $else ) {
824 - return ( (bool) $condition ? $then : $else );
822 + public static function func_if( $condition, $statement, $alternative ) /* : float|int */ {
823 + return ( (bool) $condition ? $statement : $alternative );
825 824 }
826 825
827 826 /**
828 827 * Return the negation (boolean "not") of a value.
@@ -833,9 +832,9 @@
833 832 *
834 833 * @param double|int $value Value to be negated.
835 834 * @return int Negated value (0 for false, 1 for true).
836 835 */
837 - public static function func_not( $value ) {
836 + public static function func_not( $value ): int {
838 837 return (int) ! (bool) $value;
839 838 }
840 839
841 840 /**
@@ -844,12 +843,12 @@
844 843 * "and" is not a valid function name, which is why it's prefixed with "func_".
845 844 *
846 845 * @since 1.0.0
847 846 *
848 - * @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.
849 848 * @return int Conjunction of the passed arguments.
850 849 */
851 - public static function func_and( ...$args ) {
850 + public static function func_and( ...$args ): int {
852 851 foreach ( $args as $value ) {
853 852 if ( ! $value ) {
854 853 return 0;
855 854 }
@@ -863,12 +862,12 @@
863 862 * "or" is not a valid function name, which is why it's prefixed with "func_".
864 863 *
865 864 * @since 1.0.0
866 865 *
867 - * @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.
868 867 * @return int Disjunction of the passed arguments.
869 868 */
870 - public static function func_or( ...$args ) {
869 + public static function func_or( ...$args ): int {
871 870 foreach ( $args as $value ) {
872 871 if ( $value ) {
873 872 return 1;
874 873 }
@@ -882,9 +881,9 @@
882 881 * @since 1.0.0
883 882 *
884 883 * @return double Rounded value of Pi.
885 884 */
886 - public static function pi() {
885 + public static function pi(): float {
887 886 return pi();
888 887 }
889 888
890 889 /**
@@ -891,12 +890,12 @@
891 890 * Calculate the sum of the arguments.
892 891 *
893 892 * @since 1.0.0
894 893 *
895 - * @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.
896 895 * @return double|int Sum of the passed arguments.
897 896 */
898 - public static function sum( ...$args ) {
897 + public static function sum( ...$args ) /* : float|int */ {
899 898 return array_sum( $args );
900 899 }
901 900
902 901 /**
@@ -903,12 +902,12 @@
903 902 * Count the number of non-empty arguments.
904 903 *
905 904 * @since 1.10.0
906 905 *
907 - * @param double|int $args Values for which the number of non-empty elements shall be counted.
908 - * @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.
909 908 */
910 - public static function counta( ...$args ) {
909 + public static function counta( ...$args ): int {
911 910 return count( array_filter( $args ) );
912 911 }
913 912
914 913 /**
@@ -915,12 +914,12 @@
915 914 * Calculate the product of the arguments.
916 915 *
917 916 * @since 1.0.0
918 917 *
919 - * @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.
920 919 * @return double|int Product of the passed arguments.
921 920 */
922 - public static function product( ...$args ) {
921 + public static function product( ...$args ) /* : float|int */ {
923 922 return array_product( $args );
924 923 }
925 924
926 925 /**
@@ -927,12 +926,12 @@
927 926 * Calculate the average/mean value of the arguments.
928 927 *
929 928 * @since 1.0.0
930 929 *
931 - * @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.
932 931 * @return double|int Average value of the passed arguments.
933 932 */
934 - public static function average( ...$args ) {
933 + public static function average( ...$args ) /* : float|int */ {
935 934 // Catch division by zero.
936 935 if ( 0 === count( $args ) ) {
937 936 return 0;
938 937 }
@@ -945,15 +944,15 @@
945 944 * For even counts of arguments, the upper median is returned.
946 945 *
947 946 * @since 1.0.0
948 947 *
949 - * @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.
950 949 * @return double|int Median of the passed arguments.
951 950 */
952 - public static function median( ...$args ) {
951 + public static function median( array ...$args ) /* : float|int */ {
953 952 sort( $args );
954 - $middle = floor( count( $args ) / 2 ); // Upper median for even counts.
955 - return $args[ $middle ];
953 + $middle = intdiv( count( $args ), 2 ); // Upper median for even counts.
954 + return $args[ $middle ]; // @phpstan-ignore return.type
956 955 }
957 956
958 957 /**
959 958 * Calculate the mode of the arguments.
@@ -959,16 +958,15 @@
959 958 * Calculate the mode of the arguments.
960 959 *
961 960 * @since 1.0.0
962 961 *
963 - * @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.
964 963 * @return double|int Mode of the passed arguments.
965 964 */
966 - public static function mode( ...$args ) {
967 - $values = array_count_values( $args );
965 + public static function mode( ...$args ) /* : float|int */ {
966 + $values = array_count_values( $args ); // @phpstan-ignore argument.type
968 967 asort( $values );
969 - end( $values );
970 - return key( $values );
968 + return array_key_last( $values ); // @phpstan-ignore return.type
971 969 }
972 970
973 971 /**
974 972 * Calculate the range of the arguments.
@@ -974,12 +972,12 @@
974 972 * Calculate the range of the arguments.
975 973 *
976 974 * @since 1.0.0
977 975 *
978 - * @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.
979 977 * @return double|int Range of the passed arguments.
980 978 */
981 - public static function range( ...$args ) {
979 + public static function range( ...$args ) /* : float|int */ {
982 980 sort( $args );
983 981 return end( $args ) - reset( $args );
984 982 }
985 983
@@ -987,13 +985,13 @@
987 985 * Find the maximum value of the arguments.
988 986 *
989 987 * @since 1.0.0
990 988 *
991 - * @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.
992 990 * @return double|int Maximum value of the passed arguments.
993 991 */
994 - public static function max( ...$args ) {
995 - return max( $args );
992 + public static function max( ...$args ) /* : float|int */ {
993 + return max( $args ); // @phpstan-ignore argument.type
996 994 }
997 995
998 996 /**
999 997 * Find the minimum value of the arguments.
@@ -999,13 +997,13 @@
999 997 * Find the minimum value of the arguments.
1000 998 *
1001 999 * @since 1.0.0
1002 1000 *
1003 - * @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.
1004 1002 * @return double|int Minimum value of the passed arguments.
1005 1003 */
1006 - public static function min( ...$args ) {
1007 - return min( $args );
1004 + public static function min( ...$args ) /* : float|int */ {
1005 + return min( $args ); // @phpstan-ignore argument.type
1008 1006 }
1009 1007
1010 1008 /**
1011 1009 * Calculate the remainder of a division of two numbers.
@@ -1013,11 +1011,11 @@
1013 1011 * @since 1.0.0
1014 1012 *
1015 1013 * @param double|int $op1 First number (dividend).
1016 1014 * @param double|int $op2 Second number (divisor).
1017 - * @return double|int Remainer of the division (dividend / divisor).
1015 + * @return int Remainder of the division (dividend / divisor).
1018 1016 */
1019 - public static function mod( $op1, $op2 ) {
1017 + public static function mod( $op1, $op2 ): int {
1020 1018 return $op1 % $op2;
1021 1019 }
1022 1020
1023 1021 /**
@@ -1028,9 +1026,9 @@
1028 1026 * @param double|int $base Base.
1029 1027 * @param double|int $exponent Exponent.
1030 1028 * @return double|int Power base^exponent.
1031 1029 */
1032 - public static function power( $base, $exponent ) {
1030 + public static function power( $base, $exponent ) /* : float|int */ {
1033 1031 return pow( $base, $exponent );
1034 1032 }
1035 1033
1036 1034 /**
@@ -1041,9 +1039,9 @@
1041 1039 * @param double|int $number Number.
1042 1040 * @param double|int $base Optional. Base for the logarithm. Default e (for the natural logarithm).
1043 1041 * @return double Logarithm of the number to the base.
1044 1042 */
1045 - public static function log( $number, $base = M_E ) {
1043 + public static function log( $number, $base = M_E ): float {
1046 1044 return log( $number, $base );
1047 1045 }
1048 1046
1049 1047 /**
@@ -1056,9 +1054,9 @@
1056 1054 * @param double|int $op1 First number.
1057 1055 * @param double|int $op2 Second number.
1058 1056 * @return double Arc tangent of two numbers, similar to arc tangent of $op1/op$ except for the sign.
1059 1057 */
1060 - public static function atan2( $op1, $op2 ) {
1058 + public static function atan2( $op1, $op2 ): float {
1061 1059 return atan2( $op1, $op2 );
1062 1060 }
1063 1061
1064 1062 /**
@@ -1069,9 +1067,9 @@
1069 1067 * @param double|int $value Number to be rounded.
1070 1068 * @param int $decimals Optional. Number of decimals after the comma after the rounding.
1071 1069 * @return double Rounded number.
1072 1070 */
1073 - public static function round( $value, $decimals = 0 ) {
1071 + public static function round( $value, $decimals = 0 ): float {
1074 1072 return round( $value, $decimals );
1075 1073 }
1076 1074
1077 1075 /**
@@ -1084,9 +1082,9 @@
1084 1082 * @param double|int $value Number to be rounded and formatted.
1085 1083 * @param int $decimals Optional. Number of decimals after the decimal separator after the rounding.
1086 1084 * @return string Formatted number.
1087 1085 */
1088 - public static function number_format( $value, $decimals = 0 ) {
1086 + public static function number_format( $value, $decimals = 0 ): string {
1089 1087 return number_format( $value, $decimals, '.', ',' );
1090 1088 }
1091 1089
1092 1090 /**
@@ -1099,9 +1097,9 @@
1099 1097 * @param double|int $value Number to be rounded and formatted.
1100 1098 * @param int $decimals Optional. Number of decimals after the decimal separator after the rounding.
1101 1099 * @return string Formatted number.
1102 1100 */
1103 - public static function number_format_eu( $value, $decimals = 0 ) {
1101 + public static function number_format_eu( $value, $decimals = 0 ): string {
1104 1102 return number_format( $value, $decimals, ',', ' ' );
1105 1103 }
1106 1104
1107 1105 /**
@@ -1110,9 +1108,9 @@
1110 1108 * @since 1.0.0
1111 1109 *
1112 1110 * @param string $random_seed The seed.
1113 1111 */
1114 - protected static function _set_random_seed( $random_seed ) {
1112 + protected static function _set_random_seed( $random_seed ): void {
1115 1113 self::$random_seed = $random_seed;
1116 1114 }
1117 1115
1118 1116 /**
@@ -1121,14 +1119,13 @@
1121 1119 * @since 1.0.0
1122 1120 *
1123 1121 * @return string The seed.
1124 1122 */
1125 - protected static function _get_random_seed() {
1123 + protected static function _get_random_seed(): string {
1126 1124 if ( is_null( self::$random_seed ) ) {
1127 1125 return microtime();
1128 - } else {
1129 - return self::$random_seed;
1130 1126 }
1127 + return self::$random_seed;
1131 1128 }
1132 1129
1133 1130 /**
1134 1131 * Get a random integer from a range.
@@ -1138,9 +1135,9 @@
1138 1135 * @param int $min Minimum value for the range.
1139 1136 * @param int $max Maximum value for the range.
1140 1137 * @return int Random integer from the range [$min, $max].
1141 1138 */
1142 - public static function rand_int( $min, $max ) {
1139 + public static function rand_int( $min, $max ): int {
1143 1140 // Swap min and max value if min is bigger than max.
1144 1141 if ( $min > $max ) {
1145 1142 $tmp = $max;
1146 1143 $max = $min;
@@ -1150,15 +1147,15 @@
1150 1147 $number_characters = (int) ceil( log( $max + 1 - $min, 16 ) );
1151 1148 $md5string = md5( self::_get_random_seed() );
1152 1149 $offset = 0;
1153 1150 do {
1154 - while ( ( $offset + $number_characters ) > strlen( $md5string ) ) {
1151 + while ( ( $offset + $number_characters ) > strlen( $md5string ) ) { // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
1155 1152 $md5string .= md5( $md5string );
1156 1153 }
1157 - $randomno = hexdec( substr( $md5string, $offset, $number_characters ) );
1154 + $random_number = (int) hexdec( substr( $md5string, $offset, $number_characters ) );
1158 1155 $offset += $number_characters;
1159 - } while ( ( $min + $randomno ) > $max );
1160 - return $min + $randomno;
1156 + } while ( ( $min + $random_number ) > $max );
1157 + return $min + $random_number;
1161 1158 }
1162 1159
1163 1160 /**
1164 1161 * Get a random double value from a range [0, 1].
@@ -1166,10 +1163,10 @@
1166 1163 * @since 1.0.0
1167 1164 *
1168 1165 * @return double Random number from the range [0, 1].
1169 1166 */
1170 - public static function rand_float() {
1167 + public static function rand_float(): float {
1171 1168 $random_values = unpack( 'v', md5( self::_get_random_seed(), true ) );
1172 - return array_shift( $random_values ) / 65536;
1169 + return array_shift( $random_values ) / 65536; // @phpstan-ignore argument.type
1173 1170 }
1174 1171
1175 1172 } // class EvalMath_Functions