Commit:    30d0ae42b56c62bc441d763dfa8388c43625b83d
Author:    Lonny Kapelushnik <lon...@gmail.com>         Fri, 28 Sep 2012 
12:15:20 +0000
Committer: Derick Rethans <git...@derickrethans.nl>      Sun, 31 Mar 2013 
10:45:00 +0100
Parents:   5dd73b9e540206a4b084b915caec1579dfcb19f2
Branches:  PHP-5.5 master

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

Log:
Bug 54567 DateTimeZone serialize/unserialize
Make DateTimeZone serializable and implement __set_state

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

Changed paths:
  M  ext/date/php_date.c
  M  ext/date/php_date.h
  M  ext/date/tests/014.phpt
  M  ext/date/tests/DateTimeZone_clone_basic1.phpt
  M  ext/date/tests/DateTimeZone_clone_basic2.phpt
  M  ext/date/tests/DateTimeZone_clone_basic3.phpt
  M  ext/date/tests/DateTimeZone_construct_basic.phpt
  M  ext/date/tests/DateTimeZone_serialize.phpt
  M  ext/date/tests/DateTimeZone_verify.phpt
  M  ext/date/tests/timezone_open_basic1.phpt

diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index c61a4d3..16eb6db 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -500,6 +500,8 @@ const zend_function_entry date_funcs_immutable[] = {
 
 const zend_function_entry date_funcs_timezone[] = {
        PHP_ME(DateTimeZone,              __construct,                 
arginfo_timezone_open, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
+       PHP_ME(DateTimeZone,              __wakeup,                    NULL, 
ZEND_ACC_PUBLIC)
+       PHP_ME(DateTimeZone,              __set_state,                 NULL, 
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
        PHP_ME_MAPPING(getName,           timezone_name_get,           
arginfo_timezone_method_name_get, 0)
        PHP_ME_MAPPING(getOffset,         timezone_offset_get,         
arginfo_timezone_method_offset_get, 0)
        PHP_ME_MAPPING(getTransitions,    timezone_transitions_get,    
arginfo_timezone_method_transitions_get, 0)
@@ -630,6 +632,7 @@ static HashTable *date_object_get_gc_interval(zval *object, 
zval ***table, int *
 static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC);
 static HashTable *date_object_get_gc_period(zval *object, zval ***table, int 
*n TSRMLS_DC);
 static HashTable *date_object_get_properties_period(zval *object TSRMLS_DC);
+static HashTable *date_object_get_properties_timezone(zval *object TSRMLS_DC);
 
 zval *date_interval_read_property(zval *object, zval *member, int type, const 
zend_literal *key TSRMLS_DC);
 void date_interval_write_property(zval *object, zval *member, zval *value, 
const zend_literal *key TSRMLS_DC);
@@ -2017,6 +2020,7 @@ static void date_register_classes(TSRMLS_D)
        date_ce_timezone = zend_register_internal_class_ex(&ce_timezone, NULL, 
NULL TSRMLS_CC);
        memcpy(&date_object_handlers_timezone, zend_get_std_object_handlers(), 
sizeof(zend_object_handlers));
        date_object_handlers_timezone.clone_obj = date_object_clone_timezone;
+       date_object_handlers_timezone.get_properties = 
date_object_get_properties_timezone;
 
 #define REGISTER_TIMEZONE_CLASS_CONST_STRING(const_name, value) \
        zend_declare_class_constant_long(date_ce_timezone, const_name, 
sizeof(const_name)-1, value TSRMLS_CC);
@@ -2269,6 +2273,50 @@ static zend_object_value date_object_clone_timezone(zval 
*this_ptr TSRMLS_DC)
        return new_ov;
 }
 
+static HashTable *date_object_get_properties_timezone(zval *object TSRMLS_DC)
+{
+       HashTable *props;
+       zval *zv;
+       php_timezone_obj     *tzobj;
+
+
+       tzobj = (php_timezone_obj *) zend_object_store_get_object(object 
TSRMLS_CC);
+
+       props = zend_std_get_properties(object TSRMLS_CC);
+
+       if (!tzobj->initialized || GC_G(gc_active)) {
+               return props;
+       }
+
+       MAKE_STD_ZVAL(zv);
+       ZVAL_LONG(zv, tzobj->type);
+       zend_hash_update(props, "timezone_type", 14, &zv, sizeof(zval), NULL);
+
+       MAKE_STD_ZVAL(zv);
+       switch (tzobj->type) {
+               case TIMELIB_ZONETYPE_ID:
+                       ZVAL_STRING(zv, tzobj->tzi.tz->name, 1);
+                       break;
+               case TIMELIB_ZONETYPE_OFFSET: {
+                       char *tmpstr = emalloc(sizeof("UTC+05:00"));
+
+                       snprintf(tmpstr, sizeof("+05:00"), "%c%02d:%02d",
+                       tzobj->tzi.z.utc_offset > 0 ? '-' : '+',
+                       abs(tzobj->tzi.z.utc_offset / 60),
+                       abs((tzobj->tzi.z.utc_offset % 60)));
+
+                       ZVAL_STRING(zv, tmpstr, 0);
+                       }
+                       break;
+               case TIMELIB_ZONETYPE_ABBR:
+                       ZVAL_STRING(zv, tzobj->tzi.tz->timezone_abbr, 1);
+                       break;
+       }
+       zend_hash_update(props, "timezone", 9, &zv, sizeof(zval), NULL);
+
+       return props;
+}
+
 static inline zend_object_value date_object_new_interval_ex(zend_class_entry 
*class_type, php_interval_obj **ptr TSRMLS_DC)
 {
        php_interval_obj *intern;
@@ -3643,6 +3691,73 @@ PHP_METHOD(DateTimeZone, __construct)
 }
 /* }}} */
 
+static int php_date_timezone_initialize_from_hash(zval **return_value, 
php_timezone_obj **tzobj, HashTable *myht TSRMLS_DC)
+{
+       zval            **z_timezone = NULL;
+       zval            **z_timezone_type = NULL;
+       timelib_tzinfo  *tzi;
+
+       if (zend_hash_find(myht, "timezone_type", 14, (void**) 
&z_timezone_type) == SUCCESS) {
+               if (zend_hash_find(myht, "timezone", 9, (void**) &z_timezone) 
== SUCCESS) {
+                       convert_to_long(*z_timezone_type);
+                       switch (Z_LVAL_PP(z_timezone_type)) {
+                               case TIMELIB_ZONETYPE_OFFSET:
+                                       (*tzobj)->type = 
TIMELIB_ZONETYPE_OFFSET;
+                                       (*tzobj)->tzi.utc_offset = 
Z_LVAL_PP(z_timezone);
+                                       break;
+                               case TIMELIB_ZONETYPE_ABBR:
+                                       (*tzobj)->type = TIMELIB_ZONETYPE_ABBR;
+                                       (*tzobj)->tzi.z.utc_offset = 
Z_LVAL_PP(z_timezone);
+                                       break;
+                               case TIMELIB_ZONETYPE_ID:
+                                       if (SUCCESS == 
timezone_initialize(&tzi, Z_STRVAL_PP(z_timezone) TSRMLS_CC)) {
+                                               (*tzobj)->type = 
TIMELIB_ZONETYPE_ID;
+                                               (*tzobj)->tzi.tz = tzi;
+                                               (*tzobj)->initialized = 1;
+                                               return 1;
+                                       }
+                       }
+               }
+       }
+       return 0;
+}
+
+/* {{{ proto DateTimeZone::__set_state()
+ *  */
+PHP_METHOD(DateTimeZone, __set_state)
+{
+       php_timezone_obj *tzobj;
+       zval             *array;
+       HashTable        *myht;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == 
FAILURE) {
+               RETURN_FALSE;
+       }
+
+       myht = HASH_OF(array);
+
+       php_date_instantiate(date_ce_timezone, return_value TSRMLS_CC);
+       tzobj = (php_timezone_obj *) zend_object_store_get_object(return_value 
TSRMLS_CC);
+       php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht 
TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto DateTimeZone::__wakeup()
+ *  */
+PHP_METHOD(DateTimeZone, __wakeup)
+{
+       zval             *object = getThis();
+       php_timezone_obj *tzobj;
+       HashTable        *myht;
+
+       tzobj = (php_timezone_obj *) zend_object_store_get_object(object 
TSRMLS_CC);
+
+       myht = Z_OBJPROP_P(object);
+
+       php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht 
TSRMLS_CC);
+}
+/* }}} */
+
 /* {{{ proto string timezone_name_get(DateTimeZone object)
    Returns the name of the timezone.
 */
diff --git a/ext/date/php_date.h b/ext/date/php_date.h
index efae0a1..7255901 100644
--- a/ext/date/php_date.h
+++ b/ext/date/php_date.h
@@ -84,6 +84,8 @@ PHP_METHOD(DateTimeImmutable, setISODate);
 PHP_METHOD(DateTimeImmutable, setTimestamp);
 
 PHP_METHOD(DateTimeZone, __construct);
+PHP_METHOD(DateTimeZone, __wakeup);
+PHP_METHOD(DateTimeZone, __set_state);
 PHP_FUNCTION(timezone_open);
 PHP_FUNCTION(timezone_name_get);
 PHP_FUNCTION(timezone_name_from_abbr);
@@ -144,6 +146,7 @@ struct _php_timezone_obj {
                        int          dst;
                } z;
        } tzi;
+       HashTable *props;
 };
 
 struct _php_interval_obj {
diff --git a/ext/date/tests/014.phpt b/ext/date/tests/014.phpt
index be08477..5e609c8 100644
--- a/ext/date/tests/014.phpt
+++ b/ext/date/tests/014.phpt
@@ -26,7 +26,11 @@ object(DateTime)#%d (3) {
   ["timezone"]=>
   string(3) "UTC"
 }
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(3) "UTC"
 }
 
 Warning: timezone_offset_get() expects exactly 2 parameters, 0 given in %s on 
