PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/vendor/symfony/lib/config/sfConfigCache.class.php

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