Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Command.php

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 19.41 KiB


001  <?php
002   
003  /*
004   * This file is part of the Symfony package.
005   *
006   * (c) Fabien Potencier <fabien@symfony.com>
007   *
008   * For the full copyright and license information, please view the LICENSE
009   * file that was distributed with this source code.
010   */
011   
012  namespace Symfony\Component\Console\Command;
013   
014  use Symfony\Component\Console\Descriptor\TextDescriptor;
015  use Symfony\Component\Console\Descriptor\XmlDescriptor;
016  use Symfony\Component\Console\Exception\ExceptionInterface;
017  use Symfony\Component\Console\Input\InputDefinition;
018  use Symfony\Component\Console\Input\InputOption;
019  use Symfony\Component\Console\Input\InputArgument;
020  use Symfony\Component\Console\Input\InputInterface;
021  use Symfony\Component\Console\Output\BufferedOutput;
022  use Symfony\Component\Console\Output\OutputInterface;
023  use Symfony\Component\Console\Application;
024  use Symfony\Component\Console\Helper\HelperSet;
025  use Symfony\Component\Console\Exception\InvalidArgumentException;
026  use Symfony\Component\Console\Exception\LogicException;
027   
028  /**
029   * Base class for all commands.
030   *
031   * @author Fabien Potencier <fabien@symfony.com>
032   */
033  class Command
034  {
035      private $application;
036      private $name;
037      private $processTitle;
038      private $aliases = array();
039      private $definition;
040      private $help;
041      private $description;
042      private $ignoreValidationErrors = false;
043      private $applicationDefinitionMerged = false;
044      private $applicationDefinitionMergedWithArgs = false;
045      private $code;
046      private $synopsis = array();
047      private $usages = array();
048      private $helperSet;
049   
050      /**
051       * Constructor.
052       *
053       * @param string|null $name The name of the command; passing null means it must be set in configure()
054       *
055       * @throws LogicException When the command name is empty
056       */
057      public function __construct($name = null)
058      {
059          $this->definition = new InputDefinition();
060   
061          if (null !== $name) {
062              $this->setName($name);
063          }
064   
065          $this->configure();
066   
067          if (!$this->name) {
068              throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
069          }
070      }
071   
072      /**
073       * Ignores validation errors.
074       *
075       * This is mainly useful for the help command.
076       */
077      public function ignoreValidationErrors()
078      {
079          $this->ignoreValidationErrors = true;
080      }
081   
082      /**
083       * Sets the application instance for this command.
084       *
085       * @param Application $application An Application instance
086       */
087      public function setApplication(Application $application = null)
088      {
089          $this->application = $application;
090          if ($application) {
091              $this->setHelperSet($application->getHelperSet());
092          } else {
093              $this->helperSet = null;
094          }
095      }
096   
097      /**
098       * Sets the helper set.
099       *
100       * @param HelperSet $helperSet A HelperSet instance
101       */
102      public function setHelperSet(HelperSet $helperSet)
103      {
104          $this->helperSet = $helperSet;
105      }
106   
107      /**
108       * Gets the helper set.
109       *
110       * @return HelperSet A HelperSet instance
111       */
112      public function getHelperSet()
113      {
114          return $this->helperSet;
115      }
116   
117      /**
118       * Gets the application instance for this command.
119       *
120       * @return Application An Application instance
121       */
122      public function getApplication()
123      {
124          return $this->application;
125      }
126   
127      /**
128       * Checks whether the command is enabled or not in the current environment.
129       *
130       * Override this to check for x or y and return false if the command can not
131       * run properly under the current conditions.
132       *
133       * @return bool
134       */
135      public function isEnabled()
136      {
137          return true;
138      }
139   
140      /**
141       * Configures the current command.
142       */
143      protected function configure()
144      {
145      }
146   
147      /**
148       * Executes the current command.
149       *
150       * This method is not abstract because you can use this class
151       * as a concrete class. In this case, instead of defining the
152       * execute() method, you set the code to execute by passing
153       * a Closure to the setCode() method.
154       *
155       * @param InputInterface  $input  An InputInterface instance
156       * @param OutputInterface $output An OutputInterface instance
157       *
158       * @return null|int null or 0 if everything went fine, or an error code
159       *
160       * @throws LogicException When this abstract method is not implemented
161       *
162       * @see setCode()
163       */
164      protected function execute(InputInterface $input, OutputInterface $output)
165      {
166          throw new LogicException('You must override the execute() method in the concrete command class.');
167      }
168   
169      /**
170       * Interacts with the user.
171       *
172       * This method is executed before the InputDefinition is validated.
173       * This means that this is the only place where the command can
174       * interactively ask for values of missing required arguments.
175       *
176       * @param InputInterface  $input  An InputInterface instance
177       * @param OutputInterface $output An OutputInterface instance
178       */
179      protected function interact(InputInterface $input, OutputInterface $output)
180      {
181      }
182   
183      /**
184       * Initializes the command just after the input has been validated.
185       *
186       * This is mainly useful when a lot of commands extends one main command
187       * where some things need to be initialized based on the input arguments and options.
188       *
189       * @param InputInterface  $input  An InputInterface instance
190       * @param OutputInterface $output An OutputInterface instance
191       */
192      protected function initialize(InputInterface $input, OutputInterface $output)
193      {
194      }
195   
196      /**
197       * Runs the command.
198       *
199       * The code to execute is either defined directly with the
200       * setCode() method or by overriding the execute() method
201       * in a sub-class.
202       *
203       * @param InputInterface  $input  An InputInterface instance
204       * @param OutputInterface $output An OutputInterface instance
205       *
206       * @return int The command exit code
207       *
208       * @see setCode()
209       * @see execute()
210       */
211      public function run(InputInterface $input, OutputInterface $output)
212      {
213          // force the creation of the synopsis before the merge with the app definition
214          $this->getSynopsis(true);
215          $this->getSynopsis(false);
216   
217          // add the application arguments and options
218          $this->mergeApplicationDefinition();
219   
220          // bind the input against the command specific arguments/options
221          try {
222              $input->bind($this->definition);
223          } catch (ExceptionInterface $e) {
224              if (!$this->ignoreValidationErrors) {
225                  throw $e;
226              }
227          }
228   
229          $this->initialize($input, $output);
230   
231          if (null !== $this->processTitle) {
232              if (function_exists('cli_set_process_title')) {
233                  cli_set_process_title($this->processTitle);
234              } elseif (function_exists('setproctitle')) {
235                  setproctitle($this->processTitle);
236              } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
237                  $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
238              }
239          }
240   
241          if ($input->isInteractive()) {
242              $this->interact($input, $output);
243          }
244   
245          // The command name argument is often omitted when a command is executed directly with its run() method.
246          // It would fail the validation if we didn't make sure the command argument is present,
247          // since it's required by the application.
248          if ($input->hasArgument('command') && null === $input->getArgument('command')) {
249              $input->setArgument('command', $this->getName());
250          }
251   
252          $input->validate();
253   
254          if ($this->code) {
255              $statusCode = call_user_func($this->code, $input, $output);
256          } else {
257              $statusCode = $this->execute($input, $output);
258          }
259   
260          return is_numeric($statusCode) ? (int) $statusCode : 0;
261      }
262   
263      /**
264       * Sets the code to execute when running this command.
265       *
266       * If this method is used, it overrides the code defined
267       * in the execute() method.
268       *
269       * @param callable $code A callable(InputInterface $input, OutputInterface $output)
270       *
271       * @return Command The current instance
272       *
273       * @throws InvalidArgumentException
274       *
275       * @see execute()
276       */
277      public function setCode($code)
278      {
279          if (!is_callable($code)) {
280              throw new InvalidArgumentException('Invalid callable provided to Command::setCode.');
281          }
282   
283          if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) {
284              $r = new \ReflectionFunction($code);
285              if (null === $r->getClosureThis()) {
286                  $code = \Closure::bind($code, $this);
287              }
288          }
289   
290          $this->code = $code;
291   
292          return $this;
293      }
294   
295      /**
296       * Merges the application definition with the command definition.
297       *
298       * This method is not part of public API and should not be used directly.
299       *
300       * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
301       */
302      public function mergeApplicationDefinition($mergeArgs = true)
303      {
304          if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
305              return;
306          }
307   
308          $this->definition->addOptions($this->application->getDefinition()->getOptions());
309   
310          if ($mergeArgs) {
311              $currentArguments = $this->definition->getArguments();
312              $this->definition->setArguments($this->application->getDefinition()->getArguments());
313              $this->definition->addArguments($currentArguments);
314          }
315   
316          $this->applicationDefinitionMerged = true;
317          if ($mergeArgs) {
318              $this->applicationDefinitionMergedWithArgs = true;
319          }
320      }
321   
322      /**
323       * Sets an array of argument and option instances.
324       *
325       * @param array|InputDefinition $definition An array of argument and option instances or a definition instance
326       *
327       * @return Command The current instance
328       */
329      public function setDefinition($definition)
330      {
331          if ($definition instanceof InputDefinition) {
332              $this->definition = $definition;
333          } else {
334              $this->definition->setDefinition($definition);
335          }
336   
337          $this->applicationDefinitionMerged = false;
338   
339          return $this;
340      }
341   
342      /**
343       * Gets the InputDefinition attached to this Command.
344       *
345       * @return InputDefinition An InputDefinition instance
346       */
347      public function getDefinition()
348      {
349          return $this->definition;
350      }
351   
352      /**
353       * Gets the InputDefinition to be used to create XML and Text representations of this Command.
354       *
355       * Can be overridden to provide the original command representation when it would otherwise
356       * be changed by merging with the application InputDefinition.
357       *
358       * This method is not part of public API and should not be used directly.
359       *
360       * @return InputDefinition An InputDefinition instance
361       */
362      public function getNativeDefinition()
363      {
364          return $this->getDefinition();
365      }
366   
367      /**
368       * Adds an argument.
369       *
370       * @param string $name        The argument name
371       * @param int    $mode        The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
372       * @param string $description A description text
373       * @param mixed  $default     The default value (for InputArgument::OPTIONAL mode only)
374       *
375       * @return Command The current instance
376       */
377      public function addArgument($name, $mode = null, $description = '', $default = null)
378      {
379          $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
380   
381          return $this;
382      }
383   
384      /**
385       * Adds an option.
386       *
387       * @param string $name        The option name
388       * @param string $shortcut    The shortcut (can be null)
389       * @param int    $mode        The option mode: One of the InputOption::VALUE_* constants
390       * @param string $description A description text
391       * @param mixed  $default     The default value (must be null for InputOption::VALUE_NONE)
392       *
393       * @return Command The current instance
394       */
395      public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
396      {
397          $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
398   
399          return $this;
400      }
401   
402      /**
403       * Sets the name of the command.
404       *
405       * This method can set both the namespace and the name if
406       * you separate them by a colon (:)
407       *
408       *     $command->setName('foo:bar');
409       *
410       * @param string $name The command name
411       *
412       * @return Command The current instance
413       *
414       * @throws InvalidArgumentException When the name is invalid
415       */
416      public function setName($name)
417      {
418          $this->validateName($name);
419   
420          $this->name = $name;
421   
422          return $this;
423      }
424   
425      /**
426       * Sets the process title of the command.
427       *
428       * This feature should be used only when creating a long process command,
429       * like a daemon.
430       *
431       * PHP 5.5+ or the proctitle PECL library is required
432       *
433       * @param string $title The process title
434       *
435       * @return Command The current instance
436       */
437      public function setProcessTitle($title)
438      {
439          $this->processTitle = $title;
440   
441          return $this;
442      }
443   
444      /**
445       * Returns the command name.
446       *
447       * @return string The command name
448       */
449      public function getName()
450      {
451          return $this->name;
452      }
453   
454      /**
455       * Sets the description for the command.
456       *
457       * @param string $description The description for the command
458       *
459       * @return Command The current instance
460       */
461      public function setDescription($description)
462      {
463          $this->description = $description;
464   
465          return $this;
466      }
467   
468      /**
469       * Returns the description for the command.
470       *
471       * @return string The description for the command
472       */
473      public function getDescription()
474      {
475          return $this->description;
476      }
477   
478      /**
479       * Sets the help for the command.
480       *
481       * @param string $help The help for the command
482       *
483       * @return Command The current instance
484       */
485      public function setHelp($help)
486      {
487          $this->help = $help;
488   
489          return $this;
490      }
491   
492      /**
493       * Returns the help for the command.
494       *
495       * @return string The help for the command
496       */
497      public function getHelp()
498      {
499          return $this->help;
500      }
501   
502      /**
503       * Returns the processed help for the command replacing the %command.name% and
504       * %command.full_name% patterns with the real values dynamically.
505       *
506       * @return string The processed help for the command
507       */
508      public function getProcessedHelp()
509      {
510          $name = $this->name;
511   
512          $placeholders = array(
513              '%command.name%',
514              '%command.full_name%',
515          );
516          $replacements = array(
517              $name,
518              $_SERVER['PHP_SELF'].' '.$name,
519          );
520   
521          return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());
522      }
523   
524      /**
525       * Sets the aliases for the command.
526       *
527       * @param string[] $aliases An array of aliases for the command
528       *
529       * @return Command The current instance
530       *
531       * @throws InvalidArgumentException When an alias is invalid
532       */
533      public function setAliases($aliases)
534      {
535          if (!is_array($aliases) && !$aliases instanceof \Traversable) {
536              throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
537          }
538   
539          foreach ($aliases as $alias) {
540              $this->validateName($alias);
541          }
542   
543          $this->aliases = $aliases;
544   
545          return $this;
546      }
547   
548      /**
549       * Returns the aliases for the command.
550       *
551       * @return array An array of aliases for the command
552       */
553      public function getAliases()
554      {
555          return $this->aliases;
556      }
557   
558      /**
559       * Returns the synopsis for the command.
560       *
561       * @param bool $short Whether to show the short version of the synopsis (with options folded) or not
562       *
563       * @return string The synopsis
564       */
565      public function getSynopsis($short = false)
566      {
567          $key = $short ? 'short' : 'long';
568   
569          if (!isset($this->synopsis[$key])) {
570              $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
571          }
572   
573          return $this->synopsis[$key];
574      }
575   
576      /**
577       * Add a command usage example.
578       *
579       * @param string $usage The usage, it'll be prefixed with the command name
580       *
581       * @return Command The current instance
582       */
583      public function addUsage($usage)
584      {
585          if (0 !== strpos($usage, $this->name)) {
586              $usage = sprintf('%s %s', $this->name, $usage);
587          }
588   
589          $this->usages[] = $usage;
590   
591          return $this;
592      }
593   
594      /**
595       * Returns alternative usages of the command.
596       *
597       * @return array
598       */
599      public function getUsages()
600      {
601          return $this->usages;
602      }
603   
604      /**
605       * Gets a helper instance by name.
606       *
607       * @param string $name The helper name
608       *
609       * @return mixed The helper value
610       *
611       * @throws LogicException           if no HelperSet is defined
612       * @throws InvalidArgumentException if the helper is not defined
613       */
614      public function getHelper($name)
615      {
616          if (null === $this->helperSet) {
617              throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
618          }
619   
620          return $this->helperSet->get($name);
621      }
622   
623      /**
624       * Returns a text representation of the command.
625       *
626       * @return string A string representing the command
627       *
628       * @deprecated since version 2.3, to be removed in 3.0.
629       */
630      public function asText()
631      {
632          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
633   
634          $descriptor = new TextDescriptor();
635          $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
636          $descriptor->describe($output, $this, array('raw_output' => true));
637   
638          return $output->fetch();
639      }
640   
641      /**
642       * Returns an XML representation of the command.
643       *
644       * @param bool $asDom Whether to return a DOM or an XML string
645       *
646       * @return string|\DOMDocument An XML string representing the command
647       *
648       * @deprecated since version 2.3, to be removed in 3.0.
649       */
650      public function asXml($asDom = false)
651      {
652          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
653   
654          $descriptor = new XmlDescriptor();
655   
656          if ($asDom) {
657              return $descriptor->getCommandDocument($this);
658          }
659   
660          $output = new BufferedOutput();
661          $descriptor->describe($output, $this);
662   
663          return $output->fetch();
664      }
665   
666      /**
667       * Validates a command name.
668       *
669       * It must be non-empty and parts can optionally be separated by ":".
670       *
671       * @param string $name
672       *
673       * @throws InvalidArgumentException When the name is invalid
674       */
675      private function validateName($name)
676      {
677          if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
678              throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
679          }
680      }
681  }
682