Test Failed
Push — develop ( 351362...f1cb30 )
by Remco
03:55
created

Money::get_calculator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 6
ccs 2
cts 2
cp 1
crap 2
rs 10
1
<?php
2
/**
3
 * Money
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2021 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Money
9
 */
10
11
namespace Pronamic\WordPress\Money;
12
13
use JsonSerializable;
14
use Pronamic\WordPress\Number\Number;
15
16
/**
17
 * Money
18
 *
19
 * @author Remco Tolsma
20
 * @version 1.2.5
21
 * @since   1.0.0
22
 */
23
class Money implements JsonSerializable {
24
	/**
25
	 * Number.
26
	 *
27
	 * @var Number
28
	 */
29
	private $amount;
30
31
	/**
32
	 * Currency.
33
	 *
34
	 * @var Currency
35
	 */
36
	private $currency;
37
38
	/**
39
	 * Construct and initialize money object.
40
	 *
41
	 * @param mixed           $value    Amount value.
42
	 * @param Currency|string $currency Currency.
43
	 */
44
	public function __construct( $value = 0, $currency = 'EUR' ) {
45
		$this->set_value( $value );
46
		$this->set_currency( $currency );
47
	}
48
49
	/**
50
	 * Get default format.
51
	 *
52
	 * @return string
53
	 */
54
	public static function get_default_format() {
55
		/* translators: 1: currency symbol, 2: amount value, 3: currency code, note: use non-breaking space! */
56
		$format = _x( '%1$s%2$s %3$s', 'money format', 'pronamic-money' );
57
		// Note:               ↳ Non-breaking space.
58
		$format = apply_filters( 'pronamic_money_default_format', $format );
59
60
		return $format;
61 95
	}
62 95
63 95
	/**
64 95
	 * Format i18n.
65
	 *
66
	 * @param string|null $format Format.
67
	 *
68
	 * @return string
69
	 */
70
	public function format_i18n( $format = null ) {
71 17
		if ( is_null( $format ) ) {
72
			$format = self::get_default_format();
73 17
		}
74
75 17
		$alphabetic_code = $this->currency->get_alphabetic_code();
76
77 17
		if ( ! empty( $alphabetic_code ) ) {
78
			$number_decimals = $this->currency->get_number_decimals();
79
80
			// Handle non trailing zero formatter.
81
			if ( false !== strpos( $format, '%2$NTZ' ) ) {
82
				$decimals = substr( $this->format(), ( - 1 * $number_decimals ), $number_decimals );
83
84
				if ( 0 === (int) $decimals ) {
85
					$number_decimals = 0;
86
				}
87 14
88 14
				$format = str_replace( '%2$NTZ', '%2$s', $format );
89 7
			}
90
91
			return sprintf(
92 14
				$format,
93
				(string) $this->currency->get_symbol(),
94 14
				$this->amount->format_i18n( $number_decimals ),
95 14
				strval( $alphabetic_code )
96
			);
97
		}
98 14
99 7
		return $this->amount->format_i18n( 2 );
100
	}
101 7
102 5
	/**
103
	 * Format i18n without trailing zeros.
104
	 *
105 7
	 * @param string|null $format Format.
106
	 *
107
	 * @return string
108 14
	 */
109 14
	public function format_i18n_non_trailing_zeros( $format = null ) {
110 14
		if ( is_null( $format ) ) {
111 14
			$format = self::get_default_format();
112 14
		}
113
114
		$format = str_replace( '%2$s', '%2$NTZ', $format );
115
116
		return $this->format_i18n( $format );
117
	}
118
119
	/**
120
	 * Format.
121
	 *
122
	 * @param string|null $format Format.
123
	 *
124
	 * @return string
125
	 */
126 7
	public function format( $format = null ) {
127 7
		if ( is_null( $format ) ) {
128 7
			$format = '%2$s';
129
		}
130
131 7
		$alphabetic_code = $this->currency->get_alphabetic_code();
132
133 7
		if ( ! empty( $alphabetic_code ) ) {
134
			return sprintf(
135
				$format,
136
				(string) $this->currency->get_symbol(),
137
				$this->amount->format_i18n( $this->get_currency()->get_number_decimals() ),
138
				strval( $alphabetic_code )
139
			);
140
		}
141
142
		return $this->amount->format( 2 );
143 7
	}
144 7
145 7
	/**
146
	 * Get value.
147
	 *
148 7
	 * @return string Amount value.
149
	 */
150 7
	public function get_value() {
151 7
		return $this->amount->get_value();
152 7
	}
153 7
154 7
	/**
155 7
	 * Get number.
156
	 *
157
	 * @return Number
158
	 */
159
	public function get_number() {
160
		return $this->amount;
161
	}
162
163
	/**
164
	 * Get amount.
165
	 *
166
	 * @deprecated 1.2.0
167 95
	 * @return string Amount value.
168 95
	 */
169
	public function get_amount() {
170
		_deprecated_function( __METHOD__, '1.2.0', 'Money::get_value()' );
171
172
		return $this->get_value();
173
	}
174
175
	/**
176
	 * Get cents.
177
	 *
178
	 * @return float
179
	 *
180
	 * @deprecated 1.2.2 Use `Money::get_minor_units()` instead.
181
	 */
182
	public function get_cents() {
183
		return (float) $this->get_minor_units();
184
	}
185
186
	/**
187
	 * Get amount in minor units.
188
	 *
189
	 * Examples for value 10:
190 1
	 *   JPY 0 decimals: 10
191 1
	 *   EUR 2 decimals: 1000
192
	 *   BHD 3 decimals: 10000
193
	 *   NLG 4 decimals: 100000
194
	 *
195
	 * @since 1.2.1
196
	 *
197
	 * @return int
198
	 */
199
	public function get_minor_units() {
200
		$minor_units = $this->amount->multiply( Number::from_mixed( \pow( 10, $this->currency->get_number_decimals() ) ) );
201
202
		return (int) $minor_units->get_value();
203
	}
204
205
	/**
206
	 * Set value.
207 21
	 *
208 21
	 * @param mixed $value Amount value.
209
	 * @return void
210
	 */
211 21
	final public function set_value( $value ) {
212
		$this->amount = Number::from_mixed( $value );
213 21
	}
214
215 21
	/**
216
	 * Set amount.
217
	 *
218
	 * @deprecated 1.2.0
219
	 * @param mixed $value Amount value.
220
	 * @return void
221
	 */
222
	public function set_amount( $value ) {
223
		_deprecated_function( __METHOD__, '1.2.0', 'Money::set_value()' );
224 95
225 95
		$this->set_value( $value );
226 95
	}
227
228
	/**
229
	 * Get currency.
230
	 *
231
	 * @return Currency
232
	 */
233
	public function get_currency() {
234
		return $this->currency;
235
	}
236
237
	/**
238
	 * Set currency.
239
	 *
240
	 * @param string|Currency $currency Currency.
241
	 * @return void
242
	 */
243
	final public function set_currency( $currency ) {
244
		if ( $currency instanceof Currency ) {
245
			$this->currency = $currency;
246 7
247 7
			return;
248
		}
249
250
		$this->currency = Currency::get_instance( $currency );
251
	}
252
253
	/**
254
	 * Create a string representation of this money object.
255
	 *
256 95
	 * @return string
257 95
	 */
258
	public function __toString() {
259
		return $this->format_i18n();
260
	}
261
262
	/**
263 95
	 * JSON serialize.
264 95
	 *
265
	 * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php
266
	 * @return object
267
	 */
268
	public function jsonSerialize() {
269
		$properties = array(
270
			'value' => $this->amount->get_value(),
271
		);
272
273
		if ( null !== $this->currency ) {
274
			$properties['currency'] = $this->currency->jsonSerialize();
275
		}
276
277
		$object = (object) $properties;
278
279
		return $object;
280
	}
281
282
	/**
283 1
	 * Returns a new Money object that represents
284 1
	 * the sum of this and an other Money object.
285
	 *
286 1
	 * @param Money $addend Addend.
287
	 *
288
	 * @return Money
289 1
	 */
290 1
	public function add( Money $addend ) {
291
		$result = $this->amount->add( $addend->get_number() );
292 1
293
		return new self( $result, $this->currency );
294 1
	}
295
296 1
	/**
297
	 * Returns a new Money object that represents
298 1
	 * the difference of this and an other Money object.
299
	 *
300
	 * @link https://github.com/moneyphp/money/blob/v3.2.1/src/Money.php#L235-L255
301
	 *
302
	 * @param Money $subtrahend Subtrahend.
303
	 *
304
	 * @return Money
305
	 */
306
	public function subtract( Money $subtrahend ) {
307
		$result = $this->amount->subtract( $subtrahend->get_number() );
308
309
		return new self( $result, $this->currency );
310
	}
311
312
	/**
313
	 * Returns a new Money object that represents
314
	 * the multiplied value of this Money object.
315
	 *
316
	 * @link https://github.com/moneyphp/money/blob/v3.2.1/src/Money.php#L299-L316
317
	 *
318
	 * @param mixed $multiplier Multiplier.
319
	 *
320
	 * @return Money
321
	 */
322
	public function multiply( $multiplier ) {
323
		$multiplier = Number::from_mixed( $multiplier );
324
325
		$result = $this->amount->multiply( $multiplier );
326
327
		return new self( $result, $this->currency );
328
	}
329
330
	/**
331
	 * Returns a new Money object that represents
332
	 * the divided value of this Money object.
333
	 *
334
	 * @link https://github.com/moneyphp/money/blob/v3.2.1/src/Money.php#L318-L341
335
	 *
336
	 * @param mixed $divisor Divisor.
337
	 *
338
	 * @return Money
339
	 */
340
	public function divide( $divisor ) {
341
		$divisor = Number::from_mixed( $divisor );
342
343
		$result = $this->amount->divide( $divisor );
344
345
		return new self( $result, $this->currency );
346
	}
347
348
	/**
349
	 * Absolute.
350
	 *
351
	 * @link https://github.com/moneyphp/money/blob/v4.0.1/src/Money.php#L411-L417
352
	 * @return Money
353
	 */
354
	public function absolute() {
355
		return new self(
356
			$this->amount->absolute(),
357
			$this->currency
358
		);
359
	}
360
}
361