Completed
Branch FET-10619-money-entity (f30b90)
by
unknown
141:01 queued 130:50
created
core/entities/money/Money.php 2 patches
Indentation   +312 added lines, -312 removed lines patch added patch discarded remove patch
@@ -22,318 +22,318 @@
 block discarded – undo
22 22
 class Money
23 23
 {
24 24
 
25
-    /**
26
-     * number of decimal places to be added to currencies for internal computations,
27
-     * but removed before any output or formatting is applied.
28
-     * This allows us to avoid rounding errors during calculations.
29
-     */
30
-    const EXTRA_PRECISION = 3;
31
-
32
-    /**
33
-     * @var int $amount
34
-     */
35
-    private $amount;
36
-
37
-    /**
38
-     * @var Currency $currency
39
-     */
40
-    private $currency;
41
-
42
-    /**
43
-     * @var Calculator $calculator
44
-     */
45
-    protected $calculator;
46
-
47
-    /**
48
-     * @var MoneyFormatter[] $formatters
49
-     */
50
-    protected $formatters;
51
-
52
-
53
-
54
-    /**
55
-     * Money constructor.
56
-     *
57
-     * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
58
-     *                                 example: $12.5 USD would equate to a value amount of 12.50
59
-     * @param Currency         $currency
60
-     * @param Calculator       $calculator
61
-     * @param MoneyFormatter[] $formatters
62
-     * @throws InvalidDataTypeException
63
-     */
64
-    public function __construct($amount, Currency $currency, Calculator $calculator, array $formatters)
65
-    {
66
-        $this->currency = $currency;
67
-        $this->amount = (string)$this->parseAmount($amount);
68
-        $this->calculator = $calculator;
69
-        $this->formatters = $formatters;
70
-    }
71
-
72
-
73
-
74
-    /**
75
-     * @return Calculator
76
-     */
77
-    protected function calculator()
78
-    {
79
-        return $this->calculator;
80
-    }
81
-
82
-
83
-
84
-    /**
85
-     * @return MoneyFormatter[]
86
-     */
87
-    protected function formatters()
88
-    {
89
-        return $this->formatters;
90
-    }
91
-
92
-
93
-
94
-    /**
95
-     * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
96
-     *                                 example: $12.5 USD would equate to a value amount of 12.50
97
-     * @return float|int|number|string
98
-     * @throws InvalidDataTypeException
99
-     */
100
-    private function parseAmount($amount)
101
-    {
102
-        $type = gettype($amount);
103
-        switch ($type) {
104
-            case 'integer' :
105
-            case 'double' :
106
-            case 'string' :
107
-            break;
108
-            default  :
109
-                throw new InvalidDataTypeException(
110
-                    '$amount',
111
-                    $amount,
112
-                    'integer (or float or string)'
113
-                );
114
-        }
115
-        if ($this->currency->decimalMark() !== '.') {
116
-            // remove thousands separator and replace decimal place with standard decimal.
117
-            $amount = str_replace(
118
-                array(
119
-                    $this->currency->thousands(),
120
-                    $this->currency->decimalMark()
121
-                ),
122
-                array(
123
-                    '',
124
-                    '.'
125
-                ),
126
-                $amount
127
-            );
128
-        }
129
-        // remove any non numeric values but leave the decimal
130
-        $amount = (float)preg_replace('/([^0-9\\.])/i', '', $amount);
131
-        // shift the decimal position by the number of decimal places used internally
132
-        // ex: 12.5 for a currency using 2 decimal places, would become 1250
133
-        // then if our extra internal precision was 3, it would become 1250000
134
-        $amount *= pow(10, $this->precision());
135
-        // then round up the remaining value if there is still a fractional amount left
136
-        $amount = round($amount, 0, PHP_ROUND_HALF_UP);
137
-        return $amount;
138
-    }
139
-
140
-
141
-
142
-    /**
143
-     * adds or subtracts additional decimal places based on the value of the Money::EXTRA_PRECISION constant
144
-     *
145
-     * @param bool $positive
146
-     * @return int
147
-     */
148
-    private function precision($positive = true)
149
-    {
150
-        $sign = $positive ? 1 : -1;
151
-        return ((int)$this->currency->decimalPlaces() + Money::EXTRA_PRECISION) * $sign;
152
-    }
153
-
154
-
155
-
156
-    /**
157
-     * Returns the money amount as an unformatted string
158
-     * IF YOU REQUIRE A FORMATTED STRING, THEN USE Money::format()
159
-     *
160
-     * @return string
161
-     */
162
-    public function amount()
163
-    {
164
-        // shift the decimal position BACK by the number of decimal places used internally
165
-        // ex: 1250 for a currency using 2 decimal places, would become 12.5
166
-        $amount = (string)$this->amount * pow(10, $this->precision(false));
167
-        // then shave off our extra internal precision using the number of decimal places for the currency
168
-        $amount = round($amount, $this->currency->decimalPlaces());
169
-        return $amount;
170
-    }
171
-
172
-
173
-
174
-    /**
175
-     * applies formatting based on the specified formatting level
176
-     * corresponding to one of the constants on \EventEspresso\core\services\currency\MoneyFormatter
177
-     *
178
-     * @param int $formatting_level
179
-     * @return string
180
-     */
181
-    public function format($formatting_level = MoneyFormatter::ADD_THOUSANDS)
182
-    {
183
-        $formatted_amount = $this->amount();
184
-        $formatters = $this->formatters();
185
-        // if we are applying thousands formatting...
186
-        if ($formatting_level >= MoneyFormatter::ADD_THOUSANDS) {
187
-            // then let's remove decimal formatting since it's included in thousands formatting
188
-            unset($formatters[MoneyFormatter::DECIMAL_ONLY]);
189
-        }
190
-        for ($x = 1; $x <= $formatting_level; $x++) {
191
-            if (isset($formatters[$x]) && $formatters[$x] instanceof MoneyFormatter) {
192
-                $formatted_amount = $formatters[$x]->format($formatted_amount, $this->currency);
193
-            }
194
-        }
195
-        return $formatted_amount;
196
-    }
197
-
198
-
199
-
200
-    /**
201
-     * Returns the Currency object for this money
202
-     *
203
-     * @return Currency
204
-     */
205
-    public function currency()
206
-    {
207
-        return $this->currency;
208
-    }
209
-
210
-
211
-
212
-    /**
213
-     * adds the supplied Money amount to this Money amount
214
-     * and returns a new Money object
215
-     *
216
-     * @param Money $other
217
-     * @return Money
218
-     * @throws InvalidArgumentException
219
-     */
220
-    public function add(Money $other)
221
-    {
222
-        $this->verifySameCurrency($other->currency());
223
-        return new Money(
224
-            $this->calculator()->add(
225
-                $this->amount(),
226
-                $other->amount()
227
-            ),
228
-            $this->currency(),
229
-            $this->calculator(),
230
-            $this->formatters()
231
-        );
232
-    }
233
-
234
-
235
-
236
-    /**
237
-     * subtracts the supplied Money amount from this Money amount
238
-     * and returns a new Money object
239
-     *
240
-     * @param Money $other
241
-     * @return Money
242
-     * @throws InvalidArgumentException
243
-     */
244
-    public function subtract(Money $other)
245
-    {
246
-        $this->verifySameCurrency($other->currency());
247
-        return new Money(
248
-            $this->calculator()->subtract(
249
-                $this->amount(),
250
-                $other->amount()
251
-            ),
252
-            $this->currency(),
253
-            $this->calculator(),
254
-            $this->formatters()
255
-        );
256
-    }
257
-
258
-
259
-
260
-    /**
261
-     * multiplies this Money amount by the supplied $multiplier
262
-     * and returns a new Money object
263
-     *
264
-     * @param float|int|string $multiplier
265
-     * @param int              $rounding_mode
266
-     * @return Money
267
-     * @throws InvalidDataTypeException
268
-     */
269
-    public function multiply($multiplier, $rounding_mode = Calculator::ROUND_HALF_UP)
270
-    {
271
-        return new Money(
272
-            $this->calculator()->multiply(
273
-                $this->amount(),
274
-                $multiplier,
275
-                $this->precision(),
276
-                $rounding_mode
277
-            ),
278
-            $this->currency(),
279
-            $this->calculator(),
280
-            $this->formatters()
281
-        );
282
-    }
283
-
284
-
285
-
286
-    /**
287
-     * divides this Money amount by the supplied $divisor
288
-     * and returns a new Money object
289
-     *
290
-     * @param float|int|string $divisor
291
-     * @param int              $rounding_mode
292
-     * @return Money
293
-     * @throws InvalidDataTypeException
294
-     */
295
-    public function divide($divisor, $rounding_mode = Calculator::ROUND_HALF_UP)
296
-    {
297
-        return new Money(
298
-            $this->calculator()->divide(
299
-                $this->amount(),
300
-                $divisor,
301
-                $this->precision(),
302
-                $rounding_mode
303
-            ),
304
-            $this->currency(),
305
-            $this->calculator(),
306
-            $this->formatters()
307
-        );
308
-    }
309
-
310
-
311
-
312
-    /**
313
-     * @param Currency $other_currency
314
-     * @throws InvalidArgumentException
315
-     */
316
-    public function verifySameCurrency(Currency $other_currency)
317
-    {
318
-        if ($this->currency()->equals($other_currency) !== true) {
319
-            throw new InvalidArgumentException(
320
-                esc_html__(
321
-                    'Currencies must be the same in order to add or subtract their values.',
322
-                    'event_espresso'
323
-                )
324
-            );
325
-        }
326
-    }
327
-
328
-
329
-
330
-    /**
331
-     * @return string
332
-     */
333
-    public function __toString()
334
-    {
335
-        return $this->format(MoneyFormatter::DECIMAL_ONLY);
336
-    }
25
+	/**
26
+	 * number of decimal places to be added to currencies for internal computations,
27
+	 * but removed before any output or formatting is applied.
28
+	 * This allows us to avoid rounding errors during calculations.
29
+	 */
30
+	const EXTRA_PRECISION = 3;
31
+
32
+	/**
33
+	 * @var int $amount
34
+	 */
35
+	private $amount;
36
+
37
+	/**
38
+	 * @var Currency $currency
39
+	 */
40
+	private $currency;
41
+
42
+	/**
43
+	 * @var Calculator $calculator
44
+	 */
45
+	protected $calculator;
46
+
47
+	/**
48
+	 * @var MoneyFormatter[] $formatters
49
+	 */
50
+	protected $formatters;
51
+
52
+
53
+
54
+	/**
55
+	 * Money constructor.
56
+	 *
57
+	 * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
58
+	 *                                 example: $12.5 USD would equate to a value amount of 12.50
59
+	 * @param Currency         $currency
60
+	 * @param Calculator       $calculator
61
+	 * @param MoneyFormatter[] $formatters
62
+	 * @throws InvalidDataTypeException
63
+	 */
64
+	public function __construct($amount, Currency $currency, Calculator $calculator, array $formatters)
65
+	{
66
+		$this->currency = $currency;
67
+		$this->amount = (string)$this->parseAmount($amount);
68
+		$this->calculator = $calculator;
69
+		$this->formatters = $formatters;
70
+	}
71
+
72
+
73
+
74
+	/**
75
+	 * @return Calculator
76
+	 */
77
+	protected function calculator()
78
+	{
79
+		return $this->calculator;
80
+	}
81
+
82
+
83
+
84
+	/**
85
+	 * @return MoneyFormatter[]
86
+	 */
87
+	protected function formatters()
88
+	{
89
+		return $this->formatters;
90
+	}
91
+
92
+
93
+
94
+	/**
95
+	 * @param float|int|string $amount money amount IN THE STANDARD UNIT FOR THE CURRENCY ie: dollars, Euros, etc
96
+	 *                                 example: $12.5 USD would equate to a value amount of 12.50
97
+	 * @return float|int|number|string
98
+	 * @throws InvalidDataTypeException
99
+	 */
100
+	private function parseAmount($amount)
101
+	{
102
+		$type = gettype($amount);
103
+		switch ($type) {
104
+			case 'integer' :
105
+			case 'double' :
106
+			case 'string' :
107
+			break;
108
+			default  :
109
+				throw new InvalidDataTypeException(
110
+					'$amount',
111
+					$amount,
112
+					'integer (or float or string)'
113
+				);
114
+		}
115
+		if ($this->currency->decimalMark() !== '.') {
116
+			// remove thousands separator and replace decimal place with standard decimal.
117
+			$amount = str_replace(
118
+				array(
119
+					$this->currency->thousands(),
120
+					$this->currency->decimalMark()
121
+				),
122
+				array(
123
+					'',
124
+					'.'
125
+				),
126
+				$amount
127
+			);
128
+		}
129
+		// remove any non numeric values but leave the decimal
130
+		$amount = (float)preg_replace('/([^0-9\\.])/i', '', $amount);
131
+		// shift the decimal position by the number of decimal places used internally
132
+		// ex: 12.5 for a currency using 2 decimal places, would become 1250
133
+		// then if our extra internal precision was 3, it would become 1250000
134
+		$amount *= pow(10, $this->precision());
135
+		// then round up the remaining value if there is still a fractional amount left
136
+		$amount = round($amount, 0, PHP_ROUND_HALF_UP);
137
+		return $amount;
138
+	}
139
+
140
+
141
+
142
+	/**
143
+	 * adds or subtracts additional decimal places based on the value of the Money::EXTRA_PRECISION constant
144
+	 *
145
+	 * @param bool $positive
146
+	 * @return int
147
+	 */
148
+	private function precision($positive = true)
149
+	{
150
+		$sign = $positive ? 1 : -1;
151
+		return ((int)$this->currency->decimalPlaces() + Money::EXTRA_PRECISION) * $sign;
152
+	}
153
+
154
+
155
+
156
+	/**
157
+	 * Returns the money amount as an unformatted string
158
+	 * IF YOU REQUIRE A FORMATTED STRING, THEN USE Money::format()
159
+	 *
160
+	 * @return string
161
+	 */
162
+	public function amount()
163
+	{
164
+		// shift the decimal position BACK by the number of decimal places used internally
165
+		// ex: 1250 for a currency using 2 decimal places, would become 12.5
166
+		$amount = (string)$this->amount * pow(10, $this->precision(false));
167
+		// then shave off our extra internal precision using the number of decimal places for the currency
168
+		$amount = round($amount, $this->currency->decimalPlaces());
169
+		return $amount;
170
+	}
171
+
172
+
173
+
174
+	/**
175
+	 * applies formatting based on the specified formatting level
176
+	 * corresponding to one of the constants on \EventEspresso\core\services\currency\MoneyFormatter
177
+	 *
178
+	 * @param int $formatting_level
179
+	 * @return string
180
+	 */
181
+	public function format($formatting_level = MoneyFormatter::ADD_THOUSANDS)
182
+	{
183
+		$formatted_amount = $this->amount();
184
+		$formatters = $this->formatters();
185
+		// if we are applying thousands formatting...
186
+		if ($formatting_level >= MoneyFormatter::ADD_THOUSANDS) {
187
+			// then let's remove decimal formatting since it's included in thousands formatting
188
+			unset($formatters[MoneyFormatter::DECIMAL_ONLY]);
189
+		}
190
+		for ($x = 1; $x <= $formatting_level; $x++) {
191
+			if (isset($formatters[$x]) && $formatters[$x] instanceof MoneyFormatter) {
192
+				$formatted_amount = $formatters[$x]->format($formatted_amount, $this->currency);
193
+			}
194
+		}
195
+		return $formatted_amount;
196
+	}
197
+
198
+
199
+
200
+	/**
201
+	 * Returns the Currency object for this money
202
+	 *
203
+	 * @return Currency
204
+	 */
205
+	public function currency()
206
+	{
207
+		return $this->currency;
208
+	}
209
+
210
+
211
+
212
+	/**
213
+	 * adds the supplied Money amount to this Money amount
214
+	 * and returns a new Money object
215
+	 *
216
+	 * @param Money $other
217
+	 * @return Money
218
+	 * @throws InvalidArgumentException
219
+	 */
220
+	public function add(Money $other)
221
+	{
222
+		$this->verifySameCurrency($other->currency());
223
+		return new Money(
224
+			$this->calculator()->add(
225
+				$this->amount(),
226
+				$other->amount()
227
+			),
228
+			$this->currency(),
229
+			$this->calculator(),
230
+			$this->formatters()
231
+		);
232
+	}
233
+
234
+
235
+
236
+	/**
237
+	 * subtracts the supplied Money amount from this Money amount
238
+	 * and returns a new Money object
239
+	 *
240
+	 * @param Money $other
241
+	 * @return Money
242
+	 * @throws InvalidArgumentException
243
+	 */
244
+	public function subtract(Money $other)
245
+	{
246
+		$this->verifySameCurrency($other->currency());
247
+		return new Money(
248
+			$this->calculator()->subtract(
249
+				$this->amount(),
250
+				$other->amount()
251
+			),
252
+			$this->currency(),
253
+			$this->calculator(),
254
+			$this->formatters()
255
+		);
256
+	}
257
+
258
+
259
+
260
+	/**
261
+	 * multiplies this Money amount by the supplied $multiplier
262
+	 * and returns a new Money object
263
+	 *
264
+	 * @param float|int|string $multiplier
265
+	 * @param int              $rounding_mode
266
+	 * @return Money
267
+	 * @throws InvalidDataTypeException
268
+	 */
269
+	public function multiply($multiplier, $rounding_mode = Calculator::ROUND_HALF_UP)
270
+	{
271
+		return new Money(
272
+			$this->calculator()->multiply(
273
+				$this->amount(),
274
+				$multiplier,
275
+				$this->precision(),
276
+				$rounding_mode
277
+			),
278
+			$this->currency(),
279
+			$this->calculator(),
280
+			$this->formatters()
281
+		);
282
+	}
283
+
284
+
285
+
286
+	/**
287
+	 * divides this Money amount by the supplied $divisor
288
+	 * and returns a new Money object
289
+	 *
290
+	 * @param float|int|string $divisor
291
+	 * @param int              $rounding_mode
292
+	 * @return Money
293
+	 * @throws InvalidDataTypeException
294
+	 */
295
+	public function divide($divisor, $rounding_mode = Calculator::ROUND_HALF_UP)
296
+	{
297
+		return new Money(
298
+			$this->calculator()->divide(
299
+				$this->amount(),
300
+				$divisor,
301
+				$this->precision(),
302
+				$rounding_mode
303
+			),
304
+			$this->currency(),
305
+			$this->calculator(),
306
+			$this->formatters()
307
+		);
308
+	}
309
+
310
+
311
+
312
+	/**
313
+	 * @param Currency $other_currency
314
+	 * @throws InvalidArgumentException
315
+	 */
316
+	public function verifySameCurrency(Currency $other_currency)
317
+	{
318
+		if ($this->currency()->equals($other_currency) !== true) {
319
+			throw new InvalidArgumentException(
320
+				esc_html__(
321
+					'Currencies must be the same in order to add or subtract their values.',
322
+					'event_espresso'
323
+				)
324
+			);
325
+		}
326
+	}
327
+
328
+
329
+
330
+	/**
331
+	 * @return string
332
+	 */
333
+	public function __toString()
334
+	{
335
+		return $this->format(MoneyFormatter::DECIMAL_ONLY);
336
+	}
337 337
 
338 338
 
339 339
 
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
     public function __construct($amount, Currency $currency, Calculator $calculator, array $formatters)
65 65
     {
66 66
         $this->currency = $currency;
67
-        $this->amount = (string)$this->parseAmount($amount);
67
+        $this->amount = (string) $this->parseAmount($amount);
68 68
         $this->calculator = $calculator;
69 69
         $this->formatters = $formatters;
70 70
     }
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
             );
