Test Failed
Push — intl ( c6271f...00087a )
by Fabio
06:11
created

TNumberFormat::I18N_toEncoding()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8

Duplication

Lines 8
Ratio 100 %

Importance

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

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
258
	{
259
		if ($to != 'UTF-8') {
260
			$s = iconv('UTF-8', $to, $string);
261
			return $s !== false ? $s : $string;
262
		}
263
		return $string;
264
	}
265
}
266