Skip to content

Commit 097ce25

Browse files
committed
formatCurrency
1 parent 405b0ba commit 097ce25

File tree

4 files changed

+60
-23
lines changed

4 files changed

+60
-23
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: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -171,33 +171,60 @@ PHP_FUNCTION( numfmt_format_currency )
171171
size_t currency_len = 0;
172172
UChar* scurrency = NULL;
173173
int32_t scurrency_len = 0;
174+
bool currency_is_null = false;
175+
UFormattedNumber *result = NULL;
174176
FORMATTER_METHOD_INIT_VARS;
175177

176178
/* Parse parameters. */
177-
if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ods",
178-
&object, NumberFormatter_ce_ptr, &number, &currency, &currency_len ) == FAILURE )
179+
if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Od|s!",
180+
&object, NumberFormatter_ce_ptr, &number, &currency, &currency_len, &currency_is_null ) == FAILURE )
179181
{
180182
RETURN_THROWS();
181183
}
182184

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

203230
if( U_FAILURE( INTL_DATA_ERROR_CODE((nfo)) ) ) {
@@ -214,6 +241,8 @@ PHP_FUNCTION( numfmt_format_currency )
214241
if(scurrency) {
215242
efree(scurrency);
216243
}
244+
245+
unumf_closeResult(result);
217246
}
218247

219248
/* }}} */

ext/intl/tests/gh17006.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,15 @@ 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+
$fmt = new \NumberFormatter('en_US', "group-auto currency/USD");
19+
var_dump($fmt->formatCurrency($number));
1420
?>
1521
--EXPECT--
1622
string(11) "one million"
1723
string(9) "1 million"
24+
string(13) "$1,000,000.00"
25+
string(13) "$1,000,000.00"

0 commit comments

Comments
 (0)