This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php defined('SYSPATH') OR die('No direct script access.'); |
||
2 | |||
3 | use OpenBuildings\Monetary\Monetary; |
||
4 | |||
5 | /** |
||
6 | * @package Openbuildings\Jam |
||
7 | * @author Ivan Kerin <[email protected]> |
||
8 | * @copyright (c) 2013 OpenBuildings Ltd. |
||
9 | * @license http://spdx.org/licenses/BSD-3-Clause |
||
10 | */ |
||
11 | class Kohana_Jam_Price implements Serializable { |
||
12 | |||
13 | const EQUAL_TO = '='; |
||
14 | const GREATER_THAN = '>'; |
||
15 | const LESS_THAN = '<'; |
||
16 | const GREATER_THAN_OR_EQUAL_TO = '>='; |
||
17 | const LESS_THAN_OR_EQUAL_TO = '<='; |
||
18 | |||
19 | const EPSILON = 0.000001; |
||
20 | |||
21 | 1 | public static function min(array $prices) |
|
22 | { |
||
23 | 1 | $min = reset($prices); |
|
24 | |||
25 | 1 | foreach (array_slice($prices, 1) as $price) |
|
26 | { |
||
27 | 1 | if ($price->is(Jam_Price::LESS_THAN, $min)) |
|
28 | { |
||
29 | 1 | $min = $price; |
|
30 | } |
||
31 | } |
||
32 | |||
33 | 1 | return $min; |
|
34 | } |
||
35 | |||
36 | 1 | public static function max(array $prices) |
|
37 | { |
||
38 | 1 | $max = reset($prices); |
|
39 | |||
40 | 1 | foreach (array_slice($prices, 1) as $price) |
|
41 | { |
||
42 | 1 | if ($price->is(Jam_Price::GREATER_THAN, $max)) |
|
43 | { |
||
44 | 1 | $max = $price; |
|
45 | } |
||
46 | } |
||
47 | |||
48 | 1 | return $max; |
|
49 | } |
||
50 | |||
51 | 5 | public static function ceil($amount, $precision) |
|
52 | { |
||
53 | 5 | $fraction = pow(10, $precision); |
|
54 | |||
55 | 5 | return ceil($fraction * $amount) / $fraction; |
|
56 | } |
||
57 | |||
58 | 1 | public static function sum(array $prices, $currency, $monetary = NULL, $display_currency = NULL, $ceil_on_convert = FALSE) |
|
59 | { |
||
60 | 1 | $amount = 0; |
|
61 | |||
62 | 1 | foreach ($prices as $price) |
|
63 | { |
||
64 | 1 | if ( ! ($price instanceof Jam_Price)) |
|
65 | { |
||
66 | 1 | $amount += (float) $price; |
|
67 | } |
||
68 | 1 | elseif ($price->currency() == $currency) |
|
69 | { |
||
70 | 1 | $amount += $price->amount(); |
|
71 | } |
||
72 | else |
||
73 | { |
||
74 | 1 | $amount += $price->in($currency, $monetary); |
|
75 | } |
||
76 | } |
||
77 | |||
78 | 1 | return new Jam_Price($amount, $currency, $monetary, $display_currency, $ceil_on_convert); |
|
79 | } |
||
80 | |||
81 | protected $_amount = 0; |
||
82 | protected $_currency; |
||
83 | protected $_monetary; |
||
84 | protected $_ceil_on_convert = FALSE; |
||
85 | protected $_display_currency; |
||
86 | |||
87 | 3 | public function ceil_on_convert($ceil_on_convert = NULL) |
|
88 | { |
||
89 | 3 | if ($ceil_on_convert !== NULL) |
|
90 | { |
||
91 | 3 | $this->_ceil_on_convert = $ceil_on_convert; |
|
92 | 3 | return $this; |
|
93 | } |
||
94 | 3 | return $this->_ceil_on_convert; |
|
95 | } |
||
96 | |||
97 | 2 | public function display_currency($display_currency = NULL) |
|
98 | { |
||
99 | 2 | if ($display_currency !== NULL) |
|
100 | { |
||
101 | 2 | $this->_display_currency = $display_currency; |
|
102 | 2 | return $this; |
|
103 | } |
||
104 | 1 | return $this->_display_currency; |
|
105 | } |
||
106 | |||
107 | /** |
||
108 | * Getter / Setter of amount, casts to float |
||
109 | * @param float $amount |
||
110 | * @return float|$this |
||
111 | */ |
||
112 | 3 | public function amount($amount = NULL) |
|
113 | { |
||
114 | 3 | if ($amount !== NULL) |
|
115 | { |
||
116 | 3 | $this->_amount = (float) $amount; |
|
0 ignored issues
–
show
|
|||
117 | 3 | return $this; |
|
118 | } |
||
119 | 2 | return $this->_amount; |
|
120 | } |
||
121 | |||
122 | /** |
||
123 | * Getter / Setter |
||
124 | * @param string $currency |
||
125 | * @return string|$this |
||
126 | */ |
||
127 | 3 | public function currency($currency = NULL) |
|
128 | { |
||
129 | 3 | if ($currency !== NULL) |
|
130 | { |
||
131 | 3 | $this->_currency = $currency; |
|
132 | 3 | return $this; |
|
133 | } |
||
134 | 3 | return $this->_currency; |
|
135 | } |
||
136 | |||
137 | /** |
||
138 | * Getter / Setter, defaults to Monetary::instance() |
||
139 | * @param OpenBuildings\Monetary\Monetary $monetary |
||
140 | * @return OpenBuildings\Monetary\Monetary|$this |
||
141 | */ |
||
142 | 3 | public function monetary($monetary = NULL) |
|
143 | { |
||
144 | 3 | if ($monetary !== NULL) |
|
145 | { |
||
146 | 3 | $this->_monetary = $monetary; |
|
147 | 3 | return $this; |
|
148 | } |
||
149 | |||
150 | 3 | if ( ! $this->_monetary) |
|
151 | { |
||
152 | $this->_monetary = Monetary::instance(); |
||
153 | } |
||
154 | |||
155 | 3 | return $this->_monetary; |
|
156 | } |
||
157 | |||
158 | 3 | public function __construct($amount, $currency, $monetary = NULL, $display_currency = NULL, $ceil_on_convert = FALSE) |
|
159 | { |
||
160 | 3 | $this->amount($amount); |
|
161 | 3 | $this->currency($currency); |
|
162 | 3 | $this->display_currency($display_currency); |
|
163 | 3 | $this->monetary($monetary); |
|
164 | 3 | $this->ceil_on_convert($ceil_on_convert); |
|
165 | 3 | } |
|
166 | |||
167 | /** |
||
168 | * Use as_string method |
||
169 | * @return string |
||
170 | */ |
||
171 | 2 | public function __toString() |
|
172 | { |
||
173 | 2 | return $this->as_string(); |
|
174 | } |
||
175 | |||
176 | /** |
||
177 | * Use number_format with 2 digits after the decimal dot |
||
178 | * @return string |
||
179 | */ |
||
180 | 2 | public function as_string($currency = NULL) |
|
181 | { |
||
182 | 2 | return number_format($this->in($currency), 2, '.', ''); |
|
183 | } |
||
184 | |||
185 | /** |
||
186 | * Use Monetary's "format" method |
||
187 | * @param string $currency optionally convert to another currency |
||
188 | * @return string |
||
189 | */ |
||
190 | 1 | public function humanize($currency = NULL) |
|
191 | { |
||
192 | 1 | $currency = $currency ?: ($this->display_currency() ?: $this->currency()); |
|
193 | |||
194 | 1 | return $this->monetary()->format($this->in($currency), $currency); |
|
0 ignored issues
–
show
The method
format does only exist in OpenBuildings\Monetary\Monetary , but not in Kohana_Jam_Price .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
195 | } |
||
196 | |||
197 | /** |
||
198 | * Replace HTML entities in humanize |
||
199 | * @param string $currency optionally convert to another currency |
||
200 | * @return string |
||
201 | */ |
||
202 | 1 | public function as_html($currency = NULL) |
|
203 | { |
||
204 | 1 | return HTML::entities($this->humanize($currency)); |
|
205 | } |
||
206 | |||
207 | /** |
||
208 | * Perform price arithmetic - add / remove prices with correct currency convertions |
||
209 | * @return $this |
||
210 | */ |
||
211 | 1 | public function add($price) |
|
0 ignored issues
–
show
|
|||
212 | { |
||
213 | 1 | $prices = func_get_args(); |
|
214 | 1 | array_unshift($prices, $this); |
|
215 | |||
216 | 1 | return Jam_Price::sum($prices, $this->currency(), $this->monetary(), $this->display_currency(), $this->ceil_on_convert()); |
|
0 ignored issues
–
show
It seems like
$this->ceil_on_convert() targeting Kohana_Jam_Price::ceil_on_convert() can also be of type this<Kohana_Jam_Price> ; however, Kohana_Jam_Price::sum() does only seem to accept boolean , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
217 | } |
||
218 | |||
219 | /** |
||
220 | * Myltiply by a value |
||
221 | * @param mixed $value |
||
222 | * @return Jam_Price |
||
223 | */ |
||
224 | 1 | public function multiply_by($value) |
|
225 | { |
||
226 | 1 | return new Jam_Price($this->amount() * $value, $this->currency(), $this->monetary(), $this->display_currency(), $this->ceil_on_convert()); |
|
0 ignored issues
–
show
It seems like
$this->ceil_on_convert() targeting Kohana_Jam_Price::ceil_on_convert() can also be of type this<Kohana_Jam_Price> ; however, Kohana_Jam_Price::__construct() does only seem to accept boolean , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
227 | } |
||
228 | |||
229 | /** |
||
230 | * Convert the price to a different currency |
||
231 | * @param string $currency |
||
232 | * @return Jam_Price |
||
233 | */ |
||
234 | 1 | public function convert_to($currency) |
|
235 | { |
||
236 | 1 | return new Jam_Price($this->in($currency), $currency, $this->monetary(), $this->display_currency(), $this->ceil_on_convert()); |
|
0 ignored issues
–
show
It seems like
$this->ceil_on_convert() targeting Kohana_Jam_Price::ceil_on_convert() can also be of type this<Kohana_Jam_Price> ; however, Kohana_Jam_Price::__construct() does only seem to accept boolean , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
237 | } |
||
238 | |||
239 | /** |
||
240 | * Perform price comparation, e.g. =, >, <, => or =<. Performs currency conversion if nesessary |
||
241 | * @return boolean |
||
242 | * @param string $operator |
||
243 | * @param mixed value |
||
244 | */ |
||
245 | 2 | public function is($operator, $value) |
|
246 | { |
||
247 | 2 | if ($value instanceof Jam_Price) |
|
248 | { |
||
249 | 2 | $value = $value->in($this->currency()); |
|
0 ignored issues
–
show
It seems like
$this->currency() targeting Kohana_Jam_Price::currency() can also be of type object<Kohana_Jam_Price> ; however, Kohana_Jam_Price::in() does only seem to accept string|null , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
250 | } |
||
251 | |||
252 | switch ($operator) |
||
253 | { |
||
254 | 2 | case Jam_Price::EQUAL_TO: |
|
255 | 1 | $result = (abs($this->amount() - $value) < Jam_Price::EPSILON); |
|
256 | 1 | break; |
|
257 | 2 | case Jam_Price::GREATER_THAN: |
|
258 | 1 | $result = (($this->amount() - $value) >= Jam_Price::EPSILON); |
|
259 | 1 | break; |
|
260 | 2 | case Jam_Price::LESS_THAN: |
|
261 | 1 | $result = (($value - $this->amount()) >= Jam_Price::EPSILON); |
|
262 | 1 | break; |
|
263 | 2 | case Jam_Price::GREATER_THAN_OR_EQUAL_TO: |
|
264 | 1 | $result = (($value - $this->amount()) < Jam_Price::EPSILON); |
|
265 | 1 | break; |
|
266 | 2 | case Jam_Price::LESS_THAN_OR_EQUAL_TO: |
|
267 | 1 | $result = (($this->amount() - $value) < Jam_Price::EPSILON); |
|
268 | 1 | break; |
|
269 | default; |
||
270 | 1 | throw new Kohana_Exception('Operator not supported :operator', array(':operator' => $operator)); |
|
271 | } |
||
272 | 1 | return $result; |
|
273 | } |
||
274 | |||
275 | /** |
||
276 | * Display the amount in a currency |
||
277 | * @param string|null $currency |
||
278 | * @param OpenBuildings\Monetary\Monetary|null $monetary |
||
279 | * @return float |
||
280 | */ |
||
281 | 2 | public function in($currency = NULL, $monetary = NULL) |
|
282 | { |
||
283 | 2 | if ( ! $currency OR $currency == $this->currency()) |
|
284 | { |
||
285 | 2 | return $this->amount(); |
|
0 ignored issues
–
show
|
|||
286 | } |
||
287 | else |
||
288 | { |
||
289 | 2 | $monetary = $monetary ?: $this->monetary(); |
|
290 | |||
291 | 2 | $amount = $monetary->convert($this->amount(), $this->currency(), $currency); |
|
0 ignored issues
–
show
$this->amount() is of type this<Kohana_Jam_Price>|integer , but the function expects a double .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() It seems like
$this->currency() targeting Kohana_Jam_Price::currency() can also be of type object<Kohana_Jam_Price> ; however, OpenBuildings\Monetary\Monetary::convert() does only seem to accept string|null , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() The method
convert does only exist in OpenBuildings\Monetary\Monetary , but not in Kohana_Jam_Price .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
292 | |||
293 | 2 | if ($this->ceil_on_convert() !== FALSE) |
|
294 | { |
||
295 | 2 | $amount = static::ceil($amount, $this->ceil_on_convert() === TRUE ? 0 : $this->ceil_on_convert()); |
|
296 | } |
||
297 | |||
298 | 2 | return $amount; |
|
299 | } |
||
300 | } |
||
301 | |||
302 | /** |
||
303 | * implement Serializable |
||
304 | * @return string |
||
305 | */ |
||
306 | 1 | public function serialize() |
|
307 | { |
||
308 | 1 | return serialize(array($this->amount(), $this->currency(), $this->display_currency(), $this->ceil_on_convert())); |
|
309 | } |
||
310 | |||
311 | /** |
||
312 | * implement Serializable |
||
313 | * @param string $data |
||
314 | */ |
||
315 | 1 | public function unserialize($data) |
|
316 | { |
||
317 | 1 | $data = unserialize($data); |
|
318 | |||
319 | 1 | $this->amount($data[0]); |
|
320 | 1 | $this->currency($data[1]); |
|
321 | 1 | $this->display_currency($data[2]); |
|
322 | 1 | $this->ceil_on_convert($data[3]); |
|
323 | 1 | $this->monetary(Monetary::instance()); |
|
324 | 1 | } |
|
325 | } |
||
326 |
This check looks for assignments to scalar types that may be of the wrong type.
To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.