TYPO3  7.6
vendor/symfony/console/Command/Command.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
13 
24 
32 class Command
33 {
34  private $application;
35  private $name;
36  private $processTitle;
37  private $aliases = array();
38  private $definition;
39  private $help;
40  private $description;
41  private $ignoreValidationErrors = false;
44  private $code;
45  private $synopsis = array();
46  private $usages = array();
47  private $helperSet;
48 
58  public function __construct($name = null)
59  {
60  $this->definition = new InputDefinition();
61 
62  if (null !== $name) {
63  $this->setName($name);
64  }
65 
66  $this->configure();
67 
68  if (!$this->name) {
69  throw new \LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
70  }
71  }
72 
78  public function ignoreValidationErrors()
79  {
80  $this->ignoreValidationErrors = true;
81  }
82 
90  public function setApplication(Application $application = null)
91  {
92  $this->application = $application;
93  if ($application) {
94  $this->setHelperSet($application->getHelperSet());
95  } else {
96  $this->helperSet = null;
97  }
98  }
99 
106  {
107  $this->helperSet = $helperSet;
108  }
109 
115  public function getHelperSet()
116  {
117  return $this->helperSet;
118  }
119 
127  public function getApplication()
128  {
129  return $this->application;
130  }
131 
140  public function isEnabled()
141  {
142  return true;
143  }
144 
148  protected function configure()
149  {
150  }
151 
169  protected function execute(InputInterface $input, OutputInterface $output)
170  {
171  throw new \LogicException('You must override the execute() method in the concrete command class.');
172  }
173 
184  protected function interact(InputInterface $input, OutputInterface $output)
185  {
186  }
187 
197  protected function initialize(InputInterface $input, OutputInterface $output)
198  {
199  }
200 
220  public function run(InputInterface $input, OutputInterface $output)
221  {
222  // force the creation of the synopsis before the merge with the app definition
223  $this->getSynopsis(true);
224  $this->getSynopsis(false);
225 
226  // add the application arguments and options
228 
229  // bind the input against the command specific arguments/options
230  try {
231  $input->bind($this->definition);
232  } catch (\Exception $e) {
233  if (!$this->ignoreValidationErrors) {
234  throw $e;
235  }
236  }
237 
238  $this->initialize($input, $output);
239 
240  if (null !== $this->processTitle) {
241  if (function_exists('cli_set_process_title')) {
242  cli_set_process_title($this->processTitle);
243  } elseif (function_exists('setproctitle')) {
244  setproctitle($this->processTitle);
246  $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
247  }
248  }
249 
250  if ($input->isInteractive()) {
251  $this->interact($input, $output);
252  }
253 
254  $input->validate();
255 
256  if ($this->code) {
257  $statusCode = call_user_func($this->code, $input, $output);
258  } else {
259  $statusCode = $this->execute($input, $output);
260  }
261 
262  return is_numeric($statusCode) ? (int) $statusCode : 0;
263  }
264 
281  public function setCode($code)
282  {
283  if (!is_callable($code)) {
284  throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.');
285  }
286 
287  $this->code = $code;
288 
289  return $this;
290  }
291 
299  public function mergeApplicationDefinition($mergeArgs = true)
300  {
301  if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
302  return;
303  }
304 
305  if ($mergeArgs) {
306  $currentArguments = $this->definition->getArguments();
307  $this->definition->setArguments($this->application->getDefinition()->getArguments());
308  $this->definition->addArguments($currentArguments);
309  }
310 
311  $this->definition->addOptions($this->application->getDefinition()->getOptions());
312 
313  $this->applicationDefinitionMerged = true;
314  if ($mergeArgs) {
315  $this->applicationDefinitionMergedWithArgs = true;
316  }
317  }
318 
328  public function setDefinition($definition)
329  {
330  if ($definition instanceof InputDefinition) {
331  $this->definition = $definition;
332  } else {
333  $this->definition->setDefinition($definition);
334  }
335 
336  $this->applicationDefinitionMerged = false;
337 
338  return $this;
339  }
340 
348  public function getDefinition()
349  {
350  return $this->definition;
351  }
352 
363  public function getNativeDefinition()
364  {
365  return $this->getDefinition();
366  }
367 
380  public function addArgument($name, $mode = null, $description = '', $default = null)
381  {
382  $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
383 
384  return $this;
385  }
386 
400  public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
401  {
402  $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
403 
404  return $this;
405  }
406 
423  public function setName($name)
424  {
425  $this->validateName($name);
426 
427  $this->name = $name;
428 
429  return $this;
430  }
431 
444  public function setProcessTitle($title)
445  {
446  $this->processTitle = $title;
447 
448  return $this;
449  }
450 
458  public function getName()
459  {
460  return $this->name;
461  }
462 
472  public function setDescription($description)
473  {
474  $this->description = $description;
475 
476  return $this;
477  }
478 
486  public function getDescription()
487  {
488  return $this->description;
489  }
490 
500  public function setHelp($help)
501  {
502  $this->help = $help;
503 
504  return $this;
505  }
506 
514  public function getHelp()
515  {
516  return $this->help ?: $this->description;
517  }
518 
525  public function getProcessedHelp()
526  {
527  $name = $this->name;
528 
529  $placeholders = array(
530  '%command.name%',
531  '%command.full_name%',
532  );
533  $replacements = array(
534  $name,
535  $_SERVER['PHP_SELF'].' '.$name,
536  );
537 
538  return str_replace($placeholders, $replacements, $this->getHelp());
539  }
540 
552  public function setAliases($aliases)
553  {
554  if (!is_array($aliases) && !$aliases instanceof \Traversable) {
555  throw new \InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
556  }
557 
558  foreach ($aliases as $alias) {
559  $this->validateName($alias);
560  }
561 
562  $this->aliases = $aliases;
563 
564  return $this;
565  }
566 
574  public function getAliases()
575  {
576  return $this->aliases;
577  }
578 
586  public function getSynopsis($short = false)
587  {
588  $key = $short ? 'short' : 'long';
589 
590  if (!isset($this->synopsis[$key])) {
591  $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
592  }
593 
594  return $this->synopsis[$key];
595  }
596 
602  public function addUsage($usage)
603  {
604  if (0 !== strpos($usage, $this->name)) {
605  $usage = sprintf('%s %s', $this->name, $usage);
606  }
607 
608  $this->usages[] = $usage;
609 
610  return $this;
611  }
612 
618  public function getUsages()
619  {
620  return $this->usages;
621  }
622 
634  public function getHelper($name)
635  {
636  return $this->helperSet->get($name);
637  }
638 
646  public function asText()
647  {
648  @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
649 
650  $descriptor = new TextDescriptor();
652  $descriptor->describe($output, $this, array('raw_output' => true));
653 
654  return $output->fetch();
655  }
656 
666  public function asXml($asDom = false)
667  {
668  @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
669 
670  $descriptor = new XmlDescriptor();
671 
672  if ($asDom) {
673  return $descriptor->getCommandDocument($this);
674  }
675 
676  $output = new BufferedOutput();
677  $descriptor->describe($output, $this);
678 
679  return $output->fetch();
680  }
681 
691  private function validateName($name)
692  {
693  if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
694  throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
695  }
696  }
697 }