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