1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Moip\Helper; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Class Utils. |
7
|
|
|
*/ |
8
|
|
|
class Utils |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* convert a money amount (represented by a float or string (based on locale) ie.: R$ 5,00) to cents (represented by an int). |
12
|
|
|
* |
13
|
|
|
* @param float $amount |
14
|
|
|
* |
15
|
|
|
* @throws \UnexpectedValueException |
16
|
|
|
* |
17
|
|
|
* @return int |
18
|
|
|
*/ |
19
|
|
|
public static function toCents($amount) |
20
|
|
|
{ |
21
|
|
|
/* |
22
|
|
|
* There's probably a better way, but this is what i could come up with |
23
|
|
|
* to avoid rounding errors |
24
|
|
|
* todo: search for a better way |
25
|
|
|
*/ |
26
|
|
|
|
27
|
|
|
if (!is_float($amount)) { |
28
|
|
|
$type = gettype($amount); |
29
|
|
|
|
30
|
|
|
throw new \UnexpectedValueException("Needs a float! not $type"); |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
//handle locales |
34
|
|
|
$locale = localeconv(); |
35
|
|
|
|
36
|
|
|
$amount = str_replace($locale['mon_thousands_sep'], '', $amount); |
37
|
|
|
$amount = str_replace($locale['mon_decimal_point'], '.', $amount); |
38
|
|
|
$amount = str_replace($locale['decimal_point'], '.', $amount); |
39
|
|
|
|
40
|
|
|
$parts = explode('.', "$amount"); |
41
|
|
|
|
42
|
|
|
// handle the case where $amount has a .0 fraction part |
43
|
|
|
if (count($parts) == 1) { |
44
|
|
|
$parts[] = '00'; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
list($whole, $fraction) = $parts; |
48
|
|
|
|
49
|
|
|
/* |
50
|
|
|
* since the documentation only mentions decimals with a precision of two |
51
|
|
|
* and doesn't specify any rounding method i'm truncating the number |
52
|
|
|
* |
53
|
|
|
* the str_pad is to handle the case where $amount is, for example, 6.9 |
54
|
|
|
*/ |
55
|
|
|
$fraction = str_pad(substr($fraction, 0, 2), 2, '0'); |
56
|
|
|
|
57
|
|
|
$whole = (int) $whole * 100; |
58
|
|
|
$fraction = (int) $fraction; |
59
|
|
|
|
60
|
|
|
return $whole + $fraction; |
61
|
|
|
} |
62
|
|
|
} |
63
|
|
|
|