baseline
[omp.pkp.sfu.ca.git] / lib / pkp / classes / config / ConfigParser.inc.php
blobb4254b4f7644e4a1e05bf2b40bb72ea98002fcee
1 <?php
3 /**
4 * @file classes/config/ConfigParser.inc.php
6 * Copyright (c) 2000-2009 John Willinsky
7 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
9 * @class ConfigParser
10 * @ingroup config
12 * @brief Class for parsing and modifying php.ini style configuration files.
15 // $Id: ConfigParser.inc.php,v 1.3 2009/04/08 21:34:53 asmecher Exp $
18 class ConfigParser {
20 /** Contents of the config file currently being parsed */
21 var $content;
23 /**
24 * Constructor.
26 function ConfigParser() {
29 /**
30 * Read a configuration file into a multidimensional array.
31 * This is a replacement for the PHP parse_ini_file function, which does not type setting values.
32 * @param $file string full path to the config file
33 * @return array the configuration data (same format as http://php.net/parse_ini_file)
35 function &readConfig($file) {
36 $configData = array();
37 $currentSection = false;
38 $falseValue = false;
40 if (!file_exists($file) || !is_readable($file)) {
41 return $falseValue;
44 $fp = fopen($file, 'rb');
45 if (!$fp) {
46 return $falseValue;
49 while (!feof($fp)) {
50 $line = fgets($fp, 1024);
51 $line = trim($line);
52 if ($line === '' || strpos($line, ';') === 0) {
53 // Skip empty or commented line
54 continue;
57 if (preg_match('/^\[(.+)\]/', $line, $matches)) {
58 // Found a section
59 $currentSection = $matches[1];
60 if (!isset($configData[$currentSection])) {
61 $configData[$currentSection] = array();
64 } else if (strpos($line, '=') !== false) {
65 // Found a setting
66 list($key, $value) = explode('=', $line, 2);
67 $key = trim($key);
68 $value = trim($value);
70 // FIXME This may produce incorrect results if the line contains a comment
71 if (preg_match('/^[\"\'](.*)[\"\']$/', $value, $matches)) {
72 // Treat value as a string
73 $value = stripslashes($matches[1]);
75 } else {
76 preg_match('/^([\S]*)/', $value, $matches);
77 $value = $matches[1];
79 // Try to determine the type of the value
80 if ($value === '') {
81 $value = null;
83 } else if (is_numeric($value)) {
84 if (strstr($value, '.')) {
85 // floating-point
86 $value = (float) $value;
87 } else if (substr($value, 0, 2) == '0x') {
88 // hex
89 $value = intval($value, 16);
90 } else if (substr($value, 0, 1) == '0') {
91 // octal
92 $value = intval($value, 8);
93 } else {
94 // integer
95 $value = (int) $value;
98 } else if (strtolower($value) == 'true' || strtolower($value) == 'on') {
99 $value = true;
101 } else if (strtolower($value) == 'false' || strtolower($value) == 'off') {
102 $value = false;
104 } else if (defined($value)) {
105 // The value matches a named constant
106 $value = constant($value);
110 if ($currentSection === false) {
111 $configData[$key] = $value;
113 } else if (is_array($configData[$currentSection])) {
114 $configData[$currentSection][$key] = $value;
119 fclose($fp);
121 return $configData;
125 * Read a configuration file and update variables.
126 * This method stores the updated configuration but does not write it out.
127 * Use writeConfig() or getFileContents() afterwards to do something with the new config.
128 * @param $file string full path to the config file
129 * @param $params array an associative array of configuration parameters to update. If the value is an associative array (of variable name/value pairs) instead of a scalar, the key is treated as a section instead of a variable. Parameters not in $params remain unchanged
130 * @return boolean true if file could be read, false otherwise
132 function updateConfig($file, $params) {
133 if (!file_exists($file) || !is_readable($file)) {
134 return false;
137 $this->content = '';
138 $lines = file($file);
140 // Parse each line of the configuration file
141 for ($i=0, $count=count($lines); $i < $count; $i++) {
142 $line = $lines[$i];
144 if (preg_match('/^;/', $line) || preg_match('/^\s*$/', $line)) {
145 // Comment or empty line
146 $this->content .= $line;
148 } else if (preg_match('/^\s*\[(\w+)\]/', $line, $matches)) {
149 // Start of new section
150 $currentSection = $matches[1];
151 $this->content .= $line;
153 } else if (preg_match('/^\s*(\w+)\s*=/', $line, $matches)) {
154 // Variable definition
155 $key = $matches[1];
157 if (!isset($currentSection) && array_key_exists($key, $params) && !is_array($params[$key])) {
158 // Variable not in a section
159 $value = $params[$key];
161 } else if (isset($params[$currentSection]) && is_array($params[$currentSection]) && array_key_exists($key, $params[$currentSection])) {
162 // Variable in a section
163 $value = $params[$currentSection][$key];
165 } else {
166 // Variable not to be changed, do not modify line
167 $this->content .= $line;
168 continue;
171 if (preg_match('/[^\w\-\/]/', $value)) {
172 // Escape strings containing non-alphanumeric characters
173 $valueString = '"' . $value . '"';
174 } else {
175 $valueString = $value;
178 $this->content .= "$key = $valueString\n";
180 } else {
181 $this->content .= $line;
185 return true;
189 * Write contents of current config file
190 * @param $file string full path to output file
191 * @return boolean file write is successful
193 function writeConfig($file) {
194 if (!(file_exists($file) && is_writable($file))
195 && !(!file_exists($file) && is_dir(dirname($file)) && is_writable(dirname($file)))) {
196 // File location cannot be written to
197 return false;
200 $fp = @fopen($file, 'wb');
201 if (!$fp) {
202 return false;
205 fwrite($fp, $this->content);
206 fclose($fp);
207 return true;
211 * Return the contents of the current config file.
212 * @return string
214 function getFileContents() {
215 return $this->content;