]> granicus.if.org Git - php/commitdiff
DateFormat plays nice with Calendar, TimeZone
authorGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 3 Jun 2012 22:01:48 +0000 (00:01 +0200)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 3 Jun 2012 22:01:48 +0000 (00:01 +0200)
The following changes were made:

* The IntlDateFormatter constructor now accepts the usual values
  for its $timezone argument. This includes timezone identifiers,
  IntlTimeZone objects, DateTimeZone objects and NULL. An empty
  string is not accepted. An invalid time zone is no longer accepted
  (it used to use UTC in this case).
* When NULL is passed to IntlDateFormatter, the time zone specified in
  date.timezone is used instead of the ICU default.
* The IntlDateFormatter $calendar argument now accepts also an
  IntlCalendar. In this case, IntlDateFormatter::getCalendar() will
  return false.
* The time zone passed to the IntlDateFormatter is ignored if it is
  NULL and if the calendar passed is an IntlCalendar object -- in this
  case, the IntlCalendar time zone will be used instead. Otherwise,
  the time zone specified in the $timezone argument is used instead.
* Added IntlDateFormatter::getCalendarObject(), which always returns
  the IntlCalendar object that backs the DateFormat, even if a
  constant was passed to the constructor, i.e., if an IntlCalendar
  was not passed to the constructor.
* Added IntlDateFormatter::setTimeZone(). It accepts the usual values
  for time zone arguments. If NULL is passed, the time zone of the
  IntlDateFormatter WILL be overridden with the default time zone,
  even if an IntlCalendar object was passed to the constructor.
* Added IntlDateFormatter::getTimeZone(), which returns the time zone
  that's associated with the DateFormat.
* Depreacated IntlDateFormatter::setTimeZoneId() and made it an alias
  for IntlDateFormatter::setTimeZone(), as the new ::setTimeZone()
  also accepts plain identifiers, besides other types.
  IntlDateFormatter::getTimeZoneId() is not deprecated however.
* IntlDateFormatter::setCalendar() with a constant passed should now
  work correctly. This requires saving the requested locale to the
  constructor.
* Centralized the hacks required to avoid compilation disasters on
  Windows due to some headers being included inside and outside of
  extern "C" blocks.

28 files changed:
ext/intl/calendar/calendar_class.cpp
ext/intl/calendar/calendar_class.h
ext/intl/calendar/calendar_methods.cpp
ext/intl/calendar/gregoriancalendar_methods.cpp
ext/intl/common/common_enum.cpp
ext/intl/config.m4
ext/intl/config.w32
ext/intl/dateformat/dateformat.c
ext/intl/dateformat/dateformat_attr.c
ext/intl/dateformat/dateformat_attr.h
ext/intl/dateformat/dateformat_attrcpp.cpp [new file with mode: 0644]
ext/intl/dateformat/dateformat_attrcpp.h [new file with mode: 0644]
ext/intl/dateformat/dateformat_class.c
ext/intl/dateformat/dateformat_class.h
ext/intl/dateformat/dateformat_create.cpp [new file with mode: 0644]
ext/intl/dateformat/dateformat_create.h [new file with mode: 0644]
ext/intl/dateformat/dateformat_format.c
ext/intl/dateformat/dateformat_helpers.cpp [new file with mode: 0644]
ext/intl/dateformat/dateformat_helpers.h [new file with mode: 0644]
ext/intl/grapheme/grapheme.h
ext/intl/intl_convertcpp.cpp
ext/intl/intl_cppshims.h [new file with mode: 0644]
ext/intl/msgformat/msgformat_helpers.cpp
ext/intl/php_intl.c
ext/intl/php_intl.h
ext/intl/timezone/timezone_class.cpp
ext/intl/timezone/timezone_methods.cpp
ext/intl/timezone/timezone_methods.h

index 130c6b59f32c67c44edfb8759dfcbcc16d694a8d..beb65f718f43f6ce235b8e7023582a4a2a45f0fc 100644 (file)
@@ -18,6 +18,8 @@
 #include "config.h"
 #endif
 
+#include "../intl_cppshims.h"
+
 #include <unicode/calendar.h>
 #include <unicode/gregocal.h>
 
@@ -55,6 +57,14 @@ U_CFUNC      void calendar_object_create(zval *object,
        calendar_object_construct(object, calendar TSRMLS_CC);
 }
 