128 128
         }
129 129
         // remove any non numeric values but leave the decimal
130
-        $amount = (float)preg_replace('/([^0-9\\.])/i', '', $amount);
130
+        $amount = (float) preg_replace('/([^0-9\\.])/i', '', $amount);
131 131
         // shift the decimal position by the number of decimal places used internally
132 132
         // ex: 12.5 for a currency using 2 decimal places, would become 1250
133 133
         // then if our extra internal precision was 3, it would become 1250000
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
     private function precision($positive = true)
149 149
     {
150 150
         $sign = $positive ? 1 : -1;
151
-        return ((int)$this->currency->decimalPlaces() + Money::EXTRA_PRECISION) * $sign;
151
+        return ((int) $this->currency->decimalPlaces() + Money::EXTRA_PRECISION) * $sign;
152 152
     }
153 153
 
154 154
 
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
     {
164 164
         // shift the decimal position BACK by the number of decimal places used internally
165 165
         // ex: 1250 for a currency using 2 decimal places, would become 12.5
166
-        $amount = (string)$this->amount * pow(10, $this->precision(false));
166
+        $amount = (string) $this->amount * pow(10, $this->precision(false));
167 167
         // then shave off our extra internal precision using the number of decimal places for the currency
168 168
         $amount = round($amount, $this->currency->decimalPlaces());
169 169
         return $amount;
Please login to merge, or discard this patch.