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

Debug toolbar