diff --git a/cake/libs/config/ini_reader.php b/cake/libs/config/ini_reader.php index 7163a47b5..e901d4e18 100644 --- a/cake/libs/config/ini_reader.php +++ b/cake/libs/config/ini_reader.php @@ -13,7 +13,7 @@ * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package cake - * @subpackage cake.cake.libs.controller.components + * @subpackage cake.libs.config * @since CakePHP(tm) v 2.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ @@ -23,6 +23,16 @@ * you should be aware that this class shares the same behavior, especially with * regards to boolean and null values. * + * In addition to the native parse_ini_file features, IniReader also allows you + * to create nested array structures through usage of . delimited names. This allows + * you to create nested arrays structures in an ini config file. For example: + * + * `db.password = secret` would turn into `array('db' => array('password' => 'secret'))` + * + * You can nest properties as deeply as needed using .'s. IniReader also manipulates + * how the special ini values of 'yes', 'no', 'on', 'off', 'null' are handled. + * These values will be converted to their boolean equivalents. + * * @package cake.config * @see http://php.net/parse_ini_file */ @@ -64,9 +74,35 @@ class IniReader implements ConfigReaderInterface { $filename = $this->_path . $file; $contents = parse_ini_file($filename, true); if (!empty($this->_section) && isset($contents[$this->_section])) { - $values = $contents[$this->_section]; + $values = $this->_parseNestedValues($contents[$this->_section]); } else { - $values = $contents; + $values = array(); + foreach ($contents as $section => $attribs) { + $values[$section] = $this->_parseNestedValues($attribs); + } + } + return $values; + } + +/** + * parses nested values out of keys. + * + * @param array $values Values to be exploded. + * @return array Array of values exploded + */ + protected function _parseNestedValues($values) { + foreach ($values as $key => $value) { + if ($value === '1') { + $value = true; + } + if ($value === '') { + $value = false; + } + if (strpos($key, '.') !== false) { + $values = Set::insert($values, $key, $value); + } else { + $values[$key] = $value; + } } return $values; } diff --git a/cake/tests/cases/libs/config/ini_reader.test.php b/cake/tests/cases/libs/config/ini_reader.test.php index c3da7edf0..ef397dece 100644 --- a/cake/tests/cases/libs/config/ini_reader.test.php +++ b/cake/tests/cases/libs/config/ini_reader.test.php @@ -65,4 +65,32 @@ class IniReaderTest extends CakeTestCase { $this->assertEquals('administrators', $config['groups']); } +/** + * test that names with .'s get exploded into arrays. + * + * @return void + */ + function testReadingValuesWithDots() { + $reader = new IniReader($this->path); + $config = $reader->read('nested.ini'); + + $this->assertTrue(isset($config['database']['db']['username'])); + $this->assertEquals('mark', $config['database']['db']['username']); + $this->assertEquals(3, $config['nesting']['one']['two']['three']); + } + +/** + * test boolean reading + * + * @return void + */ + function testBooleanReading() { + $reader = new IniReader($this->path); + $config = $reader->read('nested.ini'); + + $this->assertTrue($config['bools']['test_on']); + $this->assertTrue($config['bools']['test_yes']); + $this->assertFalse($config['bools']['test_no']); + $this->assertFalse($config['bools']['test_off']); + } } \ No newline at end of file