Commit 065db64d by Carsten Brandt

finsihed formatter implementation

neads cleanup
parent 2a15ae12
...@@ -104,36 +104,47 @@ class Formatter extends Component ...@@ -104,36 +104,47 @@ class Formatter extends Component
* If [PHP intl extension](http://php.net/manual/en/book.intl.php) is not available, the default value is ','. * If [PHP intl extension](http://php.net/manual/en/book.intl.php) is not available, the default value is ','.
*/ */
public $thousandSeparator; public $thousandSeparator;
/**
// TODO refactor number formatters * @var array a list of name value pairs that are passed to the
// /** * intl [Numberformatter::setAttribute()](http://php.net/manual/en/numberformatter.setattribute.php) method of all
// * @var array the options to be set for the NumberFormatter objects (eg. grouping used). Please refer to * the number formatter objects created by [[createNumberFormatter()]].
// * [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute) * This property takes only effect if the [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed.
// * for the possible options. This property is used by [[createNumberFormatter]] when *
// * creating a new number formatter to format decimals, currencies, etc. * Please refer to the [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute)
// */ * for the possible options.
// public $numberFormatOptions = []; *
// /** * For example to change the grouping size you can configure this property like the following:
// * @var array the text options to be set for the NumberFormatter objects (eg. Negative sign). Please refer to *
// * [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute) * ```php
// * for the possible options. This property is used by [[createNumberFormatter]] when * [
// * creating a new number formatter to format decimals, currencies, etc. * NumberFormatter::GROUPING_SIZE => 4,
// * * ]
// * Default value: GOUPING_USED = 1 / MAX_FRACTION_DIGITS = 3 / GROUPING_SIZE = 3 / ROUNDING_MODE = 4 * ```
// */ */
// public $numberTextFormartOptions = []; public $numberFormatterOptions = [];
/**
* @var array a list of name value pairs that are passed to the
* intl [Numberformatter::setTextAttribute()](http://php.net/manual/en/numberformatter.settextattribute.php) method of all
* the number formatter objects created by [[createNumberFormatter()]].
* This property takes only effect if the [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed.
*
* Please refer to the [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformattextattribute)
* for the possible options.
*
* For example to change the minus sign for negative numbers you can configure this property like the following:
*
* ```php
* [
* NumberFormatter::NEGATIVE_PREFIX => 'MINUS',
* ]
* ```
*/
public $numberFormatterTextOptions = [];
/** /**
* @var string the international currency code displayed when formatting a number. * @var string the international currency code displayed when formatting a number.
* If not set, the currency code corresponding to [[locale]] will be used. TODO default value? * If not set, the currency code corresponding to [[locale]] will be used. TODO default value?
*/ */
public $currencyCode; public $currencyCode;
// /**
// * @var float "intl" numberformat library knows a rounding increment
// * This means that any value is rounded to this increment.
// * Example: increment of 0.05 rounds values <= 2.024 to 2.00 / values >= 2.025 to 2.05
// */
// public $roundingIncrement;
// public $roundingIncrCurrency;
/** /**
* @var array the format used to format size (bytes). Three elements may be specified: "base", "decimals" and "decimalSeparator". * @var array the format used to format size (bytes). Three elements may be specified: "base", "decimals" and "decimalSeparator".
* They correspond to the base at which a kilobyte is calculated (1000 or 1024 bytes per kilobyte, defaults to 1024), * They correspond to the base at which a kilobyte is calculated (1000 or 1024 bytes per kilobyte, defaults to 1024),
...@@ -173,17 +184,6 @@ class Formatter extends Component ...@@ -173,17 +184,6 @@ class Formatter extends Component
$this->decimalSeparator = '.'; $this->decimalSeparator = '.';
$this->thousandSeparator = ','; $this->thousandSeparator = ',';
} }
// if (extension_loaded('intl')) {
// $this->_intlLoaded = true;
// $this->numberFormatOptions = [NumberFormatter::ROUNDING_MODE => NumberFormatter::ROUND_HALFUP];
// }
//
// if (preg_match('/\bde-CH\b|\bfr-CH\b|\bit-CH\b/', $this->locale)){
// // Swiss currency amounts must be rounded to 0.05 (5-Rappen) instead of
// // 0.01 as usual
// $this->roundingIncrCurrency = '0.05';
// }
} }
/** /**
...@@ -191,7 +191,7 @@ class Formatter extends Component ...@@ -191,7 +191,7 @@ class Formatter extends Component
* This method will call one of the "as" methods available in this class to do the formatting. * This method will call one of the "as" methods available in this class to do the formatting.
* For type "xyz", the method "asXyz" will be used. For example, if the format is "html", * For type "xyz", the method "asXyz" will be used. For example, if the format is "html",
* then [[asHtml()]] will be used. Format names are case insensitive. * then [[asHtml()]] will be used. Format names are case insensitive.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @param string|array $format the format of the value, e.g., "html", "text". To specify additional * @param string|array $format the format of the value, e.g., "html", "text". To specify additional
* parameters of the formatting method, you may use an array. The first element of the array * parameters of the formatting method, you may use an array. The first element of the array
* specifies the format name, while the rest of the elements will be used as the parameters to the formatting * specifies the format name, while the rest of the elements will be used as the parameters to the formatting
...@@ -227,8 +227,8 @@ class Formatter extends Component ...@@ -227,8 +227,8 @@ class Formatter extends Component
/** /**
* Formats the value as is without any formatting. * Formats the value as is without any formatting.
* This method simply returns back the parameter without any format. * This method simply returns back the parameter without any format.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @return string the formatted result * @return string the formatted result.
*/ */
public function asRaw($value) public function asRaw($value)
{ {
...@@ -240,8 +240,8 @@ class Formatter extends Component ...@@ -240,8 +240,8 @@ class Formatter extends Component
/** /**
* Formats the value as an HTML-encoded plain text. * Formats the value as an HTML-encoded plain text.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @return string the formatted result * @return string the formatted result.
*/ */
public function asText($value) public function asText($value)
{ {
...@@ -253,8 +253,8 @@ class Formatter extends Component ...@@ -253,8 +253,8 @@ class Formatter extends Component
/** /**
* Formats the value as an HTML-encoded plain text with newlines converted into breaks. * Formats the value as an HTML-encoded plain text with newlines converted into breaks.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @return string the formatted result * @return string the formatted result.
*/ */
public function asNtext($value) public function asNtext($value)
{ {
...@@ -268,8 +268,8 @@ class Formatter extends Component ...@@ -268,8 +268,8 @@ class Formatter extends Component
* Formats the value as HTML-encoded text paragraphs. * Formats the value as HTML-encoded text paragraphs.
* Each text paragraph is enclosed within a `<p>` tag. * Each text paragraph is enclosed within a `<p>` tag.
* One or multiple consecutive empty lines divide two paragraphs. * One or multiple consecutive empty lines divide two paragraphs.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @return string the formatted result * @return string the formatted result.
*/ */
public function asParagraphs($value) public function asParagraphs($value)
{ {
...@@ -283,9 +283,9 @@ class Formatter extends Component ...@@ -283,9 +283,9 @@ class Formatter extends Component
* Formats the value as HTML text. * Formats the value as HTML text.
* The value will be purified using [[HtmlPurifier]] to avoid XSS attacks. * The value will be purified using [[HtmlPurifier]] to avoid XSS attacks.
* Use [[asRaw()]] if you do not want any purification of the value. * Use [[asRaw()]] if you do not want any purification of the value.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @param array|null $config the configuration for the HTMLPurifier class. * @param array|null $config the configuration for the HTMLPurifier class.
* @return string the formatted result * @return string the formatted result.
*/ */
public function asHtml($value, $config = null) public function asHtml($value, $config = null)
{ {
...@@ -297,8 +297,8 @@ class Formatter extends Component ...@@ -297,8 +297,8 @@ class Formatter extends Component
/** /**
* Formats the value as a mailto link. * Formats the value as a mailto link.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @return string the formatted result * @return string the formatted result.
*/ */
public function asEmail($value) public function asEmail($value)
{ {
...@@ -310,8 +310,8 @@ class Formatter extends Component ...@@ -310,8 +310,8 @@ class Formatter extends Component
/** /**
* Formats the value as an image tag. * Formats the value as an image tag.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @return string the formatted result * @return string the formatted result.
*/ */
public function asImage($value) public function asImage($value)
{ {
...@@ -323,8 +323,8 @@ class Formatter extends Component ...@@ -323,8 +323,8 @@ class Formatter extends Component
/** /**
* Formats the value as a hyperlink. * Formats the value as a hyperlink.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @return string the formatted result * @return string the formatted result.
*/ */
public function asUrl($value) public function asUrl($value)
{ {
...@@ -341,8 +341,8 @@ class Formatter extends Component ...@@ -341,8 +341,8 @@ class Formatter extends Component
/** /**
* Formats the value as a boolean. * Formats the value as a boolean.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @return string the formatted result * @return string the formatted result.
* @see booleanFormat * @see booleanFormat
*/ */
public function asBoolean($value) public function asBoolean($value)
...@@ -378,7 +378,7 @@ class Formatter extends Component ...@@ -378,7 +378,7 @@ class Formatter extends Component
* *
* @throws InvalidParamException if the input value can not be evaluated as a date value. * @throws InvalidParamException if the input value can not be evaluated as a date value.
* @throws InvalidConfigException if the date format is invalid. * @throws InvalidConfigException if the date format is invalid.
* @return string the formatted result * @return string the formatted result.
* @see dateFormat * @see dateFormat
*/ */
public function asDate($value, $format = null) public function asDate($value, $format = null)
...@@ -409,7 +409,7 @@ class Formatter extends Component ...@@ -409,7 +409,7 @@ class Formatter extends Component
* *
* @throws InvalidParamException if the input value can not be evaluated as a date value. * @throws InvalidParamException if the input value can not be evaluated as a date value.
* @throws InvalidConfigException if the date format is invalid. * @throws InvalidConfigException if the date format is invalid.
* @return string the formatted result * @return string the formatted result.
* @see timeFormat * @see timeFormat
*/ */
public function asTime($value, $format = null) public function asTime($value, $format = null)
...@@ -440,7 +440,7 @@ class Formatter extends Component ...@@ -440,7 +440,7 @@ class Formatter extends Component
* *
* @throws InvalidParamException if the input value can not be evaluated as a date value. * @throws InvalidParamException if the input value can not be evaluated as a date value.
* @throws InvalidConfigException if the date format is invalid. * @throws InvalidConfigException if the date format is invalid.
* @return string the formatted result * @return string the formatted result.
* @see datetimeFormat * @see datetimeFormat
*/ */
public function asDatetime($value, $format = null) public function asDatetime($value, $format = null)
...@@ -494,7 +494,7 @@ class Formatter extends Component ...@@ -494,7 +494,7 @@ class Formatter extends Component
* @param string $format the format used to convert the value into a date string. * @param string $format the format used to convert the value into a date string.
* @param string $type 'date', 'time', or 'datetime'. * @param string $type 'date', 'time', or 'datetime'.
* @throws InvalidConfigException if the date format is invalid. * @throws InvalidConfigException if the date format is invalid.
* @return string the formatted result * @return string the formatted result.
*/ */
private function formatDateTimeValue($value, $format, $type) private function formatDateTimeValue($value, $format, $type)
{ {
...@@ -752,9 +752,16 @@ class Formatter extends Component ...@@ -752,9 +752,16 @@ class Formatter extends Component
} }
/** /**
* Formats a date, time or datetime in a float number as timestamp (seconds since 01-01-1970). * Formats a date, time or datetime in a float number as UNIX timestamp (seconds since 01-01-1970).
* @param string $value * @param integer|string|DateTime|\DateInterval $value the value to be formatted. The following
* @return float timestamp TODO * types of value are supported:
*
* - an integer representing a UNIX timestamp
* - a string that can be parsed into a UNIX timestamp via `strtotime()` or that can be passed to a DateInterval constructor.
* - a PHP DateTime object
* - a PHP DateInterval object (a positive time interval will refer to the past, a negative one to the future)
*
* @return string the formatted result.
*/ */
public function asTimestamp($value) public function asTimestamp($value)
{ {
...@@ -775,8 +782,8 @@ class Formatter extends Component ...@@ -775,8 +782,8 @@ class Formatter extends Component
* - a PHP DateTime object * - a PHP DateTime object
* - a PHP DateInterval object (a positive time interval will refer to the past, a negative one to the future) * - a PHP DateInterval object (a positive time interval will refer to the past, a negative one to the future)
* *
* @param integer|string|DateTime|\DateInterval $referenceTime if specified the value is used instead of now * @param integer|string|DateTime|\DateInterval $referenceTime if specified the value is used instead of `now`.
* @return string the formatted result * @return string the formatted result.
* @throws InvalidParamException if the input value can not be evaluated as a date value. * @throws InvalidParamException if the input value can not be evaluated as a date value.
*/ */
public function asRelativeTime($value, $referenceTime = null) public function asRelativeTime($value, $referenceTime = null)
...@@ -861,19 +868,22 @@ class Formatter extends Component ...@@ -861,19 +868,22 @@ class Formatter extends Component
/** /**
* Formats the value as an integer number by removing any digits without rounding. * Formats the value as an integer number by removing any decimal digits without rounding.
* @param mixed $value the value to be formatted *
* @return string the formatting result. * @param mixed $value the value to be formatted.
* @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]].
* @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]].
* @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric. * @throws InvalidParamException if the input value is not numeric.
*/ */
public function asInteger($value) // TODO customizing public function asInteger($value, $options = [], $textOptions = [])
{ {
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
} }
$value = $this->normalizeNumericValue($value); $value = $this->normalizeNumericValue($value);
if ($this->_intlLoaded) { if ($this->_intlLoaded) {
$f = $this->createNumberFormatter(NumberFormatter::DECIMAL); $f = $this->createNumberFormatter(NumberFormatter::DECIMAL, null, $options, $textOptions);
return $f->format($value, NumberFormatter::TYPE_INT64); return $f->format($value, NumberFormatter::TYPE_INT64);
} else { } else {
return number_format((int) $value, 0, $this->decimalSeparator, $this->thousandSeparator); return number_format((int) $value, 0, $this->decimalSeparator, $this->thousandSeparator);
...@@ -886,22 +896,16 @@ class Formatter extends Component ...@@ -886,22 +896,16 @@ class Formatter extends Component
* Property [[decimalSeparator]] will be used to represent the decimal point. The * Property [[decimalSeparator]] will be used to represent the decimal point. The
* value is rounded automatically to the defined decimal digits. * value is rounded automatically to the defined decimal digits.
* *
* PHP and ICU has different behaviour about number of zeros in fraction digits. * @param mixed $value the value to be formatted.
* PHP fills up to defined decimals (eg. 2.500000 [6]) while ICU hide unnecessary digits. * @param integer $decimals the number of digits after the decimal point.
* (eg. 2.5 [6]). Until 5 fractional digits in this function is defined to 5 up with zeros. * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]].
* * @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]].
* @param mixed $value the value to be formatted * @return string the formatted result.
* @param integer|string $decimals the number of digits after the decimal point if the value is an integer
* otherwise it's is a format pattern string (this works only with [PHP intl extension](http://php.net/manual/en/book.intl.php) [icu]).
// * @param float $roundIncr Amount to which smaller fractation are rounded. Ex. 0.05 -> <=2.024 to 2.00 / >=2.025 to 2.05
// * works with [PHP intl extension](http://php.net/manual/en/book.intl.php) library only.
// * @param boolean $grouping Per standard numbers are grouped in thousands. False = no grouping
* @return string the formatting result.
* @throws InvalidParamException if the input value is not numeric. * @throws InvalidParamException if the input value is not numeric.
* @see decimalSeparator * @see decimalSeparator
* @see thousandSeparator * @see thousandSeparator
*/ */
public function asDecimal($value, $decimals = 2) public function asDecimal($value, $decimals = null, $options = [], $textOptions = [])
{ {
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
...@@ -909,51 +913,12 @@ class Formatter extends Component ...@@ -909,51 +913,12 @@ class Formatter extends Component
$value = $this->normalizeNumericValue($value); $value = $this->normalizeNumericValue($value);
if ($this->_intlLoaded) { if ($this->_intlLoaded) {
$f = $this->createNumberFormatter(NumberFormatter::DECIMAL); $f = $this->createNumberFormatter(NumberFormatter::DECIMAL, $decimals, $options, $textOptions);
// if ($decimals !== null){
// $f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
// if ($decimals <= 5){
// $f->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals);
// }
// }
// if ($roundIncr == null and $this->roundingIncrement != null){
// $roundIncr = $this->roundingIncrement;
// }
// if ($roundIncr != null){
// $f->setAttribute(NumberFormatter::ROUNDING_INCREMENT, $roundIncr);
// }
// if ($grouping === false){
// $f->setAttribute(NumberFormatter::GROUPING_USED, false);
// }
return $f->format($value); return $f->format($value);
} else { } else {
if ($decimals === null){
// if ($roundIncr !== null){ $decimals = 2;
// $part = explode('.', (string)$roundIncr); }
// if ((string)$roundIncr != '0.05'){ // exception for Swiss rounding.
// $roundIncr = $decimals;
// if (intval($part[0]) > 0){
// if (substr($part[0], 0, 1) === '1'){
// $roundIncr = (strlen($part[0]) -1) * -1 ;
// } else {
// throw new InvalidParamException('$roundIncr must have "1" only eg. 0.01 or 10 but not 0.02 or 20');
// }
// } elseif (isset($part[1]) and intval($part[1])>0) {
// if (substr($part[1], -1) === '1'){
// $roundIncr = strlen($part[1]);
// } else {
// throw new InvalidParamException('$roundIncr must have "1" only eg. 0.01 or 10 but not 0.02 or 20');
// }
// }
// $value = round($value, $roundIncr);
// } else {
// $value = round($value/5,2)*5;
// }
// }
// if ($decimals === null){
// $decimals = 0;
// }
// $grouping = $grouping === true ? $this->thousandSeparator : '';
return number_format($value, $decimals, $this->decimalSeparator, $this->thousandSeparator); return number_format($value, $decimals, $this->decimalSeparator, $this->thousandSeparator);
} }
} }
...@@ -961,16 +926,15 @@ class Formatter extends Component ...@@ -961,16 +926,15 @@ class Formatter extends Component
/** /**
* Formats the value as a percent number with "%" sign. * Formats the value as a percent number with "%" sign.
* @param mixed $value the value to be formatted. It must be a factor eg. 0.75 -> 75% *
// * @param string $format Number of decimals (default = 2) or format pattern ICU * @param mixed $value the value to be formatted. It must be a factor e.g. `0.75` will result in `75%`.
// * Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) * @param integer $decimals the number of digits after the decimal point.
// * for details on how to specify a format. * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]].
* @param int $decimals * @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]].
// * @param bool $grouping
* @return string the formatted result. * @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric. * @throws InvalidParamException if the input value is not numeric.
*/ */
public function asPercent($value, $decimals = 0) public function asPercent($value, $decimals = null, $options = [], $textOptions = [])
{ {
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
...@@ -978,18 +942,12 @@ class Formatter extends Component ...@@ -978,18 +942,12 @@ class Formatter extends Component
$value = $this->normalizeNumericValue($value); $value = $this->normalizeNumericValue($value);
if ($this->_intlLoaded) { if ($this->_intlLoaded) {
$f = $this->createNumberFormatter(NumberFormatter::PERCENT); $f = $this->createNumberFormatter(NumberFormatter::PERCENT, $decimals, $options, $textOptions);
// if ($decimals !== null){
// $f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
// if ($decimals <= 5){
// $f->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals);
// }
// }
// if ($grouping === false){
// $f->setAttribute(NumberFormatter::GROUPING_USED, false);
// }
return $f->format($value); return $f->format($value);
} else { } else {
if ($decimals === null){
$decimals = 0;
}
$value = $value * 100; $value = $value * 100;
return number_format($value, $decimals, $this->decimalSeparator, $this->thousandSeparator) . '%'; return number_format($value, $decimals, $this->decimalSeparator, $this->thousandSeparator) . '%';
} }
...@@ -997,14 +955,14 @@ class Formatter extends Component ...@@ -997,14 +955,14 @@ class Formatter extends Component
/** /**
* Formats the value as a scientific number. * Formats the value as a scientific number.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
// * @param string $format the format to be used. Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) * @param integer $decimals the number of digits after the decimal point.
// * for details on how to specify a format. * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]].
* @param int $decimals * @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]].
* @return string the formatted result. * @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric. * @throws InvalidParamException if the input value is not numeric.
*/ */
public function asScientific($value, $decimals = 0) public function asScientific($value, $decimals = null, $options = [], $textOptions = [])
{ {
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
...@@ -1012,14 +970,11 @@ class Formatter extends Component ...@@ -1012,14 +970,11 @@ class Formatter extends Component
$value = $this->normalizeNumericValue($value); $value = $this->normalizeNumericValue($value);
if ($this->_intlLoaded){ if ($this->_intlLoaded){
$f = $this->createNumberFormatter(NumberFormatter::SCIENTIFIC); $f = $this->createNumberFormatter(NumberFormatter::SCIENTIFIC, $decimals, $options, $textOptions);
// if ($decimals !== null){
// $f->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
// }
return $f->format($value); return $f->format($value);
} else { } else {
if ($decimals !== null) { if ($decimals !== null) {
return sprintf("%.{$decimals}E", $value); return sprintf("%.{$decimals}E", $value); // TODO
} else { } else {
return sprintf("%.E", $value); return sprintf("%.E", $value);
} }
...@@ -1028,17 +983,14 @@ class Formatter extends Component ...@@ -1028,17 +983,14 @@ class Formatter extends Component
/** /**
* Formats the value as a currency number. * Formats the value as a currency number.
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted.
* @param string $currency the 3-letter ISO 4217 currency code indicating the currency to use. * @param string $currency the 3-letter ISO 4217 currency code indicating the currency to use.
* @param string $format the format to be used. Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) * @param array $options optional configuration for the number formatter. This parameter will be merged with [[numberFormatterOptions]].
* for details on how to specify a format. TODO ignored when not [PHP intl extension](http://php.net/manual/en/book.intl.php) * @param array $textOptions optional configuration for the number formatter. This parameter will be merged with [[numberFormatterTextOptions]].
* @param float $roundIncrement : Amount to which smaller fractation are rounded. Ex. 0.05 -> <=2.024 to 2.00 / >=2.025 to 2.05
* works with "intl" library only.
* @param null $grouping
* @return string the formatted result. * @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric. * @throws InvalidParamException if the input value is not numeric.
*/ */
public function asCurrency($value, $currency = null) //, $format = null, $roundIncrement = null, $grouping = null) public function asCurrency($value, $currency = null, $options = [], $textOptions = [])
{ {
if ($value === null) { if ($value === null) {
return $this->nullDisplay; return $this->nullDisplay;
...@@ -1048,31 +1000,23 @@ class Formatter extends Component ...@@ -1048,31 +1000,23 @@ class Formatter extends Component
if ($currency === null) { if ($currency === null) {
$currency = $this->currencyCode; $currency = $this->currencyCode;
} }
// if ($roundIncrement === null and $this->roundingIncrCurrency != null){
// $roundIncrement = $this->roundingIncrCurrency;
// }
if ($this->_intlLoaded) { if ($this->_intlLoaded) {
$formatter = $this->createNumberFormatter(NumberFormatter::CURRENCY); $formatter = $this->createNumberFormatter(NumberFormatter::CURRENCY, null, $options, $textOptions);
// if ($grouping !== null){
// $formatter->setAttribute(NumberFormatter::GROUPING_USED, false);
// }
// if ($roundIncrement !== null){
// $formatter->setAttribute(NumberFormatter::ROUNDING_INCREMENT, $roundIncrement);
// }
return $formatter->formatCurrency($value, $currency); return $formatter->formatCurrency($value, $currency);
} else { } else {
return $currency . ' ' . $this->asDecimal($value, 2); return $currency . ' ' . $this->asDecimal($value, null, $options, $textOptions); // TODO be compatible to intl
} }
} }
/** /**
* Formats the value as a number spellout. * Formats the value as a number spellout.
* // TODO requires intl *
* This function requires the [PHP intl extension](http://php.net/manual/en/book.intl.php) to be installed.
*
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted
* @return string the formatted result. * @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric. * @throws InvalidParamException if the input value is not numeric.
* @throws NotSupportedException * @throws InvalidConfigException when the [PHP intl extension](http://php.net/manual/en/book.intl.php) is not available.
*/ */
public function asSpellout($value) public function asSpellout($value)
{ {
...@@ -1084,17 +1028,19 @@ class Formatter extends Component ...@@ -1084,17 +1028,19 @@ class Formatter extends Component
$f = $this->createNumberFormatter(NumberFormatter::SPELLOUT); $f = $this->createNumberFormatter(NumberFormatter::SPELLOUT);
return $f->format($value); return $f->format($value);
} else { } else {
throw new NotSupportedException('Format as Spellout is only supported when PHP intl extension is installed.'); throw new InvalidConfigException('Format as Spellout is only supported when PHP intl extension is installed.');
} }
} }
/** /**
* Formats the value as a ordinal value of a number. * Formats the value as a ordinal value of a number.
* // TODO requires intl *
* This function requires the [PHP intl extension](http://php.net/manual/en/book.intl.php) to be installed.
*
* @param mixed $value the value to be formatted * @param mixed $value the value to be formatted
* @return string the formatted result. * @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric. * @throws InvalidParamException if the input value is not numeric.
* @throws NotSupportedException * @throws InvalidConfigException when the [PHP intl extension](http://php.net/manual/en/book.intl.php) is not available.
*/ */
public function asOrdinal($value) public function asOrdinal($value)
{ {
...@@ -1106,7 +1052,7 @@ class Formatter extends Component ...@@ -1106,7 +1052,7 @@ class Formatter extends Component
$f = $this->createNumberFormatter(NumberFormatter::ORDINAL); $f = $this->createNumberFormatter(NumberFormatter::ORDINAL);
return $f->format($value); return $f->format($value);
} else { } else {
throw new NotSupportedException('Format as Ordinal is only supported when PHP intl extension is installed.'); throw new InvalidConfigException('Format as Ordinal is only supported when PHP intl extension is installed.');
} }
} }
...@@ -1115,12 +1061,18 @@ class Formatter extends Component ...@@ -1115,12 +1061,18 @@ class Formatter extends Component
* @param integer $value value in bytes to be formatted * @param integer $value value in bytes to be formatted
* @param boolean $verbose if full names should be used (e.g. bytes, kilobytes, ...). * @param boolean $verbose if full names should be used (e.g. bytes, kilobytes, ...).
* Defaults to false meaning that short names will be used (e.g. B, KB, ...). * Defaults to false meaning that short names will be used (e.g. B, KB, ...).
* @return string the formatted result * @param boolean $binaryPrefix if binary prefixes should be used for base 1024
* Defaults to true meaning that binary prefixes are used (e.g. kibibyte/KiB, mebibyte/MiB, ...).
* See also <http://en.wikipedia.org/wiki/Binary_prefix>.
* @return string the formatted result.
* @throws InvalidParamException if the input value is not numeric. * @throws InvalidParamException if the input value is not numeric.
* @see sizeFormat * @see sizeFormat
*/ */
public function asSize($value, $verbose = false) public function asSize($value, $verbose = false, $binaryPrefix = true) // TODO format
{ {
if ($value === null) {
return $this->nullDisplay;
}
$position = 0; $position = 0;
do { do {
if ($value < $this->sizeFormat['base']) { if ($value < $this->sizeFormat['base']) {
...@@ -1128,12 +1080,29 @@ class Formatter extends Component ...@@ -1128,12 +1080,29 @@ class Formatter extends Component
} }
$value = $value / $this->sizeFormat['base']; $value = $value / $this->sizeFormat['base'];
$position++; $position++;
} while ($position < 6); } while ($position < 5);
$value = round($value, $this->sizeFormat['decimals']); // todo $value = round($value, $this->sizeFormat['decimals']); // todo
$formattedValue = isset($this->sizeFormat['decimalSeparator']) ? str_replace('.', $this->sizeFormat['decimalSeparator'], $value) : $value; $formattedValue = isset($this->sizeFormat['decimalSeparator']) ? str_replace('.', $this->sizeFormat['decimalSeparator'], $value) : $value;
$params = ['n' => $formattedValue]; $params = ['n' => $formattedValue];
if ($binaryPrefix && $this->sizeFormat['base'] === 1024) {
switch ($position) {
case 0:
return $verbose ? Yii::t('yii', '{n, plural, =1{# byte} other{# bytes}}', $params) : Yii::t('yii', '{n} B', $params);
case 1:
return $verbose ? Yii::t('yii', '{n, plural, =1{# kibibyte} other{# kibibytes}}', $params) : Yii::t('yii', '{n} KiB', $params);
case 2:
return $verbose ? Yii::t('yii', '{n, plural, =1{# mebibyte} other{# mebibytes}}', $params) : Yii::t('yii', '{n} MiB', $params);
case 3:
return $verbose ? Yii::t('yii', '{n, plural, =1{# gibibyte} other{# gibibytes}}', $params) : Yii::t('yii', '{n} GiB', $params);
case 4:
return $verbose ? Yii::t('yii', '{n, plural, =1{# tebibyte} other{# tebibytes}}', $params) : Yii::t('yii', '{n} TiB', $params);
default:
return $verbose ? Yii::t('yii', '{n, plural, =1{# pebibyte} other{# pebibytes}}', $params) : Yii::t('yii', '{n} PiB', $params);
}
}
switch ($position) { switch ($position) {
case 0: case 0:
return $verbose ? Yii::t('yii', '{n, plural, =1{# byte} other{# bytes}}', $params) : Yii::t('yii', '{n} B', $params); return $verbose ? Yii::t('yii', '{n, plural, =1{# byte} other{# bytes}}', $params) : Yii::t('yii', '{n} B', $params);
...@@ -1150,6 +1119,13 @@ class Formatter extends Component ...@@ -1150,6 +1119,13 @@ class Formatter extends Component
} }
} }
/**
* TODO
*
* @param $value
* @return float
* @throws InvalidParamException
*/
protected function normalizeNumericValue($value) protected function normalizeNumericValue($value)
{ {
if (is_string($value) && is_numeric($value)) { if (is_string($value) && is_numeric($value)) {
...@@ -1161,9 +1137,11 @@ class Formatter extends Component ...@@ -1161,9 +1137,11 @@ class Formatter extends Component
return $value; return $value;
} }
/** /**
* Creates a number formatter based on the given type and format. * Creates a number formatter based on the given type and format.
*
* You may overide this to support format pattern. TODO
*
* @param integer $type the type of the number formatter * @param integer $type the type of the number formatter
* Values: NumberFormatter::DECIMAL, ::CURRENCY, ::PERCENT, ::SCIENTIFIC, ::SPELLOUT, ::ORDINAL * Values: NumberFormatter::DECIMAL, ::CURRENCY, ::PERCENT, ::SCIENTIFIC, ::SPELLOUT, ::ORDINAL
* ::DURATION, ::PATTERN_RULEBASED, ::DEFAULT_STYLE, ::IGNORE * ::DURATION, ::PATTERN_RULEBASED, ::DEFAULT_STYLE, ::IGNORE
...@@ -1171,7 +1149,7 @@ class Formatter extends Component ...@@ -1171,7 +1149,7 @@ class Formatter extends Component
* [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) * [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details)
* @return NumberFormatter the created formatter instance * @return NumberFormatter the created formatter instance
*/ */
protected function createNumberFormatter($style) protected function createNumberFormatter($style, $decimals = null, $options = [], $textOptions = [])
{ {
$formatter = new NumberFormatter($this->locale, $style); $formatter = new NumberFormatter($this->locale, $style);
...@@ -1182,24 +1160,17 @@ class Formatter extends Component ...@@ -1182,24 +1160,17 @@ class Formatter extends Component
$formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, $this->thousandSeparator); $formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, $this->thousandSeparator);
} }
// if ($format !== null) { if ($decimals !== null) {
// $formatter->setPattern($format); $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
// } else { $formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals);
// $formatter->setSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL, $this->decimalSeparator); }
// $formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, $this->thousandSeparator);
// }
// if (!empty($this->numberFormatOptions)) {
// foreach ($this->numberFormatOptions as $name => $attribute) {
// $formatter->setAttribute($name, $attribute);
// }
// }
// if (!empty($this->numberTextFormatOptions)) {
// foreach ($this->numberTextFormatOptions as $name => $attribute) {
// $formatter->setTextAttribute($name, $attribute);
// }
// }
foreach (($this->numberFormatterOptions + $options) as $name => $value) {
$formatter->setAttribute($name, $value);
}
foreach (($this->numberFormatterTextOptions + $textOptions) as $name => $attribute) {
$formatter->setTextAttribute($name, $attribute);
}
return $formatter; return $formatter;
} }
......
...@@ -556,7 +556,27 @@ class FormatterTest extends TestCase ...@@ -556,7 +556,27 @@ class FormatterTest extends TestCase
public function testAsSize() public function testAsSize()
{ {
// TODO // tests for base 1000
$this->formatter->sizeFormat['base'] = 1000;
$this->assertSame("999 B", $this->formatter->asSize(999));
$this->assertSame("1.05 MB", $this->formatter->asSize(1024 * 1024));
$this->assertSame("1.05 MB", $this->formatter->asSize(1024 * 1024, false, false));
$this->assertSame("1 KB", $this->formatter->asSize(1000));
$this->assertSame("1.02 KB", $this->formatter->asSize(1023));
$this->assertSame("3 gigabytes", $this->formatter->asSize(3 * 1000 * 1000 * 1000, true));
$this->assertNotEquals("3 PB", $this->formatter->asSize(3 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000)); // this is 3 EB not 3 PB
// tests for base 1024
$this->formatter->sizeFormat['base'] = 1024;
$this->assertSame("1 KiB", $this->formatter->asSize(1024));
$this->assertSame("1 MB", $this->formatter->asSize(1024 * 1024, false, false));
$this->assertSame("1023 B", $this->formatter->asSize(1023));
$this->assertSame("5 GiB", $this->formatter->asSize(5 * 1024 * 1024 * 1024));
$this->assertSame("5 gibibytes", $this->formatter->asSize(5 * 1024 * 1024 * 1024,true));
$this->assertNotEquals("5 PiB", $this->formatter->asSize(5 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024)); // this is 5 EiB not 5 PiB
//$this->assertSame("1 YiB", $this->formatter->asSize(pow(2, 80)));
$this->assertSame("2 GiB", $this->formatter->asSize(2147483647)); // round 1.999 up to 2
$this->formatter->sizeFormat['decimalSeparator'] = ',';
$this->formatter->sizeFormat['decimals'] = 3;
$this->assertSame("1,001 KiB", $this->formatter->asSize(1025));
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment