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