PageRenderTime 29ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/src/vendor/akelos/active_support/config/base.php

https://github.com/bermi/sintags
PHP | 367 lines | 244 code | 39 blank | 84 comment | 48 complexity | 3dcb34472160289fb0299ab1d94745a1 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. # This file is part of the Akelos Framework
  3. # (Copyright) 2004-2010 Bermi Ferrer bermi a t bermilabs com
  4. # See LICENSE and CREDITS for details
  5. /**
  6. * Config Reader
  7. *
  8. * Provides access to config files stored in:
  9. *
  10. * AK_APP_DIR/config/*.yml
  11. *
  12. * = Structure of a config file
  13. *
  14. * A config file contains configuration directives for all
  15. * configured environments (development,testing,production).
  16. *
  17. * A config file can have a default configuration section, which will
  18. * be the base for all other environments. That means if a default configuration
  19. * directive is not overwritten in an environment, the default directive is active.
  20. *
  21. * Example:
  22. *
  23. * <code>
  24. * default:
  25. * log:
  26. * file: /tmp/debug.log
  27. * level: verbose
  28. *
  29. * development:
  30. * log:
  31. * file: /tmp/development.log
  32. *
  33. * testing:
  34. * log:
  35. * file: /tmp/testing.log
  36. *
  37. * production:
  38. * log:
  39. * file: /tmp/production.log
  40. * level: error
  41. * </code>
  42. *
  43. * The above example sets a log level of "verbose" as the default.
  44. * The default log file is in "/tmp/debug.log".
  45. *
  46. * The environments development and testing overwrite the default log file.
  47. *
  48. * The production environment overwrites as well the log file and the log level.
  49. *
  50. * The Log level for development will be "verbose" (inherited from default).
  51. * The log level for testing will be "verbose" (inherited from default).
  52. * The log level for production will be "error" (overwritten the default level).
  53. *
  54. *
  55. * = Accessing configuration files
  56. *
  57. * The format of the config files is YAML.
  58. * The convention is that a yaml file in:
  59. *
  60. * AK_APP_DIR/config/myconfig.yml
  61. *
  62. * can be accessed via:
  63. *
  64. * $config = new AkConfig();
  65. * $config->get('myconfig'); // loads myconfig.yml and section "AK_ENVIRONMENT"
  66. *
  67. * By default the configuration for the environment defined in AK_ENVIRONMENT will be loaded.
  68. *
  69. * By providing the desired environment in the get call you can change that:
  70. *
  71. * $config = new AkConfig();
  72. * $config->get('myconfig','production'); // loads myconfig.yml and section production
  73. *
  74. * = Config caching
  75. *
  76. * The AkConfig class caches php representations of the yaml files inside:
  77. *
  78. * AK_TMP_DIR/ak_config/cache/$environment/$config.yml
  79. *
  80. * As soon as the modification time of a yaml-config file changes, the cache is invalidated
  81. * and will be regenerated.
  82. */
  83. class AkConfig
  84. {
  85. const CONFIG_DIR = AK_CONFIG_DIR;
  86. public $options = array(
  87. 'skip_cache' => false
  88. );
  89. public function __construct($options = array()){
  90. if(!empty($options)){
  91. $this->options = array_merge($this->options, $options);
  92. }
  93. }
  94. public function &get($namespace, $environment = AK_ENVIRONMENT, $raise_error_if_config_file_not_found = true) {
  95. $key = $this->_getCacheKey($namespace,$environment);
  96. if(empty($this->options['skip_cache']) && ($config = Ak::getStaticVar($key))){
  97. return $config;
  98. }
  99. if (!($config = $this->readCache($namespace, $environment))) {
  100. $config = $this->readConfig($namespace, $environment, $raise_error_if_config_file_not_found);
  101. }
  102. if (!isset($_configs[$namespace])) {
  103. $_configs[$namespace] = array($environment=>$config);
  104. } else {
  105. $_configs[$namespace][$environment] = $config;
  106. }
  107. Ak::setStaticVar($key, $_configs[$namespace][$environment]);
  108. return $_configs[$namespace][$environment];
  109. }
  110. static function getConstant($name) {
  111. return defined($name[1]) ? constant($name[1]) : '';
  112. }
  113. static function getDir($type, $_set_value = false, $fail_if_not_found = true) {
  114. static $dir_names = array();
  115. if($_set_value){
  116. $dir_names[$type] = $_set_value;
  117. }
  118. if(!isset($dir_names[$type])){
  119. $contstant_name = 'AK_'.strtoupper(AkInflector::underscore($type)).'_DIR';
  120. if(defined($contstant_name)){
  121. $dir_names[$type] = constant($contstant_name);
  122. }
  123. }
  124. if(!isset($dir_names[$type])){
  125. if($fail_if_not_found){
  126. trigger_error(Ak::t('Can\'t find path for directory %dir', array('%dir'=>$type)).' '.Ak::getFileAndNumberTextForError(1), E_USER_ERROR);
  127. }else{
  128. return false;
  129. }
  130. }
  131. return $dir_names[$type];
  132. }
  133. static function setDir($type, $value) {
  134. AkConfig::getDir($type, $value, false);
  135. }
  136. static function getOption($key, $default = null) {
  137. $option = Ak::getStaticVar('AkConfig_'.$key);
  138. if(is_null($option) && !is_null($default)){
  139. return $default;
  140. }
  141. return $option;
  142. }
  143. static function rebaseApp($base_path) {
  144. static $bases = array();
  145. if($base_path == false){
  146. if(count($bases) > 1){
  147. $base = array_shift($bases);
  148. foreach ($base as $type => $original_path){
  149. AkConfig::setDir($type, $original_path);
  150. }
  151. return true;
  152. }
  153. return false;
  154. }
  155. $bases[] =
  156. array(
  157. 'app' => AkConfig::getDir('app'),
  158. 'models' => AkConfig::getDir('models'),
  159. 'app_installers' => AkConfig::getDir('app_installers'),
  160. 'controllers' => AkConfig::getDir('controllers'),
  161. 'views' => AkConfig::getDir('views'),
  162. 'apis' => AkConfig::getDir('apis'),
  163. 'helpers' => AkConfig::getDir('helpers'),
  164. 'public' => AkConfig::getDir('public'),
  165. );
  166. AkConfig::setDir('app', $base_path);
  167. AkConfig::setDir('app_installers', $base_path.DS.'installers');
  168. AkConfig::setDir('models', $base_path.DS.'models');
  169. AkConfig::setDir('controllers', $base_path.DS.'controllers');
  170. AkConfig::setDir('views', $base_path.DS.'views');
  171. AkConfig::setDir('apis', $base_path.DS.'apis');
  172. AkConfig::setDir('helpers', $base_path.DS.'helpers');
  173. AkConfig::setDir('public', $base_path.DS.'public');
  174. return true;
  175. }
  176. static function leaveBase() {
  177. return AkConfig::rebaseApp(false);
  178. }
  179. static function setOption($key, $value) {
  180. Ak::setStaticVar('AkConfig_'.$key, $value);
  181. return $value;
  182. }
  183. static function getLocalesReady() {
  184. Ak::t('Akelos');
  185. AK_ENABLE_PROFILER && Ak::profile('Got multilingual ');
  186. }
  187. static function parseSettingsConstants($settingsStr) {
  188. return preg_replace_callback('/\$\{(AK_.*?)\}/',array('AkConfig','getConstant'),$settingsStr);
  189. }
  190. public function readConfig($namespace, $environment = AK_ENVIRONMENT, $raise_error_if_config_file_not_found = true) {
  191. $yaml_file_name = $this->_generateConfigFileName($namespace);
  192. if (!file_exists($yaml_file_name)){
  193. if($raise_error_if_config_file_not_found){
  194. trigger_error(Ak::t('Could not find %namespace settings file in %path.', array('%namespace'=>$namespace, '%path'=>$yaml_file_name)).' '.Ak::getFileAndNumberTextForError(1)."\n", E_USER_ERROR);
  195. }
  196. return false;
  197. }
  198. return $this->readConfigYaml($namespace, file_get_contents($yaml_file_name), $environment);
  199. }
  200. public function readConfigYaml($namespace, $yaml_string, $environment = AK_ENVIRONMENT){
  201. require_once(AK_CONTRIB_DIR.DS.'TextParsers'.DS.'spyc.php');
  202. $content = self::parseSettingsConstants($yaml_string);
  203. $config = Spyc::YAMLLoad($content);
  204. return $this->readConfigArray($namespace, $config, $environment);
  205. }
  206. public function readConfigArray($namespace, $config = array(), $environment = AK_ENVIRONMENT){
  207. if (!is_array($config)){
  208. return false;
  209. }
  210. $default = isset($config['default']) ? $config['default'] : array();
  211. $configs = array();
  212. unset($config['default']);
  213. $environments = array_keys($config);
  214. $default_environments = Ak::toArray(AK_AVAILABLE_ENVIRONMENTS);
  215. $environments = array_merge($default_environments, $environments);
  216. foreach($environments as $env) {
  217. $envConfig = $this->_merge($default, isset($config[$env]) ? $config[$env] : array());
  218. $this->writeCache($envConfig, $namespace, $env, $this->_useWriteCache($environment));
  219. $configs[$env] = $envConfig;
  220. }
  221. return isset($configs[$environment]) ? $configs[$environment] : (in_array($environments, $environments) ? $default : false);
  222. }
  223. static function getCacheFileName($namespace, $environment = AK_ENVIRONMENT) {
  224. return AkConfig::getCacheBasePath($environment).DS.'ak_config'.DS.'cache'.DS.$environment.DS.Ak::sanitize_include($namespace, 'high').'.php';
  225. }
  226. static function getCacheBasePath() {
  227. return AK_TMP_DIR;
  228. }
  229. public function readCache($namespace, $environment = AK_ENVIRONMENT, $force = false) {
  230. if ((!$force && !$this->_useReadCache($environment))){
  231. return false;
  232. }
  233. $cacheFileName = $this->getCacheFileName($namespace,$environment);
  234. if (!$this->_configNeedsToBeCached($namespace, $environment)) {
  235. $config = include $cacheFileName;
  236. } else {
  237. $config = false;
  238. }
  239. return $config;
  240. }
  241. public function writeCache($config, $namespace, $environment = AK_ENVIRONMENT, $force = false) {
  242. if (!$force && !$this->_useWriteCache($environment)){
  243. return false;
  244. }
  245. $key = $this->_getCacheKey($namespace,$environment);
  246. Ak::setStaticVar($key, $config);
  247. $var_export = var_export($config, true);
  248. $cache = <<<CACHE
  249. <?php
  250. /**
  251. * Auto-generated config cache from $namespace in environment $environment
  252. */
  253. \$config = $var_export;
  254. return \$config;
  255. CACHE;
  256. $cache_file_name = $this->getCacheFileName($namespace, $environment);
  257. if(!Ak::file_put_contents($cache_file_name, $cache, array('base_path' => AkConfig::getCacheBasePath()))){
  258. trigger_error(Ak::t('Could not create config cache file %file', array('%file'=>$cache_file_name)).' '.Ak::getFileAndNumberTextForError(1), E_USER_ERROR);
  259. return false;
  260. }else{
  261. return true;
  262. }
  263. }
  264. public function clearStaticCache($namespace, $environment = AK_ENVIRONMENT){
  265. $key = $this->_getCacheKey($namespace,$environment);
  266. Ak::unsetStaticVar($key);
  267. }
  268. static function getErrorReportingLevelDescription($error_reporting_level = null) {
  269. if(is_null($error_reporting_level)){
  270. $error_reporting_level = error_reporting();
  271. }
  272. $_constants = get_defined_constants(true);
  273. $internal_constants = !empty($_constants['internal']) ? $_constants['internal'] : (array)@$_constants['mhash'];
  274. unset($_constants);
  275. $result = array();
  276. if(($error_reporting_level & E_ALL) == E_ALL){
  277. $result[] = 'E_ALL';
  278. $error_reporting_level &=~ E_ALL;
  279. }
  280. foreach($internal_constants as $error_reporting_level_name => $constant){
  281. if(preg_match('/^E_/', $error_reporting_level_name)){
  282. if(($error_reporting_level & $constant) == $constant){
  283. $result[] = $error_reporting_level_name;
  284. }
  285. }
  286. }
  287. return join(' | ',$result);
  288. }
  289. protected function _useReadCache($environment = AK_ENVIRONMENT) {
  290. if(AK_CLI && AK_ENVIRONMENT != 'testing'){
  291. return false;
  292. }
  293. return ($environment == 'production' || $environment == 'setup');
  294. }
  295. protected function _useWriteCache($environment = AK_ENVIRONMENT) {
  296. if(AK_CLI && AK_ENVIRONMENT != 'testing'){
  297. return false;
  298. }
  299. return $environment != 'setup';
  300. }
  301. protected function _configNeedsToBeCached($namespace,$environment) {
  302. $cache_file = $this->getCacheFileName($namespace,$environment);
  303. $config_file = $this->_generateConfigFileName($namespace);
  304. return (@filemtime($config_file) > @filemtime($cache_file)) || !file_exists($config_file);
  305. }
  306. protected function _generateConfigFileName($namespace) {
  307. $namespace = Ak::sanitize_include($namespace, 'high');
  308. $yaml_file_name = self::CONFIG_DIR.DS.$namespace.'.yml';
  309. return $yaml_file_name;
  310. }
  311. protected function _merge($default,$env) {
  312. if (is_array($default)) {
  313. foreach($default as $key => $value) {
  314. if (!is_array($value)) {
  315. $env[$key] = isset($env[$key]) ? $env[$key] : $value;
  316. } else {
  317. $env[$key] = $this->_merge($value, isset($env[$key])?$env[$key] : array());
  318. }
  319. }
  320. } else {
  321. $env = empty($env) ? $default : $env;
  322. }
  323. return $env;
  324. }
  325. protected function _getCacheKey($namespace, $environment){
  326. return '_config_'.$namespace.$environment.AK_WEB_REQUEST;
  327. }
  328. }