f841fee1dc7147d8f8dfc9455a252d4923b217c7
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Console / CommandRequestHandler.php
1 <?php
2 namespace TYPO3\CMS\Core\Console;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Symfony\Component\Console\Application;
18 use Symfony\Component\Console\Command\Command;
19 use Symfony\Component\Console\Input\InputInterface;
20 use Symfony\Component\Console\Output\ConsoleOutput;
21 use TYPO3\CMS\Core\Authentication\CommandLineUserAuthentication;
22 use TYPO3\CMS\Core\Core\Bootstrap;
23 use TYPO3\CMS\Core\Package\PackageManager;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * Command Line Interface Request Handler dealing with registered commands.
28 */
29 class CommandRequestHandler implements RequestHandlerInterface
30 {
31 /**
32 * Instance of the current TYPO3 bootstrap
33 * @var Bootstrap
34 */
35 protected $bootstrap;
36
37 /**
38 * Instance of the symfony application
39 * @var Application
40 */
41 protected $application;
42
43 /**
44 * Constructor handing over the bootstrap
45 *
46 * @param Bootstrap $bootstrap
47 */
48 public function __construct(Bootstrap $bootstrap)
49 {
50 $this->bootstrap = $bootstrap;
51 $this->application = new Application('TYPO3 CMS', TYPO3_version);
52 }
53
54 /**
55 * Handles any commandline request
56 *
57 * @param InputInterface $input
58 */
59 public function handleRequest(InputInterface $input)
60 {
61 $output = new ConsoleOutput();
62
63 $this->bootstrap
64 ->loadBaseTca()
65 ->loadExtTables()
66 // create the BE_USER object (not logged in yet)
67 ->initializeBackendUser(CommandLineUserAuthentication::class)
68 ->initializeLanguageObject()
69 // Make sure output is not buffered, so command-line output and interaction can take place
70 ->endOutputBufferingAndCleanPreviousOutput();
71
72 // Check if the command to run needs a backend user to be loaded
73 $command = $this->getCommandToRun($input);
74
75 if (!$command) {
76 // Using old "cliKeys" is marked as deprecated and will be removed in TYPO3 v9
77 $cliKeys = array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys']);
78
79 $output->writeln('Using old "cliKeys" ($GLOBALS[TYPO3_CONF_VARS][SC_OPTIONS][GLOBAL][cliKeys]) is marked as deprecated and will be removed in TYPO3 v9:');
80 $output->writeln('Old entrypoint keys available:');
81 asort($cliKeys);
82 foreach ($cliKeys as $key => $value) {
83 $output->writeln(' ' . $value);
84 }
85 $output->writeln('');
86 $output->writeln('TYPO3 Console Commands:');
87 }
88
89 $exitCode = $this->application->run($input, $output);
90 exit($exitCode);
91 }
92
93 /**
94 * This request handler can handle any CLI request
95 *
96 * @param InputInterface $input
97 * @return bool Always TRUE
98 */
99 public function canHandleRequest(InputInterface $input)
100 {
101 $this->populateAvailableCommands();
102 return true;
103 }
104
105 /**
106 * Returns the priority - how eager the handler is to actually handle the request.
107 *
108 * @return int The priority of the request handler.
109 */
110 public function getPriority()
111 {
112 return 50;
113 }
114
115 /**
116 * @param InputInterface $input
117 * @return bool|Command
118 */
119 protected function getCommandToRun(InputInterface $input)
120 {
121 $firstArgument = $input->getFirstArgument();
122 try {
123 return $this->application->find($firstArgument);
124 } catch (\InvalidArgumentException $e) {
125 return false;
126 }
127 }
128
129 /**
130 * Put all available commands inside the application
131 */
132 protected function populateAvailableCommands()
133 {
134 /** @var PackageManager $packageManager */
135 $packageManager = Bootstrap::getInstance()->getEarlyInstance(PackageManager::class);
136
137 foreach ($packageManager->getActivePackages() as $package) {
138 $commandsOfExtension = $package->getPackagePath() . 'Configuration/Commands.php';
139 if (@is_file($commandsOfExtension)) {
140 $commands = require_once $commandsOfExtension;
141 if (is_array($commands)) {
142 foreach ($commands as $commandName => $commandDescription) {
143 /** @var Command $cmd */
144 $cmd = GeneralUtility::makeInstance($commandDescription['class'], $commandName);
145 // Check if the command name is already in use
146 if ($this->application->has($commandName)) {
147 throw new CommandNameAlreadyInUseException('Command "' . $commandName . '" registered by "' . $package->getPackageKey() . '" is already in use', 1484486383);
148 }
149 $this->application->add($cmd);
150 }
151 }
152 }
153 }
154 }
155 }