+U_CFUNC Calendar *calendar_fetch_native_calendar(zval *object TSRMLS_DC)
+{
+       Calendar_object *co = (Calendar_object*)
+                       zend_object_store_get_object(object TSRMLS_CC);
+
+       return co->ucal;
+}
+
 U_CFUNC void calendar_object_construct(zval *object,
                                                                           Calendar *calendar TSRMLS_DC)
 {
index abf9555292d60382ce6dfdc1339405a59d6b6653..140389b63937881988b2da2303d522db28f947d9 100644 (file)
@@ -56,6 +56,8 @@ typedef struct {
 
 void calendar_object_create(zval *object, Calendar *calendar TSRMLS_DC);
 
+Calendar *calendar_fetch_native_calendar(zval *object TSRMLS_DC);
+
 void calendar_object_construct(zval *object, Calendar *calendar TSRMLS_DC);
 
 void calendar_register_IntlCalendar_class(TSRMLS_D);
index 1e8c9e7fefd35f73aeaea80c84ae218ef1ef4d76..8562a2d69eaf451f151e8290f6f3baaef74c84ad 100644 (file)
@@ -18,6 +18,8 @@
 #include "config.h"
 #endif
 
+#include "../intl_cppshims.h"
+
 #include <unicode/locid.h>
 #include <unicode/calendar.h>
 #include <unicode/ustring.h>
@@ -31,7 +33,6 @@ extern "C" {
 #include "../locale/locale.h"
 #include <zend_exceptions.h>
 #include <zend_interfaces.h>
-#define _MSC_STDINT_H_ /* avoid redefinitions */
 #include <ext/date/php_date.h>
 }
 #include "../common/common_enum.h"
index 4f26cc59457acf8c6979a6266c9f4ba6d3212f9c..47e84633a2d009a7f8a547da4464cf062c65baa8 100644 (file)
@@ -18,6 +18,8 @@
 #include "config.h"
 #endif
 
+#include "../intl_cppshims.h"
+
 #include <unicode/locid.h>
 #include <unicode/calendar.h>
 #include <unicode/gregocal.h>
@@ -27,8 +29,6 @@ extern "C" {
 #define USE_CALENDAR_POINTER 1
 #include "calendar_class.h"
 #include "../locale/locale.h"
-/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
-#define _MSC_STDINT_H_ 1
 #include <ext/date/php_date.h>
 }
 
index 14265d459711c8712d56436679ed5d0e7c578419..a0e346061a75ad0523a41f43e39cedefc16e2126 100644 (file)
@@ -18,6 +18,8 @@
 #include "config.h"
 #endif
 
+#include "../intl_cppshims.h"
+
 // Fix build on Windows/old versions of ICU
 #include <stdio.h>
 
index b1845d8febd7c1719557ae5bea9ca2ad291dc4e6..431deeb7d290681e08f6c0944a98b3cb89271f56 100755 (executable)
@@ -52,6 +52,9 @@ if test "$PHP_INTL" != "no"; then
     dateformat/dateformat_data.c \
     dateformat/dateformat_format.c \
     dateformat/dateformat_parse.c \
+    dateformat/dateformat_create.cpp \
+    dateformat/dateformat_attrcpp.cpp \
+    dateformat/dateformat_helpers.cpp \
     msgformat/msgformat.c \
     msgformat/msgformat_attr.c \
     msgformat/msgformat_class.c \
@@ -67,11 +70,11 @@ if test "$PHP_INTL" != "no"; then
     transliterator/transliterator.c \
     transliterator/transliterator_class.c \
     transliterator/transliterator_methods.c \
-       timezone/timezone_class.cpp \
-       timezone/timezone_methods.cpp \
-       calendar/calendar_class.cpp \
-       calendar/calendar_methods.cpp \
-       calendar/gregoriancalendar_methods.cpp \
+    timezone/timezone_class.cpp \
+    timezone/timezone_methods.cpp \
+    calendar/calendar_class.cpp \
+    calendar/calendar_methods.cpp \
+    calendar/gregoriancalendar_methods.cpp \
     idn/idn.c \
     $icu_spoof_src, $ext_shared,,$ICU_INCS -Wno-write-strings)
   PHP_ADD_BUILD_DIR($ext_builddir/collator)
index ce12d9d3420e32eecd05aadd96a9bf0ff2c06edd..735749ab438d9fe2ae065713be4e3e0da4dabd52 100755 (executable)
@@ -63,6 +63,9 @@ if (PHP_INTL != "no") {
                                dateformat_format.c \
                                dateformat_parse.c \
                                dateformat_data.c \
+                               dateformat_attrcpp.cpp \
+                               dateformat_helpers.cpp \
+                               dateformat_create.cpp \
                                ", "intl");
                ADD_SOURCES(configure_module_dirname + "/idn", "\
                                idn.c",
index b399a39fcb51156db0a86a3bd12becb34db4d979..fb83eeef05b766d9cf7148aae434cdb0ab710559 100755 (executable)
 #include "config.h"
 #endif
 
-#include <unicode/ustring.h>
 #include <unicode/udat.h>
-#include <unicode/ucal.h>
 
 #include "php_intl.h"
-#include "intl_convert.h"
 #include "dateformat_class.h"
 #include "dateformat.h"
 
@@ -67,157 +64,6 @@ void dateformat_register_constants( INIT_FUNC_ARGS )
 }
 /* }}} */
 
-/* {{{ */
-static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
-{
-    char*       locale;
-       int         locale_len = 0;
-       zval*       object;
-    long        date_type = 0;
-    long        time_type = 0;
-    long        calendar = UCAL_GREGORIAN;
-    char*       timezone_str = NULL;
-    int         timezone_str_len = 0;
-    char*       pattern_str = NULL;
-    int         pattern_str_len = 0;
-    UChar*      svalue = NULL;         /* UTF-16 pattern_str */
-    int         slength = 0;
-    UChar*      timezone_utf16 = NULL;         /* UTF-16 timezone_str */
-    int         timezone_utf16_len = 0;
-       UCalendar   ucal_obj = NULL;
-       IntlDateFormatter_object* dfo;
-       
-       intl_error_reset( NULL TSRMLS_CC );
-       object = return_value;
-       /* Parse parameters. */
-    if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "sll|sls",
-               &locale, &locale_len, &date_type, &time_type, &timezone_str, &timezone_str_len, &calendar,&pattern_str, &pattern_str_len ) == FAILURE )
-    {
-               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: unable to parse input parameters", 0 TSRMLS_CC );
-               zval_dtor(return_value);
-               RETURN_NULL();
-    }
-
-       INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
-       
-       if (calendar != UCAL_TRADITIONAL && calendar != UCAL_GREGORIAN) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: "
-                               "invalid value for calendar type; it must be one of "
-                               "IntlDateFormatter::TRADITIONAL (locale's default calendar) "
-                               "or IntlDateFormatter::GREGORIAN", 0 TSRMLS_CC);
-               goto error;
-       }
-       
-       DATE_FORMAT_METHOD_FETCH_OBJECT;
-       
-       if (DATE_FORMAT_OBJECT(dfo) != NULL) {
-               intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
-                               "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC);
-               return;
-       }
-       
-       /* Convert pattern (if specified) to UTF-16. */
-       if( pattern_str && pattern_str_len>0 ){
-               intl_convert_utf8_to_utf16(&svalue, &slength,
-                               pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
-               if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
-                       /* object construction -> only set global error */
-                       intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
-                                       "error converting pattern to UTF-16", 0 TSRMLS_CC);
-                       goto error;
-               }
-       }
-       
-       /* resources allocated from now on */
-
-       /* Convert pattern (if specified) to UTF-16. */
-       if( timezone_str && timezone_str_len >0 ){
-               intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len,
-                               timezone_str, timezone_str_len, &INTL_DATA_ERROR_CODE(dfo));
-               if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
-                       intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
-                                       "error converting timezone_str to UTF-16", 0 TSRMLS_CC);
-                       goto error;
-               }
-       }
-
-       if(locale_len == 0) {
-               locale = INTL_G(default_locale);
-       }
-
-       if( pattern_str && pattern_str_len>0 ){
-               DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo));
-       } else {
-               DATE_FORMAT_OBJECT(dfo) = udat_open(time_type, date_type, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo));
-       }
-
-    if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
-               if (calendar != UCAL_TRADITIONAL) {
-                       ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale,
-                                       calendar, &INTL_DATA_ERROR_CODE(dfo));
-                       if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
-                               udat_setCalendar(DATE_FORMAT_OBJECT(dfo), ucal_obj);
-                               ucal_close(ucal_obj);
-                       } else {
-                               intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create"
-                                               ": error opening calendar", 0 TSRMLS_CC);
-                               goto error;
-                       }
-               }
-    } else {
-               intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date "
-                               "formatter creation failed", 0 TSRMLS_CC);
-               goto error;
-       }
-
-       /* Set the class variables */
-       dfo->date_type = date_type;
-       dfo->time_type = time_type;
-       dfo->calendar  = calendar;
-       if( timezone_str && timezone_str_len > 0){
-               dfo->timezone_id = estrndup( timezone_str, timezone_str_len);
-       }
-       
-error:
-       if (svalue) {
-               efree(svalue);
-       }
-       if (timezone_utf16) {
-               efree(timezone_utf16);
-       }
-       if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) {
-               /* free_object handles partially constructed instances fine */
-               zval_dtor(return_value);
-               RETVAL_NULL();
-       }
-}
-/* }}} */
-
-/* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
- * Create formatter. }}} */
-/* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
- * Create formatter.
- */
-PHP_FUNCTION( datefmt_create )
-{
-    object_init_ex( return_value, IntlDateFormatter_ce_ptr );
-       datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-/* }}} */
-
-/* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern])
- * IntlDateFormatter object constructor.
- */
-PHP_METHOD( IntlDateFormatter, __construct )
-{
-       /* return_value param is being changed, therefore we will always return
-        * NULL here */
-       return_value = getThis();
-       datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-/* }}} */
-
 /* {{{ proto int IntlDateFormatter::getErrorCode()
  * Get formatter's last error code. }}} */
 /* {{{ proto int datefmt_get_error_code( IntlDateFormatter $nf )
index 6131cedc956b5fd156486b7d38ad33bb1c4a35a6..a32a4860c938469cc85275031ec37bed29c4e02e 100755 (executable)
 
 #include <unicode/ustring.h>
 #include <unicode/udat.h>
-#include <unicode/ucal.h>
-
-static void internal_set_calendar(IntlDateFormatter_object *dfo, char* timezone_id, int timezone_id_len, int calendar, zval* return_value TSRMLS_DC){
-       int         timezone_utf16_len = 0;
-       UChar*      timezone_utf16  = NULL; /* timezone_id in UTF-16 */
-       char*       locale = NULL;
-
-       UCalendar*   ucal_obj = NULL;
-
-       /* check for the validity  of value of calendar passed */
-       intl_error_reset( NULL TSRMLS_CC );
-       if( calendar > 1){
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "datefmt_set_calendar: calendar value specified is out of valid range", 0 TSRMLS_CC);
-               RETURN_FALSE;
-       }
-
-       /* Convert timezone to UTF-16. */
-       intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len, timezone_id, timezone_id_len, &INTL_DATA_ERROR_CODE(dfo));
-       INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" );
-
-       /* Get the locale for the dateformatter */
-       locale = (char *)udat_getLocaleByType(DATE_FORMAT_OBJECT(dfo), ULOC_ACTUAL_LOCALE, &INTL_DATA_ERROR_CODE(dfo));
-
-       /* Set the calendar if passed */
-       ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale, calendar, &INTL_DATA_ERROR_CODE(dfo) );
-       udat_setCalendar( DATE_FORMAT_OBJECT(dfo), ucal_obj );
-       INTL_METHOD_CHECK_STATUS(dfo, "Error setting the calendar.");
-
-       if( timezone_utf16){
-               efree(timezone_utf16);
-       }
-}
 
 /* {{{ proto unicode IntlDateFormatter::getDateType( )
  * Get formatter datetype. }}} */
