Commit | Line | Data |
---|---|---|
51ff3226 | 1 | <?php |
2 | ||
3 | /** | |
4 | * Config_File class. | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2.1 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | * | |
9b7c11be H |
20 | * For questions, help, comments, discussion, etc., please join the |
21 | * Smarty mailing list. Send a blank e-mail to | |
22 | * smarty-discussion-subscribe@googlegroups.com | |
23 | * | |
24 | * @link http://www.smarty.net/ | |
25 | * @version 2.6.26 | |
51ff3226 | 26 | * @copyright Copyright: 2001-2005 New Digital Group, Inc. |
27 | * @author Andrei Zmievski <andrei@php.net> | |
28 | * @access public | |
29 | * @package Smarty | |
30 | */ | |
31 | ||
9b7c11be | 32 | /* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */ |
51ff3226 | 33 | |
34 | /** | |
35 | * Config file reading class | |
36 | * @package Smarty | |
37 | */ | |
38 | class Config_File { | |
39 | /**#@+ | |
40 | * Options | |
41 | * @var boolean | |
42 | */ | |
43 | /** | |
44 | * Controls whether variables with the same name overwrite each other. | |
45 | */ | |
46 | var $overwrite = true; | |
47 | ||
48 | /** | |
49 | * Controls whether config values of on/true/yes and off/false/no get | |
50 | * converted to boolean values automatically. | |
51 | */ | |
52 | var $booleanize = true; | |
53 | ||
54 | /** | |
55 | * Controls whether hidden config sections/vars are read from the file. | |
56 | */ | |
57 | var $read_hidden = true; | |
58 | ||
59 | /** | |
60 | * Controls whether or not to fix mac or dos formatted newlines. | |
61 | * If set to true, \r or \r\n will be changed to \n. | |
62 | */ | |
63 | var $fix_newlines = true; | |
64 | /**#@-*/ | |
65 | ||
66 | /** @access private */ | |
67 | var $_config_path = ""; | |
68 | var $_config_data = array(); | |
69 | /**#@-*/ | |
70 | ||
71 | /** | |
72 | * Constructs a new config file class. | |
73 | * | |
74 | * @param string $config_path (optional) path to the config files | |
75 | */ | |
76 | function Config_File($config_path = NULL) | |
77 | { | |
78 | if (isset($config_path)) | |
79 | $this->set_path($config_path); | |
80 | } | |
81 | ||
82 | ||
83 | /** | |
84 | * Set the path where configuration files can be found. | |
85 | * | |
86 | * @param string $config_path path to the config files | |
87 | */ | |
88 | function set_path($config_path) | |
89 | { | |
90 | if (!empty($config_path)) { | |
91 | if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { | |
92 | $this->_trigger_error_msg("Bad config file path '$config_path'"); | |
93 | return; | |
94 | } | |
95 | if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { | |
96 | $config_path .= DIRECTORY_SEPARATOR; | |
97 | } | |
98 | ||
99 | $this->_config_path = $config_path; | |
100 | } | |
101 | } | |
102 | ||
103 | ||
104 | /** | |
105 | * Retrieves config info based on the file, section, and variable name. | |
106 | * | |
107 | * @param string $file_name config file to get info for | |
108 | * @param string $section_name (optional) section to get info for | |
109 | * @param string $var_name (optional) variable to get info for | |
110 | * @return string|array a value or array of values | |
111 | */ | |
112 | function get($file_name, $section_name = NULL, $var_name = NULL) | |
113 | { | |
114 | if (empty($file_name)) { | |
115 | $this->_trigger_error_msg('Empty config file name'); | |
116 | return; | |
117 | } else { | |
118 | $file_name = $this->_config_path . $file_name; | |
119 | if (!isset($this->_config_data[$file_name])) | |
120 | $this->load_file($file_name, false); | |
121 | } | |
122 | ||
123 | if (!empty($var_name)) { | |
124 | if (empty($section_name)) { | |
125 | return $this->_config_data[$file_name]["vars"][$var_name]; | |
126 | } else { | |
127 | if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) | |
128 | return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; | |
129 | else | |
130 | return array(); | |
131 | } | |
132 | } else { | |
133 | if (empty($section_name)) { | |
134 | return (array)$this->_config_data[$file_name]["vars"]; | |
135 | } else { | |
136 | if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) | |
137 | return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; | |
138 | else | |
139 | return array(); | |
140 | } | |
141 | } | |
142 | } | |
143 | ||
144 | ||
145 | /** | |
146 | * Retrieves config info based on the key. | |
147 | * | |
148 | * @param $file_name string config key (filename/section/var) | |
149 | * @return string|array same as get() | |
150 | * @uses get() retrieves information from config file and returns it | |
151 | */ | |
152 | function &get_key($config_key) | |
153 | { | |
154 | list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); | |
155 | $result = &$this->get($file_name, $section_name, $var_name); | |
156 | return $result; | |
157 | } | |
158 | ||
159 | /** | |
160 | * Get all loaded config file names. | |
161 | * | |
162 | * @return array an array of loaded config file names | |
163 | */ | |
164 | function get_file_names() | |
165 | { | |
166 | return array_keys($this->_config_data); | |
167 | } | |
168 | ||
169 | ||
170 | /** | |
171 | * Get all section names from a loaded file. | |
172 | * | |
173 | * @param string $file_name config file to get section names from | |
174 | * @return array an array of section names from the specified file | |
175 | */ | |
176 | function get_section_names($file_name) | |
177 | { | |
178 | $file_name = $this->_config_path . $file_name; | |
179 | if (!isset($this->_config_data[$file_name])) { | |
180 | $this->_trigger_error_msg("Unknown config file '$file_name'"); | |
181 | return; | |
182 | } | |
183 | ||
184 | return array_keys($this->_config_data[$file_name]["sections"]); | |
185 | } | |
186 | ||
187 | ||
188 | /** | |
189 | * Get all global or section variable names. | |
190 | * | |
191 | * @param string $file_name config file to get info for | |
192 | * @param string $section_name (optional) section to get info for | |
193 | * @return array an array of variables names from the specified file/section | |
194 | */ | |
195 | function get_var_names($file_name, $section = NULL) | |
196 | { | |
197 | if (empty($file_name)) { | |
198 | $this->_trigger_error_msg('Empty config file name'); | |
199 | return; | |
200 | } else if (!isset($this->_config_data[$file_name])) { | |
201 | $this->_trigger_error_msg("Unknown config file '$file_name'"); | |
202 | return; | |
203 | } | |
204 | ||
205 | if (empty($section)) | |
206 | return array_keys($this->_config_data[$file_name]["vars"]); | |
207 | else | |
208 | return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); | |
209 | } | |
210 | ||
211 | ||
212 | /** | |
213 | * Clear loaded config data for a certain file or all files. | |
214 | * | |
215 | * @param string $file_name file to clear config data for | |
216 | */ | |
217 | function clear($file_name = NULL) | |
218 | { | |
219 | if ($file_name === NULL) | |
220 | $this->_config_data = array(); | |
221 | else if (isset($this->_config_data[$file_name])) | |
222 | $this->_config_data[$file_name] = array(); | |
223 | } | |
224 | ||
225 | ||
226 | /** | |
227 | * Load a configuration file manually. | |
228 | * | |
229 | * @param string $file_name file name to load | |
230 | * @param boolean $prepend_path whether current config path should be | |
231 | * prepended to the filename | |
232 | */ | |
233 | function load_file($file_name, $prepend_path = true) | |
234 | { | |
235 | if ($prepend_path && $this->_config_path != "") | |
236 | $config_file = $this->_config_path . $file_name; | |
237 | else | |
238 | $config_file = $file_name; | |
239 | ||
240 | ini_set('track_errors', true); | |
241 | $fp = @fopen($config_file, "r"); | |
242 | if (!is_resource($fp)) { | |
243 | $this->_trigger_error_msg("Could not open config file '$config_file'"); | |
244 | return false; | |
245 | } | |
246 | ||
247 | $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; | |
248 | fclose($fp); | |
249 | ||
250 | $this->_config_data[$config_file] = $this->parse_contents($contents); | |
251 | return true; | |
252 | } | |
253 | ||
254 | /** | |
255 | * Store the contents of a file manually. | |
256 | * | |
257 | * @param string $config_file file name of the related contents | |
258 | * @param string $contents the file-contents to parse | |
259 | */ | |
260 | function set_file_contents($config_file, $contents) | |
261 | { | |
262 | $this->_config_data[$config_file] = $this->parse_contents($contents); | |
263 | return true; | |
264 | } | |
265 | ||
266 | /** | |
267 | * parse the source of a configuration file manually. | |
268 | * | |
269 | * @param string $contents the file-contents to parse | |
270 | */ | |
271 | function parse_contents($contents) | |
272 | { | |
273 | if($this->fix_newlines) { | |
274 | // fix mac/dos formatted newlines | |
275 | $contents = preg_replace('!\r\n?!', "\n", $contents); | |
276 | } | |
277 | ||
278 | $config_data = array(); | |
279 | $config_data['sections'] = array(); | |
280 | $config_data['vars'] = array(); | |
281 | ||
282 | /* reference to fill with data */ | |
283 | $vars =& $config_data['vars']; | |
284 | ||
285 | /* parse file line by line */ | |
286 | preg_match_all('!^.*\r?\n?!m', $contents, $match); | |
287 | $lines = $match[0]; | |
288 | for ($i=0, $count=count($lines); $i<$count; $i++) { | |
289 | $line = $lines[$i]; | |
290 | if (empty($line)) continue; | |
291 | ||
9b7c11be | 292 | if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { |
51ff3226 | 293 | /* section found */ |
9b7c11be | 294 | if (substr($match[1], 0, 1) == '.') { |
51ff3226 | 295 | /* hidden section */ |
296 | if ($this->read_hidden) { | |
297 | $section_name = substr($match[1], 1); | |
298 | } else { | |
299 | /* break reference to $vars to ignore hidden section */ | |
300 | unset($vars); | |
301 | $vars = array(); | |
302 | continue; | |
303 | } | |
9b7c11be | 304 | } else { |
51ff3226 | 305 | $section_name = $match[1]; |
306 | } | |
307 | if (!isset($config_data['sections'][$section_name])) | |
308 | $config_data['sections'][$section_name] = array('vars' => array()); | |
309 | $vars =& $config_data['sections'][$section_name]['vars']; | |
310 | continue; | |
311 | } | |
312 | ||
313 | if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { | |
314 | /* variable found */ | |
315 | $var_name = rtrim($match[1]); | |
316 | if (strpos($match[2], '"""') === 0) { | |
317 | /* handle multiline-value */ | |
318 | $lines[$i] = substr($match[2], 3); | |
319 | $var_value = ''; | |
320 | while ($i<$count) { | |
321 | if (($pos = strpos($lines[$i], '"""')) === false) { | |
322 | $var_value .= $lines[$i++]; | |
323 | } else { | |
324 | /* end of multiline-value */ | |
325 | $var_value .= substr($lines[$i], 0, $pos); | |
326 | break; | |
327 | } | |
328 | } | |
329 | $booleanize = false; | |
330 | ||
331 | } else { | |
332 | /* handle simple value */ | |
333 | $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); | |
334 | $booleanize = $this->booleanize; | |
335 | ||
336 | } | |
337 | $this->_set_config_var($vars, $var_name, $var_value, $booleanize); | |
338 | } | |
339 | /* else unparsable line / means it is a comment / means ignore it */ | |
340 | } | |
341 | return $config_data; | |
342 | } | |
343 | ||
344 | /**#@+ @access private */ | |
345 | /** | |
346 | * @param array &$container | |
347 | * @param string $var_name | |
348 | * @param mixed $var_value | |
349 | * @param boolean $booleanize determines whether $var_value is converted to | |
350 | * to true/false | |
351 | */ | |
352 | function _set_config_var(&$container, $var_name, $var_value, $booleanize) | |
353 | { | |
9b7c11be | 354 | if (substr($var_name, 0, 1) == '.') { |
51ff3226 | 355 | if (!$this->read_hidden) |
356 | return; | |
357 | else | |
358 | $var_name = substr($var_name, 1); | |
359 | } | |
360 | ||
361 | if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { | |
362 | $this->_trigger_error_msg("Bad variable name '$var_name'"); | |
363 | return; | |
364 | } | |
365 | ||
366 | if ($booleanize) { | |
367 | if (preg_match("/^(on|true|yes)$/i", $var_value)) | |
368 | $var_value = true; | |
369 | else if (preg_match("/^(off|false|no)$/i", $var_value)) | |
370 | $var_value = false; | |
371 | } | |
372 | ||
373 | if (!isset($container[$var_name]) || $this->overwrite) | |
374 | $container[$var_name] = $var_value; | |
375 | else { | |
376 | settype($container[$var_name], 'array'); | |
377 | $container[$var_name][] = $var_value; | |
378 | } | |
379 | } | |
380 | ||
381 | /** | |
382 | * @uses trigger_error() creates a PHP warning/error | |
383 | * @param string $error_msg | |
384 | * @param integer $error_type one of | |
385 | */ | |
386 | function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) | |
387 | { | |
388 | trigger_error("Config_File error: $error_msg", $error_type); | |
389 | } | |
390 | /**#@-*/ | |
391 | } | |
392 | ||
393 | ?> |