1. sfApplicationConfiguration.class.php
  2. /** * sfConfiguration represents a configuration for a symfony application. * * @package symfony * @subpackage config * @author Fabien Potencier * @version SVN: $Id: sfApplicationConfiguration.class.php 24042 2009-11-16 18:07:52Z Kris.Wallsmith $ */
  3. abstract class sfApplicationConfiguration extends ProjectConfiguration
  4. {
  5. static protected
  6. $coreLoaded = false,
  7. $loadedHelpers = array();
  8. protected
  9. $configCache = null,
  10. $application = null,
  11. $environment = null,
  12. $debug = false,
  13. $config = array(),
  14. $cache = null;
  15. /**
  16. * Constructor.
  17. *
  18. * @param string $environment The environment name
  19. * @param Boolean $debug true to enable debug mode
  20. * @param string $rootDir The project root directory
  21. * @param sfEventDispatcher $dispatcher An event dispatcher
  22. */
  23. public function __construct($environment, $debug, $rootDir = null, sfEventDispatcher $dispatcher = null)
  24. {
  25. $this->environment = $environment;
  26. $this->debug = (boolean) $debug;
  27. $this->application = str_replace('Configuration', '', get_class($this));
  28. parent::__construct($rootDir, $dispatcher);
  29. $this->configure();
  30. $this->initConfiguration();
  31. if (sfConfig::get('sf_check_lock'))
  32. {
  33. $this->checkLock();
  34. }
  35. if (file_exists($file = sfConfig::get('sf_app_cache_dir').'/config/configuration.php'))
  36. {
  37. $this->cache = require $file;
  38. }
  39. $this->initialize();
  40. // store current sfConfig values
  41. $this->config = sfConfig::getAll();
  42. }
  43. /**
  44. * Configures the current configuration.
  45. *
  46. * Override this method if you want to customize your application configuration.
  47. */
  48. public function configure()
  49. {
  50. }
  51. /**
  52. * Initialized the current configuration.
  53. *
  54. * Override this method if you want to customize your application initialization.
  55. */
  56. public function initialize()
  57. {
  58. }
  59. public function activate()
  60. {
  61. sfConfig::clear();
  62. sfConfig::add($this->config);
  63. }
  64. /**
  65. * Various initializations.
  66. */
  67. public function initConfiguration()
  68. {
  69. $configCache = $this->getConfigCache();
  70. // in debug mode, start global timer
  71. if ($this->isDebug() && !sfWebDebugPanelTimer::isStarted())
  72. {
  73. sfWebDebugPanelTimer::startTime();
  74. }
  75. // required core classes for the framework
  76. if (!$this->isDebug() && !sfConfig::get('sf_test') && !self::$coreLoaded)
  77. {
  78. $configCache->import('config/core_compile.yml', false);
  79. }
  80. // autoloader(s)
  81. $this->dispatcher->connect('autoload.filter_config', array($this, 'filterAutoloadConfig'));
  82. sfAutoload::getInstance()->register();
  83. if ($this->isDebug())
  84. {
  85. sfAutoloadAgain::getInstance()->register();
  86. }
  87. // load base settings
  88. include($configCache->checkConfig('config/settings.yml'));
  89. if ($file = $configCache->checkConfig('config/app.yml', true))
  90. {
  91. include($file);
  92. }
  93. if (false !== sfConfig::get('sf_csrf_secret'))
  94. {
  95. sfForm::enableCSRFProtection(sfConfig::get('sf_csrf_secret'));
  96. }
  97. sfWidget::setCharset(sfConfig::get('sf_charset'));
  98. sfValidatorBase::setCharset(sfConfig::get('sf_charset'));
  99. // force setting default timezone if not set
  100. if ($default_timezone = sfConfig::get('sf_default_timezone'))
  101. {
  102. date_default_timezone_set($default_timezone);
  103. }
  104. else if (sfConfig::get('sf_force_default_timezone', true))
  105. {
  106. date_default_timezone_set(@date_default_timezone_get());
  107. }
  108. // error settings
  109. ini_set('display_errors', $this->isDebug() ? 'on' : 'off');
  110. error_reporting(sfConfig::get('sf_error_reporting'));
  111. // initialize plugin configuration objects
  112. $this->initializePlugins();
  113. // compress output
  114. if (!self::$coreLoaded)
  115. {
  116. ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : '');
  117. }
  118. self::$coreLoaded = true;
  119. }
  120. /**
  121. * Initializes plugin configuration objects.
  122. */
  123. protected function initializePlugins()
  124. {
  125. foreach ($this->pluginConfigurations as $name => $configuration)
  126. {
  127. if (
  128. false === $configuration->initialize()
  129. &&
  130. is_readable($config = $configuration->getRootDir().'/config/config.php')
  131. )
  132. {
  133. require $config;
  134. }
  135. }
  136. }
  137. /**
  138. * Adds enabled plugins to autoload config.
  139. *
  140. * @param sfEvent $event
  141. * @param array $config
  142. *
  143. * @return array
  144. */
  145. public function filterAutoloadConfig(sfEvent $event, array $config)
  146. {
  147. foreach ($this->pluginConfigurations as $name => $configuration)
  148. {
  149. $config = $configuration->filterAutoloadConfig($event, $config);
  150. }
  151. return $config;
  152. }
  153. /**
  154. * Returns a configuration cache object for the current configuration.
  155. *
  156. * @return sfConfigCache A sfConfigCache instance
  157. */
  158. public function getConfigCache()
  159. {
  160. if (null === $this->configCache)
  161. {
  162. $this->configCache = new sfConfigCache($this);
  163. }
  164. return $this->configCache;
  165. }
  166. /**
  167. * Check lock files to see if we're not in a cache cleaning process.
  168. *
  169. * @return void
  170. */
  171. public function checkLock()
  172. {
  173. if (
  174. $this->hasLockFile(sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.$this->getApplication().'_'.$this->getEnvironment().'-cli.lck', 5)
  175. ||
  176. $this->hasLockFile(sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.$this->getApplication().'_'.$this->getEnvironment().'.lck')
  177. )
  178. {
  179. // application is not available - we'll find the most specific unavailable page...
  180. $files = array(
  181. sfConfig::get('sf_app_config_dir').'/unavailable.php',
  182. sfConfig::get('sf_config_dir').'/unavailable.php',
  183. sfConfig::get('sf_web_dir').'/errors/unavailable.php',
  184. $this->getSymfonyLibDir().'/exception/data/unavailable.php',
  185. );
  186. foreach ($files as $file)
  187. {
  188. if (is_readable($file))
  189. {
  190. include $file;
  191. break;
  192. }
  193. }
  194. die(1);
  195. }
  196. }
  197. /**
  198. * Determines if a lock file is present.
  199. *
  200. * @param string $lockFile Name of the lock file.
  201. * @param integer $maxLockFileLifeTime A max amount of life time for the lock file.
  202. *
  203. * @return bool true, if the lock file is present, otherwise false.
  204. */
  205. protected function hasLockFile($lockFile, $maxLockFileLifeTime = 0)
  206. {
  207. $isLocked = false;
  208. if (is_readable($lockFile) && ($last_access = fileatime($lockFile)))
  209. {
  210. $now = time();
  211. $timeDiff = $now - $last_access;
  212. if (!$maxLockFileLifeTime || $timeDiff < $maxLockFileLifeTime)
  213. {
  214. $isLocked = true;
  215. }
  216. else
  217. {
  218. $isLocked = @unlink($lockFile) ? false : true;
  219. }
  220. }
  221. return $isLocked;
  222. }
  223. /**
  224. * Sets the project root directory.
  225. *
  226. * @param string $rootDir The project root directory
  227. */
  228. public function setRootDir($rootDir)
  229. {
  230. parent::setRootDir($rootDir);
  231. sfConfig::add(array(
  232. 'sf_app' => $this->getApplication(),
  233. 'sf_environment' => $this->getEnvironment(),
  234. 'sf_debug' => $this->isDebug(),
  235. ));
  236. $this->setAppDir(sfConfig::get('sf_apps_dir').DIRECTORY_SEPARATOR.$this->getApplication());
  237. }
  238. /**
  239. * Sets the app directory.
  240. *
  241. * @param string $appDir The absolute path to the app dir.
  242. */
  243. public function setAppDir($appDir)
  244. {
  245. sfConfig::add(array(
  246. 'sf_app_dir' => $appDir,
  247. // SF_APP_DIR directory structure
  248. 'sf_app_config_dir' => $appDir.DIRECTORY_SEPARATOR.'config',
  249. 'sf_app_lib_dir' => $appDir.DIRECTORY_SEPARATOR.'lib',
  250. 'sf_app_module_dir' => $appDir.DIRECTORY_SEPARATOR.'modules',
  251. 'sf_app_template_dir' => $appDir.DIRECTORY_SEPARATOR.'templates',
  252. 'sf_app_i18n_dir' => $appDir.DIRECTORY_SEPARATOR.'i18n',
  253. ));
  254. }
  255. /**
  256. * @see sfProjectConfiguration
  257. */
  258. public function setCacheDir($cacheDir)
  259. {
  260. parent::setCacheDir($cacheDir);
  261. sfConfig::add(array(
  262. 'sf_app_base_cache_dir' => $cacheDir.DIRECTORY_SEPARATOR.$this->getApplication(),
  263. 'sf_app_cache_dir' => $appCacheDir = $cacheDir.DIRECTORY_SEPARATOR.$this->getApplication().DIRECTORY_SEPARATOR.$this->getEnvironment(),
  264. // SF_CACHE_DIR directory structure
  265. 'sf_template_cache_dir' => $appCacheDir.DIRECTORY_SEPARATOR.'template',
  266. 'sf_i18n_cache_dir' => $appCacheDir.DIRECTORY_SEPARATOR.'i18n',
  267. 'sf_config_cache_dir' => $appCacheDir.DIRECTORY_SEPARATOR.'config',
  268. 'sf_test_cache_dir' => $appCacheDir.DIRECTORY_SEPARATOR.'test',
  269. 'sf_module_cache_dir' => $appCacheDir.DIRECTORY_SEPARATOR.'modules',
  270. ));
  271. }
  272. /**
  273. * Gets directories where controller classes are stored for a given module.
  274. *
  275. * @param string $moduleName The module name
  276. *
  277. * @return array An array of directories
  278. */
  279. public function getControllerDirs($moduleName)
  280. {
  281. if (!isset($this->cache['getControllerDirs'][$moduleName]))
  282. {
  283. $dirs = array();
  284. $dirs[sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/actions'] = false; // application
  285. foreach ($this->getPluginPaths() as $path)
  286. {
  287. if (is_dir($dir = $path.'/modules/'.$moduleName.'/actions'))
  288. {
  289. $dirs[$dir] = true; // plugins
  290. }
  291. }
  292. if (is_dir($dir = $this->getSymfonyLibDir().'/controller/'.$moduleName.'/actions'))
  293. {
  294. $dirs[$dir] = true; // core modules
  295. }
  296. $this->cache['getControllerDirs'][$moduleName] = $dirs;
  297. }
  298. return $this->cache['getControllerDirs'][$moduleName];
  299. }
  300. /**
  301. * Gets directories where lib files are stored for a given module.
  302. *
  303. * @param string $moduleName The module name
  304. *
  305. * @return array An array of directories
  306. */
  307. public function getLibDirs($moduleName)
  308. {
  309. $dirs = array();
  310. $dirs[] = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/lib'; // application
  311. $dirs = array_merge($dirs, $this->getPluginSubPaths('/modules/'.$moduleName.'/lib')); // plugins
  312. $dirs[] = $this->getSymfonyLibDir().'/controller/'.$moduleName.'/lib'; // core modules
  313. $dirs[] = sfConfig::get('sf_module_cache_dir').'/auto'.ucfirst($moduleName.'/lib'); // generated templates in cache
  314. return $dirs;
  315. }
  316. /**
  317. * Gets directories where template files are stored for a given module.
  318. *
  319. * @param string $moduleName The module name
  320. *
  321. * @return array An array of directories
  322. */
  323. public function getTemplateDirs($moduleName)
  324. {
  325. $dirs = array();
  326. $dirs[] = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/templates'; // application
  327. $dirs = array_merge($dirs, $this->getPluginSubPaths('/modules/'.$moduleName.'/templates')); // plugins
  328. $dirs[] = $this->getSymfonyLibDir().'/controller/'.$moduleName.'/templates'; // core modules
  329. $dirs[] = sfConfig::get('sf_module_cache_dir').'/auto'.ucfirst($moduleName.'/templates'); // generated templates in cache
  330. return $dirs;
  331. }
  332. /**
  333. * Gets the helper directories for a given module name.
  334. *
  335. * @param string $moduleName The module name
  336. *
  337. * @return array An array of directories
  338. */
  339. public function getHelperDirs($moduleName = '')
  340. {
  341. $dirs = array();
  342. if ($moduleName)
  343. {
  344. $dirs[] = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/lib/helper'; // module
  345. $dirs = array_merge($dirs, $this->getPluginSubPaths('/modules/'.$moduleName.'/lib/helper'));
  346. }
  347. return array_merge(
  348. $dirs,
  349. array(
  350. sfConfig::get('sf_app_lib_dir').'/helper', // application
  351. sfConfig::get('sf_lib_dir').'/helper', // project
  352. ),
  353. $this->getPluginSubPaths('/lib/helper'), // plugins
  354. array($this->getSymfonyLibDir().'/helper') // symfony
  355. );
  356. }
  357. /**
  358. * Gets the template directory to use for a given module and template file.
  359. *
  360. * @param string $moduleName The module name
  361. * @param string $templateFile The template file
  362. *
  363. * @return string A template directory
  364. */
  365. public function getTemplateDir($moduleName, $templateFile)
  366. {
  367. if (!isset($this->cache['getTemplateDir'][$moduleName][$templateFile]))
  368. {
  369. $this->cache['getTemplateDir'][$moduleName][$templateFile] = null;
  370. foreach ($this->getTemplateDirs($moduleName) as $dir)
  371. {
  372. if (is_readable($dir.'/'.$templateFile))
  373. {
  374. $this->cache['getTemplateDir'][$moduleName][$templateFile] = $dir;
  375. break;
  376. }
  377. }
  378. }
  379. return $this->cache['getTemplateDir'][$moduleName][$templateFile];
  380. }
  381. /**
  382. * Gets the template to use for a given module and template file.
  383. *
  384. * @param string $moduleName The module name
  385. * @param string $templateFile The template file
  386. *
  387. * @return string A template path
  388. */
  389. public function getTemplatePath($moduleName, $templateFile)
  390. {
  391. $dir = $this->getTemplateDir($moduleName, $templateFile);
  392. return $dir ? $dir.'/'.$templateFile : null;
  393. }
  394. /**
  395. * @see sfProjectConfiguration
  396. */
  397. public function getPluginPaths()
  398. {
  399. if (!isset($this->cache['getPluginPaths']))
  400. {
  401. $this->cache['getPluginPaths'] = parent::getPluginPaths();
  402. }
  403. return $this->cache['getPluginPaths'];
  404. }
  405. /**
  406. * Gets the decorator directories.
  407. *
  408. * @return array An array of the decorator directories
  409. */
  410. public function getDecoratorDirs()
  411. {
  412. return array(sfConfig::get('sf_app_template_dir'));
  413. }
  414. /**
  415. * Gets the decorator directory for a given template.
  416. *
  417. * @param string $template The template file
  418. *
  419. * @return string A template directory
  420. */
  421. public function getDecoratorDir($template)
  422. {
  423. foreach ($this->getDecoratorDirs() as $dir)
  424. {
  425. if (is_readable($dir.'/'.$template))
  426. {
  427. return $dir;
  428. }
  429. }
  430. }
  431. /**
  432. * Gets the i18n directories to use globally.
  433. *
  434. * @return array An array of i18n directories
  435. */
  436. public function getI18NGlobalDirs()
  437. {
  438. $dirs = array();
  439. // application
  440. if (is_dir($dir = sfConfig::get('sf_app_i18n_dir')))
  441. {
  442. $dirs[] = $dir;
  443. }
  444. // plugins
  445. return array_merge($dirs, $this->getPluginSubPaths('/i18n'));
  446. }
  447. /**
  448. * Gets the i18n directories to use for a given module.
  449. *
  450. * @param string $moduleName The module name
  451. *
  452. * @return array An array of i18n directories
  453. */
  454. public function getI18NDirs($moduleName)
  455. {
  456. $dirs = array();
  457. // module
  458. if (is_dir($dir = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/i18n'))
  459. {
  460. $dirs[] = $dir;
  461. }
  462. // application
  463. if (is_dir($dir = sfConfig::get('sf_app_i18n_dir')))
  464. {
  465. $dirs[] = $dir;
  466. }
  467. return array_merge(
  468. $dirs,
  469. $this->getPluginSubPaths('/modules/'.$moduleName.'/i18n'), // module in plugins
  470. $this->getPluginSubPaths('/i18n') // plugins
  471. );
  472. }
  473. /**
  474. * Gets the configuration file paths for a given relative configuration path.
  475. *
  476. * @param string $configPath The configuration path
  477. *
  478. * @return array An array of paths
  479. */
  480. public function getConfigPaths($configPath)
  481. {
  482. $globalConfigPath = basename(dirname($configPath)).'/'.basename($configPath);
  483. $files = array(
  484. $this->getSymfonyLibDir().'/config/'.$globalConfigPath, // symfony
  485. );
  486. foreach ($this->getPluginPaths() as $path)
  487. {
  488. if (is_file($file = $path.'/'.$globalConfigPath))
  489. {
  490. $files[] = $file; // plugins
  491. }
  492. }
  493. $files = array_merge($files, array(
  494. $this->getRootDir().'/'.$globalConfigPath, // project
  495. $this->getRootDir().'/'.$configPath, // project
  496. sfConfig::get('sf_app_dir').'/'.$globalConfigPath, // application
  497. sfConfig::get('sf_app_cache_dir').'/'.$configPath, // generated modules
  498. ));
  499. foreach ($this->getPluginPaths() as $path)
  500. {
  501. if (is_file($file = $path.'/'.$configPath))
  502. {
  503. $files[] = $file; // plugins
  504. }
  505. }
  506. $files[] = sfConfig::get('sf_app_dir').'/'.$configPath; // module
  507. $configs = array();
  508. foreach (array_unique($files) as $file)
  509. {
  510. if (is_readable($file))
  511. {
  512. $configs[] = $file;
  513. }
  514. }
  515. return $configs;
  516. }
  517. /**
  518. * Loads helpers.
  519. *
  520. * @param array $helpers An array of helpers to load
  521. * @param string $moduleName A module name (optional)
  522. */
  523. public function loadHelpers($helpers, $moduleName = '')
  524. {
  525. foreach ((array) $helpers as $helperName)
  526. {
  527. if (isset(self::$loadedHelpers[$helperName]))
  528. {
  529. continue;
  530. }
  531. if (isset($this->cache['loadedHelpers'][$moduleName][$helperName]))
  532. {
  533. include_once $this->cache['loadedHelpers'][$moduleName][$helperName];
  534. }
  535. else if (isset($this->cache['loadedHelpers'][''][$helperName]))
  536. {
  537. include_once $this->cache['loadedHelpers'][''][$helperName];
  538. }
  539. else
  540. {
  541. $fileName = $helperName.'Helper.php';
  542. if (!isset($dirs))
  543. {
  544. $dirs = $this->getHelperDirs($moduleName);
  545. }
  546. foreach ($dirs as $dir)
  547. {
  548. $included = false;
  549. if (is_readable($dir.'/'.$fileName))
  550. {
  551. include_once $dir.'/'.$fileName;
  552. $included = true;
  553. break;
  554. }
  555. }
  556. if (!$included)
  557. {
  558. throw new InvalidArgumentException(sprintf('Unable to load "%sHelper.php" helper in: %s.', $helperName, implode(', ', array_map(array('sfDebug', 'shortenFilePath'), $dirs))));
  559. }
  560. }
  561. self::$loadedHelpers[$helperName] = true;
  562. }
  563. }
  564. /**
  565. * Returns the application name.
  566. *
  567. * @return string The application name
  568. */
  569. public function getApplication()
  570. {
  571. return $this->application;
  572. }
  573. /**
  574. * Returns the environment name.
  575. *
  576. * @return string The environment name
  577. */
  578. public function getEnvironment()
  579. {
  580. return $this->environment;
  581. }
  582. /**
  583. * Returns true if this configuration has debug enabled.
  584. *
  585. * @return Boolean true if the configuration has debug enabled, false otherwise
  586. */
  587. public function isDebug()
  588. {
  589. return $this->debug;
  590. }
  591. }

Debug toolbar