summaryrefslogtreecommitdiff
path: root/ext/intl/msgformat/msgformat_helpers.cpp
diff options
context:
space:
mode:
authorGustavo André dos Santos Lopes <cataphract@php.net>2012-05-16 17:33:12 +0200
committerGustavo André dos Santos Lopes <cataphract@php.net>2012-05-17 17:57:01 +0200
commite9351b89a994464f9c0f60e039ecfaa7f2297302 (patch)
tree5b532a3cf1ac1182c1113b7dbd772e2b512a132b /ext/intl/msgformat/msgformat_helpers.cpp
parent30bf2fbb9d92b66b2f40cb3383bbb00d5921269c (diff)
downloadphp-git-e9351b89a994464f9c0f60e039ecfaa7f2297302.tar.gz
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().
Diffstat (limited to 'ext/intl/msgformat/msgformat_helpers.cpp')
-rwxr-xr-xext/intl/msgformat/msgformat_helpers.cpp55
1 files changed, 55 insertions, 0 deletions
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 <unicode/msgfmt.h>
#include <unicode/chariter.h>
#include <unicode/ustdio.h>
+#include <unicode/timezone.h>
+#include <unicode/datefmt.h>
#include <vector>
@@ -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<DateFormat*>(
+ const_cast<Format *>(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);