/vendor/zendframework/zend-i18n/src/View/Helper/CurrencyFormat.php

https://github.com/tmccormi/openemr · PHP · 262 lines · 117 code · 32 blank · 113 comment · 10 complexity · d2e8bc10c80e32b2171d425dbec61f2b MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  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. */
  9. namespace Zend\I18n\View\Helper;
  10. use Locale;
  11. use NumberFormatter;
  12. use Zend\I18n\Exception;
  13. use Zend\View\Helper\AbstractHelper;
  14. /**
  15. * View helper for formatting currency.
  16. */
  17. class CurrencyFormat extends AbstractHelper
  18. {
  19. /**
  20. * The 3-letter ISO 4217 currency code indicating the currency to use
  21. *
  22. * @var string
  23. */
  24. protected $currencyCode;
  25. /**
  26. * Formatter instances
  27. *
  28. * @var array
  29. */
  30. protected $formatters = [];
  31. /**
  32. * Locale to use instead of the default
  33. *
  34. * @var string
  35. */
  36. protected $locale;
  37. /**
  38. * Currency pattern
  39. *
  40. * @var string
  41. */
  42. protected $currencyPattern;
  43. /**
  44. * If set to true, the currency will be returned with two decimals
  45. *
  46. * @var bool
  47. */
  48. protected $showDecimals = true;
  49. /**
  50. * Special condition to be checked due to ICU bug:
  51. * http://bugs.icu-project.org/trac/ticket/10997
  52. *
  53. * @var bool
  54. */
  55. protected $correctionNeeded = false;
  56. /**
  57. * @throws Exception\ExtensionNotLoadedException if ext/intl is not present
  58. */
  59. public function __construct()
  60. {
  61. if (! extension_loaded('intl')) {
  62. throw new Exception\ExtensionNotLoadedException(sprintf(
  63. '%s component requires the intl PHP extension',
  64. __NAMESPACE__
  65. ));
  66. }
  67. }
  68. /**
  69. * Format a number
  70. *
  71. * @param float $number
  72. * @param string $currencyCode
  73. * @param bool $showDecimals
  74. * @param string $locale
  75. * @param string $pattern
  76. * @return string
  77. */
  78. public function __invoke(
  79. $number,
  80. $currencyCode = null,
  81. $showDecimals = null,
  82. $locale = null,
  83. $pattern = null
  84. ) {
  85. if (null === $locale) {
  86. $locale = $this->getLocale();
  87. }
  88. if (null === $currencyCode) {
  89. $currencyCode = $this->getCurrencyCode();
  90. }
  91. if (null === $showDecimals) {
  92. $showDecimals = $this->shouldShowDecimals();
  93. }
  94. if (null === $pattern) {
  95. $pattern = $this->getCurrencyPattern();
  96. }
  97. return $this->formatCurrency($number, $currencyCode, $showDecimals, $locale, $pattern);
  98. }
  99. /**
  100. * Format a number
  101. *
  102. * @param float $number
  103. * @param string $currencyCode
  104. * @param bool $showDecimals
  105. * @param string $locale
  106. * @param string $pattern
  107. * @return string
  108. */
  109. protected function formatCurrency(
  110. $number,
  111. $currencyCode,
  112. $showDecimals,
  113. $locale,
  114. $pattern
  115. ) {
  116. $formatterId = md5($locale);
  117. if (! isset($this->formatters[$formatterId])) {
  118. $this->formatters[$formatterId] = new NumberFormatter(
  119. $locale,
  120. NumberFormatter::CURRENCY
  121. );
  122. }
  123. if ($pattern !== null) {
  124. $this->formatters[$formatterId]->setPattern($pattern);
  125. }
  126. if ($showDecimals) {
  127. $this->formatters[$formatterId]->setAttribute(NumberFormatter::FRACTION_DIGITS, 2);
  128. $this->correctionNeeded = false;
  129. } else {
  130. $this->formatters[$formatterId]->setAttribute(NumberFormatter::FRACTION_DIGITS, 0);
  131. $defaultCurrencyCode = $this->formatters[$formatterId]->getTextAttribute(NumberFormatter::CURRENCY_CODE);
  132. $this->correctionNeeded = $defaultCurrencyCode !== $currencyCode;
  133. }
  134. $formattedNumber = $this->formatters[$formatterId]->formatCurrency($number, $currencyCode);
  135. return $this->correctionNeeded ? $this->correctICUBug($formattedNumber, $this->formatters[$formatterId]) : $formattedNumber;
  136. }
  137. /**
  138. * The 3-letter ISO 4217 currency code indicating the currency to use
  139. *
  140. * @param string $currencyCode
  141. * @return CurrencyFormat
  142. */
  143. public function setCurrencyCode($currencyCode)
  144. {
  145. $this->currencyCode = $currencyCode;
  146. return $this;
  147. }
  148. /**
  149. * Get the 3-letter ISO 4217 currency code indicating the currency to use
  150. *
  151. * @return string
  152. */
  153. public function getCurrencyCode()
  154. {
  155. return $this->currencyCode;
  156. }
  157. /**
  158. * Set the currency pattern
  159. *
  160. * @param string $currencyPattern
  161. * @return CurrencyFormat
  162. */
  163. public function setCurrencyPattern($currencyPattern)
  164. {
  165. $this->currencyPattern = $currencyPattern;
  166. return $this;
  167. }
  168. /**
  169. * Get the currency pattern
  170. *
  171. * @return string
  172. */
  173. public function getCurrencyPattern()
  174. {
  175. return $this->currencyPattern;
  176. }
  177. /**
  178. * Set locale to use instead of the default
  179. *
  180. * @param string $locale
  181. * @return CurrencyFormat
  182. */
  183. public function setLocale($locale)
  184. {
  185. $this->locale = (string) $locale;
  186. return $this;
  187. }
  188. /**
  189. * Get the locale to use
  190. *
  191. * @return string|null
  192. */
  193. public function getLocale()
  194. {
  195. if ($this->locale === null) {
  196. $this->locale = Locale::getDefault();
  197. }
  198. return $this->locale;
  199. }
  200. /**
  201. * Set if the view helper should show two decimals
  202. *
  203. * @param bool $showDecimals
  204. * @return CurrencyFormat
  205. */
  206. public function setShouldShowDecimals($showDecimals)
  207. {
  208. $this->showDecimals = (bool) $showDecimals;
  209. return $this;
  210. }
  211. /**
  212. * Get if the view helper should show two decimals
  213. *
  214. * @return bool
  215. */
  216. public function shouldShowDecimals()
  217. {
  218. return $this->showDecimals;
  219. }
  220. /**
  221. * @param string $formattedNumber
  222. * @param NumberFormatter $formatter
  223. * @return string
  224. */
  225. private function correctICUBug($formattedNumber, NumberFormatter $formatter)
  226. {
  227. $pattern = sprintf('/\%s\d+$/', $formatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL));
  228. return preg_replace($pattern, '', $formattedNumber);
  229. }
  230. }