[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/ -> AkConfig.php (source)

   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  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6