@@ -110,97 +77,6 @@ PHP_FUNCTION( datefmt_get_timetype )
 }
 /* }}} */
 
-
-/* {{{ proto unicode IntlDateFormatter::getCalendar( )
- * Get formatter calendar. }}} */
-/* {{{ proto string datefmt_get_calendar( IntlDateFormatter $mf )
- * Get formatter calendar.
- */
-PHP_FUNCTION( datefmt_get_calendar )
-{
-       DATE_FORMAT_METHOD_INIT_VARS;
-
-       /* Parse parameters. */
-       if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE )
-       {
-               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, 
-                       "datefmt_get_calendar: unable to parse input params", 0 TSRMLS_CC );
-               RETURN_FALSE;
-       }
-
-       /* Fetch the object. */
-       DATE_FORMAT_METHOD_FETCH_OBJECT;
-
-       INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter calendar." );
-
-       RETURN_LONG(dfo->calendar);
-}
-/* }}} */
-
-/* {{{ proto unicode IntlDateFormatter::getTimeZoneId( )
- * Get formatter timezone_id. }}} */
-/* {{{ proto string datefmt_get_timezone_id( IntlDateFormatter $mf )
- * Get formatter timezone_id.
- */
-PHP_FUNCTION( datefmt_get_timezone_id )
-{
-       DATE_FORMAT_METHOD_INIT_VARS;
-
-       /* Parse parameters. */
-       if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE )
-       {
-               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, 
-                       "datefmt_get_timezone_id: unable to parse input params", 0 TSRMLS_CC );
-               RETURN_FALSE;
-       }
-
-       /* Fetch the object. */
-       DATE_FORMAT_METHOD_FETCH_OBJECT;
-
-       INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter timezone_id." );
-
-       if( dfo->timezone_id ){
-               RETURN_STRING((char*)dfo->timezone_id, TRUE );
-       }else{
-               RETURN_NULL();
-       }
-}
-
-/* {{{ proto boolean IntlDateFormatter::setTimeZoneId( $timezone_id)
- * Set formatter timezone_id. }}} */
-/* {{{ proto boolean datefmt_set_timezone_id( IntlDateFormatter $mf,$timezone_id)
- * Set formatter timezone_id.
- */
-PHP_FUNCTION( datefmt_set_timezone_id )
-{
-       char*           timezone_id             = NULL;
-       int             timezone_id_len         = 0;
-
-       DATE_FORMAT_METHOD_INIT_VARS;
-
-       /* Parse parameters. */
-       if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, IntlDateFormatter_ce_ptr,&timezone_id, &timezone_id_len) == FAILURE )
-       {
-               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "datefmt_set_timezone_id: unable to parse input params", 0 TSRMLS_CC );
-               RETURN_FALSE;
-       }
-
-       /* Fetch the object. */
-       DATE_FORMAT_METHOD_FETCH_OBJECT;
-
-       /* set the timezone for the calendar */
-       internal_set_calendar( dfo, timezone_id, timezone_id_len, dfo->calendar, return_value TSRMLS_CC );
-
-       /* Set the IntlDateFormatter variable */
-        if( dfo->timezone_id ){
-               efree(dfo->timezone_id);
-       }
-       dfo->timezone_id = estrndup(timezone_id, timezone_id_len);
-
-       RETURN_TRUE;
-}
-
 /* {{{ proto string IntlDateFormatter::getPattern( )
  * Get formatter pattern. }}} */
 /* {{{ proto string datefmt_get_pattern( IntlDateFormatter $mf )
@@ -369,43 +245,3 @@ PHP_FUNCTION( datefmt_set_lenient )
        udat_setLenient(DATE_FORMAT_OBJECT(dfo), (UBool)isLenient );
 }
 /* }}} */
