PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

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

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