Completed
Push — master ( b8e0a3...862faf )
by z38
02:27
created

Money   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 97.14%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 0
dl 0
loc 140
ccs 34
cts 35
cp 0.9714
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
getCurrency() 0 1 ?
getDecimals() 0 1 ?
A __construct() 0 4 2
A format() 0 13 3
A getAmount() 0 4 1
A plus() 0 8 2
A minus() 0 8 2
A compareTo() 0 14 4
A equals() 0 12 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 3
    public function __construct($cents)
21
    {
22 3
        $this->cents = is_int($cents) ? $cents : intval(round($cents));
23 3
    }
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 3
            $minor = abs($this->cents) % $base;
50 3
            $major = (abs($this->cents) - $minor) / $base;
51
52 3
            return sprintf('%s%d.%0'.$this->getDecimals().'d', $sign, $major, $minor);
53
        } else {
54 1
            return sprintf('%d', $this->cents);
55
        }
56
    }
57
58
    /**
59
     * Returns the amount of money in cents
60
     *
61
     * @return int The amount in cents
62
     */
63 3
    public function getAmount()
64
    {
65 3
        return $this->cents;
66
    }
67
68
    /**
69
     * Returns the sum of this and an other amount of money
70
     *
71
     * @param Money $addend The addend
72
     *
73
     * @return Money The sum
74
     *
75
     * @throws \InvalidArgumentException When the currencies do not match
76
     */
77 5
    public function plus(self $addend)
78
    {
79 5
        if ($this->getCurrency() !== $addend->getCurrency()) {
80 1
            throw new \InvalidArgumentException('Can not add different currencies');
81
        }
82
83 4
        return new static($this->cents + $addend->getAmount());
84
    }
85
86
    /**
87
     * Returns the subtraction of this and an other amount of money
88
     *
89
     * @param Money $subtrahend The subtrahend
90
     *
91
     * @return Money The difference
92
     *
93
     * @throws \InvalidArgumentException When the currencies do not match
94
     */
95 5
    public function minus(self $subtrahend)
96
    {
97 5
        if ($this->getCurrency() !== $subtrahend->getCurrency()) {
98 1
            throw new \InvalidArgumentException('Can not subtract different currencies');
99
        }
100
101 4
        return new static($this->cents - $subtrahend->getAmount());
102
    }
103
104
    /**
105
     * Compares this instance with an other instance.
106
     *
107
     * @param Money $b The instance to which this instance is to be compared.
108
     *
109
     * @return int -1, 0 or 1 as this instance is less than, equal to, or greater than $b
110
     *
111
     * @throws \InvalidArgumentException When the currencies do not match
112
     */
113 4
    public function compareTo(self $b)
114
    {
115 4
        if ($this->getCurrency() !== $b->getCurrency()) {
116
            throw new \InvalidArgumentException('Can not compare different currencies');
117
        }
118
119 4
        if ($this->getAmount() < $b->getAmount()) {
120 1
            return -1;
121 3
        } elseif ($this->getAmount() == $b->getAmount()) {
122 1
            return 0;
123
        } else {
124 2
            return 1;
125
        }
126
    }
127
128
    /**
129
     * Returns true if the argument contains the same amount and the same currency.
130
     *
131
     * @param object $obj
132
     *
133
     * @return bool True if $obj is equal to this instance
134
     */
135 1
    public function equals($obj)
136
    {
137 1
        if (!($obj instanceof self)) {
138 1
            return false;
139
        }
140
141 1
        if ($this->getCurrency() !== $obj->getCurrency()) {
142 1
            return false;
143
        }
144
145 1
        return ($this->getAmount() == $obj->getAmount());
146
    }
147
}
148