Completed
Push — master ( 080ba5...2a2655 )
by Fabio
13:17 queued 07:29
created

TNumberFormat   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 203
rs 10
c 0
b 0
f 0
wmc 28
lcom 2
cbo 2

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getPattern() 0 4 1
A setPattern() 0 4 1
A getValue() 0 4 1
A setValue() 0 4 1
A getDefaultText() 0 4 1
A setDefaultText() 0 4 1
A getData() 0 4 1
A setData() 0 4 1
A getType() 0 4 1
B setType() 0 23 8
A getCurrency() 0 4 1
A setCurrency() 0 4 1
A getFormatter() 0 9 3
A getFormattedValue() 0 29 5
A render() 0 4 1
1
<?php
2
/**
3
 * TNumberFromat component.
4
 *
5
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
6
 * @link https://github.com/pradosoft/prado
7
 * @copyright Copyright &copy; 2005-2016 The PRADO Group
8
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
9
 * @package Prado\I18N
10
 */
11
12
namespace Prado\I18N;
13
14
use Prado\Exceptions\TInvalidDataValueException;
15
use Prado\Prado;
16
use Prado\Util\TUtf8Converter;
17
18
/**
19
 * To format numbers in locale sensitive manner use
20
 * <code>
21
 * <com:TNumberFormat Pattern="0.##" value="2.0" />
22
 * </code>
23
 *
24
 * The format used for numbers can be selected by specifying the Type attribute.
25
 * The known types are "decimal", "currency", "percentage", "scientific",
26
 * "spellout", "ordinal" and "duration"
27
 *
28
 * If someone from US want to see sales figures from a store in
29
 * Germany (say using the EURO currency), formatted using the german
30
 * currency, you would need to use the attribute Culture="de_DE" to get
31
 * the currency right, e.g. 100,00. The decimal and grouping separator is
32
 * then also from the de_DE locale. This may lead to some confusion because
33
 * people from US know the "," as thousand separator. Therefore a "Currency"
34
 * attribute is available, so that the output from the following example
35
 * results in 100.00.
36
 * <code>
37
 * <com:TNumberFormat Type="currency" Culture="en_US" Currency="EUR" Value="100" />
38
 * </code>
39
 *
40
 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
41
 * @author Fabio Bas <ctrlaltca[at]gmail[dot]com>
42
 * @package Prado\I18N
43
 */
