PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/vendor/Symfony/Component/Console/Command/Command.php

https://github.com/esimionato/mongodb-odm
PHP | 512 lines | 235 code | 67 blank | 210 comment | 15 complexity | 6d3f6de8c6664c2459666e8ca7881b15 MD5 | raw file
  1. <?php
  2. namespace Symfony\Component\Console\Command;
  3. use Symfony\Component\Console\Input\InputDefinition;
  4. use Symfony\Component\Console\Input\InputOption;
  5. use Symfony\Component\Console\Input\InputArgument;
  6. use Symfony\Component\Console\Input\InputInterface;
  7. use Symfony\Component\Console\Output\OutputInterface;
  8. use Symfony\Component\Console\Application;
  9. /*
  10. * This file is part of the Symfony framework.
  11. *
  12. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  13. *
  14. * This source file is subject to the MIT license that is bundled
  15. * with this source code in the file LICENSE.
  16. */
  17. /**
  18. * Base class for all commands.
  19. *
  20. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  21. */
  22. class Command
  23. {
  24. protected $name;
  25. protected $namespace;
  26. protected $aliases;
  27. protected $definition;
  28. protected $help;
  29. protected $application;
  30. protected $description;
  31. protected $ignoreValidationErrors;
  32. protected $applicationDefinitionMerged;
  33. protected $code;
  34. /**
  35. * Constructor.
  36. *
  37. * @param string $name The name of the command
  38. *
  39. * @throws \LogicException When the command name is empty
  40. */
  41. public function __construct($name = null)
  42. {
  43. $this->definition = new InputDefinition();
  44. $this->ignoreValidationErrors = false;
  45. $this->applicationDefinitionMerged = false;
  46. $this->aliases = array();
  47. if (null !== $name) {
  48. $this->setName($name);
  49. }
  50. $this->configure();
  51. if (!$this->name) {
  52. throw new \LogicException('The command name cannot be empty.');
  53. }
  54. }
  55. /**
  56. * Sets the application instance for this command.
  57. *
  58. * @param Application $application An Application instance
  59. */
  60. public function setApplication(Application $application = null)
  61. {
  62. $this->application = $application;
  63. }
  64. /**
  65. * Configures the current command.
  66. */
  67. protected function configure()
  68. {
  69. }
  70. /**
  71. * Executes the current command.
  72. *
  73. * @param InputInterface $input An InputInterface instance
  74. * @param OutputInterface $output An OutputInterface instance
  75. *
  76. * @return integer 0 if everything went fine, or an error code
  77. *
  78. * @throws \LogicException When this abstract class is not implemented
  79. */
  80. protected function execute(InputInterface $input, OutputInterface $output)
  81. {
  82. throw new \LogicException('You must override the execute() method in the concrete command class.');
  83. }
  84. /**
  85. * Interacts with the user.
  86. *
  87. * @param InputInterface $input An InputInterface instance
  88. * @param OutputInterface $output An OutputInterface instance
  89. */
  90. protected function interact(InputInterface $input, OutputInterface $output)
  91. {
  92. }
  93. /**
  94. * Initializes the command just after the input has been validated.
  95. *
  96. * This is mainly useful when a lot of commands extends one main command
  97. * where some things need to be initialized based on the input arguments and options.
  98. *
  99. * @param InputInterface $input An InputInterface instance
  100. * @param OutputInterface $output An OutputInterface instance
  101. */
  102. protected function initialize(InputInterface $input, OutputInterface $output)
  103. {
  104. }
  105. /**
  106. * Runs the command.
  107. *
  108. * @param InputInterface $input An InputInterface instance
  109. * @param OutputInterface $output An OutputInterface instance
  110. */
  111. public function run(InputInterface $input, OutputInterface $output)
  112. {
  113. // add the application arguments and options
  114. $this->mergeApplicationDefinition();
  115. // bind the input against the command specific arguments/options
  116. try {
  117. $input->bind($this->definition);
  118. } catch (\Exception $e) {
  119. if (!$this->ignoreValidationErrors) {
  120. throw $e;
  121. }
  122. }
  123. $this->initialize($input, $output);
  124. if ($input->isInteractive()) {
  125. $this->interact($input, $output);
  126. }
  127. $input->validate();
  128. if ($this->code) {
  129. return call_user_func($this->code, $input, $output);
  130. } else {
  131. return $this->execute($input, $output);
  132. }
  133. }
  134. /**
  135. * Sets the code to execute when running this command.
  136. *
  137. * @param \Closure $code A \Closure
  138. *
  139. * @return Command The current instance
  140. */
  141. public function setCode(\Closure $code)
  142. {
  143. $this->code = $code;
  144. return $this;
  145. }
  146. /**
  147. * Merges the application definition with the command definition.
  148. */
  149. protected function mergeApplicationDefinition()
  150. {
  151. if (null === $this->application || true === $this->applicationDefinitionMerged) {
  152. return;
  153. }
  154. $this->definition->setArguments(array_merge(
  155. $this->application->getDefinition()->getArguments(),
  156. $this->definition->getArguments()
  157. ));
  158. $this->definition->addOptions($this->application->getDefinition()->getOptions());
  159. $this->applicationDefinitionMerged = true;
  160. }
  161. /**
  162. * Sets an array of argument and option instances.
  163. *
  164. * @param array|Definition $definition An array of argument and option instances or a definition instance
  165. *
  166. * @return Command The current instance
  167. */
  168. public function setDefinition($definition)
  169. {
  170. if ($definition instanceof InputDefinition) {
  171. $this->definition = $definition;
  172. } else {
  173. $this->definition->setDefinition($definition);
  174. }
  175. $this->applicationDefinitionMerged = false;
  176. return $this;
  177. }
  178. /**
  179. * Gets the InputDefinition attached to this Command.
  180. *
  181. * @return InputDefinition An InputDefinition instance
  182. */
  183. public function getDefinition()
  184. {
  185. return $this->definition;
  186. }
  187. /**
  188. * Adds an argument.
  189. *
  190. * @param string $name The argument name
  191. * @param integer $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
  192. * @param string $description A description text
  193. * @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
  194. *
  195. * @return Command The current instance
  196. */
  197. public function addArgument($name, $mode = null, $description = '', $default = null)
  198. {
  199. $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
  200. return $this;
  201. }
  202. /**
  203. * Adds an option.
  204. *
  205. * @param string $name The option name
  206. * @param string $shortcut The shortcut (can be null)
  207. * @param integer $mode The option mode: One of the InputOption::VALUE_* constants
  208. * @param string $description A description text
  209. * @param mixed $default The default value (must be null for InputOption::VALUE_REQUIRED or self::VALUE_NONE)
  210. *
  211. * @return Command The current instance
  212. */
  213. public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
  214. {
  215. $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
  216. return $this;
  217. }
  218. /**
  219. * Sets the name of the command.
  220. *
  221. * This method can set both the namespace and the name if
  222. * you separate them by a colon (:)
  223. *
  224. * $command->setName('foo:bar');
  225. *
  226. * @param string $name The command name
  227. *
  228. * @return Command The current instance
  229. *
  230. * @throws \InvalidArgumentException When command name given is empty
  231. */
  232. public function setName($name)
  233. {
  234. if (false !== $pos = strrpos($name, ':')) {
  235. $namespace = substr($name, 0, $pos);
  236. $name = substr($name, $pos + 1);
  237. } else {
  238. $namespace = $this->namespace;
  239. }
  240. if (!$name) {
  241. throw new \InvalidArgumentException('A command name cannot be empty.');
  242. }
  243. $this->namespace = $namespace;
  244. $this->name = $name;
  245. return $this;
  246. }
  247. /**
  248. * Returns the command namespace.
  249. *
  250. * @return string The command namespace
  251. */
  252. public function getNamespace()
  253. {
  254. return $this->namespace;
  255. }
  256. /**
  257. * Returns the command name
  258. *
  259. * @return string The command name
  260. */
  261. public function getName()
  262. {
  263. return $this->name;
  264. }
  265. /**
  266. * Returns the fully qualified command name.
  267. *
  268. * @return string The fully qualified command name
  269. */
  270. public function getFullName()
  271. {
  272. return $this->getNamespace() ? $this->getNamespace().':'.$this->getName() : $this->getName();
  273. }
  274. /**
  275. * Sets the description for the command.
  276. *
  277. * @param string $description The description for the command
  278. *
  279. * @return Command The current instance
  280. */
  281. public function setDescription($description)
  282. {
  283. $this->description = $description;
  284. return $this;
  285. }
  286. /**
  287. * Returns the description for the command.
  288. *
  289. * @return string The description for the command
  290. */
  291. public function getDescription()
  292. {
  293. return $this->description;
  294. }
  295. /**
  296. * Sets the help for the command.
  297. *
  298. * @param string $help The help for the command
  299. *
  300. * @return Command The current instance
  301. */
  302. public function setHelp($help)
  303. {
  304. $this->help = $help;
  305. return $this;
  306. }
  307. /**
  308. * Returns the help for the command.
  309. *
  310. * @return string The help for the command
  311. */
  312. public function getHelp()
  313. {
  314. return $this->help;
  315. }
  316. /**
  317. * Returns the processed help for the command replacing the %command.name% and
  318. * %command.full_name% patterns with the real values dynamically.
  319. *
  320. * @return string The processed help for the command
  321. */
  322. public function getProcessedHelp()
  323. {
  324. $name = $this->namespace.':'.$this->name;
  325. $placeholders = array(
  326. '%command.name%',
  327. '%command.full_name%'
  328. );
  329. $replacements = array(
  330. $name,
  331. $_SERVER['PHP_SELF'].' '.$name
  332. );
  333. return str_replace($placeholders, $replacements, $this->getHelp());
  334. }
  335. /**
  336. * Sets the aliases for the command.
  337. *
  338. * @param array $aliases An array of aliases for the command
  339. *
  340. * @return Command The current instance
  341. */
  342. public function setAliases($aliases)
  343. {
  344. $this->aliases = $aliases;
  345. return $this;
  346. }
  347. /**
  348. * Returns the aliases for the command.
  349. *
  350. * @return array An array of aliases for the command
  351. */
  352. public function getAliases()
  353. {
  354. return $this->aliases;
  355. }
  356. /**
  357. * Returns the synopsis for the command.
  358. *
  359. * @return string The synopsis
  360. */
  361. public function getSynopsis()
  362. {
  363. return sprintf('%s %s', $this->getFullName(), $this->definition->getSynopsis());
  364. }
  365. /**
  366. * Gets a helper instance by name.
  367. *
  368. * @param string $name The helper name
  369. *
  370. * @return mixed The helper value
  371. *
  372. * @throws \InvalidArgumentException if the helper is not defined
  373. */
  374. protected function getHelper($name)
  375. {
  376. return $this->application->getHelperSet()->get($name);
  377. }
  378. /**
  379. * Gets a helper instance by name.
  380. *
  381. * @param string $name The helper name
  382. *
  383. * @return mixed The helper value
  384. *
  385. * @throws \InvalidArgumentException if the helper is not defined
  386. */
  387. public function __get($name)
  388. {
  389. return $this->application->getHelperSet()->get($name);
  390. }
  391. /**
  392. * Returns a text representation of the command.
  393. *
  394. * @return string A string representing the command
  395. */
  396. public function asText()
  397. {
  398. $messages = array(
  399. '<comment>Usage:</comment>',
  400. ' '.$this->getSynopsis(),
  401. '',
  402. );
  403. if ($this->getAliases()) {
  404. $messages[] = '<comment>Aliases:</comment> <info>'.implode(', ', $this->getAliases()).'</info>';
  405. }
  406. $messages[] = $this->definition->asText();
  407. if ($help = $this->getProcessedHelp()) {
  408. $messages[] = '<comment>Help:</comment>';
  409. $messages[] = ' '.implode("\n ", explode("\n", $help))."\n";
  410. }
  411. return implode("\n", $messages);
  412. }
  413. /**
  414. * Returns an XML representation of the command.
  415. *
  416. * @param Boolean $asDom Whether to return a DOM or an XML string
  417. *
  418. * @return string|DOMDocument An XML string representing the command
  419. */
  420. public function asXml($asDom = false)
  421. {
  422. $dom = new \DOMDocument('1.0', 'UTF-8');
  423. $dom->formatOutput = true;
  424. $dom->appendChild($commandXML = $dom->createElement('command'));
  425. $commandXML->setAttribute('id', $this->getFullName());
  426. $commandXML->setAttribute('namespace', $this->getNamespace() ? $this->getNamespace() : '_global');
  427. $commandXML->setAttribute('name', $this->getName());
  428. $commandXML->appendChild($usageXML = $dom->createElement('usage'));
  429. $usageXML->appendChild($dom->createTextNode(sprintf($this->getSynopsis(), '')));
  430. $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
  431. $descriptionXML->appendChild($dom->createTextNode(implode("\n ", explode("\n", $this->getDescription()))));
  432. $commandXML->appendChild($helpXML = $dom->createElement('help'));
  433. $help = $this->help;
  434. $helpXML->appendChild($dom->createTextNode(implode("\n ", explode("\n", $help))));
  435. $commandXML->appendChild($aliasesXML = $dom->createElement('aliases'));
  436. foreach ($this->getAliases() as $alias) {
  437. $aliasesXML->appendChild($aliasXML = $dom->createElement('alias'));
  438. $aliasXML->appendChild($dom->createTextNode($alias));
  439. }
  440. $definition = $this->definition->asXml(true);
  441. $commandXML->appendChild($dom->importNode($definition->getElementsByTagName('arguments')->item(0), true));
  442. $commandXML->appendChild($dom->importNode($definition->getElementsByTagName('options')->item(0), true));
  443. return $asDom ? $dom : $dom->saveXml();
  444. }
  445. }