sfTask.class.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 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. * Abstract class for all tasks.
  11. *
  12. * @package symfony
  13. * @subpackage task
  14. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  15. * @version SVN: $Id: sfTask.class.php 18135 2009-05-11 11:55:46Z fabien $
  16. */
  17. abstract class sfTask
  18. {
  19. protected
  20. $namespace = '',
  21. $name = null,
  22. $aliases = array(),
  23. $briefDescription = '',
  24. $detailedDescription = '',
  25. $arguments = array(),
  26. $options = array(),
  27. $dispatcher = null,
  28. $formatter = null;
  29. /**
  30. * Constructor.
  31. *
  32. * @param sfEventDispatcher $dispatcher An sfEventDispatcher instance
  33. * @param sfFormatter $formatter An sfFormatter instance
  34. */
  35. public function __construct(sfEventDispatcher $dispatcher, sfFormatter $formatter)
  36. {
  37. $this->initialize($dispatcher, $formatter);
  38. $this->configure();
  39. }
  40. /**
  41. * Initializes the sfTask instance.
  42. *
  43. * @param sfEventDispatcher $dispatcher A sfEventDispatcher instance
  44. * @param sfFormatter $formatter A sfFormatter instance
  45. */
  46. public function initialize(sfEventDispatcher $dispatcher, sfFormatter $formatter)
  47. {
  48. $this->dispatcher = $dispatcher;
  49. $this->formatter = $formatter;
  50. }
  51. /**
  52. * Configures the current task.
  53. */
  54. protected function configure()
  55. {
  56. }
  57. /**
  58. * Runs the task from the CLI.
  59. *
  60. * @param sfCommandManager $commandManager An sfCommandManager instance
  61. * @param mixed $options The command line options
  62. *
  63. * @return integer 0 if everything went fine, or an error code
  64. */
  65. public function runFromCLI(sfCommandManager $commandManager, $options = null)
  66. {
  67. $commandManager->getArgumentSet()->addArguments($this->getArguments());
  68. $commandManager->getOptionSet()->addOptions($this->getOptions());
  69. return $this->doRun($commandManager, $options);
  70. }
  71. /**
  72. * Runs the task.
  73. *
  74. * @param array $arguments An array of arguments
  75. * @param array $options An array of options
  76. *
  77. * @return integer 0 if everything went fine, or an error code
  78. */
  79. public function run($arguments = array(), $options = array())
  80. {
  81. $commandManager = new sfCommandManager(new sfCommandArgumentSet($this->getArguments()), new sfCommandOptionSet($this->getOptions()));
  82. // add -- before each option if needed
  83. foreach ($options as &$option)
  84. {
  85. if (0 !== strpos($option, '--'))
  86. {
  87. $option = '--'.$option;
  88. }
  89. }
  90. return $this->doRun($commandManager, implode(' ', array_merge($arguments, $options)));
  91. }
  92. /**
  93. * Returns the argument objects.
  94. *
  95. * @return sfCommandArgument An array of sfCommandArgument objects.
  96. */
  97. public function getArguments()
  98. {
  99. return $this->arguments;
  100. }
  101. /**
  102. * Adds an array of argument objects.
  103. *
  104. * @param array $arguments An array of arguments
  105. */
  106. public function addArguments($arguments)
  107. {
  108. $this->arguments = array_merge($this->arguments, $arguments);
  109. }
  110. /**
  111. * Add an argument.
  112. *
  113. * This method always use the sfCommandArgument class to create an option.
  114. *
  115. * @see sfCommandArgument::__construct()
  116. */
  117. public function addArgument($name, $mode = null, $help = '', $default = null)
  118. {
  119. $this->arguments[] = new sfCommandArgument($name, $mode, $help, $default);
  120. }
  121. /**
  122. * Returns the options objects.
  123. *
  124. * @return sfCommandOption An array of sfCommandOption objects.
  125. */
  126. public function getOptions()
  127. {
  128. return $this->options;
  129. }
  130. /**
  131. * Adds an array of option objects.
  132. *
  133. * @param array $options An array of options
  134. */
  135. public function addOptions($options)
  136. {
  137. $this->options = array_merge($this->options, $options);
  138. }
  139. /**
  140. * Add an option.
  141. *
  142. * This method always use the sfCommandOption class to create an option.
  143. *
  144. * @see sfCommandOption::__construct()
  145. */
  146. public function addOption($name, $shortcut = null, $mode = null, $help = '', $default = null)
  147. {
  148. $this->options[] = new sfCommandOption($name, $shortcut, $mode, $help, $default);
  149. }
  150. /**
  151. * Returns the task namespace.
  152. *
  153. * @param string The task namespace
  154. */
  155. public function getNamespace()
  156. {
  157. return $this->namespace;
  158. }
  159. /**
  160. * Returns the task name
  161. *
  162. * @return string The task name
  163. */
  164. public function getName()
  165. {
  166. if ($this->name)
  167. {
  168. return $this->name;
  169. }
  170. $name = get_class($this);
  171. if ('sf' == substr($name, 0, 2))
  172. {
  173. $name = substr($name, 2);
  174. }
  175. if ('Task' == substr($name, -4))
  176. {
  177. $name = substr($name, 0, -4);
  178. }
  179. return str_replace('_', '-', sfInflector::underscore($name));
  180. }
  181. /**
  182. * Returns the fully qualified task name.
  183. *
  184. * @return string The fully qualified task name
  185. */
  186. final function getFullName()
  187. {
  188. return $this->getNamespace() ? $this->getNamespace().':'.$this->getName() : $this->getName();
  189. }
  190. /**
  191. * Returns the brief description for the task.
  192. *
  193. * @return string The brief description for the task
  194. */
  195. public function getBriefDescription()
  196. {
  197. return $this->briefDescription;
  198. }
  199. /**
  200. * Returns the detailed description for the task.
  201. *
  202. * It also formats special string like [...|COMMENT]
  203. * depending on the current formatter.
  204. *
  205. * @return string The detailed description for the task
  206. */
  207. public function getDetailedDescription()
  208. {
  209. return preg_replace('/\[(.+?)\|(\w+)\]/se', '$this->formatter->format("$1", "$2")', $this->detailedDescription);
  210. }
  211. /**
  212. * Returns the aliases for the task.
  213. *
  214. * @return array An array of aliases for the task
  215. */
  216. public function getAliases()
  217. {
  218. return $this->aliases;
  219. }
  220. /**
  221. * Returns the synopsis for the task.
  222. *
  223. * @param string The synopsis
  224. */
  225. public function getSynopsis()
  226. {
  227. $options = array();
  228. foreach ($this->getOptions() as $option)
  229. {
  230. $shortcut = $option->getShortcut() ? sprintf('|-%s', $option->getShortcut()) : '';
  231. $options[] = sprintf('['.($option->isParameterRequired() ? '--%s%s="..."' : ($option->isParameterOptional() ? '--%s%s[="..."]' : '--%s%s')).']', $option->getName(), $shortcut);
  232. }
  233. $arguments = array();
  234. foreach ($this->getArguments() as $argument)
  235. {
  236. $arguments[] = sprintf($argument->isRequired() ? '%s' : '[%s]', $argument->getName().($argument->isArray() ? '1' : ''));
  237. if ($argument->isArray())
  238. {
  239. $arguments[] = sprintf('... [%sN]', $argument->getName());
  240. }
  241. }
  242. return sprintf('%%s %s %s %s', $this->getFullName(), implode(' ', $options), implode(' ', $arguments));
  243. }
  244. protected function process(sfCommandManager $commandManager, $options)
  245. {
  246. $commandManager->process($options);
  247. if (!$commandManager->isValid())
  248. {
  249. throw new sfCommandArgumentsException(sprintf("The execution of task \"%s\" failed.\n- %s", $this->getFullName(), implode("\n- ", $commandManager->getErrors())));
  250. }
  251. }
  252. protected function doRun(sfCommandManager $commandManager, $options)
  253. {
  254. $this->dispatcher->filter(new sfEvent($this, 'command.filter_options', array('command_manager' => $commandManager)), $options);
  255. $this->process($commandManager, $options);
  256. $event = new sfEvent($this, 'command.pre_command', array('arguments' => $commandManager->getArgumentValues(), 'options' => $commandManager->getOptionValues()));
  257. $this->dispatcher->notifyUntil($event);
  258. if ($event->isProcessed())
  259. {
  260. return $event->getReturnValue();
  261. }
  262. $ret = $this->execute($commandManager->getArgumentValues(), $commandManager->getOptionValues());
  263. $this->dispatcher->notify(new sfEvent($this, 'command.post_command'));
  264. return $ret;
  265. }
  266. /**
  267. * Logs a message.
  268. *
  269. * @param mixed $messages The message as an array of lines of a single string
  270. */
  271. public function log($messages)
  272. {
  273. if (!is_array($messages))
  274. {
  275. $messages = array($messages);
  276. }
  277. $this->dispatcher->notify(new sfEvent($this, 'command.log', $messages));
  278. }
  279. /**
  280. * Logs a message in a section.
  281. *
  282. * @param string $section The section name
  283. * @param string $message The message
  284. * @param int $size The maximum size of a line
  285. * @param string $style The color scheme to apply to the section string (INFO, ERROR, or COMMAND)
  286. */
  287. public function logSection($section, $message, $size = null, $style = 'INFO')
  288. {
  289. $this->dispatcher->notify(new sfEvent($this, 'command.log', array($this->formatter->formatSection($section, $message, $size, $style))));
  290. }
  291. /**
  292. * Executes the current task.
  293. *
  294. * @param array $arguments An array of arguments
  295. * @param array $options An array of options
  296. *
  297. * @return integer 0 if everything went fine, or an error code
  298. */
  299. abstract protected function execute($arguments = array(), $options = array());
  300. }