Development

/branches/1.3/lib/config/sfProjectConfiguration.class.php

You must first sign up to be able to contribute.

root/branches/1.3/lib/config/sfProjectConfiguration.class.php

Revision 27191, 16.2 kB (checked in by FabianLange, 5 years ago)

[1.2, 1.3, 1.4] fixed missing variable declaration in sfProjectCOnfiguration (closes #7949)

  • 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  * sfProjectConfiguration represents a configuration for a symfony project.
13  *
14  * @package    symfony
15  * @subpackage config
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 class sfProjectConfiguration
20 {
21   protected
22     $rootDir               = null,
23     $symfonyLibDir         = null,
24     $dispatcher            = null,
25     $plugins               = array(),
26     $pluginPaths           = array(),
27     $overriddenPluginPaths = array(),
28     $pluginConfigurations  = array(),
29     $pluginsLoaded         = false;
30
31   static protected
32     $active = null;
33
34   /**
35    * Constructor.
36    *
37    * @param string              $rootDir    The project root directory
38    * @param sfEventDispatcher   $dispatcher The event dispatcher
39    */
40   public function __construct($rootDir = null, sfEventDispatcher $dispatcher = null)
41   {
42     if (null === self::$active || $this instanceof sfApplicationConfiguration)
43     {
44       self::$active = $this;
45     }
46
47     $this->rootDir = null === $rootDir ? self::guessRootDir() : realpath($rootDir);
48     $this->symfonyLibDir = realpath(dirname(__FILE__).'/..');
49     $this->dispatcher = null === $dispatcher ? new sfEventDispatcher() : $dispatcher;
50
51     ini_set('magic_quotes_runtime', 'off');
52
53     sfConfig::set('sf_symfony_lib_dir', $this->symfonyLibDir);
54
55     $this->setRootDir($this->rootDir);
56
57     // provide forms the dispatcher
58     sfFormSymfony::setEventDispatcher($this->dispatcher);
59
60     $this->setup();
61
62     $this->loadPlugins();
63     $this->setupPlugins();
64   }
65
66   /**
67    * Setups the current configuration.
68    *
69    * Override this method if you want to customize your project configuration.
70    */
71   public function setup()
72   {
73   }
74
75   /**
76    * Loads the project's plugin configurations.
77    */
78   public function loadPlugins()
79   {
80     foreach ($this->getPluginPaths() as $path)
81     {
82       if (false === $plugin = array_search($path, $this->overriddenPluginPaths))
83       {
84         $plugin = basename($path);
85       }
86       $class = $plugin.'Configuration';
87
88       if (is_readable($file = sprintf('%s/config/%s.class.php', $path, $class)))
89       {
90         require_once $file;
91         $configuration = new $class($this, $path, $plugin);
92       }
93       else
94       {
95         $configuration = new sfPluginConfigurationGeneric($this, $path, $plugin);
96       }
97
98       $this->pluginConfigurations[$plugin] = $configuration;
99     }
100
101     $this->pluginsLoaded = true;
102   }
103
104   /**
105    * Sets up plugin configurations.
106    *
107    * Override this method if you want to customize plugin configurations.
108    */
109   public function setupPlugins()
110   {
111   }
112
113   /**
114    * Sets the project root directory.
115    *
116    * @param string $rootDir The project root directory
117    */
118   public function setRootDir($rootDir)
119   {
120     $this->rootDir = $rootDir;
121
122     sfConfig::add(array(
123       'sf_root_dir' => $rootDir,
124
125       // global directory structure
126       'sf_apps_dir'    => $rootDir.DIRECTORY_SEPARATOR.'apps',
127       'sf_lib_dir'     => $rootDir.DIRECTORY_SEPARATOR.'lib',
128       'sf_log_dir'     => $rootDir.DIRECTORY_SEPARATOR.'log',
129       'sf_data_dir'    => $rootDir.DIRECTORY_SEPARATOR.'data',
130       'sf_config_dir'  => $rootDir.DIRECTORY_SEPARATOR.'config',
131       'sf_test_dir'    => $rootDir.DIRECTORY_SEPARATOR.'test',
132       'sf_plugins_dir' => $rootDir.DIRECTORY_SEPARATOR.'plugins',
133     ));
134
135     $this->setWebDir($rootDir.DIRECTORY_SEPARATOR.'web');
136     $this->setCacheDir($rootDir.DIRECTORY_SEPARATOR.'cache');
137   }
138
139   /**
140    * Returns the project root directory.
141    *
142    * @return string The project root directory
143    */
144   public function getRootDir()
145   {
146     return $this->rootDir;
147   }
148
149   /**
150    * Sets the cache root directory.
151    *
152    * @param string $cacheDir The absolute path to the cache dir.
153    */
154   public function setCacheDir($cacheDir)
155   {
156     sfConfig::set('sf_cache_dir', $cacheDir);
157   }
158
159   /**
160    * Sets the log directory.
161    *
162    * @param string $logDir The absolute path to the log dir.
163    */
164   public function setLogDir($logDir)
165   {
166     sfConfig::set('sf_log_dir', $logDir);
167   }
168
169   /**
170    * Sets the web root directory.
171    *
172    * @param string $webDir The absolute path to the web dir.
173    */
174   public function setWebDir($webDir)
175   {
176     sfConfig::add(array(
177       'sf_web_dir'    => $webDir,
178       'sf_upload_dir' => $webDir.DIRECTORY_SEPARATOR.'uploads',
179     ));
180   }
181
182   /**
183    * Gets directories where model classes are stored. The order of returned paths is lowest precedence
184    * to highest precedence.
185    *
186    * @return array An array of directories
187    */
188   public function getModelDirs()
189   {
190     return array_merge(
191       $this->getPluginSubPaths('/lib/model'),     // plugins
192       array(sfConfig::get('sf_lib_dir').'/model') // project
193     );
194   }
195
196   /**
197    * Gets directories where template files are stored for a generator class and a specific theme.
198    *
199    * @param string $class  The generator class name
200    * @param string $theme  The theme name
201    *
202    * @return array An array of directories
203    */
204   public function getGeneratorTemplateDirs($class, $theme)
205   {
206     return array_merge(
207       array(sfConfig::get('sf_data_dir').'/generator/'.$class.'/'.$theme.'/template'), // project
208       $this->getPluginSubPaths('/data/generator/'.$class.'/'.$theme.'/template'),      // plugins
209       array(sfConfig::get('sf_data_dir').'/generator/'.$class.'/default/template'),    // project (default theme)
210       $this->getPluginSubPaths('/data/generator/'.$class.'/default/template')          // plugins (default theme)
211     );
212   }
213
214   /**
215    * Gets directories where the skeleton is stored for a generator class and a specific theme.
216    *
217    * @param string $class   The generator class name
218    * @param string $theme   The theme name
219    *
220    * @return array An array of directories
221    */
222   public function getGeneratorSkeletonDirs($class, $theme)
223   {
224     return array_merge(
225       array(sfConfig::get('sf_data_dir').'/generator/'.$class.'/'.$theme.'/skeleton'), // project
226       $this->getPluginSubPaths('/data/generator/'.$class.'/'.$theme.'/skeleton'),      // plugins
227       array(sfConfig::get('sf_data_dir').'/generator/'.$class.'/default/skeleton'),    // project (default theme)
228       $this->getPluginSubPaths('/data/generator/'.$class.'/default/skeleton')          // plugins (default theme)
229     );
230   }
231
232   /**
233    * Gets the template to use for a generator class.
234    *
235    * @param string $class   The generator class name
236    * @param string $theme   The theme name
237    * @param string $path    The template path
238    *
239    * @return string A template path
240    *
241    * @throws sfException
242    */
243   public function getGeneratorTemplate($class, $theme, $path)
244   {
245     $dirs = $this->getGeneratorTemplateDirs($class, $theme);
246     foreach ($dirs as $dir)
247     {
248       if (is_readable($dir.'/'.$path))
249       {
250         return $dir.'/'.$path;
251       }
252     }
253
254     throw new sfException(sprintf('Unable to load "%s" generator template in: %s.', $path, implode(', ', $dirs)));
255   }
256
257   /**
258    * Gets the configuration file paths for a given relative configuration path.
259    *
260    * @param string $configPath The configuration path
261    *
262    * @return array An array of paths
263    */
264   public function getConfigPaths($configPath)
265   {
266     $globalConfigPath = basename(dirname($configPath)).'/'.basename($configPath);
267
268     $files = array(
269       $this->getSymfonyLibDir().'/config/'.$globalConfigPath, // symfony
270     );
271
272     foreach ($this->getPluginPaths() as $path)
273     {
274       if (is_file($file = $path.'/'.$globalConfigPath))
275       {
276         $files[] = $file;                                     // plugins
277       }
278     }
279
280     $files = array_merge($files, array(
281       $this->getRootDir().'/'.$globalConfigPath,              // project
282       $this->getRootDir().'/'.$configPath,                    // project
283     ));
284
285     foreach ($this->getPluginPaths() as $path)
286     {
287       if (is_file($file = $path.'/'.$configPath))
288       {
289         $files[] = $file;                                     // plugins
290       }
291     }
292
293     $configs = array();
294     foreach (array_unique($files) as $file)
295     {
296       if (is_readable($file))
297       {
298         $configs[] = $file;
299       }
300     }
301
302     return $configs;
303   }
304
305   /**
306    * Sets the enabled plugins.
307    *
308    * @param array $plugins An array of plugin names
309    *
310    * @throws LogicException If plugins have already been loaded
311    */
312   public function setPlugins(array $plugins)
313   {
314     if ($this->pluginsLoaded)
315     {
316       throw new LogicException('Plugins have already been loaded.');
317     }
318
319     $this->plugins = $plugins;
320
321     $this->pluginPaths = array();
322   }
323
324   /**
325    * Enables a plugin or a list of plugins.
326    *
327    * @param array|string $plugins A plugin name or a plugin list
328    */
329   public function enablePlugins($plugins)
330   {
331     if (!is_array($plugins))
332     {
333       if (func_num_args() > 1)
334       {
335         $plugins = func_get_args();
336       }
337       else
338       {
339         $plugins = array($plugins);
340       }
341     }
342     
343     $this->setPlugins(array_merge($this->plugins, $plugins));
344   }
345
346   /**
347    * Disables a plugin.
348    *
349    * @param array|string $plugins A plugin name or a plugin list
350    *
351    * @throws LogicException If plugins have already been loaded
352    */
353   public function disablePlugins($plugins)
354   {
355     if ($this->pluginsLoaded)
356     {
357       throw new LogicException('Plugins have already been loaded.');
358     }
359
360     if (!is_array($plugins))
361     {
362       $plugins = array($plugins);
363     }
364
365     foreach ($plugins as $plugin)
366     {
367       if (false !== $pos = array_search($plugin, $this->plugins))
368       {
369         unset($this->plugins[$pos]);
370       }
371       else
372       {
373         throw new InvalidArgumentException(sprintf('The plugin "%s" does not exist.', $plugin));
374       }
375     }
376
377     $this->pluginPaths = array();
378   }
379
380   /**
381    * Enabled all installed plugins except the one given as argument.
382    *
383    * @param array|string $plugins A plugin name or a plugin list
384    *
385    * @throws LogicException If plugins have already been loaded
386    */
387   public function enableAllPluginsExcept($plugins = array())
388   {
389     if ($this->pluginsLoaded)
390     {
391       throw new LogicException('Plugins have already been loaded.');
392     }
393
394     $this->plugins = array_keys($this->getAllPluginPaths());
395
396     sort($this->plugins);
397
398     $this->disablePlugins($plugins);
399   }
400
401   /**
402    * Gets the list of enabled plugins.
403    *
404    * @return array An array of enabled plugins
405    */
406   public function getPlugins()
407   {
408     return $this->plugins;
409   }
410
411   /**
412    * Gets the paths plugin sub-directories, minding overloaded plugins.
413    *
414    * @param  string $subPath The subdirectory to look for
415    *
416    * @return array The plugin paths.
417    */
418   public function getPluginSubPaths($subPath = '')
419   {
420     if (array_key_exists($subPath, $this->pluginPaths))
421     {
422       return $this->pluginPaths[$subPath];
423     }
424
425     $this->pluginPaths[$subPath] = array();
426     $pluginPaths = $this->getPluginPaths();
427     foreach ($pluginPaths as $pluginPath)
428     {
429       if (is_dir($pluginPath.$subPath))
430       {
431         $this->pluginPaths[$subPath][] = $pluginPath.$subPath;
432       }
433     }
434
435     return $this->pluginPaths[$subPath];
436   }
437
438   /**
439    * Gets the paths to plugins root directories, minding overloaded plugins.
440    *
441    * @return array The plugin root paths.
442    *
443    * @throws InvalidArgumentException If an enabled plugin does not exist
444    */
445   public function getPluginPaths()
446   {
447     if (!isset($this->pluginPaths['']))
448     {
449       $pluginPaths = $this->getAllPluginPaths();
450
451       $this->pluginPaths[''] = array();
452       foreach ($this->getPlugins() as $plugin)
453       {
454         if (isset($pluginPaths[$plugin]))
455         {
456           $this->pluginPaths[''][] = $pluginPaths[$plugin];
457         }
458         else
459         {
460           throw new InvalidArgumentException(sprintf('The plugin "%s" does not exist.', $plugin));
461         }
462       }
463     }
464
465     return $this->pluginPaths[''];
466   }
467
468   /**
469    * Returns an array of paths for all available plugins.
470    *
471    * @return array
472    */
473   public function getAllPluginPaths()
474   {
475     $pluginPaths = array();
476
477     // search for *Plugin directories representing plugins
478     // follow links and do not recurse. No need to exclude VC because they do not end with *Plugin
479     $finder = sfFinder::type('dir')->maxdepth(0)->ignore_version_control(false)->follow_link()->name('*Plugin');
480     $dirs = array(
481       $this->getSymfonyLibDir().'/plugins',
482       sfConfig::get('sf_plugins_dir'),
483     );
484
485     foreach ($finder->in($dirs) as $path)
486     {
487       $pluginPaths[basename($path)] = $path;
488     }
489
490     foreach ($this->overriddenPluginPaths as $plugin => $path)
491     {
492       $pluginPaths[$plugin] = $path;
493     }
494
495     return $pluginPaths;
496   }
497
498   /**
499    * Manually sets the location of a particular plugin.
500    *
501    * This method can be used to ease functional testing of plugins. It is not
502    * intended to support sharing plugins between projects, as many plugins
503    * save project specific code (to /lib/form/base, for example).
504    *
505    * @param string $plugin
506    * @param string $path
507    */
508   public function setPluginPath($plugin, $path)
509   {
510     $this->overriddenPluginPaths[$plugin] = realpath($path);
511   }
512
513   /**
514    * Returns the configuration for the requested plugin.
515    *
516    * @param   string $name
517    *
518    * @return  sfPluginConfiguration
519    */
520   public function getPluginConfiguration($name)
521   {
522     if (!isset($this->pluginConfigurations[$name]))
523     {
524       throw new InvalidArgumentException(sprintf('There is no configuration object for the "%s" object.', $name));
525     }
526
527     return $this->pluginConfigurations[$name];
528   }
529
530   /**
531    * Returns the event dispatcher.
532    *
533    * @return sfEventDispatcher A sfEventDispatcher instance
534    */
535   public function getEventDispatcher()
536   {
537     return $this->dispatcher;
538   }
539
540   /**
541    * Returns the symfony lib directory.
542    *
543    * @return string The symfony lib directory
544    */
545   public function getSymfonyLibDir()
546   {
547     return $this->symfonyLibDir;
548   }
549
550   /**
551    * Returns the active configuration.
552    *
553    * @return sfProjectConfiguration The current sfProjectConfiguration instance
554    */
555   static public function getActive()
556   {
557     if (!self::hasActive())
558     {
559       throw new RuntimeException('There is no active configuration.');
560     }
561
562     return self::$active;
563   }
564
565   /**
566    * Returns true if these is an active configuration.
567    *
568    * @return boolean
569    */
570   static public function hasActive()
571   {
572     return null !== self::$active;
573   }
574
575   /**
576    * Guesses the project root directory.
577    *
578    * @return string The project root directory
579    */
580   static public function guessRootDir()
581   {
582     $r = new ReflectionClass('ProjectConfiguration');
583
584     return realpath(dirname($r->getFileName()).'/..');
585   }
586
587   /**
588    * Returns a sfApplicationConfiguration configuration for a given application.
589    *
590    * @param string            $application    An application name
591    * @param string            $environment    The environment name
592    * @param Boolean           $debug          true to enable debug mode
593    * @param string            $rootDir        The project root directory
594    * @param sfEventDispatcher $dispatcher     An event dispatcher
595    *
596    * @return sfApplicationConfiguration A sfApplicationConfiguration instance
597    */
598   static public function getApplicationConfiguration($application, $environment, $debug, $rootDir = null, sfEventDispatcher $dispatcher = null)
599   {
600     $class = $application.'Configuration';
601
602     if (null === $rootDir)
603     {
604       $rootDir = self::guessRootDir();
605     }
606
607     if (!file_exists($file = $rootDir.'/apps/'.$application.'/config/'.$class.'.class.php'))
608     {
609       throw new InvalidArgumentException(sprintf('The application "%s" does not exist.', $application));
610     }
611
612     require_once $file;
613
614     return new $class($environment, $debug, $rootDir, $dispatcher);
615   }
616
617   /**
618    * Calls methods defined via sfEventDispatcher.
619    *
620    * @param string $method The method name
621    * @param array  $arguments The method arguments
622    *
623    * @return mixed The returned value of the called method
624    */
625   public function __call($method, $arguments)
626   {
627     $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'configuration.method_not_found', array('method' => $method, 'arguments' => $arguments)));
628     if (!$event->isProcessed())
629     {
630       throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
631     }
632
633     return $event->getReturnValue();
634   }
635 }
Note: See TracBrowser for help on using the browser.