line %d
diff --git a/ext/date/tests/DateTimeZone_clone_basic1.phpt 
b/ext/date/tests/DateTimeZone_clone_basic1.phpt
index 6de5d4b..a89005a 100644
--- a/ext/date/tests/DateTimeZone_clone_basic1.phpt
+++ b/ext/date/tests/DateTimeZone_clone_basic1.phpt
@@ -29,9 +29,17 @@ if ($clone != $orig) {
 ===DONE===
 --EXPECTF--
 *** Testing clone on DateTime objects ***
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(3) "UTC"
 }
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(3) "UTC"
 }
 TEST PASSED : Objects equal but not indetical
 ===DONE===
diff --git a/ext/date/tests/DateTimeZone_clone_basic2.phpt 
b/ext/date/tests/DateTimeZone_clone_basic2.phpt
index a499510..92f8330 100644
--- a/ext/date/tests/DateTimeZone_clone_basic2.phpt
+++ b/ext/date/tests/DateTimeZone_clone_basic2.phpt
@@ -31,19 +31,27 @@ var_dump($d2_clone);
 ===DONE===
 --EXPECTF--
 *** Testing clone on objects whoose class derived from DateTimeZone class ***
-object(DateTimeZoneExt1)#%d (2) {
+object(DateTimeZoneExt1)#%d (4) {
   ["property1"]=>
   int(99)
   ["property2"]=>
   string(5) "Hello"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
 }
