[BUGFIX] canBeInterpretedAsInteger fatals if given an object
[Packages/TYPO3.CMS.git] / t3lib / utility / class.t3lib_utility_math.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2011 Susanne Moog <typo3@susanne-moog.de>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Class with helper functions for mathematical calculations
29 *
30 * @author Susanne Moog <typo3@susanne-moog.de>
31 * @package TYPO3
32 * @subpackage t3lib
33 */
34
35 final class t3lib_utility_Math {
36
37 /**
38 * Forces the integer $theInt into the boundaries of $min and $max. If the $theInt is FALSE then the $defaultValue is applied.
39 *
40 * @param $theInt integer Input value
41 * @param $min integer Lower limit
42 * @param $max integer Higher limit
43 * @param $defaultValue integer Default value if input is FALSE.
44 * @return integer The input value forced into the boundaries of $min and $max
45 */
46 public static function forceIntegerInRange($theInt, $min, $max = 2000000000, $defaultValue = 0) {
47 // Returns $theInt as an integer in the integerspace from $min to $max
48 $theInt = intval($theInt);
49 if ($defaultValue && !$theInt) {
50 $theInt = $defaultValue;
51 } // If the input value is zero after being converted to integer, defaultValue may set another default value for it.
52 if ($theInt < $min) {
53 $theInt = $min;
54 }
55 if ($theInt > $max) {
56 $theInt = $max;
57 }
58 return $theInt;
59 }
60
61 /**
62 * Returns $theInt if it is greater than zero, otherwise returns zero.
63 *
64 * @param $theInt integer Integer string to process
65 * @return integer
66 */
67 public static function convertToPositiveInteger($theInt) {
68 $theInt = intval($theInt);
69 if ($theInt < 0) {
70 $theInt = 0;
71 }
72 return $theInt;
73 }
74
75 /**
76 * Tests if the input can be interpreted as integer.
77 *
78 * Note: Integer casting from objects or arrays is considered undefined and thus will return false.
79 * @see http://php.net/manual/en/language.types.integer.php#language.types.integer.casting.from-other
80 *
81 * @param $var mixed Any input variable to test
82 * @return boolean Returns TRUE if string is an integer
83 */
84 public static function canBeInterpretedAsInteger($var) {
85 if ($var === '' || is_object($var) || is_array($var)) {
86 return FALSE;
87 }
88 return (string) intval($var) === (string) $var;
89 }
90
91 /**
92 * Calculates the input by +,-,*,/,%,^ with priority to + and -
93 *
94 * @param $string string Input string, eg "123 + 456 / 789 - 4"
95 * @return integer Calculated value. Or error string.
96 * @see t3lib_utility_Math::calculateWithParentheses()
97 */
98 public static function calculateWithPriorityToAdditionAndSubtraction($string) {
99 $string = preg_replace('/[[:space:]]*/', '', $string); // removing all whitespace
100 $string = '+' . $string; // Ensuring an operator for the first entrance
101 $qm = '\*\/\+-^%';
102 $regex = '([' . $qm . '])([' . $qm . ']?[0-9\.]*)';
103 // split the expression here:
104 $reg = array();
105 preg_match_all('/' . $regex . '/', $string, $reg);
106
107 reset($reg[2]);
108 $number = 0;
109 $Msign = '+';
110 $err = '';
111 $buffer = doubleval(current($reg[2]));
112 next($reg[2]); // Advance pointer
113
114 while (list($k, $v) = each($reg[2])) {
115 $v = doubleval($v);
116 $sign = $reg[1][$k];
117 if ($sign == '+' || $sign == '-') {
118 $Msign == '-' ? $number -= $buffer : $number += $buffer;
119 $Msign = $sign;
120 $buffer = $v;
121 } else {
122 if ($sign == '/') {
123 if ($v) {
124 $buffer /= $v;
125 } else {
126 $err = 'dividing by zero';
127 }
128 }
129 if ($sign == '%') {
130 if ($v) {
131 $buffer %= $v;
132 } else {
133 $err = 'dividing by zero';
134 }
135 }
136 if ($sign == '*') {
137 $buffer *= $v;
138 }
139 if ($sign == '^') {
140 $buffer = pow($buffer, $v);
141 }
142 }
143 }
144 $number = $Msign == '-' ? $number -= $buffer : $number += $buffer;
145 return $err ? 'ERROR: ' . $err : $number;
146 }
147
148 /**
149 * Calculates the input with parenthesis levels
150 *
151 * @param $string string Input string, eg "(123 + 456) / 789 - 4"
152 * @return integer Calculated value. Or error string.
153 * @see calculateWithPriorityToAdditionAndSubtraction(), tslib_cObj::stdWrap()
154 */
155 public static function calculateWithParentheses($string) {
156 $securC = 100;
157 do {
158 $valueLenO = strcspn($string, '(');
159 $valueLenC = strcspn($string, ')');
160 if ($valueLenC == strlen($string) || $valueLenC < $valueLenO) {
161 $value = self::calculateWithPriorityToAdditionAndSubtraction(substr($string, 0, $valueLenC));
162 $string = $value . substr($string, $valueLenC + 1);
163 return $string;
164 } else {
165 $string = substr($string, 0, $valueLenO) . self::calculateWithParentheses(substr($string, $valueLenO + 1));
166 }
167 // Security:
168 $securC--;
169 if ($securC <= 0) {
170 break;
171 }
172 } while ($valueLenO < strlen($string));
173 return $string;
174 }
175 }
176
177 ?>