-
-/* {{{ proto bool IntlDateFormatter::setPattern( int $calendar )
- * Set formatter calendar. }}} */
-/* {{{ proto bool datefmt_set_calendar( IntlDateFormatter $mf, int $calendar )
- * Set formatter calendar.
- */
-PHP_FUNCTION( datefmt_set_calendar )
-{
-       long    calendar = 0;
-
-       DATE_FORMAT_METHOD_INIT_VARS;
-
-       /* Parse parameters. */
-       if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol",
-               &object, IntlDateFormatter_ce_ptr, &calendar ) == FAILURE ) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "datefmt_set_calendar: unable to parse input params", 0 TSRMLS_CC);
-               RETURN_FALSE;
-       }
-
-       /* check for the validity  of value of calendar passed */
-       intl_error_reset( NULL TSRMLS_CC );
-       if (calendar > 1) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "datefmt_set_calendar: calendar value specified is out of valid range", 0 TSRMLS_CC);
-               RETURN_FALSE;
-       }
-
-       DATE_FORMAT_METHOD_FETCH_OBJECT;
-
-       internal_set_calendar( dfo, dfo->timezone_id, strlen(dfo->timezone_id), calendar, return_value TSRMLS_CC );
-
-       /* Set the calendar  value in the IntlDateFormatter object */
-       dfo->calendar = calendar;
-
-       RETURN_TRUE;
-}
-/* }}} */
-
-
index bf28824d636a6af6561fadda25a8b62e5a0508bb..6fe82a6e00c2248ba21ba3e0bc81c1a1ff5961d7 100755 (executable)
 //PHP_FUNCTION( datefmt_get_timezone );
 PHP_FUNCTION( datefmt_get_datetype );
 PHP_FUNCTION( datefmt_get_timetype );
-PHP_FUNCTION( datefmt_get_calendar );
-PHP_FUNCTION( datefmt_set_calendar );
 PHP_FUNCTION( datefmt_get_locale );
-PHP_FUNCTION( datefmt_get_timezone_id );
-PHP_FUNCTION( datefmt_set_timezone_id );
 PHP_FUNCTION( datefmt_get_pattern );
 PHP_FUNCTION( datefmt_set_pattern );
 PHP_FUNCTION( datefmt_is_lenient );
diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp
new file mode 100644 (file)
index 0000000..b68abec
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Gustavo Lopes <cataphract@php.net>                          |
+   +----------------------------------------------------------------------+
+*/
+
+#include "../intl_cppshims.h"
+
+#include <unicode/timezone.h>
+#include <unicode/calendar.h>
+#include <unicode/datefmt.h>
+
+extern "C" {
+#include "../php_intl.h"
+#include "dateformat_class.h"
+#include "dateformat_attrcpp.h"
+#define USE_TIMEZONE_POINTER 1
+#include "../timezone/timezone_class.h"
+#define USE_CALENDAR_POINTER 1
+#include "../calendar/calendar_class.h"
+}
+
+#include "../intl_convertcpp.h"
+#include "dateformat_helpers.h"
+
+static inline DateFormat *fetch_datefmt(IntlDateFormatter_object *dfo) {
+       return (DateFormat *)dfo->datef_data.udatf;
+}
+
+/* {{{ proto string IntlDateFormatter::getTimeZoneId()
+ * Get formatter timezone_id. }}} */
+/* {{{ proto string datefmt_get_timezone_id(IntlDateFormatter $mf)
+ * Get formatter timezone_id.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_get_timezone_id)
+{
+       DATE_FORMAT_METHOD_INIT_VARS;
+
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+                       &object, IntlDateFormatter_ce_ptr ) == FAILURE) {
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,  "datefmt_get_timezone_"
+                               "id: unable to parse input params", 0 TSRMLS_CC);
+               RETURN_FALSE;
+       }
+
+       DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+       UnicodeString res = UnicodeString();
+       fetch_datefmt(dfo)->getTimeZone().getID(res);
+       intl_charFromString(res, &Z_STRVAL_P(return_value),
+                       &Z_STRLEN_P(return_value), &INTL_DATA_ERROR_CODE(dfo));
+       INTL_METHOD_CHECK_STATUS(dfo, "Could not convert time zone id to UTF-8");
+
+       Z_TYPE_P(return_value) = IS_STRING;
+}
+
+/* {{{ proto IntlTimeZone IntlDateFormatter::getTimeZone()
+ * Get formatter timezone. }}} */
+/* {{{ proto IntlTimeZone datefmt_get_timezone(IntlDateFormatter $mf)
+ * Get formatter timezone.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_get_timezone)
+{
+       DATE_FORMAT_METHOD_INIT_VARS;
+
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+                       &object, IntlDateFormatter_ce_ptr ) == FAILURE) {
+               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+                       "datefmt_get_timezone: unable to parse input params", 0 TSRMLS_CC );
+               RETURN_FALSE;
+       }
+
+       DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+       const TimeZone& tz = fetch_datefmt(dfo)->getTimeZone();
+       TimeZone *tz_clone = tz.clone();
+       if (tz_clone == NULL) {
+               intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR,
+                               "datefmt_get_timezone: Out of memory when cloning time zone",
+                               0 TSRMLS_CC);
+               RETURN_FALSE;
+       }
+
+       object_init_ex(return_value, TimeZone_ce_ptr);
+       timezone_object_construct(tz_clone, return_value, 1 TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(datefmt_set_timezone_id)
+{
+       php_error_docref0(NULL TSRMLS_CC, E_DEPRECATED,
+                       "Use datefmt_set_timezone() instead, which also accepts a plain "
+                       "time zone identifier and for which this function is now an "
+                       "alias");
+       PHP_FN(datefmt_set_timezone)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+/* {{{ proto boolean IntlDateFormatter::setTimeZone(mixed $timezone)
+ * Set formatter's timezone. }}} */
+/* {{{ proto boolean datefmt_set_timezone_id(IntlDateFormatter $mf, $timezone_id)
+ * Set formatter timezone_id.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_set_timezone)
+{
+       zval            **timezone_zv;
+       TimeZone        *timezone;
+
+       DATE_FORMAT_METHOD_INIT_VARS;
+
+       if ( zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+                       "OZ", &object, IntlDateFormatter_ce_ptr, &timezone_zv) == FAILURE) {
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_set_timezone: "
+                               "unable to parse input params", 0 TSRMLS_CC);
+               RETURN_FALSE;
+       }
+
+       DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+       timezone = timezone_process_timezone_argument(timezone_zv,
+                       INTL_DATA_ERROR_P(dfo), "datefmt_set_timezone" TSRMLS_CC);
+       if (timezone == NULL) {
+               RETURN_FALSE;
+       }
+
+       fetch_datefmt(dfo)->adoptTimeZone(timezone);
+}
+
+/* {{{ proto int IntlDateFormatter::getCalendar( )
+ * Get formatter calendar type. }}} */
+/* {{{ proto int datefmt_get_calendar(IntlDateFormatter $mf)
+ * Get formatter calendar type.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_get_calendar)
+{
+       DATE_FORMAT_METHOD_INIT_VARS;
+
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+                       &object, IntlDateFormatter_ce_ptr ) == FAILURE) {
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+                       "datefmt_get_calendar: unable to parse input params", 0 TSRMLS_CC);
+               RETURN_FALSE;
+       }
+
+       DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+       if (dfo->calendar == -1) {
+               /* an IntlCalendar was provided to the constructor */
+               RETURN_FALSE;
+       }
+
+       RETURN_LONG(dfo->calendar);
+}
+/* }}} */
+
+/* {{{ proto IntlCalendar IntlDateFormatter::getCalendarObject()
+ * Get formatter calendar. }}} */
+/* {{{ proto IntlCalendar datefmt_get_calendar_object(IntlDateFormatter $mf)
+ * Get formatter calendar.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_get_calendar_object)
+{
+       DATE_FORMAT_METHOD_INIT_VARS;
+
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+                       &object, IntlDateFormatter_ce_ptr ) == FAILURE) {
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+                               "datefmt_get_calendar_object: unable to parse input params",
+                               0 TSRMLS_CC);
+               RETURN_FALSE;
+       }
+
+       DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+       const Calendar *cal = fetch_datefmt(dfo)->getCalendar();
+       if (cal == NULL) {
+               RETURN_NULL();
+       }
+
+       Calendar *cal_clone = cal->clone();
+       if (cal_clone == NULL) {
+               intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR,
+                               "datefmt_get_calendar_object: Out of memory when cloning "
+                               "calendar", 0 TSRMLS_CC);
+               RETURN_FALSE;
+       }
+
+       calendar_object_create(return_value, cal_clone TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto bool IntlDateFormatter::setCalendar(mixed $calendar)
+ * Set formatter's calendar. }}} */
+/* {{{ proto bool datefmt_set_calendar(IntlDateFormatter $mf, mixed $calendar)
+ * Set formatter's calendar.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_set_calendar)
+{
+       zval    *calendar_zv;
+       DATE_FORMAT_METHOD_INIT_VARS;
+
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz",
+                       &object, IntlDateFormatter_ce_ptr, &calendar_zv) == FAILURE) {
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+                       "datefmt_set_calendar: unable to parse input params", 0 TSRMLS_CC);
+               RETURN_FALSE;
+       }
+
+       DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+       Calendar        *cal;
+       long            cal_type;
+       bool            cal_owned;
+       Locale          locale = Locale::createFromName(dfo->requested_locale);
+       // getting the actual locale from the DateFormat is not enough
+       // because we would have lost modifiers such as @calendar. We
+       // must store the requested locale on object creation
+
+       if (datefmt_process_calendar_arg(calendar_zv, locale,
+                       "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type,
+                       cal_owned TSRMLS_CC) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (cal_owned) {
+               /* a non IntlCalendar was specified, we want to keep the timezone */
+               TimeZone *old_timezone = fetch_datefmt(dfo)->getTimeZone().clone();
+               if (old_timezone == NULL) {
+                       intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR,
+                                       "datefmt_set_calendar: Out of memory when cloning calendar",
+                                       0 TSRMLS_CC);
+                       delete cal;
+                       RETURN_FALSE;
+               }
+               cal->adoptTimeZone(old_timezone);
+       } else {
+               cal = cal->clone();
+               if (cal == NULL) {
+                       intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR,
+                                       "datefmt_set_calendar: Out of memory when cloning calendar",
+                                       0 TSRMLS_CC);
+                       RETURN_FALSE;
+               }
+       }
+
+       fetch_datefmt(dfo)->adoptCalendar(cal);
+
+       dfo->calendar = cal_type;
+
+       RETURN_TRUE;
+}
+/* }}} */
+
diff --git a/ext/intl/dateformat/dateformat_attrcpp.h b/ext/intl/dateformat/dateformat_attrcpp.h
new file mode 100644 (file)
index 0000000..408232f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Gustavo Lopes <cataphract@php.net>                          |
+   +----------------------------------------------------------------------+
+*/
+
+#ifndef DATEFORMAT_ATTRCPP_H
+#define        DATEFORMAT_ATTRCPP_H
+
+PHP_FUNCTION(datefmt_get_timezone_id);
+
+PHP_FUNCTION(datefmt_set_timezone_id);
+
+PHP_FUNCTION(datefmt_get_timezone);
+
+PHP_FUNCTION(datefmt_set_timezone);
+
+PHP_FUNCTION(datefmt_get_calendar);
+
+PHP_FUNCTION(datefmt_set_calendar);
+
+PHP_FUNCTION(datefmt_get_calendar_object);
+
+#endif /* DATEFORMAT_ATTRCPP_H */
+
index c66610f23b98217b1167b5181f429e51308e4eb0..fda67f1b7000308873610f38679ac95570569499 100755 (executable)
@@ -22,6 +22,7 @@
 #include "dateformat_parse.h"
 #include "dateformat.h"
 #include "dateformat_attr.h"
