summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorLonny Kapelushnik <lonnyk@gmail.com>2012-09-28 12:15:20 +0000
committerDerick Rethans <github@derickrethans.nl>2013-03-31 10:45:00 +0100
commit30d0ae42b56c62bc441d763dfa8388c43625b83d (patch)
treeb1e476cd26f16593e76c1488e021a33c5373d5b0 /ext
parent5dd73b9e540206a4b084b915caec1579dfcb19f2 (diff)
downloadphp-git-30d0ae42b56c62bc441d763dfa8388c43625b83d.tar.gz
Bug 54567 DateTimeZone serialize/unserialize
Make DateTimeZone serializable and implement __set_state
Diffstat (limited to 'ext')
-rw-r--r--ext/date/php_date.c115
-rw-r--r--ext/date/php_date.h3
-rw-r--r--ext/date/tests/014.phpt6
-rw-r--r--ext/date/tests/DateTimeZone_clone_basic1.phpt12
-rw-r--r--ext/date/tests/DateTimeZone_clone_basic2.phpt24
-rw-r--r--ext/date/tests/DateTimeZone_clone_basic3.phpt30
-rw-r--r--ext/date/tests/DateTimeZone_construct_basic.phpt18
-rw-r--r--ext/date/tests/DateTimeZone_serialize.phpt20
-rw-r--r--ext/date/tests/DateTimeZone_verify.phpt26
-rw-r--r--ext/date/tests/timezone_open_basic1.phpt18
10 files changed, 241 insertions, 31 deletions
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index c61a4d3610..16eb6dbe82 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 efae0a1db8..725590136c 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 be0847777f..5e609c8685 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 6de5d4b463..a89005aaec 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 a499510ff9..92f833082f 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 e85f42e876..128c8ff40b 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 b681e8f9c3..2f18f81c03 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 08dd934466..49b9349bb8 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 3ca09131a7..1304000cc4 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 7a989362b0..7fcfcb34cb 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