PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / currency / currency.php
vikappointments / site / helpers / libraries / currency Last commit date
converter 4 days ago helper 4 days ago converter.php 4 days ago currency.php 4 days ago index.html 4 days ago
currency.php
414 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * Currency class handler.
16 *
17 * @since 1.7
18 */
19 class VAPCurrency
20 {
21 /**
22 * The currency code (see ISO 4217).
23 *
24 * @var string
25 */
26 private $code;
27
28 /**
29 * The currency symbol.
30 *
31 * @var string
32 */
33 private $symbol;
34
35 /**
36 * The position of the currency symbol.
37 *
38 * @var integer
39 */
40 private $position;
41
42 /**
43 * The type of separator to use (comma or period).
44 *
45 * @var integer
46 */
47 private $separator;
48
49 /**
50 * The character to use as decimal separator.
51 *
52 * @var string
53 * @since 1.7
54 */
55 private $decimalMark;
56
57 /**
58 * The character to use as thousands separator.
59 *
60 * @var string
61 * @since 1.7
62 */
63 private $thousandsMark;
64
65 /**
66 * The number of decimal digits to use.
67 *
68 * @var integer
69 */
70 private $decimalDigits;
71
72 /**
73 * True to include a space between the symbol and the amount.
74 *
75 * @var boolean
76 */
77 private $space;
78
79 /**
80 * An optional ratio to convert the global currency with the chosen one.
81 *
82 * @var float
83 * @since 1.7.6
84 */
85 private $conversionRatio = 1.0;
86
87 /**
88 * Class constructor.
89 *
90 * @param string $code
91 * @param string $symbol
92 * @param integer $position
93 * @param mixed $separator
94 * @param integer $decimalDigits
95 */
96 public function __construct($code, $symbol, $position = self::BEFORE_POSITION, $separator = self::PERIOD_SEPARATOR, $decimalDigits = 2, $space = true, $conversionRatio = 1.0)
97 {
98 $this->setCode($code)
99 ->setSymbol($symbol)
100 ->setPosition($position)
101 ->setSeparator($separator)
102 ->setDecimalDigits($decimalDigits)
103 ->setSpace($space);
104
105 // cannot change after instantiation
106 $this->conversionRatio = abs((float) $conversionRatio);
107 }
108
109 /**
110 * Get the currency code.
111 *
112 * @return string
113 */
114 public function getCode()
115 {
116 return $this->code;
117 }
118
119 /**
120 * Set the currency code (see ISO 4217).
121 *
122 * @param string $code The code.
123 *
124 * @return self This object to support chaining.
125 */
126 public function setCode($code)
127 {
128 $this->code = strtoupper(substr($code, 0, 3));
129
130 return $this;
131 }
132
133 /**
134 * Get the currency symbol.
135 *
136 * @return string
137 */
138 public function getSymbol()
139 {
140 return $this->symbol;
141 }
142
143 /**
144 * Set the currency symbol.
145 *
146 * @param string $symbol The symbol.
147 *
148 * @return self This object to support chaining.
149 */
150 public function setSymbol($symbol)
151 {
152 $this->symbol = $symbol;
153
154 return $this;
155 }
156
157 /**
158 * Check if the symbol should be displayed before the amount.
159 *
160 * @return boolean
161 */
162 public function isSymbolBefore($pos = null)
163 {
164 $pos = $pos ? $pos : $this->position;
165
166 return abs($pos) == self::BEFORE_POSITION;
167 }
168
169 /**
170 * Check if the symbol should be displayed after the amount.
171 *
172 * @return boolean
173 */
174 public function isSymbolAfter($pos = null)
175 {
176 return $this->isSymbolBefore($pos) === false;
177 }
178
179 /**
180 * Get the position of the currency symbol.
181 *
182 * @return integer
183 */
184 public function getPosition()
185 {
186 return $this->position;
187 }
188
189 /**
190 * Set the position of the currency symbol.
191 *
192 * @param integer $position The position.
193 *
194 * @return self This object to support chaining.
195 */
196 public function setPosition($position)
197 {
198 $this->position = (int) $position;
199
200 return $this;
201 }
202
203 /**
204 * Get the decimal mark to use.
205 *
206 * @return string
207 */
208 public function getDecimalMark()
209 {
210 // check whether a custom mark was specified
211 if ($this->decimalMark && preg_match("/[.,\s]/", $this->decimalMark))
212 {
213 return $this->decimalMark;
214 }
215
216 return $this->separator == self::COMMA_SEPARATOR ? ',' : '.';
217 }
218
219 /**
220 * Get the thousands mark to use.
221 *
222 * @return string
223 */
224 public function getThousandsMark()
225 {
226 $mark = $this->separator == self::COMMA_SEPARATOR ? '.' : ',';
227
228 // check whether a custom mark was specified
229 if (!is_null($this->thousandsMark) && (empty($this->thousandsMark) || preg_match("/[.,\s]/", $this->thousandsMark)))
230 {
231 // use given separator
232 $mark = $this->thousandsMark;
233 }
234
235 $decimal = $this->getDecimalMark();
236
237 // make sure the separators are not equal
238 if ($this->thousandsMark == $decimal)
239 {
240 // use comma in case the decimal mark uses a dot and viceversa
241 $mark = $decimal == ',' ? '.' : ',';
242 }
243
244 return $mark;
245 }
246
247 /**
248 * Set the type of separator to use (comma or period).
249 *
250 * @param mixed $separator The separator.
251 *
252 * @return self This object to support chaining.
253 */
254 public function setSeparator($separator)
255 {
256 if (is_array($separator) && count($separator) == 2)
257 {
258 // set custom separators
259 $this->decimalMark = substr($separator[0], 0, 1);
260 $this->thousandsMark = substr($separator[1], 0, 1);
261 }
262 else
263 {
264 if (is_string($separator))
265 {
266 // get separator code
267 $separator = $separator == ',' ? self::COMMA_SEPARATOR : self::PERIOD_SEPARATOR;
268 }
269
270 $this->separator = (int) $separator;
271 }
272
273 return $this;
274 }
275
276 /**
277 * Get the number of decimal digits.
278 *
279 * @return integer
280 */
281 public function getDecimalDigits()
282 {
283 return $this->decimalDigits;
284 }
285
286 /**
287 * Set the number of decimal digits to use.
288 *
289 * @param integer $decimalDigits The decimal digits.
290 *
291 * @return self This object to support chaining.
292 */
293 public function setDecimalDigits($decimalDigits)
294 {
295 $this->decimalDigits = (int) $decimalDigits;
296
297 return $this;
298 }
299
300 /**
301 * Check whether the currency should use a space between the
302 * currency symbol and the amount.
303 *
304 * @return boolean
305 *
306 * @since 1.7
307 */
308 public function isSpace()
309 {
310 return $this->space;
311 }
312
313 /**
314 * Sets/unsets the space between the currency symbol and the amount.
315 *
316 * @param boolean $space True to include the space.
317 *
318 * @return self This object to support chaining.
319 *
320 * @since 1.7
321 */
322 public function setSpace($space)
323 {
324 $this->space = (bool) $space;
325
326 return $this;
327 }
328
329 /**
330 * Returns the conversion ratio used to adjust calculate the real value
331 * of the preferred currency against the default one.
332 *
333 * @return float
334 *
335 * @since 1.7.6
336 */
337 public function getConversionRate()
338 {
339 return $this->conversionRatio;
340 }
341
342 /**
343 * Convert the specified amount in a price string.
344 *
345 * @param float $amount The amount to format.
346 *
347 * @return string The formatted price.
348 */
349 public function format($amount = 0.0, array $options = array())
350 {
351 /**
352 * Divide the given amount by the registered conversion ratio.
353 *
354 * @since 1.7.6
355 */
356 $amount = ((float) $amount) / $this->conversionRatio;
357
358 $options['dec_digits'] = isset($options['dec_digits']) ? $options['dec_digits'] : $this->getDecimalDigits();
359 $options['decimal_mark'] = isset($options['decimal_mark']) ? $options['decimal_mark'] : $this->getDecimalMark();
360 $options['thousands_mark'] = isset($options['thousands_mark']) ? $options['thousands_mark'] : $this->getThousandsMark();
361 $options['symbol'] = isset($options['symbol']) ? $options['symbol'] : $this->getSymbol();
362 $options['position'] = isset($options['position']) ? $options['position'] : $this->getPosition();
363 $options['space'] = isset($options['space']) ? $options['space'] : $this->isSpace();
364 $options['no_decimal'] = isset($options['no_decimal']) ? $options['no_decimal'] : false;
365
366 if ($options['no_decimal'] && (int) $amount == $amount)
367 {
368 $options['dec_digits'] = 0;
369 }
370
371 $amount = number_format(
372 $amount,
373 $options['dec_digits'],
374 $options['decimal_mark'],
375 $options['thousands_mark']
376 );
377
378 if ($this->isSymbolBefore($options['position']))
379 {
380 return $options['symbol'] . ($options['space'] ? ' ' : '') . $amount;
381 }
382
383 return $amount . ($options['space'] ? ' ' : '') . $options['symbol'];
384 }
385
386 /**
387 * Constant to display the currency symbol after the price.
388 *
389 * @var integer
390 */
391 const AFTER_POSITION = 1;
392
393 /**
394 * Constant to display the currency symbol before the price.
395 *
396 * @var integer
397 */
398 const BEFORE_POSITION = 2;
399
400 /**
401 * Constant to use the comma (,) as decimal separator.
402 *
403 * @var integer
404 */
405 const COMMA_SEPARATOR = 1;
406
407 /**
408 * Constant to use the period (.) as decimal separator.
409 *
410 * @var integer
411 */
412 const PERIOD_SEPARATOR = 2;
413 }
414