-
-
Notifications
You must be signed in to change notification settings - Fork 188
/
CurrencyViewHelper.php
executable file
·159 lines (149 loc) · 5.92 KB
/
CurrencyViewHelper.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php
namespace Neos\FluidAdaptor\ViewHelpers\Format;
/*
* This file is part of the Neos.FluidAdaptor package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/
use Neos\Flow\Annotations as Flow;
use Neos\Flow\I18n\Cldr\Reader\NumbersReader;
use Neos\Flow\I18n\Exception as I18nException;
use Neos\Flow\I18n\Formatter\NumberFormatter;
use Neos\FluidAdaptor\Core\ViewHelper\AbstractLocaleAwareViewHelper;
use Neos\FluidAdaptor\Core\ViewHelper\Exception\InvalidVariableException;
use Neos\FluidAdaptor\Core\ViewHelper\Exception as ViewHelperException;
/**
* Formats a given float to a currency representation.
*
* = Examples =
*
* <code title="Defaults">
* <f:format.currency>123.456</f:format.currency>
* </code>
* <output>
* 123,46
* </output>
*
* <code title="All parameters">
* <f:format.currency currencySign="$" decimalSeparator="." thousandsSeparator="," prependCurrency="false", separateCurrency="true", decimals="2">54321</f:format.currency>
* </code>
* <output>
* 54,321.00 $
* </output>
*
* <code title="Inline notation">
* {someNumber -> f:format.currency(thousandsSeparator: ',', currencySign: '€')}
* </code>
* <output>
* 54,321,00 €
* (depending on the value of {someNumber})
* </output>
*
* <code title="Inline notation with current locale used">
* {someNumber -> f:format.currency(currencySign: '€', forceLocale: true)}
* </code>
* <output>
* 54.321,00 €
* (depending on the value of {someNumber} and the current locale)
* </output>
*
* <code title="Inline notation with specific locale used">
* {someNumber -> f:format.currency(currencySign: 'EUR', forceLocale: 'de_DE')}
* </code>
* <output>
* 54.321,00 EUR
* (depending on the value of {someNumber})
* </output>
*
* <code title="Inline notation with different position for the currency sign">
* {someNumber -> f:format.currency(currencySign: '€', prependCurrency: 'true')}
* </code>
* <output>
* € 54.321,00
* (depending on the value of {someNumber})
* </output>
*
* <code title="Inline notation with no space between the currency and no decimal places">
* {someNumber -> f:format.currency(currencySign: '€', separateCurrency: 'false', decimals: '0')}
* </code>
* <output>
* 54.321€
* (depending on the value of {someNumber})
* </output>
*
* Note: This ViewHelper is intended to help you with formatting numbers into monetary units.
* Complex calculations and/or conversions should be done before the number is passed.
*
* Also be aware that if the ``locale`` is set, all arguments except for the currency sign (which
* then becomes mandatory) are ignored and the CLDR (Common Locale Data Repository) is used for formatting.
* Fore more information about localization see section ``Internationalization & Localization Framework`` in the
* Flow documentation.
*
* Additionally, if ``currencyCode`` is set, rounding and decimal digits are replaced by the rules for the
* respective currency (e.g. JPY never has decimal digits, CHF is rounded using 5 decimals.)
*
* @api
*/
class CurrencyViewHelper extends AbstractLocaleAwareViewHelper
{
/**
* @Flow\Inject
* @var NumberFormatter
*/
protected $numberFormatter;
/**
* Initialize the arguments.
*
* @return void
* @api
*/
public function initializeArguments()
{
$this->registerArgument('currencySign', 'string', '(optional) The currency sign, eg $ or €.', false, '');
$this->registerArgument('decimalSeparator', 'string', '(optional) The separator for the decimal point.', false, ',');
$this->registerArgument('thousandsSeparator', 'string', '(optional) The thousands separator.', false, '.');
$this->registerArgument('prependCurrency', 'boolean', '(optional) Indicates if currency symbol should be placed before or after the numeric value.', false, false);
$this->registerArgument('separateCurrency', 'boolean', '(optional) Indicates if a space character should be placed between the number and the currency sign.', false, true);
$this->registerArgument('decimals', 'integer', '(optional) The number of decimal places.', false, 2);
$this->registerArgument('currencyCode', 'string', '(optional) The ISO 4217 currency code of the currency to format. Used to set decimal places and rounding.', false, null);
}
/**
*
* @throws InvalidVariableException
* @return string the formatted amount.
* @throws ViewHelperException
* @api
*/
public function render()
{
$stringToFormat = $this->renderChildren();
$currencySign = $this->arguments['currencySign'];
$separateCurrency = $this->arguments['separateCurrency'];
$useLocale = $this->getLocale();
if ($useLocale !== null) {
if ($currencySign === '') {
throw new InvalidVariableException('Using the Locale requires a currencySign.', 1326378320);
}
try {
$output = $this->numberFormatter->formatCurrencyNumber($stringToFormat, $useLocale, $currencySign, NumbersReader::FORMAT_LENGTH_DEFAULT, $this->arguments['currencyCode']);
} catch (I18nException $exception) {
throw new ViewHelperException($exception->getMessage(), 1382350428, $exception);
}
return $output;
}
$output = number_format((float)$stringToFormat, $this->arguments['decimals'], $this->arguments['decimalSeparator'], $this->arguments['thousandsSeparator']);
if (empty($currencySign)) {
return $output;
}
if ($this->arguments['prependCurrency'] === true) {
$output = $currencySign . ($separateCurrency === true ? ' ' : '') . $output;
return $output;
}
$output .= ($separateCurrency === true ? ' ' : '') . $currencySign;
return $output;
}
}