| [ Index ] |
PHP Cross Reference of Akelos Framework |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4 // WARNING THIS CODE IS EXPERIMENTAL 5 6 // +----------------------------------------------------------------------+ 7 // | Akelos Framework - http://www.akelos.org | 8 // +----------------------------------------------------------------------+ 9 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez | 10 // | Released under the GNU Lesser General Public License, see LICENSE.txt| 11 // +----------------------------------------------------------------------+ 12 13 /** 14 * @package ActiveSupport 15 * @subpackage Experimental 16 * @author Arno Schneider 17 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org 18 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html> 19 */ 20 21 /** 22 * Config Reader 23 * 24 * Provides access to config files stored in: 25 * 26 * AK_APP_DIR/config/*.yml 27 * 28 * = Structure of a config file 29 * 30 * A config file contains configuration directives for all 31 * configured environments (development,testing,production). 32 * 33 * A config file can have a default configuration section, which will 34 * be the base for all other environments. That means if a default configuration 35 * directive is not overwritten in an environment, the default directive is active. 36 * 37 * Example: 38 * 39 * <code> 40 * default: 41 * log: 42 * file: /tmp/debug.log 43 * level: verbose 44 * 45 * development: 46 * log: 47 * file: /tmp/development.log 48 * 49 * testing: 50 * log: 51 * file: /tmp/testing.log 52 * 53 * production: 54 * log: 55 * file: /tmp/production.log 56 * level: error 57 * </code> 58 * 59 * The above example sets a log level of "verbose" as the default. 60 * The default log file is in "/tmp/debug.log". 61 * 62 * The environments development and testing overwrite the default log file. 63 * 64 * The production environment overwrites as well the log file and the log level. 65 * 66 * The Log level for development will be "verbose" (inherited from default). 67 * The log level for testing will be "verbose" (inherited from default). 68 * The log level for production will be "error" (overwritten the default level). 69 * 70 * 71 * = Accessing configuration files 72 * 73 * The format of the config files is YAML. 74 * The convention is that a yaml file in: 75 * 76 * AK_APP_DIR/config/myconfig.yml 77 * 78 * can be accessed via: 79 * 80 * <code> 81 * $config = new AkConfig(); 82 * $config->get('myconfig'); // loads myconfig.yml and section "AK_ENVIRONMENT" 83 * </code> 84 * 85 * By default the configuration for the environment defined in AK_ENVIRONMENT will be loaded. 86 * 87 * By providing the desired environment in the get call you can change that: 88 * 89 * <code> 90 * $config = new AkConfig(); 91 * $config->get('myconfig','production'); // loads myconfig.yml and section production 92 * </code> 93 * 94 * = Config caching 95 * 96 * The AkConfig class caches php representations of the yaml files inside: 97 * 98 * AK_APP_DIR/config/cache/$environment/$config.yml 99 * 100 * As soon as the modification time of a yaml-config file changes, the cache is invalidated 101 * and will be regenerated. 102 */ 103 class AkConfig 104 { 105 function _generateCacheFileName($namespace, $environment = AK_ENVIRONMENT) 106 { 107 $namespace = Ak::sanitize_include($namespace, 'high'); 108 $cacheDir = AK_CONFIG_DIR; 109 if (defined('AK_CONFIG_CACHE_TMP') && AK_CONFIG_CACHE_TMP) { 110 $cacheDir = AK_TMP_DIR.DS.'ak_config'; 111 } 112 $cacheFile = $cacheDir.DS.'cache'.DS.$environment.DS.$namespace.'.php'; 113 114 return $cacheFile; 115 } 116 function _useReadCache($environment = AK_ENVIRONMENT) 117 { 118 switch ($environment) { 119 case 'development': 120 case 'testing': 121 return false; 122 break; 123 default: 124 return true; 125 126 } 127 } 128 129 function _useWriteCache($environment = AK_ENVIRONMENT) 130 { 131 switch ($environment) { 132 case 'setup': 133 return false; 134 break; 135 case 'development': 136 case 'testing': 137 return true; 138 break; 139 default: 140 return true; 141 142 } 143 } 144 145 function _checkCacheValidity($namespace,$environment) 146 { 147 $cacheFilename = $this->_generateCacheFileName($namespace,$environment); 148 $configFilename = $this->_generateConfigFileName($namespace,$environment); 149 150 $cacheMtime = file_exists($cacheFilename) ? filemtime($cacheFilename): 1; 151 $configMtime = file_exists($cacheFilename) ? filemtime($configFilename) : 2; 152 return $cacheMtime == $configMtime; 153 } 154 155 function _setCacheValidity($namespace, $environment) 156 { 157 $cacheFilename = $this->_generateCacheFileName($namespace,$environment); 158 $configFilename = $this->_generateConfigFileName($namespace,$environment); 159 touch($cacheFilename,filemtime($configFilename)); 160 } 161 162 function _readCache($namespace, $environment = AK_ENVIRONMENT, $force = false) 163 { 164 if (!$force && !$this->_useReadCache($environment)) return false; 165 $cacheFileName = $this->_generateCacheFileName($namespace,$environment); 166 if ($this->_checkCacheValidity($namespace, $environment)) { 167 $config = include $cacheFileName; 168 } else { 169 $config = false; 170 } 171 return $config; 172 } 173 function _writeCache($config, $namespace, $environment = AK_ENVIRONMENT, $force = false) 174 { 175 if (AK_ENVIRONMENT == 'setup' || (!$force &&!$this->_useWriteCache($environment))) return false; 176 177 $var_export = var_export($config,true); 178 $cache = <<<CACHE 179 <?php 180 /** 181 * Auto-generated config cache from $namespace in environment $environment 182 */ 183 \$config = $var_export; 184 return \$config; 185 ?> 186 CACHE; 187 $cacheFileName = $this->_generateCacheFileName($namespace,$environment); 188 $cacheDir = dirname($cacheFileName); 189 190 if (!file_exists($cacheDir)) { 191 $oldumask = umask(); 192 umask(0); 193 $res = @mkdir($cacheDir,0777,true); 194 if (!$res) { 195 trigger_error(Ak::t('Could not create config cache dir %dir',array('%dir'=>$cacheDir)),E_USER_ERROR); 196 } 197 umask($oldumask); 198 } 199 $fh = fopen($cacheFileName,'w+'); 200 if ($fh) { 201 fputs($fh,$cache); 202 fclose($fh); 203 @chmod($cacheFileName,0777); 204 } else { 205 trigger_error(Ak::t('Could not create config cache file %file',array('%file'=>$cacheFileName)),E_USER_ERROR); 206 } 207 $this->_setCacheValidity($namespace,$environment); 208 } 209 function _generateConfigFileName($namespace,$environment = AK_ENVIRONMENT) 210 { 211 $namespace = Ak::sanitize_include($namespace, 'high'); 212 $yaml_file_name = AK_CONFIG_DIR.DS.$namespace.'.yml'; 213 return $yaml_file_name; 214 } 215 216 function _merge($default,$env) 217 { 218 if (is_array($default)) { 219 foreach($default as $key=>$value) { 220 if (!is_array($value)) { 221 $env[$key] = isset($env[$key])?$env[$key]:$value; 222 } else { 223 $env[$key] = $this->_merge($value,isset($env[$key])?$env[$key]:array()); 224 } 225 } 226 } else { 227 $env = empty($env)?$default:$env; 228 } 229 return $env; 230 } 231 232 function _readConfig($namespace, $environment = AK_ENVIRONMENT, $raise_error_if_config_file_not_found = true) 233 { 234 $yaml_file_name = $this->_generateConfigFileName($namespace, $environment); 235 if (!is_file($yaml_file_name)){ 236 if($raise_error_if_config_file_not_found){ 237 die(Ak::t('Could not find %namespace settings file in %path.', array('%namespace'=>$namespace, '%path'=>$yaml_file_name))."\n"); 238 } 239 return false; 240 } 241 require_once(AK_VENDOR_DIR.DS.'TextParsers'.DS.'spyc.php'); 242 $content = file_get_contents($yaml_file_name); 243 $content = $this->_parseSettingsConstants($content); 244 $config = Spyc::YAMLLoad($content); 245 246 if (!is_array($config)) return false; 247 248 $default = isset($config['default'])?$config['default']:array(); 249 250 251 $configs = array(); 252 253 unset($config['default']); 254 $environments = array_keys($config); 255 $default_environments = array('testing','development','production'); 256 $environments = array_merge($default_environments, $environments); 257 foreach($environments as $env) { 258 259 $envConfig = $this->_merge($default, isset($config[$env])?$config[$env]:array()); 260 $this->_writeCache($envConfig,$namespace,$env,$this->_useWriteCache($environment)); 261 $configs[$env] = $envConfig; 262 } 263 264 return isset($configs[$environment])?$configs[$environment]:$default; 265 266 } 267 268 function _parseSettingsConstants($settingsStr) 269 { 270 return preg_replace_callback('/\$\{(AK_.*?)\}/',array('AkConfig','_getConstant'),$settingsStr); 271 } 272 273 function _getConstant($name) 274 { 275 return defined($name[1])?constant($name[1]):''; 276 } 277 278 function &get($namespace, $environment = AK_ENVIRONMENT, $raise_error_if_config_file_not_found = true, $uncached = false) 279 { 280 static $configs = array(); 281 if (!$uncached && isset($_configs[$namespace]) && isset($_configs[$namespace][$environment])) { 282 return $_configs[$namespace][$environment]; 283 } 284 if ($uncached || !($config = $this->_readCache($namespace, $environment))) { 285 $config = $this->_readConfig($namespace, $environment,$raise_error_if_config_file_not_found); 286 } 287 if (!isset($_configs[$namespace])) { 288 $_configs[$namespace] = array($environment=>$config); 289 } else { 290 $_configs[$namespace][$environment] = $config; 291 } 292 return $_configs[$namespace][$environment]; 293 } 294 } 295 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Oct 27 12:43:49 2008 | Cross-referenced by PHPXref 0.6 |