+#include "dateformat_attrcpp.h"
 
 zend_class_entry *IntlDateFormatter_ce_ptr = NULL;
 static zend_object_handlers IntlDateFormatter_handlers;
@@ -44,12 +45,12 @@ void IntlDateFormatter_object_free( zend_object *object TSRMLS_DC )
 
        zend_object_std_dtor( &dfo->zo TSRMLS_CC );
 
-       dateformat_data_free( &dfo->datef_data TSRMLS_CC );
-       
-       if( dfo->timezone_id ){
-               efree(dfo->timezone_id);
+       if (dfo->requested_locale) {
+               efree( dfo->requested_locale );
        }
 
+       dateformat_data_free( &dfo->datef_data TSRMLS_CC );
+
        efree( dfo );
 }
 /* }}} */
@@ -63,10 +64,10 @@ zend_object_value IntlDateFormatter_object_create(zend_class_entry *ce TSRMLS_DC
        intern = ecalloc( 1, sizeof(IntlDateFormatter_object) );
        dateformat_data_init( &intern->datef_data TSRMLS_CC );
        zend_object_std_init( &intern->zo, ce TSRMLS_CC );
-       intern->date_type = 0;
-       intern->time_type = 0;
-       intern->calendar  = 1;          /* Gregorian calendar */
-       intern->timezone_id =  NULL;
+       intern->date_type                       = 0;
+       intern->time_type                       = 0;
+       intern->calendar                        = -1;
+       intern->requested_locale        = NULL;
 
        retval.handle = zend_objects_store_put(
                intern,
@@ -157,9 +158,12 @@ static zend_function_entry IntlDateFormatter_class_functions[] = {
        PHP_NAMED_FE( getDateType, ZEND_FN( datefmt_get_datetype ), arginfo_intldateformatter_getdatetype )
        PHP_NAMED_FE( getTimeType, ZEND_FN( datefmt_get_timetype ), arginfo_intldateformatter_getdatetype )
        PHP_NAMED_FE( getCalendar, ZEND_FN( datefmt_get_calendar ), arginfo_intldateformatter_getdatetype )
+       PHP_NAMED_FE( getCalendarObject, ZEND_FN( datefmt_get_calendar_object ), arginfo_intldateformatter_getdatetype )
        PHP_NAMED_FE( setCalendar, ZEND_FN( datefmt_set_calendar ), arginfo_intldateformatter_setcalendar )
        PHP_NAMED_FE( getTimeZoneId, ZEND_FN( datefmt_get_timezone_id ), arginfo_intldateformatter_getdatetype )
        PHP_NAMED_FE( setTimeZoneId, ZEND_FN( datefmt_set_timezone_id ), arginfo_intldateformatter_settimezoneid )
+       PHP_NAMED_FE( getTimeZone, ZEND_FN( datefmt_get_timezone ), arginfo_intldateformatter_getdatetype )
+       PHP_NAMED_FE( setTimeZone, ZEND_FN( datefmt_set_timezone ), arginfo_intldateformatter_settimezoneid )
        PHP_NAMED_FE( setPattern, ZEND_FN( datefmt_set_pattern ), arginfo_intldateformatter_setpattern )
        PHP_NAMED_FE( getPattern, ZEND_FN( datefmt_get_pattern ), arginfo_intldateformatter_getdatetype )
        PHP_NAMED_FE( getLocale, ZEND_FN( datefmt_get_locale ), arginfo_intldateformatter_getdatetype )
index 9ad83ee3d63c94476a5e2e5b90ccb8a4a3f2aa73..de5cf4a181380536bf56cbbc6cf49a06d9ee2736 100755 (executable)
 #include "dateformat_data.h"
 
 typedef struct {
-       zend_object             zo;
-       dateformat_data         datef_data;
-       int                     date_type ;
-       int                     time_type ;
-       int                     calendar ;
-       char*                   timezone_id;
+       zend_object             zo;
+       dateformat_data datef_data;
+       int                             date_type;
+       int                             time_type;
+       int                             calendar;
+       char                    *requested_locale;
 } IntlDateFormatter_object;
 
 void dateformat_register_IntlDateFormatter_class( TSRMLS_D );
diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp
new file mode 100644 (file)
index 0000000..fef93e9
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Kirti Velankar <kirtig@yahoo-inc.com>                       |
+   |          Gustavo Lopes <cataphract@php.net>                          |
+   +----------------------------------------------------------------------+
+*/
+
+#include "../intl_cppshims.h"
+
+#include <unicode/timezone.h>
+#include <unicode/calendar.h>
+#include <unicode/datefmt.h>
+
+extern "C" {
+#include <unicode/ustring.h>
+#include <unicode/udat.h>
+
+#include "php_intl.h"
+#include "dateformat_create.h"
+#include "dateformat_class.h"
+#define USE_TIMEZONE_POINTER 1
+#include "../timezone/timezone_class.h"
+#include "../intl_convert.h"
+}
+
+#include "dateformat_helpers.h"
+
+/* {{{ */
+static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
+{
+       zval            *object;
+
+    char               *locale_str;
+       int                     locale_len              = 0;
+       Locale          locale;
+    long               date_type               = 0;
+    long               time_type               = 0;
+       zval            *calendar_zv    = NULL;
+       Calendar        *calendar               = NULL;
+       long            calendar_type;
+       bool            calendar_owned;
+       zval            **timezone_zv   = NULL;
+       TimeZone        *timezone               = NULL;
+       bool            explicit_tz;
+    char*       pattern_str            = NULL;
+    int         pattern_str_len        = 0;
+    UChar*      svalue                 = NULL;         /* UTF-16 pattern_str */
+    int         slength                        = 0;
+       IntlDateFormatter_object* dfo;
+
+       intl_error_reset(NULL TSRMLS_CC);
+       object = return_value;
+       /* Parse parameters. */
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|Zzs",
+                       &locale_str, &locale_len, &date_type, &time_type, &timezone_zv,
+                       &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) {
+               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: "
+                               "unable to parse input parameters", 0 TSRMLS_CC);
+               zval_dtor(return_value);
+               RETURN_NULL();
+    }
+
+       INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
+       if (locale_len == 0) {
+               locale_str = INTL_G(default_locale);
+       }
+       locale = Locale::createFromName(locale_str);
+
+       DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+       if (DATE_FORMAT_OBJECT(dfo) != NULL) {
+               intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
+                               "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC);
+               return;
+       }
+
+       /* process calendar */
+       if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create",
+                       INTL_DATA_ERROR_P(dfo), calendar, calendar_type,
+                       calendar_owned TSRMLS_CC)
+                       == FAILURE) {
+               goto error;
+       }
+
+       /* process timezone */
+       explicit_tz = timezone_zv != NULL && Z_TYPE_PP(timezone_zv) != IS_NULL;
+
+       if (explicit_tz || calendar_owned ) {
+               //we have an explicit time zone or a non-object calendar
+               timezone = timezone_process_timezone_argument(timezone_zv,
+                               INTL_DATA_ERROR_P(dfo), "datefmt_create" TSRMLS_CC);
+               if (timezone == NULL) {
+                       goto error;
+               }
+       }
+
+       /* Convert pattern (if specified) to UTF-16. */
+       if (pattern_str && pattern_str_len > 0) {
+               intl_convert_utf8_to_utf16(&svalue, &slength,
+                               pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
+               if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
+                       /* object construction -> only set global error */
+                       intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
+                                       "error converting pattern to UTF-16", 0 TSRMLS_CC);
+                       goto error;
+               }
+       }
+
+       if (pattern_str && pattern_str_len > 0) {
+               DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE,
+                               locale_str, NULL, 0, svalue, slength,
+                               &INTL_DATA_ERROR_CODE(dfo));
+       } else {
+               DATE_FORMAT_OBJECT(dfo) = udat_open((UDateFormatStyle)time_type,
+                               (UDateFormatStyle)date_type, locale_str, NULL, 0, svalue,
+                               slength, &INTL_DATA_ERROR_CODE(dfo));
+       }
+
+    if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
+               DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo);
+               if (calendar_owned) {
+                       df->adoptCalendar(calendar);
+                       calendar_owned = false;
+               } else {
+                       df->setCalendar(*calendar);
+               }
+
+               if (timezone != NULL) {
+                       df->adoptTimeZone(timezone);
+               }
+    } else {
+               intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date "
+                               "formatter creation failed", 0 TSRMLS_CC);
+               goto error;
+       }
+
+       /* Set the class variables */
+       dfo->date_type                  = date_type;
+       dfo->time_type                  = time_type;
+       dfo->calendar                   = calendar_type;
+       dfo->requested_locale   = estrdup(locale_str);
+
+error:
+       if (svalue) {
+               efree(svalue);
+       }
+       if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) {
+               delete timezone;
+       }
+       if (calendar != NULL && calendar_owned) {
+               delete calendar;
+       }
+       if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) {
+               /* free_object handles partially constructed instances fine */
+               zval_dtor(return_value);
+               RETVAL_NULL();
+       }
+}
+/* }}} */
+
+/* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
+ * Create formatter. }}} */
+/* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern)
+ * Create formatter.
+ */
+U_CFUNC PHP_FUNCTION( datefmt_create )
+{
+    object_init_ex( return_value, IntlDateFormatter_ce_ptr );
+       datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern])
+ * IntlDateFormatter object constructor.
+ */
+U_CFUNC PHP_METHOD( IntlDateFormatter, __construct )
+{
+       /* return_value param is being changed, therefore we will always return
+        * NULL here */
+       return_value = getThis();
+       datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
diff --git a/ext/intl/dateformat/dateformat_create.h b/ext/intl/dateformat/dateformat_create.h
new file mode 100644 (file)
index 0000000..47e67c2
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Gustavo Lopes <cataphract@php.net>                          |
+   +----------------------------------------------------------------------+
+*/
+#ifndef DATE_FORMATTER_H
+#define DATE_FORMATTER_H
+
+#include <php.h>
+
+PHP_FUNCTION( datefmt_create );
+PHP_METHOD( IntlDateFormatter, __construct );
+void dateformat_register_constants( INIT_FUNC_ARGS );
+
+#endif // DATE_FORMATTER_H
index 4d03d924c8564696b0df2b0af024e9aa43b19656..82f825f140386a76517f5afc20ecf538065bede0 100755 (executable)
@@ -27,6 +27,8 @@
 #include "dateformat_class.h"
 #include "dateformat_format.h"
 #include "dateformat_data.h"
+/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
+#define _MSC_STDINT_H_ 1
 #include "ext/date/php_date.h"
 
 /* {{{ 
@@ -91,7 +93,7 @@ static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, HashTable* ha
        long yday =0;
        long mday =0;
        UBool isInDST = FALSE;
-       UCalendar *pcal;
+       const UCalendar *pcal;
 
        /* Fetch  values from the incoming array */
        year = internal_get_arr_ele( dfo, hash_arr, CALENDAR_YEAR TSRMLS_CC) + 1900; /* tm_year is years since 1900 */
diff --git a/ext/intl/dateformat/dateformat_helpers.cpp b/ext/intl/dateformat/dateformat_helpers.cpp
new file mode 100644 (file)
index 0000000..74758bb
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Gustavo Lopes <cataphract@php.net>                          |
+   +----------------------------------------------------------------------+
+*/
+
+#include "../intl_cppshims.h"
+
+#include <unicode/calendar.h>
+#include <unicode/gregocal.h>
+
+#include "dateformat_helpers.h"
+
+extern "C" {
+#include "../php_intl.h"
+#include <Zend/zend_operators.h>
+#define USE_CALENDAR_POINTER 1
+#include "../calendar/calendar_class.h"
+}
+
+int datefmt_process_calendar_arg(zval* calendar_zv,
+                                                                Locale const& locale,
+                                                                const char *func_name,
+                                                                intl_error *err,
+                                                                Calendar*& cal,
+                                                                long& cal_int_type,
+                                                                bool& calendar_owned TSRMLS_DC)
+{
+       char *msg;
+       UErrorCode status = UErrorCode();
+
+       if (calendar_zv == NULL || Z_TYPE_P(calendar_zv) == IS_NULL) {
+
+               // default requested
+               cal = new GregorianCalendar(locale, status);
+               calendar_owned = true;
+
+               cal_int_type = UCAL_GREGORIAN;
+
+       } else if (Z_TYPE_P(calendar_zv) == IS_LONG) {
+
+               long v = Z_LVAL_P(calendar_zv);
+               if (v != (long)UCAL_TRADITIONAL && v != (long)UCAL_GREGORIAN) {
+                       spprintf(&msg, 0, "%s: invalid value for calendar type; it must be "
+                                       "one of IntlDateFormatter::TRADITIONAL (locale's default "
+                                       "calendar) or IntlDateFormatter::GREGORIAN. "
+                                       "Alternatively, it can be an IntlCalendar object",
+                                       func_name);
+                       intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+                       efree(msg);
+                       return FAILURE;
+               } else if (v == (long)UCAL_TRADITIONAL) {
+                       cal = Calendar::createInstance(locale, status);
+               } else { //UCAL_GREGORIAN
+                       cal = new GregorianCalendar(locale, status);
+               }
+               calendar_owned = true;
+
+               cal_int_type = Z_LVAL_P(calendar_zv);
+
+       } else if (Z_TYPE_P(calendar_zv) == IS_OBJECT &&
+                       instanceof_function_ex(Z_OBJCE_P(calendar_zv),
+                       Calendar_ce_ptr, 0 TSRMLS_CC)) {
+
+               cal = calendar_fetch_native_calendar(calendar_zv TSRMLS_CC);
+               if (cal == NULL) {
+                       spprintf(&msg, 0, "%s: Found unconstructed IntlCalendar object",
+                                       func_name);
+                       intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+                       efree(msg);
+                       return FAILURE;
+               }
+               calendar_owned = false;
+
+               cal_int_type = -1;
+
+       } else {
+               spprintf(&msg, 0, "%s: Invalid calendar argument; should be an integer "
+                               "or an IntlCalendar instance", func_name);
+               intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+               efree(msg);
+               return FAILURE;
+       }
+
+       if (cal == NULL && !U_FAILURE(status)) {
+               status = U_MEMORY_ALLOCATION_ERROR;
+       }
+       if (U_FAILURE(status)) {
+               spprintf(&msg, 0, "%s: Failure instantiating calendar", func_name);
+               intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+               efree(msg);
+               return FAILURE;
+       }
+
+       return SUCCESS;
+}
diff --git a/ext/intl/dateformat/dateformat_helpers.h b/ext/intl/dateformat/dateformat_helpers.h
new file mode 100644 (file)
index 0000000..bded0b7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Gustavo Lopes <cataphract@php.net>                          |
+   +----------------------------------------------------------------------+
+*/
+
+#ifndef DATEFORMAT_HELPERS_H
+#define        DATEFORMAT_HELPERS_H
+
+#ifndef __cplusplus
+#error For C++ only
+#endif
+
+#include <unicode/calendar.h>
+
+extern "C" {
+#include "../php_intl.h"
+}
+
+int datefmt_process_calendar_arg(zval* calendar_zv,
+                                                                Locale const& locale,
+                                                                const char *func_name,
+                                                                intl_error *err,
+                                                                Calendar*& cal,
+                                                                long& cal_int_type,
+                                                                bool& calendar_owned TSRMLS_DC);
+
+#endif /* DATEFORMAT_HELPERS_H */
+
index c0e697ac1e55f639e6f7683755ccbc40698065db..756ce9173e834abc7f4013562b450ba2145c6819 100755 (executable)
@@ -19,7 +19,6 @@
 
 #include <php.h>
 #include <unicode/utypes.h>
-#include <unicode/ubrk.h>
 
 PHP_FUNCTION(grapheme_strlen);
 PHP_FUNCTION(grapheme_strpos);
index 503402871cd57824b91e691c3793037cad247566..f699a3c61c9a46f6fb0019fe64b8bd6d0dc1aabd 100644 (file)
@@ -16,8 +16,7 @@
 
 /* $Id$ */
 
-//Fixes the build on old versions of ICU with Windows
-#include <stdio.h>
+#include "intl_cppshims.h"
 
 #include "intl_convertcpp.h"
 #include <unicode/ustring.h>
diff --git a/ext/intl/intl_cppshims.h b/ext/intl/intl_cppshims.h
new file mode 100644 (file)
index 0000000..2fb70ed
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Gustavo Lopes <cataphract@php.net>                          |
+   +----------------------------------------------------------------------+
+*/
+
+#ifndef INTL_CPPSHIMS_H
+#define INTL_CPPSHIMS_H
+
+#ifndef __cplusplus
+#error For inclusion form C++ files only
+#endif
+
+#ifdef _MSC_VER
+//This is only required for old versions of ICU only
+#include <stdio.h>
+
+#include <math.h>
+
+/* avoid redefinition of int8_t, also defined in unicode/pwin32.h */
+#define _MSC_STDINT_H_ 1
+#endif
+
+#endif
\ No newline at end of file
index 6f4615e1697049b28d9b3e68f9e213a670f7d48b..fd8df1a39c3018e106991c95841c0c8a9c5dc98e 100755 (executable)
 #include "config.h"
 #endif
 
-// Fix build on Windows / old versions of ICU
-#include <stdio.h>
+#include "../intl_cppshims.h"
 
-#include <math.h>
 #include <limits.h>
 #include <unicode/msgfmt.h>
 #include <unicode/chariter.h>
index db8e00392cf293e010ac0ae595ef12aabc3f51f5..59272db71271dc45f6f6bc626b588d2b3287df89 100755 (executable)
@@ -41,6 +41,8 @@
 #include "formatter/formatter_main.h"
 #include "formatter/formatter_parse.h"
 
+#include "grapheme/grapheme.h"
+
 #include "msgformat/msgformat.h"
 #include "msgformat/msgformat_class.h"
 #include "msgformat/msgformat_attr.h"
@@ -58,6 +60,7 @@
 #include "dateformat/dateformat.h"
 #include "dateformat/dateformat_class.h"
 #include "dateformat/dateformat_attr.h"
+#include "dateformat/dateformat_attrcpp.h"
 #include "dateformat/dateformat_format.h"
 #include "dateformat/dateformat_parse.h"
 #include "dateformat/dateformat_data.h"
@@ -321,6 +324,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_pattern, 0, 0, 2)
        ZEND_ARG_INFO(0, pattern)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_timezone, 0, 0, 2)
