Commit:    e9351b89a994464f9c0f60e039ecfaa7f2297302
Author:    Gustavo André dos Santos Lopes <cataphr...@php.net>         Wed, 16 
May 2012 17:33:12 +0200
Parents:   30bf2fbb9d92b66b2f40cb3383bbb00d5921269c
Branches:  master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=e9351b89a994464f9c0f60e039ecfaa7f2297302

Log:
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().

Bugs:
https://bugs.php.net/58756

Changed paths:
  M  ext/intl/msgformat/msgformat_data.c
  M  ext/intl/msgformat/msgformat_data.h
  M  ext/intl/msgformat/msgformat_helpers.cpp
  A  ext/intl/tests/bug58756_MessageFormatter.phpt


Diff:
diff --git a/ext/intl/msgformat/msgformat_data.c 
b/ext/intl/msgformat/msgformat_data.c
index 9ed129f..62e034b 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 5a82003..063efd4 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 f8228df..84c6f40 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);
diff --git a/ext/intl/tests/bug58756_MessageFormatter.phpt 
b/ext/intl/tests/bug58756_MessageFormatter.phpt
new file mode 100644
index 0000000..bbe96b7
--- /dev/null
+++ b/ext/intl/tests/bug58756_MessageFormatter.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #58756: w.r.t MessageFormatter
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+       die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+
+$time = 1247013673;
+
+ini_set('date.timezone', 'America/New_York');
+
+$msgf = new MessageFormatter('en_US', '{0,date,full} {0,time,h:m:s a V}');
+
+echo "date:  " . date('l, F j, Y g:i:s A T', $time) . "\n";
+echo "msgf:  " . $msgf->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


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to