Skip to content

Commit a5fc2af

Browse files
committed
formatCurrency
1 parent 405b0ba commit a5fc2af

File tree

6 files changed

+69
-26
lines changed

6 files changed

+69
-26
lines changed

ext/intl/formatter/formatter.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public function parse(string $string, int $type = NumberFormatter::TYPE_DOUBLE,
208208
* @tentative-return-type
209209
* @alias numfmt_format_currency
210210
*/
211-
public function formatCurrency(float $amount, string $currency): string|false {}
211+
public function formatCurrency(float $amount, ?string $currency = null): string|false {}
212212

213213
/**
214214
* @param string $currency

ext/intl/formatter/formatter_arginfo.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/intl/formatter/formatter_format.c

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -171,33 +171,59 @@ PHP_FUNCTION( numfmt_format_currency )
171171
size_t currency_len = 0;
172172
UChar* scurrency = NULL;
173173
int32_t scurrency_len = 0;
174+
UFormattedNumber *result = NULL;
174175
FORMATTER_METHOD_INIT_VARS;
175176

176177
/* Parse parameters. */
177-
if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ods",
178+
if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Od|s!",
178179
&object, NumberFormatter_ce_ptr, &number, &currency, &currency_len ) == FAILURE )
179180
{
180181
RETURN_THROWS();
181182
}
182183

183184
/* Fetch the object. */
184-
FORMATTER_METHOD_FETCH_OBJECT;
185-
186-
/* Convert currency to UTF-16. */
187-
intl_convert_utf8_to_utf16(&scurrency, &scurrency_len, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo));
188-
INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" );
189-
190-
/* Format the number using a fixed-length buffer. */
191-
formatted_len = unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
192-
193-
/* If the buffer turned out to be too small
194-
* then allocate another buffer dynamically
195-
* and use it to format the number.
196-
*/
197-
if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) {
198-
intl_error_reset(INTL_DATA_ERROR_P(nfo));
199-
formatted = eumalloc(formatted_len);
200-
unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
185+
FORMATTER_METHOD_FETCH_OBJECT2;
186+
187+
if (FORMATTER_OBJECT(nfo)) {
188+
if (!currency) {
189+
zend_argument_value_error(3, "currency cannot be null when instantiating NumberFormatter"
190+
"with a style constant");
191+
RETURN_THROWS();
192+
}
193+
/* Convert currency to UTF-16. */
194+
intl_convert_utf8_to_utf16(&scurrency, &scurrency_len, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo));
195+
INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" );
196+
197+
/* Format the number using a fixed-length buffer. */
198+
formatted_len = unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
199+
200+
/* If the buffer turned out to be too small
201+
* then allocate another buffer dynamically
202+
* and use it to format the number.
203+
*/
204+
if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) {
205+
intl_error_reset(INTL_DATA_ERROR_P(nfo));
206+
formatted = eumalloc(formatted_len);
207+
unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo));
208+
}
209+
} else {
210+
/* The new NumberFormatter takes the currency format (aka skeleton)
211+
* from NumberFormatter::__construct 2nd argument.
212+
*/
213+
result = unumf_openResult(&INTL_DATA_ERROR_CODE(nfo));
214+
INTL_METHOD_CHECK_STATUS(nfo, "Error opening formatter result");
215+
unumf_formatDouble(FORMATTER_OBJECT2(nfo), number, result, &INTL_DATA_ERROR_CODE(nfo));
216+
INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" );
217+
formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo));
218+
/* If the buffer turned out to be too small
219+
* then allocate another buffer dynamically
220+
* and use it to format the number.
221+
*/
222+
if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) {
223+
intl_error_reset(INTL_DATA_ERROR_P(nfo));
224+
formatted = eumalloc(formatted_len);
225+
formatted_len = unumf_resultToString(result, formatted, formatted_len, &INTL_DATA_ERROR_CODE(nfo));
226+
}
201227
}
202228

203229
if( U_FAILURE( INTL_DATA_ERROR_CODE((nfo)) ) ) {
@@ -214,6 +240,8 @@ PHP_FUNCTION( numfmt_format_currency )
214240
if(scurrency) {
215241
efree(scurrency);
216242
}
243+
244+
unumf_closeResult(result);
217245
}
218246

219247
/* }}} */

ext/intl/php_intl.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ function numfmt_format(NumberFormatter $formatter, int|float $num, int $type = N
397397
/** @param int $offset */
398398
function numfmt_parse(NumberFormatter $formatter, string $string, int $type = NumberFormatter::TYPE_DOUBLE, &$offset = null): int|float|false {}
399399

400-
function numfmt_format_currency(NumberFormatter $formatter, float $amount, string $currency): string|false {}
400+
function numfmt_format_currency(NumberFormatter $formatter, float $amount, ?string $currency = null): string|false {}
401401

402402
/**
403403
* @param string $currency

ext/intl/php_intl_arginfo.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/intl/tests/gh17006.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,22 @@ var_dump($oldv);
1111
$newf = new \NumberFormatter('en_US', "compact-long");
1212
$newv = $newf->format($number);
1313
var_dump($newv);
14+
15+
$fmt = new \NumberFormatter('en_US', \NumberFormatter::CURRENCY_ACCOUNTING);
16+
var_dump($fmt->formatCurrency($number, 'USD'));
17+
18+
try {
19+
$fmt->formatCurrency($number);
20+
} catch (\ValueError $e) {
21+
echo $e->getMessage() . PHP_EOL;
22+
}
23+
24+
$fmt = new \NumberFormatter('en_US', "group-auto currency/USD");
25+
var_dump($fmt->formatCurrency($number));
1426
?>
1527
--EXPECT--
1628
string(11) "one million"
1729
string(9) "1 million"
30+
string(13) "$1,000,000.00"
31+
NumberFormatter::formatCurrency(): Argument #3 currency cannot be null when instantiating NumberFormatterwith a style constant
32+
string(13) "$1,000,000.00"

0 commit comments

Comments
 (0)