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