@@ -464,18 +464,32 @@ bool php_phongo_bson_visit_document(const bson_iter_t *iter ARG_UNUSED, const ch
464
464
array_init (state .zchild );
465
465
466
466
if (!bson_iter_visit_all (& child , & php_bson_visitors , & state )) {
467
- if ((state .map .document || state .odm ) && instanceof_function (state .odm ? state .odm : state .map .document , php_phongo_unserializable_ce TSRMLS_CC )) {
468
- zval * obj = NULL ;
469
-
470
- MAKE_STD_ZVAL (obj );
471
- object_init_ex (obj , state .odm ? state .odm : state .map .document );
472
- zend_call_method_with_1_params (& obj , NULL , NULL , BSON_UNSERIALIZE_FUNC_NAME , NULL , state .zchild );
473
- add_assoc_zval (retval , key , obj );
474
- zval_ptr_dtor (& state .zchild );
475
- } else {
476
- object_and_properties_init (state .zchild , zend_standard_class_def , Z_ARRVAL_P (state .zchild ));
477
- add_assoc_zval (retval , key , state .zchild );
478
- Z_SET_REFCOUNT_P (state .zchild , 1 );
467
+ if (state .odm ) {
468
+ state .map .document_type = PHONGO_TYPEMAP_CLASS ;
469
+ }
470
+ switch (state .map .document_type ) {
471
+ case PHONGO_TYPEMAP_NATIVE_ARRAY :
472
+ add_assoc_zval (retval , key , state .zchild );
473
+ Z_SET_REFCOUNT_P (state .zchild , 1 );
474
+ break ;
475
+
476
+ case PHONGO_TYPEMAP_CLASS :
477
+ if (instanceof_function (state .odm ? state .odm : state .map .document , php_phongo_unserializable_ce TSRMLS_CC )) {
478
+ zval * obj = NULL ;
479
+
480
+ MAKE_STD_ZVAL (obj );
481
+ object_init_ex (obj , state .odm ? state .odm : state .map .document );
482
+ zend_call_method_with_1_params (& obj , NULL , NULL , BSON_UNSERIALIZE_FUNC_NAME , NULL , state .zchild );
483
+ add_assoc_zval (retval , key , obj );
484
+ zval_ptr_dtor (& state .zchild );
485
+ break ;
486
+ }
487
+
488
+ case PHONGO_TYPEMAP_NATIVE_STDCLASS :
489
+ default :
490
+ object_and_properties_init (state .zchild , zend_standard_class_def , Z_ARRVAL_P (state .zchild ));
491
+ add_assoc_zval (retval , key , state .zchild );
492
+ Z_SET_REFCOUNT_P (state .zchild , 1 );
479
493
}
480
494
}
481
495
}
@@ -500,17 +514,35 @@ bool php_phongo_bson_visit_array(const bson_iter_t *iter ARG_UNUSED, const char
500
514
501
515
if (!bson_iter_visit_all (& child , & php_bson_visitors , & state )) {
502
516
503
- if (state .map .array && instanceof_function (state .map .array , php_phongo_unserializable_ce TSRMLS_CC )) {
504
- zval * obj = NULL ;
517
+ switch (state .map .array_type ) {
518
+ case PHONGO_TYPEMAP_CLASS :
519
+ if (instanceof_function (state .map .array , php_phongo_unserializable_ce TSRMLS_CC )) {
520
+ zval * obj = NULL ;
521
+
522
+ MAKE_STD_ZVAL (obj );
523
+ object_init_ex (obj , state .map .array );
524
+ zend_call_method_with_1_params (& obj , NULL , NULL , BSON_UNSERIALIZE_FUNC_NAME , NULL , state .zchild );
525
+ add_assoc_zval (retval , key , obj );
526
+ zval_ptr_dtor (& state .zchild );
527
+ break ;
528
+ }
529
+ /* If the object someehow doesn't implement php_phongo_unserializable_ce then use stdclass.
530
+ * This is needed as we need to know how to pass the state.zchild to the class to populate it.
531
+ * Not all classes have ctor that accepts first parameter array of values.
532
+ */
533
+
534
+ /* break intentionally omitted */
535
+ case PHONGO_TYPEMAP_NATIVE_STDCLASS :
536
+ object_and_properties_init (state .zchild , zend_standard_class_def , Z_ARRVAL_P (state .zchild ));
537
+ add_assoc_zval (retval , key , state .zchild );
538
+ Z_SET_REFCOUNT_P (state .zchild , 1 );
539
+ break ;
505
540
506
- MAKE_STD_ZVAL (obj );
507
- object_init_ex (obj , state .map .array );
508
- zend_call_method_with_1_params (& obj , NULL , NULL , BSON_UNSERIALIZE_FUNC_NAME , NULL , state .zchild );
509
- add_assoc_zval (retval , key , obj );
510
- zval_ptr_dtor (& state .zchild );
511
- } else {
512
- add_assoc_zval (retval , key , state .zchild );
513
- Z_SET_REFCOUNT_P (state .zchild , 1 );
541
+ case PHONGO_TYPEMAP_NATIVE_ARRAY :
542
+ default :
543
+ add_assoc_zval (retval , key , state .zchild );
544
+ Z_SET_REFCOUNT_P (state .zchild , 1 );
545
+ break ;
514
546
}
515
547
}
516
548
@@ -561,7 +593,7 @@ int php_phongo_is_array_or_document(zval **val TSRMLS_DC) /* {{{ */
561
593
return IS_ARRAY ;
562
594
}
563
595
/* }}} */
564
- void object_to_bson (zval * object , phongo_bson_flags_t flags , const char * key , long key_len , bson_t * bson TSRMLS_DC )
596
+ void object_to_bson (zval * object , php_phongo_bson_flags_t flags , const char * key , long key_len , bson_t * bson TSRMLS_DC )
565
597
{
566
598
bson_t child ;
567
599
@@ -667,7 +699,7 @@ void object_to_bson(zval *object, phongo_bson_flags_t flags, const char *key, lo
667
699
}
668
700
}
669
701
}
670
- void phongo_bson_append (bson_t * bson , phongo_bson_flags_t flags , const char * key , long key_len , int entry_type , zval * entry TSRMLS_DC )
702
+ void phongo_bson_append (bson_t * bson , php_phongo_bson_flags_t flags , const char * key , long key_len , int entry_type , zval * entry TSRMLS_DC )
671
703
{
672
704
switch (entry_type )
673
705
{
@@ -725,7 +757,7 @@ void phongo_bson_append(bson_t *bson, phongo_bson_flags_t flags, const char *key
725
757
}
726
758
}
727
759
728
- PHONGO_API void zval_to_bson (zval * data , phongo_bson_flags_t flags , bson_t * bson , bson_t * * bson_out TSRMLS_DC ) /* {{{ */
760
+ PHONGO_API void zval_to_bson (zval * data , php_phongo_bson_flags_t flags , bson_t * bson , bson_t * * bson_out TSRMLS_DC ) /* {{{ */
729
761
{
730
762
HashPosition pos ;
731
763
HashTable * ht_data ;
@@ -906,10 +938,17 @@ void php_phongo_bson_typemap_to_state(zval *typemap, php_phongo_bson_typemap *ma
906
938
907
939
classname = php_array_fetchl_string (typemap , "array" , sizeof ("array" )- 1 , & classname_len , & classname_free );
908
940
if (classname_len ) {
909
- array_ce = zend_fetch_class (classname , classname_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC );
941
+ if (!strcasecmp (classname , "array" )) {
942
+ map -> array_type = PHONGO_TYPEMAP_NATIVE_ARRAY ;
943
+ } else if (!strcasecmp (classname , "stdclass" )) {
944
+ map -> array_type = PHONGO_TYPEMAP_NATIVE_STDCLASS ;
945
+ } else {
946
+ map -> array_type = PHONGO_TYPEMAP_CLASS ;
947
+ array_ce = zend_fetch_class (classname , classname_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC );
910
948
911
- if (instanceof_function (array_ce , php_phongo_unserializable_ce TSRMLS_CC )) {
912
- map -> array = array_ce ;
949
+ if (instanceof_function (array_ce , php_phongo_unserializable_ce TSRMLS_CC )) {
950
+ map -> array = array_ce ;
951
+ }
913
952
}
914
953
if (classname_free ) {
915
954
efree (classname );
@@ -918,9 +957,17 @@ void php_phongo_bson_typemap_to_state(zval *typemap, php_phongo_bson_typemap *ma
918
957
919
958
classname = php_array_fetchl_string (typemap , "document" , sizeof ("document" )- 1 , & classname_len , & classname_free );
920
959
if (classname_len ) {
921
- document_ce = zend_fetch_class (classname , classname_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC );
922
- if (instanceof_function (document_ce , php_phongo_unserializable_ce TSRMLS_CC )) {
923
- map -> document = document_ce ;
960
+ if (!strcasecmp (classname , "array" )) {
961
+ map -> document_type = PHONGO_TYPEMAP_NATIVE_ARRAY ;
962
+ } else if (!strcasecmp (classname , "stdclass" )) {
963
+ map -> document_type = PHONGO_TYPEMAP_NATIVE_STDCLASS ;
964
+ } else {
965
+ map -> document_type = PHONGO_TYPEMAP_CLASS ;
966
+ document_ce = zend_fetch_class (classname , classname_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC );
967
+
968
+ if (instanceof_function (document_ce , php_phongo_unserializable_ce TSRMLS_CC )) {
969
+ map -> document = document_ce ;
970
+ }
924
971
}
925
972
if (classname_free ) {
926
973
efree (classname );
0 commit comments