Development

/branches/1.4/lib/config/sfApplicationConfiguration.class.php

You must first sign up to be able to contribute.

root/branches/1.4/lib/config/sfApplicationConfiguration.class.php

Revision 33214, 18.3 kB (checked in by fabien, 2 years ago)

[1.4] fixed ob_start() behavior on CLI (closes #9970)

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