pictcode_admin / lib / Cake / Configure / IniReader.php @ master
履歴 | 表示 | アノテート | ダウンロード (6.189 KB)
1 |
<?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 |
} |