Development

/branches/1.4/lib/task/sfBaseTask.class.php

You must first sign up to be able to contribute.

root/branches/1.4/lib/task/sfBaseTask.class.php

Revision 24341, 11.2 kB (checked in by Kris.Wallsmith, 5 years ago)

[1.3, 1.4] fixed fatal error in doctrine build/drop db tasks when no application exists (closes #7686, refs #7633)

  • 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) 2004-2006 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  * Base class for all symfony tasks.
13  *
14  * @package    symfony
15  * @subpackage task
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 abstract class sfBaseTask extends sfCommandApplicationTask
20 {
21   protected
22     $configuration = null,
23     $pluginManager = null;
24
25   /**
26    * @see sfTask
27    */
28   protected function doRun(sfCommandManager $commandManager, $options)
29   {
30     $event = $this->dispatcher->filter(new sfEvent($this, 'command.filter_options', array('command_manager' => $commandManager)), $options);
31     $options = $event->getReturnValue();
32
33     $this->process($commandManager, $options);
34
35     $event = new sfEvent($this, 'command.pre_command', array('arguments' => $commandManager->getArgumentValues(), 'options' => $commandManager->getOptionValues()));
36     $this->dispatcher->notifyUntil($event);
37     if ($event->isProcessed())
38     {
39       return $event->getReturnValue();
40     }
41
42     $this->checkProjectExists();
43
44     $requiresApplication = $commandManager->getArgumentSet()->hasArgument('application') || $commandManager->getOptionSet()->hasOption('application');
45     if (null === $this->configuration || ($requiresApplication && !$this->configuration instanceof sfApplicationConfiguration))
46     {
47       $application = $commandManager->getArgumentSet()->hasArgument('application') ? $commandManager->getArgumentValue('application') : ($commandManager->getOptionSet()->hasOption('application') ? $commandManager->getOptionValue('application') : null);
48       $env = $commandManager->getOptionSet()->hasOption('env') ? $commandManager->getOptionValue('env') : 'test';
49
50       if (true === $application)
51       {
52         $application = $this->getFirstApplication();
53
54         if ($commandManager->getOptionSet()->hasOption('application'))
55         {
56           $commandManager->setOption($commandManager->getOptionSet()->getOption('application'), $application);
57         }
58       }
59
60       $this->configuration = $this->createConfiguration($application, $env);
61     }
62
63     if (null !== $this->commandApplication && !$this->commandApplication->withTrace())
64     {
65       sfConfig::set('sf_logging_enabled', false);
66     }
67
68     $ret = $this->execute($commandManager->getArgumentValues(), $commandManager->getOptionValues());
69
70     $this->dispatcher->notify(new sfEvent($this, 'command.post_command'));
71
72     return $ret;
73   }
74
75   /**
76    * Sets the current task's configuration.
77    *
78    * @param sfProjectConfiguration $configuration
79    */
80   public function setConfiguration(sfProjectConfiguration $configuration = null)
81   {
82     $this->configuration = $configuration;
83   }
84
85   /**
86    * Returns the filesystem instance.
87    *
88    * @return sfFilesystem A sfFilesystem instance
89    */
90   public function getFilesystem()
91   {
92     if (!isset($this->filesystem))
93     {
94       if (null === $this->commandApplication || $this->commandApplication->isVerbose())
95       {
96         $this->filesystem = new sfFilesystem($this->dispatcher, $this->formatter);
97       }
98       else
99       {
100         $this->filesystem = new sfFilesystem();
101       }
102     }
103
104     return $this->filesystem;
105   }
106
107   /**
108    * Checks if the current directory is a symfony project directory.
109    *
110    * @return true if the current directory is a symfony project directory, false otherwise
111    */
112   public function checkProjectExists()
113   {
114     if (!file_exists('symfony'))
115     {
116       throw new sfException('You must be in a symfony project directory.');
117     }
118   }
119
120   /**
121    * Checks if an application exists.
122    *
123    * @param  string $app  The application name
124    *
125    * @return bool true if the application exists, false otherwise
126    */
127   public function checkAppExists($app)
128   {
129     if (!is_dir(sfConfig::get('sf_apps_dir').'/'.$app))
130     {
131       throw new sfException(sprintf('Application "%s" does not exist', $app));
132     }
133   }
134
135   /**
136    * Checks if a module exists.
137    *
138    * @param  string $app     The application name
139    * @param  string $module  The module name
140    *
141    * @return bool true if the module exists, false otherwise
142    */
143   public function checkModuleExists($app, $module)
144   {
145     if (!is_dir(sfConfig::get('sf_apps_dir').'/'.$app.'/modules/'.$module))
146     {
147       throw new sfException(sprintf('Module "%s/%s" does not exist.', $app, $module));
148     }
149   }
150
151   /**
152    * Creates a configuration object.
153    *
154    * @param string  $application The application name
155    * @param string  $env         The environment name
156    *
157    * @return sfProjectConfiguration A sfProjectConfiguration instance
158    */
159   protected function createConfiguration($application, $env)
160   {
161     if (null !== $application)
162     {
163       $this->checkAppExists($application);
164
165       require_once sfConfig::get('sf_config_dir').'/ProjectConfiguration.class.php';
166
167       $configuration = ProjectConfiguration::getApplicationConfiguration($application, $env, true, null, $this->dispatcher);
168     }
169     else
170     {
171       if (file_exists(sfConfig::get('sf_config_dir').'/ProjectConfiguration.class.php'))
172       {
173         require_once sfConfig::get('sf_config_dir').'/ProjectConfiguration.class.php';
174         $configuration = new ProjectConfiguration(null, $this->dispatcher);
175       }
176       else
177       {
178         $configuration = new sfProjectConfiguration(getcwd(), $this->dispatcher);
179       }
180
181       if (null !== $env)
182       {
183         sfConfig::set('sf_environment', $env);
184       }
185
186       $this->initializeAutoload($configuration);
187     }
188
189     return $configuration;
190   }
191
192   /**
193    * Returns the first application in apps.
194    *
195    * @return string The Application name
196    */
197   protected function getFirstApplication()
198   {
199     if (count($dirs = sfFinder::type('dir')->maxdepth(0)->follow_link()->relative()->in(sfConfig::get('sf_apps_dir'))))
200     {
201       return $dirs[0];
202     }
203
204     return null;
205   }
206
207   /**
208    * Reloads all autoloaders.
209    *
210    * This method should be called whenever a task generates new classes that
211    * are to be loaded by the symfony autoloader. It clears the autoloader
212    * cache for all applications and environments and the current execution.
213    *
214    * @see initializeAutoload()
215    */
216   protected function reloadAutoload()
217   {
218     $this->initializeAutoload($this->configuration, true);
219   }
220
221   /**
222    * Initializes autoloaders.
223    *
224    * @param sfProjectConfiguration $configuration The current project or application configuration
225    * @param boolean                $reload        If true, all autoloaders will be reloaded
226    */
227   protected function initializeAutoload(sfProjectConfiguration $configuration, $reload = false)
228   {
229     // sfAutoload
230     if ($reload)
231     {
232       $this->logSection('autoload', 'Resetting application autoloaders');
233
234       $finder = sfFinder::type('file')->name('*autoload.yml.php');
235       $this->getFilesystem()->remove($finder->in(sfConfig::get('sf_cache_dir')));
236       sfAutoload::getInstance()->reloadClasses(true);
237     }
238
239     // sfSimpleAutoload
240     if (!$configuration instanceof sfApplicationConfiguration)
241     {
242       // plugins
243       if ($reload)
244       {
245         foreach ($configuration->getPlugins() as $name)
246         {
247           $configuration->getPluginConfiguration($name)->initializeAutoload();
248         }
249       }
250
251       // project
252       $autoload = sfSimpleAutoload::getInstance(sfConfig::get('sf_cache_dir').'/project_autoload.cache');
253       $autoload->loadConfiguration(sfFinder::type('file')->name('autoload.yml')->in(array(
254         sfConfig::get('sf_symfony_lib_dir').'/config/config',
255         sfConfig::get('sf_config_dir'),
256       )));
257       $autoload->register();
258
259       if ($reload)
260       {
261         $this->logSection('autoload', 'Resetting CLI autoloader');
262         $autoload->reload();
263       }
264     }
265   }
266
267   /**
268    * Mirrors a directory structure inside the created project.
269    *
270    * @param string   $dir    The directory to mirror
271    * @param sfFinder $finder A sfFinder instance to use for the mirroring
272    */
273   protected function installDir($dir, $finder = null)
274   {
275     if (null === $finder)
276     {
277       $finder = sfFinder::type('any')->discard('.sf');
278     }
279
280     $this->getFilesystem()->mirror($dir, sfConfig::get('sf_root_dir'), $finder);
281   }
282
283   /**
284    * Replaces tokens in files contained in a given directory.
285    *
286    * If you don't pass a directory, it will replace in the config/ and lib/ directory.
287    *
288    * You can define global tokens by defining the $this->tokens property.
289    *
290    * @param array $dirs   An array of directory where to do the replacement
291    * @param array $tokens An array of tokens to use
292    */
293   protected function replaceTokens($dirs = array(), $tokens = array())
294   {
295     if (!$dirs)
296     {
297       $dirs = array(sfConfig::get('sf_config_dir'), sfConfig::get('sf_lib_dir'));
298     }
299
300     $tokens = array_merge(isset($this->tokens) ? $this->tokens : array(), $tokens);
301
302     $this->getFilesystem()->replaceTokens(sfFinder::type('file')->prune('vendor')->in($dirs), '##', '##', $tokens);
303   }
304
305   /**
306    * Reloads tasks.
307    *
308    * Useful when you install plugins with tasks and if you want to use them with the runTask() method.
309    */
310   protected function reloadTasks()
311   {
312     if (null === $this->commandApplication)
313     {
314       return;
315     }
316
317     $this->configuration = $this->createConfiguration(null, null);
318
319     $this->commandApplication->clearTasks();
320     $this->commandApplication->loadTasks($this->configuration);
321
322     $disabledPluginsRegex = sprintf('#^(%s)#', implode('|', array_diff($this->configuration->getAllPluginPaths(), $this->configuration->getPluginPaths())));
323     $tasks = array();
324     foreach (get_declared_classes() as $class)
325     {
326       $r = new Reflectionclass($class);
327       if ($r->isSubclassOf('sfTask') && !$r->isAbstract() && !preg_match($disabledPluginsRegex, $r->getFileName()))
328       {
329         $tasks[] = new $class($this->dispatcher, $this->formatter);
330       }
331     }
332
333     $this->commandApplication->registerTasks($tasks);
334   }
335
336   /**
337    * Enables a plugin in the ProjectConfiguration class.
338    *
339    * @param string $plugin The name of the plugin
340    */
341   protected function enablePlugin($plugin)
342   {
343     sfSymfonyPluginManager::enablePlugin($plugin, sfConfig::get('sf_config_dir'));
344   }
345
346   /**
347    * Disables a plugin in the ProjectConfiguration class.
348    *
349    * @param string $plugin The name of the plugin
350    */
351   protected function disablePlugin($plugin)
352   {
353     sfSymfonyPluginManager::disablePlugin($plugin, sfConfig::get('sf_config_dir'));
354   }
355
356   /**
357    * Returns a plugin manager instance.
358    *
359    * @return sfSymfonyPluginManager A sfSymfonyPluginManager instance
360    */
361   protected function getPluginManager()
362   {
363     if (null === $this->pluginManager)
364     {
365       $environment = new sfPearEnvironment($this->dispatcher, array(
366         'plugin_dir' => sfConfig::get('sf_plugins_dir'),
367         'cache_dir'  => sfConfig::get('sf_cache_dir').'/.pear',
368         'web_dir'    => sfConfig::get('sf_web_dir'),
369         'config_dir' => sfConfig::get('sf_config_dir'),
370       ));
371
372       $this->pluginManager = new sfSymfonyPluginManager($this->dispatcher, $environment);
373     }
374
375     return $this->pluginManager;
376   }
377
378   /**
379    * @see sfCommandApplicationTask
380    */
381   protected function createTask($name)
382   {
383     $task = parent::createTask($name);
384
385     if ($task instanceof sfBaseTask)
386     {
387       $task->setConfiguration($this->configuration);
388     }
389
390     return $task;
391   }
392 }
393
Note: See TracBrowser for help on using the browser.