/src/lib/Config/Lite.php

https://github.com/cpbx/snom_feedreadr · PHP · 395 lines · 306 code · 3 blank · 86 comment · 9 complexity · 17c8e2c43c271d17d08fb826c6e0cb5e MD5 · raw file

  1. <?php
  2. /**
  3. * Config_Lite (Config/Lite.php)
  4. *
  5. * PHP version 5
  6. *
  7. * @file Config/Lite.php
  8. * @category Configuration
  9. * @package Config_Lite
  10. * @author Patrick C. Engel <info@pc-e.org>
  11. * @copyright 2010 info@pc-e.org
  12. * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
  13. * @version Release: @package_version@
  14. * @link http://github.com/pce/config_lite
  15. */
  16. /**
  17. * Config_Lite Class
  18. *
  19. * read & save "INI-Style" Configuration Files,
  20. * fast and with the native php function under the hood.
  21. *
  22. * Inspired by Python's ConfigParser.
  23. *
  24. * A "Config_Lite" file consists of sections,
  25. * "[section]"
  26. * followed by "name = value" entries
  27. *
  28. * note: Config_Lite assumes that all name/value entries are in sections.
  29. *
  30. * @category Configuration
  31. * @package Config_Lite
  32. * @author Patrick C. Engel <info@pc-e.org>
  33. * @copyright 2010 info@pc-e.org
  34. * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
  35. * @version Release: @package_version@
  36. * @link http://github.com/pce/config_lite
  37. */
  38. class Config_Lite
  39. {
  40. /**
  41. * sections, holds the config sections
  42. *
  43. * @var array
  44. */
  45. protected $sections;
  46. /**
  47. * filename
  48. *
  49. * @var string
  50. */
  51. protected $filename;
  52. /**
  53. * _booleans - alias of bool in a representable Configuration String Format
  54. *
  55. * @var array
  56. */
  57. private $_booleans = array('1' => true, 'on' => true,
  58. 'true' => true, 'yes' => true,
  59. '0' => false, 'off' => false,
  60. 'false' => false, 'no' => false);
  61. /**
  62. * read, note: always assumes and works with sections
  63. *
  64. * @param string $filename Filename
  65. *
  66. * @return bool
  67. * @throws Config_Lite_Exception when file not exists
  68. */
  69. public function read($filename)
  70. {
  71. if (!file_exists($filename)) {
  72. throw new Config_Lite_Exception('file not found: ' . $filename);
  73. }
  74. $this->filename = $filename;
  75. $this->sections = parse_ini_file($filename, true);
  76. if (false === $this->sections) {
  77. throw new Config_Lite_Exception(
  78. 'failure, can not parse the file: ' . $filename);
  79. }
  80. }
  81. /**
  82. * save (active record style), note: file locking is not part of this Class
  83. *
  84. * @return bool
  85. */
  86. public function save()
  87. {
  88. return $this->write($this->filename, $this->sections);
  89. }
  90. /**
  91. * write INI File
  92. *
  93. * @param string $filename filename
  94. * @param array $sectionsarray array with sections
  95. *
  96. * @return bool
  97. * @throws Config_Lite_Exception when file is not writeable
  98. */
  99. public function write($filename, $sectionsarray)
  100. {
  101. // maybe this line should be optional
  102. $content = ';<?php exit; ?>' . "\n";
  103. $sections = '';
  104. // note: it is valid to write an empty Config file
  105. if (!empty($sectionsarray)) {
  106. foreach ($sectionsarray as $section => $item) {
  107. if (is_array($item)) {
  108. $sections.= "\n[{$section}]\n";
  109. foreach ($item as $key => $value) {
  110. if (is_numeric($value)) {
  111. $sections.= "{$key} = {$value}\n";
  112. } elseif (is_bool($value)) {
  113. $value = $this->to('bool', $value);
  114. $sections.= "{$key} = {$value}\n";
  115. } else {
  116. // $sections .= "{$key} = \"{$value}\"\n";
  117. $sections.= "{$key} = {$value}\n";
  118. }
  119. }
  120. }
  121. }
  122. $content.= $sections;
  123. }
  124. if (!$fp = fopen($filename, 'w')) {
  125. throw new Config_Lite_Exception(
  126. "failed to open file `{$filename}' for writing.");
  127. }
  128. if (!fwrite($fp, $content)) {
  129. throw new Config_Lite_Exception(
  130. "failed to write file `{$filename}'");
  131. }
  132. fclose($fp);
  133. return true;
  134. }
  135. /**
  136. * convert type to string or representable Config Format
  137. *
  138. * @param string $format `bool', `boolean'
  139. * @param string $value value
  140. *
  141. * @return mixed
  142. * @throws Config_Lite_Exception when format is unknown
  143. */
  144. public function to($format, $value)
  145. {
  146. switch ($format) {
  147. case 'bool':
  148. case 'boolean':
  149. if ($value === true) {
  150. return 'yes';
  151. }
  152. return 'no';
  153. break;
  154. default:
  155. // unknown format
  156. throw new Config_Lite_Exception(
  157. "no conversation made, unrecognized format `{$format}'");
  158. break;
  159. }
  160. }
  161. /**
  162. * get
  163. *
  164. * @param string $sec Section
  165. * @param string $key Key
  166. * @param mixed $default default return value
  167. *
  168. * @return string
  169. * @throws Config_Lite_Exception when config is empty
  170. * and no default value is given
  171. * @throws Config_Lite_Exception key not found and no default value is given
  172. */
  173. public function get($sec, $key, $default = null)
  174. {
  175. if (is_null($this->sections) && is_null($default)) {
  176. throw new Config_Lite_Exception(
  177. 'configuration seems to be empty, no sections.');
  178. }
  179. if (array_key_exists($key, $this->sections[$sec])) {
  180. return $this->sections[$sec][$key];
  181. }
  182. if (!is_null($default)) {
  183. return $default;
  184. }
  185. throw new Config_Lite_Exception('key not found, no default value given.');
  186. }
  187. /**
  188. * getBool - returns on,yes,1,true as TRUE
  189. * and no given value or off,no,0,false as FALSE
  190. *
  191. * @param string $sec Section
  192. * @param string $key Key
  193. * @param bool $default default Value
  194. *
  195. * @return bool
  196. * @throws Config_Lite_Exception when the configuration is empty
  197. * and no default value is given
  198. */
  199. public function getBool($sec, $key, $default = null)
  200. {
  201. if (is_null($this->sections) && is_null($default)) {
  202. throw new Config_Lite_Exception(
  203. 'configuration seems to be empty (no sections),'
  204. . 'and no default value given.');
  205. }
  206. if (array_key_exists($key, $this->sections[$sec])) {
  207. if (empty($this->sections[$sec][$key])) {
  208. return false;
  209. }
  210. $value = strtolower($this->sections[$sec][$key]);
  211. if (!in_array($value, $this->_booleans) && is_null($default)) {
  212. throw new Config_Lite_Exception(sprintf(
  213. 'Not a boolean: %s, and no default value given.', $value
  214. ));
  215. } else {
  216. return $this->_booleans[$value];
  217. }
  218. }
  219. if (!is_null($default)) {
  220. return $default;
  221. }
  222. throw new Config_Lite_Exception('key not found, no default value given.');
  223. }
  224. /**
  225. * array get section
  226. *
  227. * @param string $sec Section
  228. * @param array $default default value
  229. *
  230. * @return array
  231. * @throws Config_Lite_Exception when config is empty
  232. * and no default array is given
  233. * @throws Config_Lite_Exception when key not found
  234. * and no default array is given
  235. */
  236. public function getSection($sec, $default = null)
  237. {
  238. if (is_null($this->sections) && is_null($default)) {
  239. throw new Config_Lite_Exception(
  240. 'configuration seems to be empty, no sections.');
  241. }
  242. if (isset($this->sections[$sec])) {
  243. return $this->sections[$sec];
  244. }
  245. if (!is_null($default) && is_array($default)) {
  246. return $default;
  247. }
  248. throw new Config_Lite_Exception('key not found, no default array given.');
  249. }
  250. /**
  251. * has option
  252. *
  253. * @param string $sec Section
  254. * @param string $key Key
  255. *
  256. * @return bool
  257. */
  258. public function has($sec, $key)
  259. {
  260. if (!$this->hasSection($sec)) {
  261. return false;
  262. }
  263. if (isset($this->sections[$sec][$key])) {
  264. return true;
  265. }
  266. return false;
  267. }
  268. /**
  269. * has section
  270. *
  271. * @param string $sec Section
  272. *
  273. * @return bool
  274. */
  275. public function hasSection($sec)
  276. {
  277. if (isset($this->sections[$sec])) {
  278. return true;
  279. }
  280. return false;
  281. }
  282. /**
  283. * Remove option
  284. *
  285. * @param string $sec Section
  286. * @param string $key Key
  287. *
  288. * @return void
  289. * @throws Config_Lite_Exception when given Section not exists
  290. */
  291. public function remove($sec, $key)
  292. {
  293. if (!isset($this->sections[$sec])) {
  294. throw new Config_Lite_Exception('No such Section.');
  295. }
  296. unset($this->sections[$sec][$key]);
  297. }
  298. /**
  299. * Remove section
  300. *
  301. * @param string $sec Section
  302. *
  303. * @return void
  304. * @throws Config_Lite_Exception when given Section not exists
  305. */
  306. public function removeSection($sec)
  307. {
  308. if (!isset($this->sections[$sec])) {
  309. throw new Config_Lite_Exception('No such Section.');
  310. }
  311. unset($this->sections[$sec]);
  312. }
  313. /**
  314. * Set key - add key/value pairs to a section,
  315. * creates new section if necessary and overrides existing keys
  316. *
  317. * @param string $sec Section
  318. * @param string $key Key
  319. * @param mixed $value Value
  320. *
  321. * @return void
  322. * @throws Config_Lite_Exception when given key is an array
  323. */
  324. public function set($sec, $key, $value = null)
  325. {
  326. if (!is_array($this->sections)) {
  327. $this->sections = array();
  328. }
  329. if (is_array($key)) {
  330. throw new Config_Lite_Exception(
  331. 'string key expected, but array given.');
  332. }
  333. $this->sections[$sec][$key] = $value;
  334. return $this;
  335. }
  336. /**
  337. * Set section - add key/value pairs to a section,
  338. * creates new section if necessary.
  339. *
  340. * @param string $sec Section
  341. * @param array $pairs Keys and Values as Array ('key' => 'value')
  342. *
  343. * @return void|PEAR_Error
  344. */
  345. public function setSection($sec, $pairs)
  346. {
  347. if (!is_array($this->sections)) {
  348. $this->sections = array();
  349. }
  350. if (!is_array($pairs)) {
  351. throw new Config_Lite_Exception('array expected.');
  352. }
  353. $this->sections[$sec] = $pairs;
  354. return $this;
  355. }
  356. /**
  357. * Text presentation of the Configuration
  358. *
  359. * @return string
  360. */
  361. public function __toString()
  362. {
  363. $s = "";
  364. if ($this->sections != null) {
  365. foreach ($this->sections as $section => $name) {
  366. $s.= sprintf("[%s]\n", $section);
  367. if (is_array($name)) {
  368. foreach ($name as $key => $val) {
  369. $s.= sprintf("\t%s = %s\n", $key, $val);
  370. }
  371. }
  372. }
  373. return $s;
  374. }
  375. if (!isset($this->filename)) {
  376. throw new Config_Lite_Exception('Did not read a Configuration File.');
  377. }
  378. // empy config is valid, no return of "The Configuration is empty.\n";
  379. return $s;
  380. }
  381. /**
  382. * Constructor
  383. *
  384. * @param string $filename - INI Style Config File
  385. */
  386. public function __construct($filename = null)
  387. {
  388. if (($filename != null) && (file_exists($filename))) {
  389. $this->read($filename);
  390. }
  391. }
  392. }