TYPO3 CMS  TYPO3_7-6
CliRequestHandler.php
Go to the documentation of this file.
1 <?php
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 
23 
32 {
37  protected $bootstrap;
38 
44  public function __construct(Bootstrap $bootstrap)
45  {
46  $this->bootstrap = $bootstrap;
47  }
48 
55  public function handleRequest(InputInterface $input)
56  {
57  $output = GeneralUtility::makeInstance(ConsoleOutput::class);
58  $exitCode = 0;
59 
60  try {
61  $command = $this->validateCommandLineKeyFromInput($input);
62 
63  // try and look up if the CLI command user exists, throws an exception if the CLI
64  // user cannot be found
65  list($commandLineScript, $commandLineName) = $this->getIncludeScriptByCommandLineKey($command);
66  $this->boot($commandLineName);
67 
68  if (is_callable($commandLineScript)) {
69  call_user_func($commandLineScript);
70  } else {
71  // include the CLI script
72  include($commandLineScript);
73  }
74  } catch (\InvalidArgumentException $e) {
75  $output->writeln('<error>Oops, an error occurred: ' . $e->getMessage() . '</error>');
76  $output->writeln('');
77  $output->writeln('Valid keys are:');
78  $output->writeln('');
79  $cliKeys = array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys']);
80  asort($cliKeys);
81  foreach ($cliKeys as $key => $value) {
82  $output->writeln(' ' . $value);
83  }
84  $exitCode = $e->getCode();
85  } catch (\RuntimeException $e) {
86  $output->writeln('<error>Oops, an error occurred: ' . $e->getMessage() . '</error>');
87  $exitCode = $e->getCode();
88  } catch (\Exception $e) {
89  $output->writeln('<error>Oops, an error occurred: ' . $e->getMessage() . '</error>');
90  $exitCode = $e->getCode();
91  } catch (\Throwable $e) {
92  $output->writeln('<error>Oops, an error occurred: ' . $e->getMessage() . '</error>');
93  $exitCode = $e->getCode();
94  }
95 
96  if ($exitCode > 0 && 0 === $exitCode % 256) {
97  $exitCode = 1;
98  }
99 
100  exit($exitCode);
101  }
102 
108  protected function boot($commandLineName)
109  {
110  $this->bootstrap
111  ->loadExtensionTables(true)
112  ->initializeBackendUser();
113 
114  // Checks for a user called starting with _CLI_ e.g. "_CLI_lowlevel"
115  $this->loadCommandLineBackendUser($commandLineName);
116 
117  $this->bootstrap
118  ->initializeBackendAuthentication()
119  ->initializeLanguageObject();
120 
121  // Make sure output is not buffered, so command-line output and interaction can take place
123  }
124 
134  protected function validateCommandLineKeyFromInput(InputInterface $input)
135  {
136  $cliKey = $input->getFirstArgument();
137  if (empty($cliKey)) {
138  throw new \InvalidArgumentException('This script must have a command as first argument.', 1);
139  } elseif (!is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][$cliKey])) {
140  throw new \InvalidArgumentException('This supplied command is not valid.', 1);
141  }
142  return $cliKey;
143  }
144 
152  protected function getIncludeScriptByCommandLineKey($cliKey)
153  {
154  list($commandLineScript, $commandLineName) = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][$cliKey];
155  if (!is_callable($commandLineScript)) {
156  $commandLineScript = GeneralUtility::getFileAbsFileName($commandLineScript);
157  // Note: These constants are not in use anymore, and marked for deprecation and will be removed in TYPO3 CMS 8
158  define('TYPO3_cliKey', $cliKey);
159  define('TYPO3_cliInclude', $commandLineScript);
160  }
161  // This is a compatibility layer: Some cli scripts rely on this, like ext:phpunit cli
162  // This layer will be removed in TYPO3 CMS 8
163  $GLOBALS['temp_cliScriptPath'] = array_shift($_SERVER['argv']);
164  $GLOBALS['temp_cliKey'] = array_shift($_SERVER['argv']);
165  array_unshift($_SERVER['argv'], $GLOBALS['temp_cliScriptPath']);
166  return [$commandLineScript, $commandLineName];
167  }
168 
175  protected function loadCommandLineBackendUser($commandLineName)
176  {
177  if ($GLOBALS['BE_USER']->user['uid']) {
178  throw new \RuntimeException('Another user was already loaded which is impossible in CLI mode!', 3);
179  }
180  if (!StringUtility::beginsWith($commandLineName, '_CLI_')) {
181  throw new \RuntimeException('Module name, "' . $commandLineName . '", was not prefixed with "_CLI_"', 3);
182  }
183  $userName = strtolower($commandLineName);
184  $GLOBALS['BE_USER']->setBeUserByName($userName);
185  if (!$GLOBALS['BE_USER']->user['uid']) {
186  throw new \RuntimeException('No backend user named "' . $userName . '" was found!', 3);
187  }
188  if ($GLOBALS['BE_USER']->isAdmin()) {
189  throw new \RuntimeException('CLI backend user "' . $userName . '" was ADMIN which is not allowed!', 3);
190  }
191  }
192 
199  public function canHandleRequest(InputInterface $input)
200  {
201  return true;
202  }
203 
209  public function getPriority()
210  {
211  return 20;
212  }
213 }
static getFileAbsFileName($filename, $onlyRelative=true, $relToTYPO3_mainDir=false)
static beginsWith($haystack, $needle)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']