[ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 /* 4 * This file is part of the symfony package. 5 * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com> 6 * (c) 2004-2006 Sean Kerr. 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 /** 13 * sfConfigCache allows you to customize the format of a configuration file to 14 * make it easy-to-use, yet still provide a PHP formatted result for direct 15 * inclusion into your modules. 16 * 17 * @package symfony 18 * @subpackage config 19 * @author Fabien Potencier <fabien.potencier@symfony-project.com> 20 * @author Sean Kerr <skerr@mojavi.org> 21 * @version SVN: $Id: sfConfigCache.class.php 3503 2007-02-18 19:08:26Z fabien $ 22 */ 23 class sfConfigCache 24 { 25 protected 26 $handlers = array(); 27 28 protected static 29 $instance = null; 30 31 /** 32 * Retrieves the singleton instance of this class. 33 * 34 * @return sfConfigCache A sfConfigCache instance 35 */ 36 public static function getInstance() 37 { 38 if (!self::$instance) 39 { 40 self::$instance = new sfConfigCache(); 41 } 42 43 return self::$instance; 44 } 45 46 /** 47 * Loads a configuration handler. 48 * 49 * @param string The handler to use when parsing a configuration file 50 * @param array An array of absolute filesystem paths to configuration files 51 * @param string An absolute filesystem path to the cache file that will be written 52 * 53 * @throws <b>sfConfigurationException</b> If a requested configuration file does not have an associated configuration handler 54 */ 55 protected function callHandler($handler, $configs, $cache) 56 { 57 if (count($this->handlers) == 0) 58 { 59 // we need to load the handlers first 60 $this->loadConfigHandlers(); 61 } 62 63 // handler to call for this configuration file 64 $handlerToCall = null; 65 66 $handler = str_replace(DIRECTORY_SEPARATOR, '/', $handler); 67 68 // grab the base name of the handler 69 $basename = basename($handler); 70 if (isset($this->handlers[$handler])) 71 { 72 // we have a handler associated with the full configuration path 73 $handlerToCall = $this->handlers[$handler]; 74 } 75 else if (isset($this->handlers[$basename])) 76 { 77 // we have a handler associated with the configuration base name 78 $handlerToCall = $this->handlers[$basename]; 79 } 80 else 81 { 82 // let's see if we have any wildcard handlers registered that match 83 // this basename 84 foreach ($this->handlers as $key => $handlerInstance) 85 { 86 // replace wildcard chars in the configuration 87 $pattern = strtr($key, array('.' => '\.', '*' => '.*?')); 88 89 // create pattern from config 90 if (preg_match('#'.$pattern.'#', $handler)) 91 { 92 // we found a match! 93 $handlerToCall = $this->handlers[$key]; 94 95 break; 96 } 97 } 98 } 99 100 if ($handlerToCall) 101 { 102 // call the handler and retrieve the cache data 103 $data = $handlerToCall->execute($configs); 104 105 $this->writeCacheFile($handler, $cache, $data); 106 } 107 else 108 { 109 // we do not have a registered handler for this file 110 $error = sprintf('Configuration file "%s" does not have a registered handler', implode(', ', $configs)); 111 112 throw new sfConfigurationException($error); 113 } 114 } 115 116 /** 117 * Checks to see if a configuration file has been modified and if so 118 * recompile the cache file associated with it. 119 * 120 * The recompilation only occurs in a non debug environment. 121 * 122 * If the configuration file path is relative, symfony will look in directories 123 * defined in the sfLoader::getConfigPaths() method. 124 * 125 * @param string A filesystem path to a configuration file 126 * 127 * @return string An absolute filesystem path to the cache filename associated with this specified configuration file 128 * 129 * @throws <b>sfConfigurationException</b> If a requested configuration file does not exist 130 * 131 * @see sfLoader::getConfigPaths() 132 */ 133 public function checkConfig($configPath, $optional = false) 134 { 135 static $process_cache_cleared = false; 136 137 if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) 138 { 139 $timer = sfTimerManager::getTimer('Configuration'); 140 } 141 142 // the cache filename we'll be using 143 $cache = $this->getCacheName($configPath); 144 145 if (sfConfig::get('sf_in_bootstrap') && is_readable($cache)) 146 { 147 if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) 148 { 149 $timer->addTime(); 150 } 151 152 return $cache; 153 } 154 155 if (!sfToolkit::isPathAbsolute($configPath)) 156 { 157 $files = sfLoader::getConfigPaths($configPath); 158 } 159 else 160 { 161 $files = is_readable($configPath) ? array($configPath) : array(); 162 } 163 164 if (!isset($files[0])) 165 { 166 if ($optional) 167 { 168 return null; 169 } 170 171 // configuration does not exist 172 $error = sprintf('Configuration "%s" does not exist or is unreadable', $configPath); 173 174 throw new sfConfigurationException($error); 175 } 176 177 // find the more recent configuration file last modification time 178 $mtime = 0; 179 foreach ($files as $file) 180 { 181 if (filemtime($file) > $mtime) 182 { 183 $mtime = filemtime($file); 184 } 185 } 186 187 if (!is_readable($cache) || $mtime > filemtime($cache)) 188 { 189 // configuration has changed so we need to reparse it 190 $this->callHandler($configPath, $files, $cache); 191 192 // clear process cache 193 if ('config/config_handlers.yml' != $configPath && sfConfig::has('sf_use_process_cache') && !$process_cache_cleared) 194 { 195 sfProcessCache::clear(); 196 $process_cache_cleared = true; 197 } 198 } 199 200 if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) 201 { 202 $timer->addTime(); 203 } 204 205 return $cache; 206 } 207 208 /** 209 * Clears all configuration cache files. 210 */ 211 public function clear() 212 { 213 sfToolkit::clearDirectory(sfConfig::get('sf_config_cache_dir')); 214 } 215 216 /** 217 * Converts a normal filename into a cache filename. 218 * 219 * @param string A normal filename 220 * 221 * @return string An absolute filesystem path to a cache filename 222 */ 223 public function getCacheName($config) 224 { 225 if (strlen($config) > 3 && ctype_alpha($config[0]) && $config[1] == ':' && ($config[2] == '\\' || $config[2] == '/')) 226 { 227 // file is a windows absolute path, strip off the drive letter 228 $config = substr($config, 3); 229 } 230 231 // replace unfriendly filename characters with an underscore 232 $config = str_replace(array('\\', '/', ' '), '_', $config); 233 $config .= '.php'; 234 235 return sfConfig::get('sf_config_cache_dir').'/'.$config; 236 } 237 238 /** 239 * Imports a configuration file. 240 * 241 * @param string A filesystem path to a configuration file 242 * @param bool Only allow this configuration file to be included once per request? 243 * 244 * @see checkConfig() 245 */ 246 public function import($config, $once = true, $optional = false) 247 { 248 $cache = $this->checkConfig($config, $optional); 249 250 if ($optional && !$cache) 251 { 252 return; 253 } 254 255 // include cache file 256 if ($once) 257 { 258 include_once($cache); 259 } 260 else 261 { 262 include($cache); 263 } 264 } 265 266 /** 267 * Loads all configuration application and module level handlers. 268 * 269 * @throws <b>sfConfigurationException</b> If a configuration related error occurs. 270 */ 271 protected function loadConfigHandlers() 272 { 273 // manually create our config_handlers.yml handler 274 $this->handlers['config_handlers.yml'] = new sfRootConfigHandler(); 275 $this->handlers['config_handlers.yml']->initialize(); 276 277 // application configuration handlers 278 279 require_once($this->checkConfig(sfConfig::get('sf_app_config_dir_name').'/config_handlers.yml')); 280 281 // module level configuration handlers 282 283 // make sure our modules directory exists 284 if (is_readable($sf_app_module_dir = sfConfig::get('sf_app_module_dir'))) 285 { 286 // ignore names 287 $ignore = array('.', '..', 'CVS', '.svn'); 288 289 // create a file pointer to the module dir 290 $fp = opendir($sf_app_module_dir); 291 292 // loop through the directory and grab the modules 293 while (($directory = readdir($fp)) !== false) 294 { 295 if (!in_array($directory, $ignore)) 296 { 297 $configPath = $sf_app_module_dir.'/'.$directory.'/'.sfConfig::get('sf_app_module_config_dir_name').'/config_handlers.yml'; 298 299 if (is_readable($configPath)) 300 { 301 // initialize the root configuration handler with this module name 302 $params = array('module_level' => true, 'module_name' => $directory); 303 304 $this->handlers['config_handlers.yml']->initialize($params); 305 306 // replace module dir path with a special keyword that 307 // checkConfig knows how to use 308 $configPath = sfConfig::get('sf_app_module_dir_name').'/'.$directory.'/'.sfConfig::get('sf_app_module_config_dir_name').'/config_handlers.yml'; 309 310 require_once($this->checkConfig($configPath)); 311 } 312 } 313 } 314 315 // close file pointer 316 fclose($fp); 317 } 318 else 319 { 320 // module directory doesn't exist or isn't readable 321 $error = sprintf('Module directory "%s" does not exist or is not readable', 322 sfConfig::get('sf_app_module_dir')); 323 throw new sfConfigurationException($error); 324 } 325 } 326 327 /** 328 * Writes a cache file. 329 * 330 * @param string An absolute filesystem path to a configuration file 331 * @param string An absolute filesystem path to the cache file that will be written 332 * @param string Data to be written to the cache file 333 * 334 * @throws sfCacheException If the cache file cannot be written 335 */ 336 protected function writeCacheFile($config, $cache, &$data) 337 { 338 $fileCache = new sfFileCache(dirname($cache)); 339 $fileCache->setSuffix(''); 340 $fileCache->set(basename($cache), '', $data); 341 } 342 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |