composer package updates
[openemr.git] / vendor / zendframework / zend-i18n / src / View / Helper / CurrencyFormat.php
blob33a3ce0772a662da9d6197cfeddf880a82e68a6e
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\I18n\View\Helper;
12 use Locale;
13 use NumberFormatter;
14 use Zend\I18n\Exception;
15 use Zend\View\Helper\AbstractHelper;
17 /**
18 * View helper for formatting currency.
20 class CurrencyFormat extends AbstractHelper
22 /**
23 * The 3-letter ISO 4217 currency code indicating the currency to use
25 * @var string
27 protected $currencyCode;
29 /**
30 * Formatter instances
32 * @var array
34 protected $formatters = [];
36 /**
37 * Locale to use instead of the default
39 * @var string
41 protected $locale;
43 /**
44 * Currency pattern
46 * @var string
48 protected $currencyPattern;
50 /**
51 * If set to true, the currency will be returned with two decimals
53 * @var bool
55 protected $showDecimals = true;
57 /**
58 * Special condition to be checked due to ICU bug:
59 * http://bugs.icu-project.org/trac/ticket/10997
61 * @var bool
63 protected $correctionNeeded = false;
67 /**
68 * @throws Exception\ExtensionNotLoadedException if ext/intl is not present
70 public function __construct()
72 if (! extension_loaded('intl')) {
73 throw new Exception\ExtensionNotLoadedException(sprintf(
74 '%s component requires the intl PHP extension',
75 __NAMESPACE__
76 ));
80 /**
81 * Format a number
83 * @param float $number
84 * @param string $currencyCode
85 * @param bool $showDecimals
86 * @param string $locale
87 * @param string $pattern
88 * @return string
90 public function __invoke(
91 $number,
92 $currencyCode = null,
93 $showDecimals = null,
94 $locale = null,
95 $pattern = null
96 ) {
97 if (null === $locale) {
98 $locale = $this->getLocale();
100 if (null === $currencyCode) {
101 $currencyCode = $this->getCurrencyCode();
103 if (null === $showDecimals) {
104 $showDecimals = $this->shouldShowDecimals();
106 if (null === $pattern) {
107 $pattern = $this->getCurrencyPattern();
110 return $this->formatCurrency($number, $currencyCode, $showDecimals, $locale, $pattern);
114 * Format a number
116 * @param float $number
117 * @param string $currencyCode
118 * @param bool $showDecimals
119 * @param string $locale
120 * @param string $pattern
121 * @return string
123 protected function formatCurrency(
124 $number,
125 $currencyCode,
126 $showDecimals,
127 $locale,
128 $pattern
130 $formatterId = md5($locale);
132 if (! isset($this->formatters[$formatterId])) {
133 $this->formatters[$formatterId] = new NumberFormatter(
134 $locale,
135 NumberFormatter::CURRENCY
139 if ($pattern !== null) {
140 $this->formatters[$formatterId]->setPattern($pattern);
143 if ($showDecimals) {
144 $this->formatters[$formatterId]->setAttribute(NumberFormatter::FRACTION_DIGITS, 2);
145 $this->correctionNeeded = false;
146 } else {
147 $this->formatters[$formatterId]->setAttribute(NumberFormatter::FRACTION_DIGITS, 0);
148 $defaultCurrencyCode = $this->formatters[$formatterId]->getTextAttribute(NumberFormatter::CURRENCY_CODE);
149 $this->correctionNeeded = $defaultCurrencyCode !== $currencyCode;
152 $formattedNumber = $this->formatters[$formatterId]->formatCurrency($number, $currencyCode);
154 if ($this->correctionNeeded) {
155 $formattedNumber = $this->fixICUBugForNoDecimals(
156 $formattedNumber,
157 $this->formatters[$formatterId],
158 $locale,
159 $currencyCode
163 return $formattedNumber;
167 * The 3-letter ISO 4217 currency code indicating the currency to use
169 * @param string $currencyCode
170 * @return CurrencyFormat
172 public function setCurrencyCode($currencyCode)
174 $this->currencyCode = $currencyCode;
175 return $this;
179 * Get the 3-letter ISO 4217 currency code indicating the currency to use
181 * @return string
183 public function getCurrencyCode()
185 return $this->currencyCode;
189 * Set the currency pattern
191 * @param string $currencyPattern
192 * @return CurrencyFormat
194 public function setCurrencyPattern($currencyPattern)
196 $this->currencyPattern = $currencyPattern;
197 return $this;
201 * Get the currency pattern
203 * @return string
205 public function getCurrencyPattern()
207 return $this->currencyPattern;
211 * Set locale to use instead of the default
213 * @param string $locale
214 * @return CurrencyFormat
216 public function setLocale($locale)
218 $this->locale = (string) $locale;
219 return $this;
223 * Get the locale to use
225 * @return string|null
227 public function getLocale()
229 if ($this->locale === null) {
230 $this->locale = Locale::getDefault();
233 return $this->locale;
237 * Set if the view helper should show two decimals
239 * @param bool $showDecimals
240 * @return CurrencyFormat
242 public function setShouldShowDecimals($showDecimals)
244 $this->showDecimals = (bool) $showDecimals;
245 return $this;
249 * Get if the view helper should show two decimals
251 * @return bool
253 public function shouldShowDecimals()
255 return $this->showDecimals;
261 * @param string $formattedNumber
262 * @param NumberFormatter $formatter
263 * @param string $locale
264 * @param string $currencyCode
266 * @return string
268 private function fixICUBugForNoDecimals($formattedNumber, NumberFormatter $formatter, $locale, $currencyCode)
270 $pattern = sprintf(
271 '/\%s\d+(\s?%s)?$/u',
272 $formatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL),
273 preg_quote($this->getCurrencySymbol($locale, $currencyCode))
276 return preg_replace($pattern, '$1', $formattedNumber);
282 * @param string $locale
283 * @param string $currencyCode
285 * @return string
287 private function getCurrencySymbol($locale, $currencyCode)
289 $numberFormatter = new NumberFormatter($locale . '@currency=' . $currencyCode, NumberFormatter::CURRENCY);
291 return $numberFormatter->getSymbol(NumberFormatter::CURRENCY_SYMBOL);