Completed
Push — master ( 67432b...61d761 )
by z38
04:15
created

Money::format()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 5
Bugs 0 Features 2
Metric Value
c 5
b 0
f 2
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 9.4286
cc 3
eloc 7
nc 3
nop 0
crap 3
1
<?php
2
3
namespace Z38\SwissPayment\Money;
4
5
/**
6
 * Base class for all currencies
7
 */
8
abstract class Money
9
{
10
    /**
11
     * @var int
12
     */
13
    protected $cents;
14
15
    /**
16
     * Constructor
17
     *
18
     * @param int $cents Amount of money in cents
19
     */
20 2
    public function __construct($cents)
21
    {
22 2
        $this->cents = intval($cents);
23 2
    }
24
25
    /**
26
     * Gets the currency code
27
     *
28
     * @return string|null An ISO 4217 currency code or null if currency is not known
29
     */
30
    abstract public function getCurrency();
31
32
    /**
33
     * Gets the number of decimals
34
     *
35
     * @return int
36
     */
37
    abstract protected function getDecimals();
38
39
    /**
40
     * Returns a formatted string (e.g. 15.560)
41
     *
42
     * @return string The formatted value
43
     */
44 4
    public function format()
45
    {
46 4
        if ($this->getDecimals() > 0) {
47 3
            $sign = ($this->cents < 0 ? '-' : '');
48 3
            $base = pow(10, $this->getDecimals());
49
50 3
            return sprintf('%s%d.%0'.$this->getDecimals().'d', $sign, intval(abs($this->cents) / $base), abs($this->cents) % $base);
51
        } else {
52 1
            return sprintf('%d', intval($this->cents));
53
        }
54
    }
55
56
    /**
57
     * Returns the amount of money in cents
58
     *
59
     * @return int The amount in cents
60
     */
61 3
    public function getAmount()
62
    {
63 3
        return $this->cents;
64
    }
65
66
    /**
67
     * Returns the sum of this and an other amount of money
68
     *
69
     * @param Money $addend The addend
70
     *
71
     * @return Money The sum
72
     *
73
     * @throws \InvalidArgumentException When the currencies do not match
74
     */
75 5
    public function plus(Money $addend)
76
    {
77 5
        if ($this->getCurrency() !== $addend->getCurrency()) {
78 1
            throw new \InvalidArgumentException('Can not add different currencies');
79
        }
80
81 4
        return new static($this->cents + $addend->getAmount());
82
    }
83
84
    /**
85
     * Returns the subtraction of this and an other amount of money
86
     *
87
     * @param Money $subtrahend The subtrahend
88
     *
89
     * @return Money The difference
90
     *
91
     * @throws \InvalidArgumentException When the currencies do not match
92
     */
93 5
    public function minus(Money $subtrahend)
94
    {
95 5
        if ($this->getCurrency() !== $subtrahend->getCurrency()) {
96 1
            throw new \InvalidArgumentException('Can not subtract different currencies');
97
        }
98
99 4
        return new static($this->cents - $subtrahend->getAmount());
100
    }
101
102
    /**
103
     * Compares this instance with an other instance.
104
     *
105
     * @param Money $b The instance to which this instance is to be compared.
106
     *
107
     * @return int -1, 0 or 1 as this instance is less than, equal to, or greater than $b
108
     *
109
     * @throws \InvalidArgumentException When the currencies do not match
110
     */
111 4
    public function compareTo(Money $b)
112
    {
113 4
        if ($this->getCurrency() !== $b->getCurrency()) {
114
            throw new \InvalidArgumentException('Can not compare different currencies');
115
        }
116
117 4
        if ($this->getAmount() < $b->getAmount()) {
118 1
            return -1;
119 3
        } elseif ($this->getAmount() == $b->getAmount()) {
120 1
            return 0;
121
        } else {
122 2
            return 1;
123
        }
124
    }
125
126
    /**
127
     * Returns true if the argument contains the same amount and the same currency.
128
     *
129
     * @param object $obj
130
     *
131
     * @return bool True if $obj is equal to this instance
132
     */
133 1
    public function equals($obj)
134
    {
135 1
        if (!($obj instanceof self)) {
136 1
            return false;
137
        }
138
139 1
        if ($this->getCurrency() !== $obj->getCurrency()) {
140 1
            return false;
141
        }
142
143 1
        return ($this->getAmount() == $obj->getAmount());
144
    }
145
}
146