44
class TNumberFormat extends TI18NControl implements \Prado\IDataRenderer
45
{
46
	/**
47
	 * Cached NumberFormatters set to the application culture.
48
	 * @var NumberFormatter
49
	 */
50
	protected static $formatters;
51
52
	/**
53
	 * Get the number formatting pattern.
54
	 * @return string format pattern.
55
	 */
56
	public function getPattern()
57
	{
58
		return $this->getViewState('Pattern', '');
59
	}
60
61
	/**
62
	 * Set the number format pattern.
63
	 * @param string $pattern format pattern.
64
	 */
65
	public function setPattern($pattern)
66
	{
67
		$this->setViewState('Pattern', $pattern, '');
68
	}
69
70
	/**
71
	 * Get the numberic value for this control.
72
	 * @return string number
73
	 */
74
	public function getValue()
75
	{
76
		return $this->getViewState('Value', '');
77
	}
78
79
	/**
80
	 * Set the numberic value for this control.
81
	 * @param string $value the number value
82
	 */
83
	public function setValue($value)
84
	{
85
		$this->setViewState('Value', $value, '');
86
	}
87
88
	/**
89
	 * Get the default text value for this control.
90
	 * @return string default text value
91
	 */
92
	public function getDefaultText()
93
	{
94
		return $this->getViewState('DefaultText', '');
95
	}
96
97
	/**
98
	 * Set the default text value for this control.
99
	 * @param string $value default text value
100
	 */
101
	public function setDefaultText($value)
102
	{
103
		$this->setViewState('DefaultText', $value, '');
104
	}
105
106
	/**
107
	 * Get the numberic value for this control.
108
	 * This method is required by {@link \Prado\IDataRenderer}.
109
	 * It is the same as {@link getValue()}.
110
	 * @return string number
111
	 * @see getValue
112
	 * @since 3.1.2
113
	 */
114
	public function getData()
115
	{
116
		return $this->getValue();
117
	}
118
119
	/**
120
	 * Set the numberic value for this control.
121
	 * This method is required by {@link \Prado\IDataRenderer}.
122
	 * It is the same as {@link setValue()}.
123
	 * @param string $value the number value
124
	 * @see setValue
125
	 * @since 3.1.2
126
	 */
127
	public function setData($value)
128
	{
129
		$this->setValue($value);
130
	}
131
132
	/**
133
	 * Get the formatting type for this control.
134
	 * @return string formatting type.
135
	 */
136
	public function getType()
137
	{
138
		return $this->getViewState('Type', \NumberFormatter::DECIMAL);
139
	}
140
141
	/**
142
	 * Set the formatting type for this control.
143
	 * @param string $type formatting type, either "decimal", "currency", "percentage", "scientific", "spellout", "ordinal" or "duration"
144
	 * @throws TPropertyTypeInvalidException
145
	 */
146
	public function setType($type)
147
	{
148
		$type = strtolower($type);
149
150
		switch ($type) {
151
			case 'decimal':
152
				$this->setViewState('Type', \NumberFormatter::DECIMAL); break;
153
			case 'currency':
154
				$this->setViewState('Type', \NumberFormatter::CURRENCY); break;
155
			case 'percentage':
156
				$this->setViewState('Type', \NumberFormatter::PERCENT); break;
157
			case 'scientific':
158
				$this->setViewState('Type', \NumberFormatter::SCIENTIFIC); break;
159
			case 'spellout':
160
				$this->setViewState('Type', \NumberFormatter::SPELLOUT); break;
161
			case 'ordinal':
162
				$this->setViewState('Type', \NumberFormatter::ORDINAL); break;
163
			case 'duration':
164
				$this->setViewState('Type', \NumberFormatter::DURATION); break;
165
			default:
166
				throw new TInvalidDataValueException('numberformat_type_invalid', $type);
167
		}
168
	}
169
170
	/**
171
	 * @return string 3 letter currency code. Defaults to 'USD'.
172
	 */
173
	public function getCurrency()
174
	{
175
		return $this->getViewState('Currency', 'USD');
176
	}
177
178
	/**
179
	 * Set the 3-letter ISO 4217 code. For example, the code
180
	 * "USD" represents the US Dollar and "EUR" represents the Euro currency.
181
	 * @param string $currency currency code.
182
	 */
183
	public function setCurrency($currency)
184
	{
185
		$this->setViewState('Currency', $currency, '');
186
	}
187
188
	/**
189
	 * Formats the localized number, be it currency or decimal, or percentage.
190
	 * If the culture is not specified, the default application
191
	 * culture will be used.
192
	 * @param string $culture
193
	 * @param mixed $type
194
	 * @return NumberFormatter
195
	 */
196
	protected function getFormatter($culture, $type)
197
	{
198
		if(!isset(self::$formatters[$culture]))
199
			self::$formatters[$culture] = [];
200
		if(!isset(self::$formatters[$culture][$type]))
201
			self::$formatters[$culture][$type] = new \NumberFormatter($culture, $type);
202
203
		return self::$formatters[$culture][$type];
204
	}
205
206
	/**
207
	 * Formats the localized number, be it currency or decimal, or percentage.
208
	 * If the culture is not specified, the default application
209
	 * culture will be used.
210
	 * @return string formatted number
211
	 */
212
	protected function getFormattedValue()
213
	{
214
		$value = $this->getValue();
215
		$defaultText = $this->getDefaultText();
216
		if (empty($value) && !empty($defaultText)) {
217
			return $this->getDefaultText();
218
		}
219
220
		$culture = $this->getCulture();
221
		$type = $this->getType();
222
		$pattern = $this->getPattern();
223
224
		if(empty($pattern))
225
		{
226
			$formatter = $this->getFormatter($culture, $type);
227
		} else {
228
			$formatter = new \NumberFormatter($culture, \NumberFormatter::PATTERN_DECIMAL);
229
			$formatter->setPattern($pattern);
230
		}
231
232
		if($type === \NumberFormatter::CURRENCY)
233
		{
234
			$result = $formatter->formatCurrency($value, $this->getCurrency());
235
		} else {
236
			$result = $formatter->format($value);
237
		}
238
239
		return TUtf8Converter::fromUTF8($result, $this->getCharset());
240
	}
241
242
	public function render($writer)
243
	{
244
		$writer->write($this->getFormattedValue());
245
	}
246
}
247