From e9351b89a994464f9c0f60e039ecfaa7f2297302 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gustavo=20Andr=C3=A9=20dos=20Santos=20Lopes?= Date: Wed, 16 May 2012 17:33:12 +0200 Subject: [PATCH] Bug #58756: w.r.t MessageFormatter (partial fix) I don't think the current ICU API allows this bug to be completely fixed. Right now, the code cannot control the time zone used in date/time formats that appear inside complex subformats. See the comment inside umsg_set_timezone(). --- ext/intl/msgformat/msgformat_data.c | 7 ++- ext/intl/msgformat/msgformat_data.h | 1 + ext/intl/msgformat/msgformat_helpers.cpp | 55 +++++++++++++++++++ ext/intl/tests/bug58756_MessageFormatter.phpt | 34 ++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 ext/intl/tests/bug58756_MessageFormatter.phpt diff --git a/ext/intl/msgformat/msgformat_data.c b/ext/intl/msgformat/msgformat_data.c index 9ed129f058..62e034bebc 100755 --- a/ext/intl/msgformat/msgformat_data.c +++ b/ext/intl/msgformat/msgformat_data.c @@ -29,9 +29,10 @@ void msgformat_data_init( msgformat_data* mf_data TSRMLS_DC ) if( !mf_data ) return; - mf_data->umsgf = NULL; - mf_data->orig_format = NULL; - mf_data->arg_types = NULL; + mf_data->umsgf = NULL; + mf_data->orig_format = NULL; + mf_data->arg_types = NULL; + mf_data->tz_set = 0; intl_error_reset( &mf_data->error TSRMLS_CC ); } /* }}} */ diff --git a/ext/intl/msgformat/msgformat_data.h b/ext/intl/msgformat/msgformat_data.h index 5a82003240..063efd4472 100755 --- a/ext/intl/msgformat/msgformat_data.h +++ b/ext/intl/msgformat/msgformat_data.h @@ -32,6 +32,7 @@ typedef struct { char* orig_format; ulong orig_format_len; HashTable* arg_types; + int tz_set; /* if we've already the time zone in sub-formats */ } msgformat_data; msgformat_data* msgformat_data_create( TSRMLS_D ); diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index f8228df4d3..84c6f40c18 100755 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include @@ -40,6 +42,8 @@ extern "C" { /* avoid redefinition of int8_t, already defined in unicode/pwin32.h */ #define _MSC_STDINT_H_ 1 #include "ext/date/php_date.h" +#define USE_TIMEZONE_POINTER +#include "../timezone/timezone_class.h" } #ifndef INFINITY @@ -368,6 +372,55 @@ static HashTable *umsg_get_types(MessageFormatter_object *mfo, #endif } +static void umsg_set_timezone(MessageFormatter_object *mfo, + intl_error& err TSRMLS_DC) +{ + MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf; + TimeZone *used_tz = NULL; + const Format **formats; + int32_t count; + + /* Unfortanely, this cannot change the time zone for arguments that + * appear inside complex formats because ::getFormats() returns NULL + * for all uncached formats, which is the case for complex formats + * unless they were set via one of the ::setFormat() methods */ + + if (mfo->mf_data.tz_set) { + return; /* already done */ + } + + formats = mf->getFormats(count); + + if (formats == NULL) { + intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR, + "Out of memory retrieving subformats", 0 TSRMLS_CC); + } + + for (int i = 0; U_SUCCESS(err.code) && i < count; i++) { + DateFormat* df = dynamic_cast( + const_cast(formats[i])); + if (df == NULL) { + continue; + } + + if (used_tz == NULL) { + zval nullzv = zval_used_for_init, + *zvptr = &nullzv; + used_tz = timezone_process_timezone_argument(&zvptr, &err, + "msgfmt_format" TSRMLS_CC); + if (used_tz == NULL) { + continue; + } + } + + df->setTimeZone(*used_tz); + } + + if (U_SUCCESS(err.code)) { + mfo->mf_data.tz_set = 1; + } +} + U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, HashTable *args, UChar **formatted, @@ -385,6 +438,8 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, } types = umsg_get_types(mfo, err TSRMLS_CC); + + umsg_set_timezone(mfo, err TSRMLS_CC); fargs.resize(arg_count); farg_names.resize(arg_count); diff --git a/ext/intl/tests/bug58756_MessageFormatter.phpt b/ext/intl/tests/bug58756_MessageFormatter.phpt new file mode 100644 index 0000000000..bbe96b7045 --- /dev/null +++ b/ext/intl/tests/bug58756_MessageFormatter.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #58756: w.r.t MessageFormatter +--SKIPIF-- +format(array($time)) . "\n"; + +//NOT FIXED: +/*$msgf = new MessageFormatter('en_US', +'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}'); + +echo "msgf2: ", $msgf->format(array($time, 'date')), " ", + $msgf->format(array($time, 'time')), "\n"; +*/ + +?> +==DONE== +--EXPECT-- +date: Tuesday, July 7, 2009 8:41:13 PM EDT +msgf: Tuesday, July 7, 2009 8:41:13 PM EDT +==DONE== \ No newline at end of file -- 2.40.0