PageRenderTime 67ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/system/configuration.php

https://github.com/brettjamin/appleseed
PHP | 456 lines | 241 code | 110 blank | 105 comment | 49 complexity | 25b819f24670063ff5d8393a5913bef9 MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id$
  4. * @package Appleseed.Framework
  5. * @subpackage System
  6. * @copyright Copyright (C) 2004 - 2010 Michael Chisari. All rights reserved.
  7. * @link http://opensource.appleseedproject.org
  8. * @license GNU General Public License version 2.0 (See LICENSE.txt)
  9. */
  10. // Restrict direct access
  11. defined( 'APPLESEED' ) or die( 'Direct Access Denied' );
  12. /** Configuration Class
  13. *
  14. * Base class for configurations
  15. *
  16. * @package Appleseed.Framework
  17. * @subpackage System
  18. */
  19. class cConfiguration extends cBase {
  20. protected $_Data;
  21. protected $_Cleared;
  22. public $Child;
  23. /**
  24. * Constructor
  25. *
  26. * @access public
  27. */
  28. public function __construct ( ) {
  29. }
  30. /**
  31. * Load a configuration file, using inheritance if necessary
  32. *
  33. * @access public
  34. * @param string pFilename
  35. * @param array pDirectories
  36. */
  37. public function Load ( $pDirectory, $pInheritance = true ) {
  38. // Global variables
  39. eval (GLOBALS);
  40. $location = $zApp->GetPath () . DS . $pDirectory;
  41. // Check for other configuration directories
  42. $dirs = scandirs ($location);
  43. // Load all enabled configurations
  44. foreach ( $dirs as $d => $dir ) {
  45. $configurations[$dir] = new stdClass ();
  46. $configurations[$dir]->Directory = $dir;
  47. $file = $zApp->GetPath () . DS . $pDirectory . DS . $dir . DS . $dir . '.conf';
  48. if ( !$configurations[$dir]->_Data = $this->Parse ($file) ) {
  49. // Load failed. Set a warning and unset value
  50. unset ($configurations[$dir]);
  51. continue;
  52. }
  53. if ( ( strtolower ( $configurations[$dir]->_Data['enabled'] ) != 'true' ) ) {
  54. unset ($configurations[$dir]);
  55. continue;
  56. }
  57. }
  58. // Set inheritance
  59. $dirs = $configurations;
  60. // If no configurations were found, error out
  61. if ( count ( $dirs ) == 0 ) {
  62. die ( "No configurations were found or enabled: $pDirectory");
  63. }
  64. // Count inheritance levels
  65. $inheritancecount = 0;
  66. do {
  67. foreach ( $dirs as $dir => $values ) {
  68. $inherit = isset ( $configurations[$dir]->_Data['inherit'] ) ? $configurations[$dir]->_Data['inherit'] : false;
  69. $inheritanceflag = false;
  70. if ( $inherit ) {
  71. // If inheriting from self, continue
  72. if ($configurations[$dir]->Directory == $inherit) {
  73. $configurations[$dir]->Warnings[] = " Cannot Inherit $inherit From Itself. ";
  74. continue;
  75. }
  76. // Check if the inherited parent exists
  77. if ( !isset ( $configurations[$inherit] ) ) {
  78. // Set a warning and continue
  79. $configurations[$dir]->Warnings[] = " Cannot Inherit Values From '$inherit'. Does Not Exist Or Is Disabled.";
  80. continue;
  81. }
  82. $inheritancecount++;
  83. // Limit inheritance to three levels deep
  84. if ($inheritancecount > 3) {
  85. die ( "Error: Configuration Inheritance Greater Than 3 Levels. Please Resolve." );
  86. }
  87. // Set the values as a child of parent
  88. $configurations[$inherit]->Child = $configurations[$dir];
  89. unset ($configurations[$dir]);
  90. $inheritanceflag = true;
  91. }
  92. }
  93. } while ( $inheritanceflag );
  94. // Check to see if there's more than one parent left
  95. if ( count ( $configurations ) > 1 ) {
  96. die ( "More Than One Parent Configuration Is Enabled. Please Resolve." );
  97. }
  98. $parent = key ( $configurations );
  99. // Traverse and inherit values
  100. $final = $this->_Inherit ( $configurations[$parent] );
  101. $config = $final->_Data;
  102. // Internal list of the path to the final configuration
  103. $config['_path'] = array_reverse ( $this->_path );
  104. // Internal list of variables which were cleared and by which configuration
  105. if ( count ( $this->_Cleared ) > 0 ) $config['_cleared'] = array_reverse ( $this->_Cleared );
  106. unset ( $final->Directory );
  107. unset ( $config['enabled'] );
  108. return ( $config );
  109. }
  110. /**
  111. * Loads a configuration value
  112. *
  113. * @access public
  114. * @param array pVariable
  115. */
  116. function GetConfiguration ( $pVariable ) {
  117. if ( !isset ( $this->_Data[$pVariable] ) ) return ( false );
  118. return ( $this->_Data[$pVariable] );
  119. }
  120. /**
  121. * Loads the ordered path to the child configuration
  122. *
  123. * @access public
  124. */
  125. function GetPath ( ) {
  126. return ( $this->_Data['_path'] );
  127. }
  128. /**
  129. * Recursively inherit values
  130. *
  131. * @access private
  132. * @param object pConfiguration
  133. */
  134. private function _Inherit ( $pConfiguration ) {
  135. $parent = $pConfiguration;
  136. if ( isset ( $parent->Child ) ) $child = $parent->Child;
  137. $clear = isset ( $child->_Data['clear'] ) ? $configurations->_Data['clear'] : false;
  138. if ( $clear ) {
  139. $parent = $this->_Clear ( $parent, $child );
  140. }
  141. if ( isset ($child ) ) {
  142. $child = $this->_Inherit ($child);
  143. // Move all parent values to child
  144. foreach ( $child->_Data as $key => $value ) {
  145. if ( isset ( $parent->_Data[$key] ) && ( is_array ( $parent->_Data[$key] ) ) ) {
  146. $parent->_Data[$key] = array_merge ( $parent->_Data[$key], $value );
  147. } else {
  148. $parent->_Data[$key] = $value;
  149. }
  150. }
  151. $this->_path[] = $parent->Directory;
  152. unset ( $parent->_Data['inherit'] );
  153. unset ( $parent->Child );
  154. return ( $parent );
  155. } else {
  156. $this->_path[] = $parent->Directory;
  157. return ( $parent );
  158. }
  159. }
  160. /**
  161. * Clear parent values as specified by child
  162. *
  163. * @access private
  164. * @param object pParent
  165. * @param object pChild
  166. */
  167. private function _Clear ( $pParent, $pChild ) {
  168. $clearlist = array_filter ( split ( ' ', $pChild->_Data['clear'] ) );
  169. if ( count ( $clearlist ) < 1 ) {
  170. return ( false );
  171. }
  172. foreach ( $clearlist as $c => $clear ) {
  173. // Special variables which cannot be cleared
  174. if ( in_array ( $clear, array ( "inherit", "clear" ) ) ) continue;
  175. $this->_Cleared[] = $clear . ' [by ' . $pChild->Directory . '] ';
  176. unset ( $pParent->_Data[$clear] );
  177. }
  178. return ( $pParent );
  179. }
  180. /**
  181. * Loads all of the component configuration files
  182. *
  183. * @access public
  184. */
  185. public function LoadComponents ( ) {
  186. eval ( GLOBALS );
  187. $Config = $this->GetSys ( "Config" );
  188. $configpaths = $Config->GetPath();
  189. $componentdir = $zApp->GetPath() . DS . 'components';
  190. $components = scandirs ( $componentdir );
  191. $config = array ();
  192. foreach ( $components as $comp => $component ) {
  193. $filename = $componentdir . DS . $component . DS . $component . '.conf';
  194. if ( is_file ( $filename ) ) {
  195. $path[$component][] = $filename;
  196. }
  197. foreach ( $configpaths as $cpath => $configpath ) {
  198. $filename = $zApp->GetPath() . DS . 'configurations' . DS . $configpath . DS . 'components' . DS . $component . '.conf';
  199. if ( is_file ( $filename ) ) {
  200. $path[$component][] = $filename;
  201. }
  202. }
  203. // No configuration files found, continue loop
  204. if ( !isset ( $path[$component] ) ) continue;
  205. $config[$component] = array();
  206. foreach ( $path[$component] as $p => $filename ) {
  207. $currentvalues = $config[$component];
  208. $configvalues = $this->Parse ( $filename );
  209. $clearall = isset ( $configvalues['clearall'] ) ? $configvalues['clearall'] : false;
  210. if ( $clearall == 'true' ) {
  211. $currentvalues = array ();
  212. unset ( $configvalues['clearall'] );
  213. }
  214. $config[$component] = array_merge ( $currentvalues, $configvalues );
  215. }
  216. // If the component isn't enabled, then unset the values and continue
  217. if ($config[$component]['enabled'] != 'true' ) {
  218. unset ($config[$component]);
  219. continue;
  220. } else {
  221. $this->_Components[] = $component;
  222. }
  223. }
  224. return ($config);
  225. }
  226. /**
  227. * Loads all of the hook configuration files
  228. *
  229. * @access public
  230. */
  231. public function LoadHooks ( ) {
  232. eval ( GLOBALS );
  233. $Config = $this->GetSys ( "Config" );
  234. $configpaths = $Config->GetPath();
  235. $hooksdir = $zApp->GetPath() . DS . 'hooks';
  236. $hooks = scandirs ( $hooksdir );
  237. $config = array ();
  238. foreach ( $hooks as $h => $hook ) {
  239. $hookdir = $zApp->GetPath() . DS . 'hooks' . DS . $hook;
  240. $filename = $hookdir . DS . $hook . '.conf';
  241. if ( is_file ( $filename ) ) {
  242. $path[$hook][] = $filename;
  243. }
  244. foreach ( $configpaths as $cpath => $configpath ) {
  245. $filename = $zApp->GetPath() . DS . 'configurations' . DS . $configpath . DS . 'hooks' . DS . $hook . DS . $hook . '.conf';
  246. if ( is_file ( $filename ) ) {
  247. $path[$hook][] = $filename;
  248. }
  249. }
  250. }
  251. foreach ( $path as $hook=> $paths ) {
  252. $config[$hook] = array();
  253. foreach ( $paths as $p => $filename ) {
  254. $currentvalues = $config[$hook];
  255. $configvalues = $this->Parse ( $filename );
  256. $clearall = isset ( $configvalues['clearall'] ) ? $configvalues['clearall'] : false;
  257. if ( $clearall == 'true' ) {
  258. $currentvalues = array ();
  259. unset ( $configvalues['clearall'] );
  260. }
  261. $config[$hook] = array_merge ( $currentvalues, $configvalues );
  262. }
  263. // If the hook isn't enabled, then unset the values and continue
  264. if ($config[$hook]['enabled'] != 'true' ) {
  265. unset ($config[$hook]);
  266. continue;
  267. } else {
  268. $this->_Hooks[] = $hook;
  269. }
  270. }
  271. if ( count ( $config ) < 1 ) {
  272. unset ( $config );
  273. }
  274. return ($config);
  275. }
  276. /**
  277. * Parses an ini file depending on which PHP version is being used
  278. *
  279. * @access public
  280. * @var string $pFilename Full path of file to parse
  281. */
  282. function Parse ( $pFilename ) {
  283. $version = phpversion();
  284. list ( $major, $minor, $micro ) = explode ( '.', $version );
  285. // PHP 5.2 doesn't support associative arrays in ini files, so a hack is necessary
  286. if ( ( $major >= 5 ) && ( $minor >= 3 ) ) {
  287. $return = parse_ini_file ( $pFilename );
  288. } else {
  289. $data = file_get_contents ( $pFilename );
  290. // Check if we're using associative arrays
  291. if ($match = preg_match ( '/\[\S+\]=/', $data ) ) {
  292. $datalines = split ( "\n", $data );
  293. $counter = array ();
  294. foreach ( $datalines as $l => $line ) {
  295. // Skip over comments
  296. if ( preg_match ( '/^;/', $line ) ) continue;
  297. // Retrieve the regular expression key
  298. if ( preg_match ( '/\[(\S+)\]=/', $line, $retrieved ) ) {
  299. // Retrieve the variable name
  300. if ( preg_match ( '/^(\S+)\[/', $line, $name ) ) {
  301. list ( $name, $null ) = explode ( '[', $line, 2 );
  302. $regexp = rtrim ( ltrim ( $retrieved[1], '"' ), '"' );
  303. $c = (int)$counter[$name];
  304. $expressions[$name][$c] = $regexp;
  305. $counter[$name]++;
  306. }
  307. }
  308. $modified[] = preg_replace ( '/\[\S+\]=/', "[]=", $line);
  309. }
  310. $modified_data = join ("\n", $modified);
  311. // Create the temporary ini file for parsing
  312. $tmpfname = tempnam(sys_get_temp_dir(), 'temporary_ini_file');
  313. $handle = fopen ( $tmpfname, "w" );
  314. fwrite ( $handle, $modified_data );
  315. fclose ( $handle );
  316. $original = parse_ini_file ( $tmpfname );
  317. // Delete the temporary ini file
  318. unlink ( $tmpfname );
  319. // Merge the original data with the associative array data
  320. foreach ( $original as $variable => $value ) {
  321. if ( is_array ($value ) ) {
  322. foreach ( $value as $k => $v ) {
  323. $key = $expressions[$variable][$k];
  324. $final[$variable][$key] = preg_replace ( '/\\\\\$$/', '$', $v );
  325. }
  326. } else {
  327. $final[$variable] = preg_replace ( '/\\\\\$$/', '$', $value );
  328. }
  329. }
  330. $return = $final;
  331. } else {
  332. // No associative arrays are used, so parse normally
  333. $return = parse_ini_file ( $pFilename );
  334. }
  335. }
  336. return ( $return );
  337. }
  338. }
  339. /** Conf Class
  340. *
  341. * Alias class for cConfigurations
  342. *
  343. * @package Appleseed.Framework
  344. * @subpackage System
  345. */
  346. class cConf extends cConfiguration { }