PageRenderTime 46ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/pkp/classes/config/ConfigParser.inc.php

https://github.com/lib-uoguelph-ca/ocs
PHP | 219 lines | 119 code | 41 blank | 59 comment | 64 complexity | 95322d65fa763562201093034a9b5ec4 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * @file classes/config/ConfigParser.inc.php
  4. *
  5. * Copyright (c) 2000-2012 John Willinsky
  6. * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  7. *
  8. * @class ConfigParser
  9. * @ingroup config
  10. *
  11. * @brief Class for parsing and modifying php.ini style configuration files.
  12. */
  13. // $Id$
  14. class ConfigParser {
  15. /** Contents of the config file currently being parsed */
  16. var $content;
  17. /**
  18. * Constructor.
  19. */
  20. function ConfigParser() {
  21. }
  22. /**
  23. * Read a configuration file into a multidimensional array.
  24. * This is a replacement for the PHP parse_ini_file function, which does not type setting values.
  25. * @param $file string full path to the config file
  26. * @return array the configuration data (same format as http://php.net/parse_ini_file)
  27. */
  28. function &readConfig($file) {
  29. $configData = array();
  30. $currentSection = false;
  31. $falseValue = false;
  32. if (!file_exists($file) || !is_readable($file)) {
  33. return $falseValue;
  34. }
  35. $fp = fopen($file, 'rb');
  36. if (!$fp) {
  37. return $falseValue;
  38. }
  39. while (!feof($fp)) {
  40. $line = fgets($fp, 1024);
  41. $line = trim($line);
  42. if ($line === '' || strpos($line, ';') === 0) {
  43. // Skip empty or commented line
  44. continue;
  45. }
  46. if (preg_match('/^\[(.+)\]/', $line, $matches)) {
  47. // Found a section
  48. $currentSection = $matches[1];
  49. if (!isset($configData[$currentSection])) {
  50. $configData[$currentSection] = array();
  51. }
  52. } else if (strpos($line, '=') !== false) {
  53. // Found a setting
  54. list($key, $value) = explode('=', $line, 2);
  55. $key = trim($key);
  56. $value = trim($value);
  57. // FIXME This may produce incorrect results if the line contains a comment
  58. if (preg_match('/^[\"\'](.*)[\"\']$/', $value, $matches)) {
  59. // Treat value as a string
  60. $value = stripslashes($matches[1]);
  61. } else {
  62. preg_match('/^([\S]*)/', $value, $matches);
  63. $value = $matches[1];
  64. // Try to determine the type of the value
  65. if ($value === '') {
  66. $value = null;
  67. } else if (is_numeric($value)) {
  68. if (strstr($value, '.')) {
  69. // floating-point
  70. $value = (float) $value;
  71. } else if (substr($value, 0, 2) == '0x') {
  72. // hex
  73. $value = intval($value, 16);
  74. } else if (substr($value, 0, 1) == '0') {
  75. // octal
  76. $value = intval($value, 8);
  77. } else {
  78. // integer
  79. $value = (int) $value;
  80. }
  81. } else if (strtolower($value) == 'true' || strtolower($value) == 'on') {
  82. $value = true;
  83. } else if (strtolower($value) == 'false' || strtolower($value) == 'off') {
  84. $value = false;
  85. } else if (defined($value)) {
  86. // The value matches a named constant
  87. $value = constant($value);
  88. }
  89. }
  90. if ($currentSection === false) {
  91. $configData[$key] = $value;
  92. } else if (is_array($configData[$currentSection])) {
  93. $configData[$currentSection][$key] = $value;
  94. }
  95. }
  96. }
  97. fclose($fp);
  98. return $configData;
  99. }
  100. /**
  101. * Read a configuration file and update variables.
  102. * This method stores the updated configuration but does not write it out.
  103. * Use writeConfig() or getFileContents() afterwards to do something with the new config.
  104. * @param $file string full path to the config file
  105. * @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
  106. * @return boolean true if file could be read, false otherwise
  107. */
  108. function updateConfig($file, $params) {
  109. if (!file_exists($file) || !is_readable($file)) {
  110. return false;
  111. }
  112. $this->content = '';
  113. $lines = file($file);
  114. // Parse each line of the configuration file
  115. for ($i=0, $count=count($lines); $i < $count; $i++) {
  116. $line = $lines[$i];
  117. if (preg_match('/^;/', $line) || preg_match('/^\s*$/', $line)) {
  118. // Comment or empty line
  119. $this->content .= $line;
  120. } else if (preg_match('/^\s*\[(\w+)\]/', $line, $matches)) {
  121. // Start of new section
  122. $currentSection = $matches[1];
  123. $this->content .= $line;
  124. } else if (preg_match('/^\s*(\w+)\s*=/', $line, $matches)) {
  125. // Variable definition
  126. $key = $matches[1];
  127. if (!isset($currentSection) && array_key_exists($key, $params) && !is_array($params[$key])) {
  128. // Variable not in a section
  129. $value = $params[$key];
  130. } else if (isset($params[$currentSection]) && is_array($params[$currentSection]) && array_key_exists($key, $params[$currentSection])) {
  131. // Variable in a section
  132. $value = $params[$currentSection][$key];
  133. } else {
  134. // Variable not to be changed, do not modify line
  135. $this->content .= $line;
  136. continue;
  137. }
  138. if (preg_match('/[^\w\-\/]/', $value)) {
  139. // Escape strings containing non-alphanumeric characters
  140. $valueString = '"' . $value . '"';
  141. } else {
  142. $valueString = $value;
  143. }
  144. $this->content .= "$key = $valueString\n";
  145. } else {
  146. $this->content .= $line;
  147. }
  148. }
  149. return true;
  150. }
  151. /**
  152. * Write contents of current config file
  153. * @param $file string full path to output file
  154. * @return boolean file write is successful
  155. */
  156. function writeConfig($file) {
  157. if (!(file_exists($file) && is_writable($file))
  158. && !(!file_exists($file) && is_dir(dirname($file)) && is_writable(dirname($file)))) {
  159. // File location cannot be written to
  160. return false;
  161. }
  162. $fp = @fopen($file, 'wb');
  163. if (!$fp) {
  164. return false;
  165. }
  166. fwrite($fp, $this->content);
  167. fclose($fp);
  168. return true;
  169. }
  170. /**
  171. * Return the contents of the current config file.
  172. * @return string
  173. */
  174. function getFileContents() {
  175. return $this->content;
  176. }
  177. }
  178. ?>