2 /***************************************************************
6 * This class is a backport of the corresponding class of FLOW3.
7 * All credits go to the v5 team.
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
18 * This script is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * This copyright notice MUST APPEAR in all copies of the script!
24 ***************************************************************/
28 * A controller which processes requests from the command line
30 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
32 class Tx_Extbase_MVC_Controller_CommandController
implements Tx_Extbase_MVC_Controller_CommandControllerInterface
{
34 const MAXIMUM_LINE_LENGTH
= 79;
37 * @var Tx_Extbase_MVC_CLI_Request
42 * @var Tx_Extbase_MVC_CLI_Response
47 * @var Tx_Extbase_MVC_Controller_Arguments
52 * Name of the command method
56 protected $commandMethodName = '';
59 * @var Tx_Extbase_Reflection_Service
61 protected $reflectionService;
64 * @var Tx_Extbase_Object_ObjectManagerInterface
66 protected $objectManager;
69 * @param Tx_Extbase_Reflection_Service $reflectionService
72 public function injectReflectionService(Tx_Extbase_Reflection_Service
$reflectionService) {
73 $this->reflectionService
= $reflectionService;
77 * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
80 public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface
$objectManager) {
81 $this->objectManager
= $objectManager;
82 $this->arguments
= $this->objectManager
->create('Tx_Extbase_MVC_Controller_Arguments');
86 * Checks if the current request type is supported by the controller.
88 * @param Tx_Extbase_MVC_RequestInterface $request The current request
89 * @return boolean TRUE if this request type is supported, otherwise FALSE
90 * @author Robert Lemke <robert@typo3.org>
92 public function canProcessRequest(Tx_Extbase_MVC_RequestInterface
$request) {
93 return $request instanceof Tx_Extbase_MVC_CLI_Request
;
97 * Processes a command line request.
99 * @param Tx_Extbase_MVC_RequestInterface $request The request object
100 * @param Tx_Extbase_MVC_ResponseInterface $response The response, modified by this controller
102 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestTypeException if the controller doesn't support the current request type
103 * @author Robert Lemke <robert@typo3.org>
106 public function processRequest(Tx_Extbase_MVC_RequestInterface
$request, Tx_Extbase_MVC_ResponseInterface
$response) {
107 if (!$this->canProcessRequest($request)) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType(get_class($this) . ' does not support requests of type "' . get_class($request) . '".' , 1300787096);
109 $this->request
= $request;
110 $this->request
->setDispatched(TRUE);
111 $this->response
= $response;
113 $this->commandMethodName
= $this->resolveCommandMethodName();
114 $this->initializeCommandMethodArguments();
115 $this->mapRequestArgumentsToControllerArguments();
116 $this->callCommandMethod();
120 * Resolves and checks the current command method name
122 * Note: The resulting command method name might not have the correct case, which isn't a problem because PHP is
123 * case insensitive regarding method names.
125 * @return string Method name of the current command
126 * @author Robert Lemke <robert@typo3.org>
128 protected function resolveCommandMethodName() {
129 $commandMethodName = $this->request
->getControllerCommandName() . 'Command';
130 if (!is_callable(array($this, $commandMethodName))) {
131 throw new Tx_Extbase_MVC_Exception_NoSuchCommand('A command method "' . $commandMethodName . '()" does not exist in controller "' . get_class($this) . '".', 1300902143);
133 return $commandMethodName;
137 * Initializes the arguments array of this controller by creating an empty argument object for each of the
138 * method arguments found in the designated command method.
141 * @author Robert Lemke <robert@typo3.org>
143 protected function initializeCommandMethodArguments() {
144 $methodParameters = $this->reflectionService
->getMethodParameters(get_class($this), $this->commandMethodName
);
146 foreach ($methodParameters as $parameterName => $parameterInfo) {
148 if (isset($parameterInfo['type'])) {
149 $dataType = $parameterInfo['type'];
150 } elseif ($parameterInfo['array']) {
153 if ($dataType === NULL) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('The argument type for parameter $' . $parameterName . ' of method ' . get_class($this) . '->' . $this->commandMethodName
. '() could not be detected.' , 1306755296);
154 $defaultValue = (isset($parameterInfo['defaultValue']) ?
$parameterInfo['defaultValue'] : NULL);
155 $this->arguments
->addNewArgument($parameterName, $dataType, ($parameterInfo['optional'] === FALSE), $defaultValue);
160 * Maps arguments delivered by the request object to the local controller arguments.
163 * @author Robert Lemke <robert@typo3.org>
164 * @author Bastian Waidelich <bastian@typo3.org>
166 protected function mapRequestArgumentsToControllerArguments() {
167 foreach ($this->arguments
as $argument) {
168 $argumentName = $argument->getName();
170 if ($this->request
->hasArgument($argumentName)) {
171 $argument->setValue($this->request
->getArgument($argumentName));
172 } elseif ($argument->isRequired()) {
173 $exception = new Tx_Extbase_MVC_Exception_Command('Required argument "' . $argumentName . '" is not set.', 1306755520);
174 $this->forward('error', 'Tx_Extbase_Command_HelpCommandController', array('exception' => $exception));
180 * Forwards the request to another command and / or CommandController.
182 * Request is directly transferred to the other command / controller
183 * without the need for a new request.
185 * @param string $commandName
186 * @param string $controllerObjectName
187 * @param array $arguments
190 protected function forward($commandName, $controllerObjectName = NULL, array $arguments = array()) {
191 $this->request
->setDispatched(FALSE);
192 $this->request
->setControllerCommandName($commandName);
193 if ($controllerObjectName !== NULL) {
194 $this->request
->setControllerObjectName($controllerObjectName);
196 $this->request
->setArguments($arguments);
198 $this->arguments
->removeAll();
199 throw new Tx_Extbase_MVC_Exception_StopAction();
203 * Calls the specified command method and passes the arguments.
205 * If the command returns a string, it is appended to the content in the
206 * response object. If the command doesn't return anything and a valid
207 * view exists, the view is rendered automatically.
210 * @author Robert Lemke <robert@typo3.org>
212 protected function callCommandMethod() {
213 $preparedArguments = array();
214 foreach ($this->arguments
as $argument) {
215 $preparedArguments[] = $argument->getValue();
218 $commandResult = call_user_func_array(array($this, $this->commandMethodName
), $preparedArguments);
220 if (is_string($commandResult) && strlen($commandResult) > 0) {
221 $this->response
->appendContent($commandResult);
222 } elseif (is_object($commandResult) && method_exists($commandResult, '__toString')) {
223 $this->response
->appendContent((string)$commandResult);
228 * Outputs specified text to the console window
229 * You can specify arguments that will be passed to the text via sprintf
230 * @see http://www.php.net/sprintf
232 * @param string $text Text to output
233 * @param array $arguments Optional arguments to use for sprintf
236 protected function output($text, array $arguments = array()) {
237 if ($arguments !== array()) {
238 $text = vsprintf($text, $arguments);
240 $this->response
->appendContent($text);
244 * Outputs specified text to the console window and appends a line break
246 * @param string $text Text to output
247 * @param array $arguments Optional arguments to use for sprintf
251 protected function outputLine($text = '', array $arguments = array()) {
252 return $this->output($text . PHP_EOL
, $arguments);
256 * Exits the CLI through the dispatcher
257 * An exit status code can be specified @see http://www.php.net/exit
259 * @param integer $exitCode Exit code to return on exit
262 protected function quit($exitCode = 0) {
263 $this->response
->setExitCode($exitCode);
264 throw new Tx_Extbase_MVC_Exception_StopAction();
268 * Sends the response and exits the CLI without any further code execution
269 * Should be used for commands that flush code caches.
271 * @param integer $exitCode Exit code to return on exit
274 protected function sendAndExit($exitCode = 0) {
275 $this->response
->send();