pictcode / lib / Cake / Configure / IniReader.php @ 19966135
履歴 | 表示 | アノテート | ダウンロード (6.189 KB)
| 1 | 635eef61 | spyder1211 | <?php
 | 
      
|---|---|---|---|
| 2 | /**
 | 
      ||
| 3 |  * IniReader
 | 
      ||
| 4 |  *
 | 
      ||
| 5 |  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 | 
      ||
| 6 |  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 | 
      ||
| 7 |  *
 | 
      ||
| 8 |  * Licensed under The MIT License
 | 
      ||
| 9 |  * For full copyright and license information, please see the LICENSE.txt
 | 
      ||
| 10 |  * Redistributions of files must retain the above copyright notice.
 | 
      ||
| 11 |  *
 | 
      ||
| 12 |  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 | 
      ||
| 13 |  * @link          http://cakephp.org CakePHP(tm) Project
 | 
      ||
| 14 |  * @package       Cake.Configure
 | 
      ||
| 15 |  * @since         CakePHP(tm) v 2.0
 | 
      ||
| 16 |  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 | 
      ||
| 17 |  */
 | 
      ||
| 18 | |||
| 19 | App::uses('Hash', 'Utility');  | 
      ||
| 20 | App::uses('CakePlugin', 'Core');  | 
      ||
| 21 | |||
| 22 | /**
 | 
      ||
| 23 |  * Ini file configuration engine.
 | 
      ||
| 24 |  *
 | 
      ||
| 25 |  * Since IniReader uses parse_ini_file underneath, you should be aware that this
 | 
      ||
| 26 |  * class shares the same behavior, especially with regards to boolean and null values.
 | 
      ||
| 27 |  *
 | 
      ||
| 28 |  * In addition to the native `parse_ini_file` features, IniReader also allows you
 | 
      ||
| 29 |  * to create nested array structures through usage of `.` delimited names. This allows
 | 
      ||
| 30 |  * you to create nested arrays structures in an ini config file. For example:
 | 
      ||
| 31 |  *
 | 
      ||
| 32 |  * `db.password = secret` would turn into `array('db' => array('password' => 'secret'))`
 | 
      ||
| 33 |  *
 | 
      ||
| 34 |  * You can nest properties as deeply as needed using `.`'s. In addition to using `.` you
 | 
      ||
| 35 |  * can use standard ini section notation to create nested structures:
 | 
      ||
| 36 |  *
 | 
      ||
| 37 |  * ```
 | 
      ||
| 38 |  * [section]
 | 
      ||
| 39 |  * key = value
 | 
      ||
| 40 |  * ```
 | 
      ||
| 41 |  *
 | 
      ||
| 42 |  * Once loaded into Configure, the above would be accessed using:
 | 
      ||
| 43 |  *
 | 
      ||
| 44 |  * `Configure::read('section.key');
 | 
      ||
| 45 |  *
 | 
      ||
| 46 |  * You can combine `.` separated values with sections to create more deeply
 | 
      ||
| 47 |  * nested structures.
 | 
      ||
| 48 |  *
 | 
      ||
| 49 |  * IniReader also manipulates how the special ini values of
 | 
      ||
| 50 |  * 'yes', 'no', 'on', 'off', 'null' are handled. These values will be
 | 
      ||
| 51 |  * converted to their boolean equivalents.
 | 
      ||
| 52 |  *
 | 
      ||
| 53 |  * @package       Cake.Configure
 | 
      ||
| 54 |  * @see http://php.net/parse_ini_file
 | 
      ||
| 55 |  */
 | 
      ||