-object(DateTimeZoneExt1)#%d (2) {
+object(DateTimeZoneExt1)#%d (4) {
   ["property1"]=>
   int(99)
   ["property2"]=>
   string(5) "Hello"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
 }
-object(DateTimeZoneExt2)#%d (4) {
+object(DateTimeZoneExt2)#%d (6) {
   ["property3"]=>
   bool(true)
   ["property4"]=>
@@ -52,8 +60,12 @@ object(DateTimeZoneExt2)#%d (4) {
   int(99)
   ["property2"]=>
   string(5) "Hello"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
 }
-object(DateTimeZoneExt2)#%d (4) {
+object(DateTimeZoneExt2)#%d (6) {
   ["property3"]=>
   bool(true)
   ["property4"]=>
@@ -62,5 +74,9 @@ object(DateTimeZoneExt2)#%d (4) {
   int(99)
   ["property2"]=>
   string(5) "Hello"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
 }
 ===DONE===
diff --git a/ext/date/tests/DateTimeZone_clone_basic3.phpt 
b/ext/date/tests/DateTimeZone_clone_basic3.phpt
index e85f42e..128c8ff 100644
--- a/ext/date/tests/DateTimeZone_clone_basic3.phpt
+++ b/ext/date/tests/DateTimeZone_clone_basic3.phpt
@@ -30,11 +30,19 @@ var_dump($d2_clone);
 *** Testing clone on DateTime objects ***
 
 -- Create a DateTimeZone object --
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
 }
 
 -- Add some properties --
-object(DateTimeZone)#%d (2) {
+object(DateTimeZone)#%d (4) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
   ["property1"]=>
   int(99)
   ["property2"]=>
@@ -42,7 +50,11 @@ object(DateTimeZone)#%d (2) {
 }
 
 -- clone it --
-object(DateTimeZone)#%d (2) {
+object(DateTimeZone)#%d (4) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
   ["property1"]=>
   int(99)
   ["property2"]=>
@@ -50,7 +62,11 @@ object(DateTimeZone)#%d (2) {
 }
 
 -- Add some more properties --
-object(DateTimeZone)#%d (4) {
+object(DateTimeZone)#%d (6) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
   ["property1"]=>
   int(99)
   ["property2"]=>
@@ -62,7 +78,11 @@ object(DateTimeZone)#%d (4) {
 }
 
 -- clone it --
-object(DateTimeZone)#%d (4) {
+object(DateTimeZone)#%d (6) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
   ["property1"]=>
   int(99)
   ["property2"]=>
