3434#include <ext/standard/info.h>
3535#include <Zend/zend_interfaces.h>
3636#include <ext/spl/spl_iterators.h>
37+ #include <ext/standard/php_var.h>
38+ #if PHP_VERSION_ID >= 70000
39+ # include <zend_smart_str.h>
40+ #else
41+ # include <ext/standard/php_smart_str.h>
42+ #endif
3743/* Our Compatability header */
3844#include "phongo_compat.h"
3945
@@ -227,6 +233,120 @@ PHP_METHOD(Javascript, getScope)
227233}
228234/* }}} */
229235
236+ /* {{{ proto string Javascript::serialize()
237+ */
238+ PHP_METHOD (Javascript , serialize )
239+ {
240+ php_phongo_javascript_t * intern ;
241+ #if PHP_VERSION_ID >= 70000
242+ zval retval ;
243+ #else
244+ zval * retval ;
245+ #endif
246+ php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER ;
247+
248+ php_serialize_data_t var_hash ;
249+ smart_str buf = { 0 };
250+
251+ intern = Z_JAVASCRIPT_OBJ_P (getThis ());
252+
253+ if (zend_parse_parameters_none () == FAILURE ) {
254+ return ;
255+ }
256+
257+ #if PHP_VERSION_ID >= 70000
258+ if (intern -> scope && intern -> scope -> len ) {
259+ if (!phongo_bson_to_zval_ex (bson_get_data (intern -> scope ), intern -> scope -> len , & state )) {
260+ return ;
261+ }
262+ Z_ADDREF (state .zchild );
263+ } else {
264+ ZVAL_NULL (& state .zchild );
265+ }
266+ #else
267+ if (intern -> scope && intern -> scope -> len ) {
268+ if (!phongo_bson_to_zval_ex (bson_get_data (intern -> scope ), intern -> scope -> len , & state )) {
269+ return ;
270+ }
271+ Z_ADDREF_P (state .zchild );
272+ } else {
273+ MAKE_STD_ZVAL (state .zchild );
274+ ZVAL_NULL (state .zchild );
275+ Z_ADDREF_P (state .zchild );
276+ }
277+ #endif
278+
279+ #if PHP_VERSION_ID >= 70000
280+ array_init_size (& retval , 2 );
281+ ADD_ASSOC_STRINGL (& retval , "code" , intern -> code , intern -> code_len );
282+ ADD_ASSOC_ZVAL (& retval , "scope" , & state .zchild );
283+ #else
284+ ALLOC_INIT_ZVAL (retval );
285+ array_init_size (retval , 2 );
286+ ADD_ASSOC_STRINGL (retval , "code" , intern -> code , intern -> code_len );
287+ ADD_ASSOC_ZVAL (retval , "scope" , state .zchild );
288+ #endif
289+
290+ PHP_VAR_SERIALIZE_INIT (var_hash );
291+ php_var_serialize (& buf , & retval , & var_hash TSRMLS_CC );
292+ smart_str_0 (& buf );
293+ PHP_VAR_SERIALIZE_DESTROY (var_hash );
294+
295+ PHONGO_RETVAL_SMART_STR (buf );
296+
297+ smart_str_free (& buf );
298+ zval_ptr_dtor (& retval );
299+ zval_ptr_dtor (& state .zchild );
300+ }
301+ /* }}} */
302+
303+ /* {{{ proto string Javascript::unserialize(string $serialized)
304+ */
305+ PHP_METHOD (Javascript , unserialize )
306+ {
307+ php_phongo_javascript_t * intern ;
308+ zend_error_handling error_handling ;
309+ char * serialized ;
310+ phongo_zpp_char_len serialized_len ;
311+ #if PHP_VERSION_ID >= 70000
312+ zval props ;
313+ #else
314+ zval * props ;
315+ #endif
316+ php_unserialize_data_t var_hash ;
317+
318+ intern = Z_JAVASCRIPT_OBJ_P (getThis ());
319+
320+ zend_replace_error_handling (EH_THROW , phongo_exception_from_phongo_domain (PHONGO_ERROR_INVALID_ARGUMENT ), & error_handling TSRMLS_CC );
321+
322+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "s" , & serialized , & serialized_len ) == FAILURE ) {
323+ zend_restore_error_handling (& error_handling TSRMLS_CC );
324+ return ;
325+ }
326+ zend_restore_error_handling (& error_handling TSRMLS_CC );
327+
328+ #if PHP_VERSION_ID < 70000
329+ ALLOC_INIT_ZVAL (props );
330+ #endif
331+ PHP_VAR_UNSERIALIZE_INIT (var_hash );
332+ if (!php_var_unserialize (& props , (const unsigned char * * ) & serialized , (unsigned char * ) serialized + serialized_len , & var_hash TSRMLS_CC )) {
333+ zval_ptr_dtor (& props );
334+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "%s unserialization failed" , ZSTR_VAL (php_phongo_javascript_ce -> name ));
335+
336+ PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
337+ return ;
338+ }
339+ PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
340+
341+ #if PHP_VERSION_ID >= 70000
342+ php_phongo_javascript_init_from_hash (intern , HASH_OF (& props ) TSRMLS_CC );
343+ #else
344+ php_phongo_javascript_init_from_hash (intern , HASH_OF (props ) TSRMLS_CC );
345+ #endif
346+ zval_ptr_dtor (& props );
347+ }
348+ /* }}} */
349+
230350/* {{{ BSON\Javascript */
231351
232352ZEND_BEGIN_ARG_INFO_EX (ai_Javascript___construct , 0 , 0 , 1 )
@@ -238,6 +358,10 @@ ZEND_BEGIN_ARG_INFO_EX(ai_Javascript___set_state, 0, 0, 1)
238358 ZEND_ARG_ARRAY_INFO (0 , properties , 0 )
239359ZEND_END_ARG_INFO ()
240360
361+ ZEND_BEGIN_ARG_INFO_EX (ai_Javascript_unserialize , 0 , 0 , 1 )
362+ ZEND_ARG_INFO (0 , serialized )
363+ ZEND_END_ARG_INFO ()
364+
241365ZEND_BEGIN_ARG_INFO_EX (ai_Javascript_void , 0 , 0 , 0 )
242366ZEND_END_ARG_INFO ()
243367
@@ -246,6 +370,8 @@ static zend_function_entry php_phongo_javascript_me[] = {
246370 PHP_ME (Javascript , __set_state , ai_Javascript___set_state , ZEND_ACC_PUBLIC |ZEND_ACC_STATIC )
247371 PHP_ME (Javascript , __toString , ai_Javascript_void , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
248372 PHP_ME (Javascript , __wakeup , ai_Javascript_void , ZEND_ACC_PUBLIC )
373+ PHP_ME (Javascript , serialize , ai_Javascript_void , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
374+ PHP_ME (Javascript , unserialize , ai_Javascript_unserialize , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
249375 PHP_ME (Javascript , getCode , ai_Javascript_void , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
250376 PHP_ME (Javascript , getScope , ai_Javascript_void , ZEND_ACC_PUBLIC |ZEND_ACC_FINAL )
251377 PHP_FE_END
@@ -387,6 +513,7 @@ PHP_MINIT_FUNCTION(Javascript)
387513 PHONGO_CE_FINAL (php_phongo_javascript_ce );
388514
389515 zend_class_implements (php_phongo_javascript_ce TSRMLS_CC , 1 , php_phongo_type_ce );
516+ zend_class_implements (php_phongo_javascript_ce TSRMLS_CC , 1 , zend_ce_serializable );
390517
391518 memcpy (& php_phongo_handler_javascript , phongo_get_std_object_handlers (), sizeof (zend_object_handlers ));
392519 php_phongo_handler_javascript .get_properties = php_phongo_javascript_get_properties ;
0 commit comments