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