[CLEANUP] Use correct casting syntax
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Controller / CommandController.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc\Controller;
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 use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
17
18 /**
19 * A controller which processes requests from the command line
20 *
21 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
22 */
23 class CommandController implements CommandControllerInterface {
24
25 const MAXIMUM_LINE_LENGTH = 79;
26
27 /**
28 * @var \TYPO3\CMS\Extbase\Mvc\Cli\Request
29 */
30 protected $request;
31
32 /**
33 * @var \TYPO3\CMS\Extbase\Mvc\Cli\Response
34 */
35 protected $response;
36
37 /**
38 * @var \TYPO3\CMS\Extbase\Mvc\Controller\Arguments
39 */
40 protected $arguments;
41
42 /**
43 * Name of the command method
44 *
45 * @var string
46 */
47 protected $commandMethodName = '';
48
49 /**
50 * Whether the command needs admin access to perform its job
51 *
52 * @var bool
53 * @api
54 */
55 protected $requestAdminPermissions = FALSE;
56
57 /**
58 * @var AbstractUserAuthentication
59 */
60 protected $userAuthentication;
61
62 /**
63 * @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
64 * @inject
65 */
66 protected $reflectionService;
67
68 /**
69 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
70 */
71 protected $objectManager;
72
73 /**
74 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
75 * @return void
76 */
77 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
78 $this->objectManager = $objectManager;
79 $this->arguments = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments');
80 $this->userAuthentication = isset($GLOBALS['BE_USER']) ? $GLOBALS['BE_USER'] : NULL;
81 }
82
83 /**
84 * Checks if the current request type is supported by the controller.
85 *
86 * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The current request
87 * @return bool TRUE if this request type is supported, otherwise FALSE
88 */
89 public function canProcessRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request) {
90 return $request instanceof \TYPO3\CMS\Extbase\Mvc\Cli\Request;
91 }
92
93 /**
94 * Processes a command line request.
95 *
96 * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request object
97 * @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, modified by this controller
98 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
99 * @return void
100 * @api
101 */
102 public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response) {
103 if (!$this->canProcessRequest($request)) {
104 throw new \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException(get_class($this) . ' does not support requests of type "' . get_class($request) . '".', 1300787096);
105 }
106 $this->request = $request;
107 $this->request->setDispatched(TRUE);
108 $this->response = $response;
109 $this->commandMethodName = $this->resolveCommandMethodName();
110 $this->initializeCommandMethodArguments();
111 $this->mapRequestArgumentsToControllerArguments();
112 $this->callCommandMethod();
113 }
114
115 /**
116 * Resolves and checks the current command method name
117 *
118 * Note: The resulting command method name might not have the correct case, which isn't a problem because PHP is
119 * case insensitive regarding method names.
120 *
121 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException
122 * @return string Method name of the current command
123 */
124 protected function resolveCommandMethodName() {
125 $commandMethodName = $this->request->getControllerCommandName() . 'Command';
126 if (!is_callable(array($this, $commandMethodName))) {
127 throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException('A command method "' . $commandMethodName . '()" does not exist in controller "' . get_class($this) . '".', 1300902143);
128 }
129 return $commandMethodName;
130 }
131
132 /**
133 * Initializes the arguments array of this controller by creating an empty argument object for each of the
134 * method arguments found in the designated command method.
135 *
136 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException
137 * @return void
138 */
139 protected function initializeCommandMethodArguments() {
140 $methodParameters = $this->reflectionService->getMethodParameters(get_class($this), $this->commandMethodName);
141 foreach ($methodParameters as $parameterName => $parameterInfo) {
142 $dataType = NULL;
143 if (isset($parameterInfo['type'])) {
144 $dataType = $parameterInfo['type'];
145 } elseif ($parameterInfo['array']) {
146 $dataType = 'array';
147 }
148 if ($dataType === NULL) {
149 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException('The argument type for parameter $' . $parameterName . ' of method ' . get_class($this) . '->' . $this->commandMethodName . '() could not be detected.', 1306755296);
150 }
151 $defaultValue = isset($parameterInfo['defaultValue']) ? $parameterInfo['defaultValue'] : NULL;
152 $this->arguments->addNewArgument($parameterName, $dataType, $parameterInfo['optional'] === FALSE, $defaultValue);
153 }
154 }
155
156 /**
157 * Maps arguments delivered by the request object to the local controller arguments.
158 *
159 * @return void
160 */
161 protected function mapRequestArgumentsToControllerArguments() {
162 /** @var Argument $argument */
163 foreach ($this->arguments as $argument) {
164 $argumentName = $argument->getName();
165 if ($this->request->hasArgument($argumentName)) {
166 $argument->setValue($this->request->getArgument($argumentName));
167 } elseif ($argument->isRequired()) {
168 $exception = new \TYPO3\CMS\Extbase\Mvc\Exception\CommandException('Required argument "' . $argumentName . '" is not set.', 1306755520);
169 $this->forward('error', 'TYPO3\\CMS\\Extbase\\Command\\HelpCommandController', array('exception' => $exception));
170 }
171 }
172 }
173
174 /**
175 * Forwards the request to another command and / or CommandController.
176 *
177 * Request is directly transferred to the other command / controller
178 * without the need for a new request.
179 *
180 * @param string $commandName
181 * @param string $controllerObjectName
182 * @param array $arguments
183 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
184 * @return void
185 */
186 protected function forward($commandName, $controllerObjectName = NULL, array $arguments = array()) {
187 $this->request->setDispatched(FALSE);
188 $this->request->setControllerCommandName($commandName);
189 if ($controllerObjectName !== NULL) {
190 $this->request->setControllerObjectName($controllerObjectName);
191 }
192 $this->request->setArguments($arguments);
193 $this->arguments->removeAll();
194 throw new \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException();
195 }
196
197 /**
198 * Calls the specified command method and passes the arguments.
199 *
200 * If the command returns a string, it is appended to the content in the
201 * response object. If the command doesn't return anything and a valid
202 * view exists, the view is rendered automatically.
203 *
204 * @return void
205 */
206 protected function callCommandMethod() {
207 $preparedArguments = array();
208 /** @var Argument $argument */
209 foreach ($this->arguments as $argument) {
210 $preparedArguments[] = $argument->getValue();
211 }
212 $originalRole = $this->ensureAdminRoleIfRequested();
213 $commandResult = call_user_func_array(array($this, $this->commandMethodName), $preparedArguments);
214 $this->restoreUserRole($originalRole);
215 if (is_string($commandResult) && strlen($commandResult) > 0) {
216 $this->response->appendContent($commandResult);
217 } elseif (is_object($commandResult) && method_exists($commandResult, '__toString')) {
218 $this->response->appendContent((string)$commandResult);
219 }
220 }
221
222 /**
223 * Set admin permissions for currently authenticated user if requested
224 * and returns the original state or NULL
225 *
226 * @return NULL|int
227 */
228 protected function ensureAdminRoleIfRequested() {
229 if (!$this->requestAdminPermissions || !$this->userAuthentication || !isset($this->userAuthentication->user['admin'])) {
230 return NULL;
231 }
232 $originalRole = $this->userAuthentication->user['admin'];
233 $this->userAuthentication->user['admin'] = 1;
234 return $originalRole;
235 }
236
237 /**
238 * Restores the original user role
239 *
240 * @param NULL|int $originalRole
241 */
242 protected function restoreUserRole($originalRole) {
243 if ($originalRole !== NULL) {
244 $this->userAuthentication->user['admin'] = $originalRole;
245 }
246 }
247
248 /**
249 * Outputs specified text to the console window
250 * You can specify arguments that will be passed to the text via sprintf
251 *
252 * @see http://www.php.net/sprintf
253 * @param string $text Text to output
254 * @param array $arguments Optional arguments to use for sprintf
255 * @return void
256 */
257 protected function output($text, array $arguments = array()) {
258 if ($arguments !== array()) {
259 $text = vsprintf($text, $arguments);
260 }
261 $this->response->appendContent($text);
262 }
263
264 /**
265 * Outputs specified text to the console window and appends a line break
266 *
267 * @param string $text Text to output
268 * @param array $arguments Optional arguments to use for sprintf
269 * @return void
270 * @see output()
271 */
272 protected function outputLine($text = '', array $arguments = array()) {
273 $this->output($text . PHP_EOL, $arguments);
274 }
275
276 /**
277 * Exits the CLI through the dispatcher
278 * An exit status code can be specified @see http://www.php.net/exit
279 *
280 * @param int $exitCode Exit code to return on exit
281 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
282 * @return void
283 */
284 protected function quit($exitCode = 0) {
285 $this->response->setExitCode($exitCode);
286 throw new \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException();
287 }
288
289 /**
290 * Sends the response and exits the CLI without any further code execution
291 * Should be used for commands that flush code caches.
292 *
293 * @param int $exitCode Exit code to return on exit
294 * @return void
295 */
296 protected function sendAndExit($exitCode = 0) {
297 $this->response->send();
298 die($exitCode);
299 }
300 }