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