+       ZEND_ARG_INFO(0, mf)
+       ZEND_ARG_INFO(0, timezone)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_calendar, 0, 0, 2)
        ZEND_ARG_INFO(0, mf)
        ZEND_ARG_INFO(0, calendar)
@@ -675,10 +683,13 @@ zend_function_entry intl_functions[] = {
        PHP_FE( datefmt_get_datetype, arginfo_msgfmt_get_locale )
        PHP_FE( datefmt_get_timetype, arginfo_msgfmt_get_locale )
        PHP_FE( datefmt_get_calendar, arginfo_msgfmt_get_locale )
+       PHP_FE( datefmt_get_calendar_object, arginfo_msgfmt_get_locale )
        PHP_FE( datefmt_set_calendar, arginfo_datefmt_set_calendar )
        PHP_FE( datefmt_get_locale, arginfo_msgfmt_get_locale )
        PHP_FE( datefmt_get_timezone_id, arginfo_msgfmt_get_locale )
-       PHP_FE( datefmt_set_timezone_id, arginfo_msgfmt_get_locale )
+       PHP_FE( datefmt_set_timezone_id, arginfo_datefmt_set_timezone )
+       PHP_FE( datefmt_get_timezone, arginfo_msgfmt_get_locale )
+       PHP_FE( datefmt_set_timezone, arginfo_datefmt_set_timezone )
        PHP_FE( datefmt_get_pattern, arginfo_msgfmt_get_locale )
        PHP_FE( datefmt_set_pattern, arginfo_datefmt_set_pattern )
        PHP_FE( datefmt_is_lenient, arginfo_msgfmt_get_locale )
index 38f61ad8ac4d0f4237872f3d14623cc8c375e114..c3d5c60f0787ab6aae4d11292317ec18be2d43e8 100755 (executable)
 
 #include <php.h>
 
+/* Even if we're included from C++, don't introduce C++ definitions
+ * because we were included with extern "C". The effect would be that
+ * when the headers defined any method, they would do so with C linkage */
+#undef U_SHOW_CPLUSPLUS_API
+#define U_SHOW_CPLUSPLUS_API 0
 #include "collator/collator_sort.h"
-#include "grapheme/grapheme.h"
+#include <unicode/ubrk.h>
 #include "intl_error.h"
 
 extern zend_module_entry intl_module_entry;
index c976eb143ac52511ade54ff343c26d8ec01205fc..6e62c34f6d3d76012c0d30b8e890854116af34c7 100644 (file)
@@ -19,6 +19,8 @@
 #include "config.h"
 #endif
 
+#include "../intl_cppshims.h"
+
 #include <unicode/timezone.h>
 #include <unicode/calendar.h>
 #include "../intl_convertcpp.h"
@@ -30,8 +32,6 @@ extern "C" {
 #include "timezone_methods.h"
 #include <zend_exceptions.h>
 #include <zend_interfaces.h>
-/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
-#define _MSC_STDINT_H_ 1
 #include <ext/date/php_date.h>
 }
 
index b7f31c3f3b408559f9b2633aa8d846a1587084a0..1435679fe743c49a6d014ae93e1bc6741c9970dc 100644 (file)
@@ -18,6 +18,8 @@
 #include "config.h"
 #endif
 
+#include "../intl_cppshims.h"
+
 #include <unicode/locid.h>
 #include <unicode/timezone.h>
 #include <unicode/ustring.h>
@@ -28,8 +30,6 @@ extern "C" {
 #include "intl_convert.h"
 #include "../locale/locale.h"
 #include <zend_exceptions.h>
-/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
-#define _MSC_STDINT_H_ 1
 #include <ext/date/php_date.h>
 }
 #include "common/common_enum.h"
index e153418ea72465b783f9ad7faa9e97c903ce961f..28c39f4fd703b8a6ae4cf015999fa58b471207a6 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <php.h>
 
-PHP_METHOD(IntlTimeZone, __construct)
+PHP_METHOD(IntlTimeZone, __construct);
 
 PHP_FUNCTION(intltz_create_time_zone);