sfApplicationConfiguration.class.php 18 KB

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