| 56 | class IniReader implements ConfigReaderInterface {  | 
      ||
| 57 | |||
| 58 | /**
 | 
      ||
| 59 |  * The path to read ini files from.
 | 
      ||
| 60 |  *
 | 
      ||
| 61 |  * @var array
 | 
      ||
| 62 |  */
 | 
      ||
| 63 | protected $_path;  | 
      ||
| 64 | |||
| 65 | /**
 | 
      ||
| 66 |  * The section to read, if null all sections will be read.
 | 
      ||
| 67 |  *
 | 
      ||
| 68 |  * @var string
 | 
      ||
| 69 |  */
 | 
      ||
| 70 | protected $_section;  | 
      ||
| 71 | |||
| 72 | /**
 | 
      ||
| 73 |  * Build and construct a new ini file parser. The parser can be used to read
 | 
      ||
| 74 |  * ini files that are on the filesystem.
 | 
      ||
| 75 |  *
 | 
      ||
| 76 |  * @param string $path Path to load ini config files from. Defaults to APP . 'Config' . DS
 | 
      ||
| 77 |  * @param string $section Only get one section, leave null to parse and fetch
 | 
      ||
| 78 |  *     all sections in the ini file.
 | 
      ||
| 79 |  */
 | 
      ||
| 80 | public function __construct($path = null, $section = null) {  | 
      ||
| 81 | if (!$path) {  | 
      ||
| 82 | $path = APP . 'Config' . DS;  | 
      ||
| 83 | }  | 
      ||
| 84 | $this->_path = $path;  | 
      ||
| 85 | $this->_section = $section;  | 
      ||
| 86 | }  | 
      ||
| 87 | |||
| 88 | /**
 | 
      ||
| 89 |  * Read an ini file and return the results as an array.
 | 
      ||
| 90 |  *
 | 
      ||
| 91 |  * For backwards compatibility, acl.ini.php will be treated specially until 3.0.
 | 
      ||
| 92 |  *
 | 
      ||
| 93 |  * @param string $key The identifier to read from. If the key has a . it will be treated
 | 
      ||
| 94 |  *  as a plugin prefix. The chosen file must be on the reader's path.
 | 
      ||
| 95 |  * @return array Parsed configuration values.
 | 
      ||
| 96 |  * @throws ConfigureException when files don't exist.
 | 
      ||
| 97 |  *  Or when files contain '..' as this could lead to abusive reads.
 | 
      ||
| 98 |  */
 | 
      ||
| 99 | public function read($key) {  | 
      ||
| 100 | if (strpos($key, '..') !== false) {  | 
      ||
| 101 | throw new ConfigureException(__d('cake_dev', 'Cannot load configuration files with ../ in them.'));  | 
      ||
| 102 | }  | 
      ||
| 103 | |||
| 104 | $file = $this->_getFilePath($key);  | 
      ||
| 105 | if (!is_file($file)) {  | 
      ||
| 106 | throw new ConfigureException(__d('cake_dev', 'Could not load configuration file: %s', $file));  | 
      ||
| 107 | }  | 
      ||
| 108 | |||
| 109 | $contents = parse_ini_file($file, true);  | 
      ||
| 110 | if (!empty($this->_section) && isset($contents[$this->_section])) {  | 
      ||
| 111 | $values = $this->_parseNestedValues($contents[$this->_section]);  | 
      ||
| 112 |                 } else {
 | 
      ||
| 113 | $values = array();  | 
      ||
| 114 | foreach ($contents as $section => $attribs) {  | 
      ||
| 115 | if (is_array($attribs)) {  | 
      ||
| 116 | $values[$section] = $this->_parseNestedValues($attribs);  | 
      ||
| 117 |                                 } else {
 | 
      ||
| 118 | $parse = $this->_parseNestedValues(array($attribs));  | 
      ||
| 119 | $values[$section] = array_shift($parse);  | 
      ||
| 120 | }  | 
      ||
| 121 | }  | 
      ||
| 122 | }  | 
      ||
| 123 | return $values;  | 
      ||
| 124 | }  | 
      ||
| 125 | |||
| 126 | /**
 | 
      ||
| 127 |  * parses nested values out of keys.
 | 
      ||
| 128 |  *
 | 
      ||
| 129 |  * @param array $values Values to be exploded.
 | 
      ||
| 130 |  * @return array Array of values exploded
 | 
      ||
| 131 |  */
 | 
      ||
| 132 | protected function _parseNestedValues($values) {  | 
      ||
| 133 | foreach ($values as $key => $value) {  | 
      ||
| 134 | if ($value === '1') {  | 
      ||
| 135 | $value = true;  | 
      ||
| 136 | }  | 
      ||
| 137 | if ($value === '') {  | 
      ||
| 138 | $value = false;  | 
      ||
| 139 | }  | 
      ||
| 140 | unset($values[$key]);  | 
      ||
| 141 | if (strpos($key, '.') !== false) {  | 
      ||
| 142 | $values = Hash::insert($values, $key, $value);  | 
      ||
| 143 |                         } else {
 | 
      ||
| 144 | $values[$key] = $value;  | 
      ||
| 145 | }  | 
      ||
| 146 | }  | 
      ||
| 147 | return $values;  | 
      ||
| 148 | }  | 
      ||
| 149 | |||
| 150 | /**
 | 
      ||
| 151 |  * Dumps the state of Configure data into an ini formatted string.
 | 
      ||
| 152 |  *
 | 
      ||
| 153 |  * @param string $key The identifier to write to. If the key has a . it will be treated
 | 
      ||
| 154 |  *  as a plugin prefix.
 | 
      ||
| 155 |  * @param array $data The data to convert to ini file.
 | 
      ||
| 156 |  * @return int Bytes saved.
 | 
      ||
| 157 |  */
 | 
      ||
| 158 | public function dump($key, $data) {  | 
      ||
| 159 | $result = array();  | 
      ||
| 160 | foreach ($data as $k => $value) {  | 
      ||
| 161 | $isSection = false;  | 
      ||
| 162 | if ($k[0] !== '[') {  | 
      ||
| 163 | $result[] = "[$k]";  | 
      ||
| 164 | $isSection = true;  | 
      ||
| 165 | }  | 
      ||
| 166 | if (is_array($value)) {  | 
      ||
| 167 | $kValues = Hash::flatten($value, '.');  | 
      ||
| 168 | foreach ($kValues as $k2 => $v) {  | 
      ||
| 169 | $result[] = "$k2 = " . $this->_value($v);  | 
      ||
| 170 | }  | 
      ||
| 171 | }  | 
      ||
| 172 | if ($isSection) {  | 
      ||
| 173 | $result[] = '';  | 
      ||
| 174 | }  | 
      ||
| 175 | }  | 
      ||
| 176 | $contents = trim(implode("\n", $result));  | 
      ||
| 177 | |||
| 178 | $filename = $this->_getFilePath($key);  | 
      ||
| 179 | return file_put_contents($filename, $contents);  | 
      ||
| 180 | }  | 
      ||
| 181 | |||
| 182 | /**
 | 
      ||
| 183 |  * Converts a value into the ini equivalent
 | 
      ||
| 184 |  *
 | 
      ||
| 185 |  * @param mixed $val Value to export.
 | 
      ||
| 186 |  * @return string String value for ini file.
 | 
      ||
| 187 |  */
 | 
      ||
| 188 | protected function _value($val) {  | 
      ||
| 189 | if ($val === null) {  | 
      ||
| 190 | return 'null';  | 
      ||
| 191 | }  | 
      ||
| 192 | if ($val === true) {  | 
      ||
| 193 | return 'true';  | 
      ||
| 194 | }  | 
      ||
| 195 | if ($val === false) {  | 
      ||
| 196 | return 'false';  | 
      ||
| 197 | }  | 
      ||
| 198 | return (string)$val;  | 
      ||
| 199 | }  | 
      ||
| 200 | |||
| 201 | /**
 | 
      ||
| 202 |  * Get file path
 | 
      ||
| 203 |  *
 | 
      ||
| 204 |  * @param string $key The identifier to write to. If the key has a . it will be treated
 | 
      ||
| 205 |  *  as a plugin prefix.
 | 
      ||
| 206 |  * @return string Full file path
 | 
      ||
| 207 |  */
 | 
      ||
| 208 | protected function _getFilePath($key) {  | 
      ||
| 209 | if (substr($key, -8) === '.ini.php') {  | 
      ||
| 210 | $key = substr($key, 0, -8);  | 
      ||
| 211 | list($plugin, $key) = pluginSplit($key);  | 
      ||
| 212 | $key .= '.ini.php';  | 
      ||
| 213 |                 } else {
 | 
      ||
| 214 | if (substr($key, -4) === '.ini') {  | 
      ||
| 215 | $key = substr($key, 0, -4);  | 
      ||
| 216 | }  | 
      ||
| 217 | list($plugin, $key) = pluginSplit($key);  | 
      ||
| 218 | $key .= '.ini';  | 
      ||
| 219 | }  | 
      ||
| 220 | |||
| 221 | if ($plugin) {  | 
      ||
| 222 | $file = CakePlugin::path($plugin) . 'Config' . DS . $key;  | 
      ||
| 223 |                 } else {
 | 
      ||
| 224 | $file = $this->_path . $key;  | 
      ||
| 225 | }  | 
      ||
| 226 | |||
| 227 | return $file;  | 
      ||
| 228 | }  | 
      ||
| 229 | |||
| 230 | }  |