diff --git a/ext/date/tests/DateTimeZone_construct_basic.phpt 
b/ext/date/tests/DateTimeZone_construct_basic.phpt
index b681e8f..2f18f81 100644
--- a/ext/date/tests/DateTimeZone_construct_basic.phpt
+++ b/ext/date/tests/DateTimeZone_construct_basic.phpt
@@ -21,10 +21,22 @@ var_dump( new DateTimeZone("America/Los_Angeles") );
 ===DONE===
 --EXPECTF--
 *** Testing new DateTimeZone() : basic functionality ***
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(3) "UTC"
 }
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
 }
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(19) "America/Los_Angeles"
 }
 ===DONE===
diff --git a/ext/date/tests/DateTimeZone_serialize.phpt 
b/ext/date/tests/DateTimeZone_serialize.phpt
index 08dd934..49b9349 100644
--- a/ext/date/tests/DateTimeZone_serialize.phpt
+++ b/ext/date/tests/DateTimeZone_serialize.phpt
@@ -18,12 +18,18 @@ var_dump( $tz2->getName() );
 ?>
 ===DONE=== 
 --EXPECTF--
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(16) "America/New_York"
 }
-string(24) "O:12:"DateTimeZone":0:{}"
-object(DateTimeZone)#%d (0) {
+string(88) 
"O:12:"DateTimeZone":2:{s:13:"timezone_type";i:3;s:8:"timezone";s:16:"America/New_York";}"
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(16) "America/New_York"
 }
-
-Warning: DateTimeZone::getName(): The DateTimeZone object has not been 
correctly initialized by its constructor in %s on line %d
-bool(false)
-===DONE===
\ No newline at end of file
+string(16) "America/New_York"
+===DONE===
diff --git a/ext/date/tests/DateTimeZone_verify.phpt 
b/ext/date/tests/DateTimeZone_verify.phpt
index 3ca0913..1304000 100644
--- a/ext/date/tests/DateTimeZone_verify.phpt
+++ b/ext/date/tests/DateTimeZone_verify.phpt
@@ -26,7 +26,7 @@ object(ReflectionClass)#%d (1) {
   string(12) "DateTimeZone"
 }
 ..and get names of all its methods
-array(7) {
+array(9) {
   [0]=>
   &object(ReflectionMethod)#%d (2) {
     ["name"]=>
@@ -35,41 +35,55 @@ array(7) {
     string(12) "DateTimeZone"
   }
   [1]=>
+  &object(ReflectionMethod)#3 (2) {
+    ["name"]=>
+    string(8) "__wakeup"
+    ["class"]=>
+    string(12) "DateTimeZone"
+  }
+  [2]=>
+  &object(ReflectionMethod)#4 (2) {
+    ["name"]=>
+    string(11) "__set_state"
+    ["class"]=>
+    string(12) "DateTimeZone"
+  }
+  [3]=>
   &object(ReflectionMethod)#%d (2) {
     ["name"]=>
     string(7) "getName"
     ["class"]=>
     string(12) "DateTimeZone"
   }
-  [2]=>
+  [4]=>
   &object(ReflectionMethod)#%d (2) {
     ["name"]=>
     string(9) "getOffset"
     ["class"]=>
     string(12) "DateTimeZone"
   }
-  [3]=>
+  [5]=>
   &object(ReflectionMethod)#%d (2) {
     ["name"]=>
     string(14) "getTransitions"
     ["class"]=>
     string(12) "DateTimeZone"
   }
-  [4]=>
+  [6]=>
   &object(ReflectionMethod)#%d (2) {
     ["name"]=>
     string(11) "getLocation"
     ["class"]=>
     string(12) "DateTimeZone"
   }
-  [5]=>
+  [7]=>
   &object(ReflectionMethod)#%d (2) {
     ["name"]=>
     string(17) "listAbbreviations"
     ["class"]=>
     string(12) "DateTimeZone"
   }
-  [6]=>
+  [8]=>
   &object(ReflectionMethod)#%d (2) {
     ["name"]=>
     string(15) "listIdentifiers"
diff --git a/ext/date/tests/timezone_open_basic1.phpt 
b/ext/date/tests/timezone_open_basic1.phpt
index 7a98936..7fcfcb3 100644
--- a/ext/date/tests/timezone_open_basic1.phpt
+++ b/ext/date/tests/timezone_open_basic1.phpt
@@ -18,10 +18,22 @@ var_dump( timezone_open("America/Los_Angeles") );
 ===DONE===
 --EXPECTF--
 *** Testing timezone_open() : basic functionality ***
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(3) "UTC"
 }
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
 }
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(19) "America/Los_Angeles"
 }
 ===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