diff --git a/ext/config.c b/ext/config.c index e60da0c3269..54f66917c32 100644 --- a/ext/config.c +++ b/ext/config.c @@ -542,6 +542,8 @@ PHP_METHOD(Phalcon_Config, offsetUnset){ /** * Merges a configuration into the current one * + * @brief void Phalcon\Config::merge(array|object $with) + * * * $appConfig = new Phalcon\Config(array('database' => array('host' => 'localhost'))); * $globalConfig->merge($config2); @@ -559,13 +561,19 @@ PHP_METHOD(Phalcon_Config, merge){ phalcon_fetch_params(0, 1, 0, &config); - if (Z_TYPE_P(config) != IS_OBJECT) { - PHALCON_THROW_EXCEPTION_STRW(phalcon_config_exception_ce, "Configuration must be an Object"); + if (Z_TYPE_P(config) != IS_OBJECT && Z_TYPE_P(config) != IS_ARRAY) { + PHALCON_THROW_EXCEPTION_STRW(phalcon_config_exception_ce, "Configuration must be an object or array"); return; } - ALLOC_INIT_ZVAL(array_config); - phalcon_config_toarray_internal(array_config, config TSRMLS_CC); + if (Z_TYPE_P(config) == IS_OBJECT) { + ALLOC_INIT_ZVAL(array_config); + phalcon_config_toarray_internal(array_config, config TSRMLS_CC); + } + else { + array_config = config; + Z_ADDREF_P(array_config); + } phalcon_is_iterable(array_config, &ah0, &hp0, 0, 0); @@ -581,11 +589,9 @@ PHP_METHOD(Phalcon_Config, merge){ * The key is already defined in the object, we have to merge it */ if (active_value) { - if (Z_TYPE_PP(hd) == IS_OBJECT && Z_TYPE_P(active_value) == IS_OBJECT) { + if ((Z_TYPE_PP(hd) == IS_OBJECT || Z_TYPE_PP(hd) == IS_ARRAY) && Z_TYPE_P(active_value) == IS_OBJECT) { if (phalcon_method_exists_ex(active_value, SS("merge") TSRMLS_CC) == SUCCESS) { /* Path AAA in the test */ - Z_ADDREF_PP(hd); phalcon_call_method_params(NULL, active_value, SL("merge"), zend_inline_hash_func(SS("merge")) TSRMLS_CC, 1, *hd); - Z_DELREF_PP(hd); } else { /* Path AAB in the test */ phalcon_config_write_internal(obj, &key, *hd TSRMLS_CC); @@ -611,6 +617,8 @@ PHP_METHOD(Phalcon_Config, merge){ /** * Converts recursively the object to an array * + * @brief array Phalcon\Config::toArray(bool $recursive = true); + * * * print_r($config->toArray()); * @@ -619,29 +627,31 @@ PHP_METHOD(Phalcon_Config, merge){ */ PHP_METHOD(Phalcon_Config, toArray){ - zval key, *array_value = NULL, *tmp; - HashTable *ah0; - HashPosition hp0; - zval **hd; + zval key, *array_value = NULL, *recursive = NULL, *tmp; + HashPosition hp; + zval **value; phalcon_config_object *obj; + phalcon_fetch_params(0, 0, 1, &recursive); + obj = fetchPhalconConfigObject(getThis() TSRMLS_CC); array_init_size(return_value, zend_hash_num_elements(obj->props)); zend_hash_copy(Z_ARRVAL_P(return_value), obj->props, (copy_ctor_func_t)zval_add_ref, (void*)&tmp, sizeof(zval*)); - phalcon_is_iterable(return_value, &ah0, &hp0, 0, 0); - - while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) { - - key = phalcon_get_current_key_w(ah0, &hp0); - - if (Z_TYPE_PP(hd) == IS_OBJECT && phalcon_method_exists_ex(*hd, SS("toarray") TSRMLS_CC) == SUCCESS) { - ALLOC_INIT_ZVAL(array_value); - phalcon_call_method_params(array_value, *hd, SL("toarray"), zend_inline_hash_func(SS("toarray")) TSRMLS_CC, 0); - phalcon_array_update_zval(&return_value, &key, &array_value, PH_SEPARATE); + if (!recursive || zend_is_true(recursive)) { + for ( + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(return_value), &hp); + zend_hash_get_current_data_ex(Z_ARRVAL_P(return_value), (void**)&value, &hp) == SUCCESS && !EG(exception); + zend_hash_move_forward_ex(Z_ARRVAL_P(return_value), &hp) + ) { + key = phalcon_get_current_key_w(Z_ARRVAL_P(return_value), &hp); + + if (Z_TYPE_PP(value) == IS_OBJECT && phalcon_method_exists_ex(*value, SS("toarray") TSRMLS_CC) == SUCCESS) { + ALLOC_INIT_ZVAL(array_value); + phalcon_call_method_params(array_value, *value, SL("toarray"), zend_inline_hash_func(SS("toarray")) TSRMLS_CC, 0); + phalcon_array_update_zval(&return_value, &key, &array_value, 0); + } } - - zend_hash_move_forward_ex(ah0, &hp0); } } diff --git a/unit-tests/ConfigTest.php b/unit-tests/ConfigTest.php index c3a6b4218db..ccddaf0c2c2 100644 --- a/unit-tests/ConfigTest.php +++ b/unit-tests/ConfigTest.php @@ -316,4 +316,19 @@ public function testIssue1000() $t2 = new Issue1000('test', 'test'); $this->assertTrue(true); } + + public function testIssue1024() + { + $config1 = new \Phalcon\Config\Adapter\Ini(__DIR__ . '/config/1024-a.ini'); + $config2 = new \Phalcon\Config\Adapter\Ini(__DIR__ . '/config/1024-b.ini'); + + $config1->merge($config2); + $actual = $config1->toArray(); + $expected = array( + 'a' => array( + 'a_1' => 1, + 'a_2' => 1, + ), + ); + } } diff --git a/unit-tests/config/1024-a.ini b/unit-tests/config/1024-a.ini new file mode 100644 index 00000000000..b767ba1b4e0 --- /dev/null +++ b/unit-tests/config/1024-a.ini @@ -0,0 +1,2 @@ +[a] +a_1 = 1 diff --git a/unit-tests/config/1024-b.ini b/unit-tests/config/1024-b.ini new file mode 100644 index 00000000000..e588cf88cfc --- /dev/null +++ b/unit-tests/config/1024-b.ini @@ -0,0 +1,2 @@ +[a] +a_2 = 1