Development

/branches/1.2/lib/task/sfTask.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/task/sfTask.class.php

Revision 21875, 11.1 kB (checked in by fabien, 5 years ago)

[1.2, 1.3] fixed PHPDoc (closes #6279)

  • 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  * Abstract class for all 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 sfTask
20 {
21   protected
22     $namespace           = '',
23     $name                = null,
24     $aliases             = array(),
25     $briefDescription    = '',
26     $detailedDescription = '',
27     $arguments           = array(),
28     $options             = array(),
29     $dispatcher          = null,
30     $formatter           = null;
31
32   /**
33    * Constructor.
34    *
35    * @param sfEventDispatcher $dispatcher  An sfEventDispatcher instance
36    * @param sfFormatter       $formatter   An sfFormatter instance
37    */
38   public function __construct(sfEventDispatcher $dispatcher, sfFormatter $formatter)
39   {
40     $this->initialize($dispatcher, $formatter);
41
42     $this->configure();
43   }
44
45   /**
46    * Initializes the sfTask instance.
47    *
48    * @param sfEventDispatcher $dispatcher  A sfEventDispatcher instance
49    * @param sfFormatter       $formatter   A sfFormatter instance
50    */
51   public function initialize(sfEventDispatcher $dispatcher, sfFormatter $formatter)
52   {
53     $this->dispatcher = $dispatcher;
54     $this->formatter  = $formatter;
55   }
56
57   /**
58    * Configures the current task.
59    */
60   protected function configure()
61   {
62   }
63
64   /**
65    * Runs the task from the CLI.
66    *
67    * @param sfCommandManager $commandManager  An sfCommandManager instance
68    * @param mixed            $options         The command line options
69    *
70    * @return integer 0 if everything went fine, or an error code
71    */
72   public function runFromCLI(sfCommandManager $commandManager, $options = null)
73   {
74     $commandManager->getArgumentSet()->addArguments($this->getArguments());
75     $commandManager->getOptionSet()->addOptions($this->getOptions());
76
77     return $this->doRun($commandManager, $options);
78   }
79
80   /**
81    * Runs the task.
82    *
83    * @param array $arguments  An array of arguments
84    * @param array $options    An array of options
85    *
86    * @return integer 0 if everything went fine, or an error code
87    */
88   public function run($arguments = array(), $options = array())
89   {
90     $commandManager = new sfCommandManager(new sfCommandArgumentSet($this->getArguments()), new sfCommandOptionSet($this->getOptions()));
91
92     // add -- before each option if needed
93     foreach ($options as &$option)
94     {
95       if (0 !== strpos($option, '--'))
96       {
97         $option = '--'.$option;
98       }
99     }
100
101     return $this->doRun($commandManager, implode(' ', array_merge($arguments, $options)));
102   }
103
104   /**
105    * Returns the argument objects.
106    *
107    * @return sfCommandArgument An array of sfCommandArgument objects.
108    */
109   public function getArguments()
110   {
111     return $this->arguments;
112   }
113
114   /**
115    * Adds an array of argument objects.
116    *
117    * @param array $arguments  An array of arguments
118    */
119   public function addArguments($arguments)
120   {
121     $this->arguments = array_merge($this->arguments, $arguments);
122   }
123
124   /**
125    * Add an argument.
126    *
127    * This method always use the sfCommandArgument class to create an option.
128    *
129    * @see sfCommandArgument::__construct()
130    */
131   public function addArgument($name, $mode = null, $help = '', $default = null)
132   {
133     $this->arguments[] = new sfCommandArgument($name, $mode, $help, $default);
134   }
135
136   /**
137    * Returns the options objects.
138    *
139    * @return sfCommandOption An array of sfCommandOption objects.
140    */
141   public function getOptions()
142   {
143     return $this->options;
144   }
145
146   /**
147    * Adds an array of option objects.
148    *
149    * @param array $options    An array of options
150    */
151   public function addOptions($options)
152   {
153     $this->options = array_merge($this->options, $options);
154   }
155
156   /**
157    * Add an option.
158    *
159    * This method always use the sfCommandOption class to create an option.
160    *
161    * @see sfCommandOption::__construct()
162    */
163   public function addOption($name, $shortcut = null, $mode = null, $help = '', $default = null)
164   {
165     $this->options[] = new sfCommandOption($name, $shortcut, $mode, $help, $default);
166   }
167
168   /**
169    * Returns the task namespace.
170    *
171    * @return string The task namespace
172    */
173   public function getNamespace()
174   {
175     return $this->namespace;
176   }
177
178   /**
179    * Returns the task name
180    *
181    * @return string The task name
182    */
183   public function getName()
184   {
185     if ($this->name)
186     {
187       return $this->name;
188     }
189
190     $name = get_class($this);
191
192     if ('sf' == substr($name, 0, 2))
193     {
194       $name = substr($name, 2);
195     }
196
197     if ('Task' == substr($name, -4))
198     {
199       $name = substr($name, 0, -4);
200     }
201
202     return str_replace('_', '-', sfInflector::underscore($name));
203   }
204
205   /**
206    * Returns the fully qualified task name.
207    *
208    * @return string The fully qualified task name
209    */
210   final function getFullName()
211   {
212     return $this->getNamespace() ? $this->getNamespace().':'.$this->getName() : $this->getName();
213   }
214
215   /**
216    * Returns the brief description for the task.
217    *
218    * @return string The brief description for the task
219    */
220   public function getBriefDescription()
221   {
222     return $this->briefDescription;
223   }
224
225   /**
226    * Returns the detailed description for the task.
227    *
228    * It also formats special string like [...|COMMENT]
229    * depending on the current formatter.
230    *
231    * @return string The detailed description for the task
232    */
233   public function getDetailedDescription()
234   {
235     return preg_replace('/\[(.+?)\|(\w+)\]/se', '$this->formatter->format("$1", "$2")', $this->detailedDescription);
236   }
237
238   /**
239    * Returns the aliases for the task.
240    *
241    * @return array An array of aliases for the task
242    */
243   public function getAliases()
244   {
245     return $this->aliases;
246   }
247
248   /**
249    * Returns the synopsis for the task.
250    *
251    * @return string The synopsis
252    */
253   public function getSynopsis()
254   {
255     $options = array();
256     foreach ($this->getOptions() as $option)
257     {
258       $shortcut = $option->getShortcut() ? sprintf('|-%s', $option->getShortcut()) : '';
259       $options[] = sprintf('['.($option->isParameterRequired() ? '--%s%s="..."' : ($option->isParameterOptional() ? '--%s%s[="..."]' : '--%s%s')).']', $option->getName(), $shortcut);
260     }
261
262     $arguments = array();
263     foreach ($this->getArguments() as $argument)
264     {
265       $arguments[] = sprintf($argument->isRequired() ? '%s' : '[%s]', $argument->getName().($argument->isArray() ? '1' : ''));
266
267       if ($argument->isArray())
268       {
269         $arguments[] = sprintf('... [%sN]', $argument->getName());
270       }
271     }
272
273     return sprintf('%%s %s %s %s', $this->getFullName(), implode(' ', $options), implode(' ', $arguments));
274   }
275
276   protected function process(sfCommandManager $commandManager, $options)
277   {
278     $commandManager->process($options);
279     if (!$commandManager->isValid())
280     {
281       throw new sfCommandArgumentsException(sprintf("The execution of task \"%s\" failed.\n- %s", $this->getFullName(), implode("\n- ", $commandManager->getErrors())));
282     }
283   }
284
285   protected function doRun(sfCommandManager $commandManager, $options)
286   {
287     $this->dispatcher->filter(new sfEvent($this, 'command.filter_options', array('command_manager' => $commandManager)), $options);
288
289     $this->process($commandManager, $options);
290
291     $event = new sfEvent($this, 'command.pre_command', array('arguments' => $commandManager->getArgumentValues(), 'options' => $commandManager->getOptionValues()));
292     $this->dispatcher->notifyUntil($event);
293     if ($event->isProcessed())
294     {
295       return $event->getReturnValue();
296     }
297
298     $ret = $this->execute($commandManager->getArgumentValues(), $commandManager->getOptionValues());
299
300     $this->dispatcher->notify(new sfEvent($this, 'command.post_command'));
301
302     return $ret;
303   }
304
305   /**
306    * Logs a message.
307    *
308    * @param mixed $messages  The message as an array of lines of a single string
309    */
310   public function log($messages)
311   {
312     if (!is_array($messages))
313     {
314       $messages = array($messages);
315     }
316
317     $this->dispatcher->notify(new sfEvent($this, 'command.log', $messages));
318   }
319
320   /**
321    * Logs a message in a section.
322    *
323    * @param string  $section  The section name
324    * @param string  $message  The message
325    * @param int     $size     The maximum size of a line
326    * @param string  $style    The color scheme to apply to the section string (INFO, ERROR, or COMMAND)
327    */
328   public function logSection($section, $message, $size = null, $style = 'INFO')
329   {
330     $this->dispatcher->notify(new sfEvent($this, 'command.log', array($this->formatter->formatSection($section, $message, $size, $style))));
331   }
332
333   /**
334    * Logs a message as a block of text.
335    *
336    * @param string|array $messages The message to display in the block
337    * @param string       $style    The style to use
338    */
339   public function logBlock($messages, $style)
340   {
341     if (!is_array($messages))
342     {
343       $messages = array($messages);
344     }
345
346     $len = 0;
347     $lines = array();
348     foreach ($messages as $message)
349     {
350       $lines[] = sprintf('  %s  ', $message);
351       $len = max($this->strlen($message) + 4, $len);
352     }
353
354     $messages = array(str_repeat(' ', $len));
355     foreach ($lines as $line)
356     {
357       $messages[] = $line.str_repeat(' ', $len - $this->strlen($line));
358     }
359     $messages[] = str_repeat(' ', $len);
360
361     foreach ($messages as $message)
362     {
363       $this->log($this->formatter->format($message, $style));
364     }
365   }
366
367   /**
368    * Asks a question to the user.
369    *
370    * @param string|array $question The question to ask
371    * @param string       $style    The style to use (QUESTION by default)
372    *
373    * @param string       The user answer
374    */
375   public function ask($question, $style = 'QUESTION')
376   {
377     if (false === $style)
378     {
379       $this->log($question);
380     }
381     else
382     {
383       $this->logBlock($question, is_null($style) ? 'QUESTION' : $style);
384     }
385
386     return trim(fgets(STDIN));
387   }
388
389   /**
390    * Asks a confirmation to the user.
391    *
392    * The question will be asked until the user answer by nothing, yes, or no.
393    *
394    * @param string|array $question The question to ask
395    * @param string       $style    The style to use (QUESTION by default)
396    * @param Boolean      $default  The default answer if the user enters nothing
397    *
398    * @param Boolean      true if the user has confirmed, false otherwise
399    */
400   public function askConfirmation($question, $style = 'QUESTION', $default = true)
401   {
402     $answer = 'z';
403     while ($answer && !in_array(strtolower($answer[0]), array('y', 'n')))
404     {
405       $answer = $this->ask($question, $style);
406     }
407
408     if (false === $default)
409     {
410       return $answer && 'y' == strtolower($answer[0]);
411     }
412     else
413     {
414       return !$answer || 'y' == strtolower($answer[0]);
415     }
416   }
417
418   /**
419    * Executes the current task.
420    *
421    * @param array    $arguments  An array of arguments
422    * @param array    $options    An array of options
423    *
424    * @return integer 0 if everything went fine, or an error code
425    */
426    abstract protected function execute($arguments = array(), $options = array());
427
428    protected function strlen($string)
429    {
430      return function_exists('mb_strlen') ? mb_strlen($string) : strlen($string);
431    }
432 }
433
Note: See TracBrowser for help on using the browser.