[+FEATURE] Backport CommandController Implementation
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / MVC / CLI / Command.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 * All rights reserved
5 *
6 * This class is a backport of the corresponding class of FLOW3.
7 * All credits go to the v5 team.
8 *
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.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 *
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.
22 *
23 * This copyright notice MUST APPEAR in all copies of the script!
24 ***************************************************************/
25
26 /**
27 * Represents a Command
28 *
29 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
30 */
31 class Tx_Extbase_MVC_CLI_Command {
32
33 /**
34 * @var Tx_Extbase_Object_ObjectManagerInterface
35 */
36 protected $objectManager;
37
38 /**
39 * @var string
40 */
41 protected $controllerClassName;
42
43 /**
44 * @var string
45 */
46 protected $controllerCommandName;
47
48 /**
49 * @var string
50 */
51 protected $commandIdentifier;
52
53 /**
54 * @var Tx_Extbase_Reflection_MethodReflection
55 */
56 protected $commandMethodReflection;
57
58 /**
59 * Reflection service
60 * @var Tx_Extbase_Reflection_Service
61 */
62 private $reflectionService;
63
64 /**
65 * Constructor
66 *
67 * @param string $controllerClassName Class name of the controller providing the command
68 * @param string $controllerCommandName Command name, i.e. the method name of the command, without the "Command" suffix
69 * @author Robert Lemke <robert@typo3.org>
70 */
71 public function __construct($controllerClassName, $controllerCommandName) {
72 $this->controllerClassName = $controllerClassName;
73 $this->controllerCommandName = $controllerCommandName;
74
75 $classNameParts = explode('_', $controllerClassName);
76 if (count($classNameParts) !== 4 || strpos($classNameParts[3], 'CommandController') === FALSE) {
77 throw new InvalidArgumentException('Invalid controller class name "' . $controllerClassName . '"', 1305100019);
78 }
79 $extensionKey = t3lib_div::camelCaseToLowerCaseUnderscored($classNameParts[1]);
80 $this->commandIdentifier = strtolower($extensionKey . ':' . substr($classNameParts[3], 0, -17) . ':' . $controllerCommandName);
81 }
82
83 /**
84 * @param Tx_Extbase_Reflection_Service $reflectionService Reflection service
85 */
86 public function injectReflectionService(Tx_Extbase_Reflection_Service $reflectionService) {
87 $this->reflectionService = $reflectionService;
88 }
89
90 /**
91 * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager A reference to the object manager
92 * @return void
93 */
94 public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
95 $this->objectManager = $objectManager;
96 }
97
98 /**
99 * @return string
100 */
101 public function getControllerClassName() {
102 return $this->controllerClassName;
103 }
104
105 /**
106 * @return string
107 */
108 public function getControllerCommandName() {
109 return $this->controllerCommandName;
110 }
111
112 /**
113 * Returns the command identifier for this command
114 *
115 * @return string The command identifier for this command, following the pattern extensionname:controllername:commandname
116 * @author Robert Lemke <robert@typo3.org>
117 */
118 public function getCommandIdentifier() {
119 return $this->commandIdentifier;
120 }
121
122 /**
123 * Returns a short description of this command
124 *
125 * @return string A short description
126 * @author Robert Lemke <robert@typo3.org>
127 */
128 public function getShortDescription() {
129 $lines = explode(chr(10), $this->getCommandMethodReflection()->getDescription());
130 return (count($lines) > 0) ? trim($lines[0]) : '<no description available>';
131 }
132
133 /**
134 * Returns a longer description of this command
135 * This is the complete method description except for the first line which can be retrieved via getShortDescription()
136 * If The command description only consists of one line, an empty string is returned
137 *
138 * @return string A longer description of this command
139 * @author Bastian Waidelich <bastian@typo3.org>
140 */
141 public function getDescription() {
142 $lines = explode(chr(10), $this->getCommandMethodReflection()->getDescription());
143 array_shift($lines);
144 $descriptionLines = array();
145 foreach ($lines as $line) {
146 $trimmedLine = trim($line);
147 if ($descriptionLines !== array() || $trimmedLine !== '') {
148 $descriptionLines[] = $trimmedLine;
149 }
150 }
151 return implode(chr(10), $descriptionLines);
152 }
153
154 /**
155 * Returns TRUE if this command expects required and/or optional arguments, otherwise FALSE
156 *
157 * @return boolean
158 */
159 public function hasArguments() {
160 return count($this->getCommandMethodReflection()->getParameters()) > 0;
161 }
162
163 /**
164 * Returns an array of Tx_Extbase_MVC_CLI_CommandArgumentDefinition that contains
165 * information about required/optional arguments of this command.
166 * If the command does not expect any arguments, an empty array is returned
167 *
168 * @return array<Tx_Extbase_MVC_CLI_CommandArgumentDefinition>
169 * @author Bastian Waidelich <bastian@typo3.org>
170 */
171 public function getArgumentDefinitions() {
172 if (!$this->hasArguments()) {
173 return array();
174 }
175 $commandArgumentDefinitions = array();
176 $commandMethodReflection = $this->getCommandMethodReflection();
177 $annotations = $commandMethodReflection->getTagsValues();
178 $commandParameters = $this->reflectionService->getMethodParameters($this->controllerClassName, $this->controllerCommandName . 'Command');
179 $i = 0;
180 foreach ($commandParameters as $commandParameterName => $commandParameterDefinition) {
181 $explodedAnnotation = explode(' ', $annotations['param'][$i]);
182 array_shift($explodedAnnotation);
183 array_shift($explodedAnnotation);
184 $description = implode(' ', $explodedAnnotation);
185 $required = $commandParameterDefinition['optional'] !== TRUE;
186 $commandArgumentDefinitions[] = $this->objectManager->get('Tx_Extbase_MVC_CLI_CommandArgumentDefinition', $commandParameterName, $required, $description);
187 $i ++;
188 }
189 return $commandArgumentDefinitions;
190 }
191
192 /**
193 * Tells if this command is internal and thus should not be exposed through help texts, user documentation etc.
194 * Internall commands are still accessible through the regular command line interface, but should not be used
195 * by users.
196 *
197 * @return boolean
198 * @author Robert Lemke <robert@typo3.org>
199 * @author Bastian Waidelich <bastian@typo3.org>
200 */
201 public function isInternal() {
202 return $this->getCommandMethodReflection()->isTaggedWith('internal');
203 }
204
205 /**
206 * Tells if this command flushes all caches and thus needs special attention in the interactive shell.
207 *
208 * Note that neither this method nor the @flushesCaches annotation is currently part of the official API.
209 *
210 * @return boolean
211 * @author Robert Lemke <robert@typo3.org>
212 */
213 public function isFlushingCaches() {
214 return $this->getCommandMethodReflection()->isTaggedWith('flushesCaches');
215 }
216
217 /**
218 * Returns an array of command identifiers which were specified in the "@see"
219 * annotation of a command method.
220 *
221 * @return array
222 * @author Robert Lemke <robert@typo3.org>
223 */
224 public function getRelatedCommandIdentifiers() {
225 $commandMethodReflection = $this->getCommandMethodReflection();
226 if (!$commandMethodReflection->isTaggedWith('see')) {
227 return array();
228 }
229
230 $relatedCommandIdentifiers = array();
231 foreach ($commandMethodReflection->getTagValues('see') as $tagValue) {
232 if (preg_match('/^[\w\d\.]+:[\w\d]+:[\w\d]+$/', $tagValue) === 1) {
233 $relatedCommandIdentifiers[] = $tagValue;
234 }
235 }
236 return $relatedCommandIdentifiers;
237 }
238
239 /**
240 * @return Tx_Extbase_Reflection_MethodReflection
241 */
242 protected function getCommandMethodReflection() {
243 if ($this->commandMethodReflection === NULL) {
244 $this->commandMethodReflection = $this->objectManager->get('Tx_Extbase_Reflection_MethodReflection', $this->controllerClassName, $this->controllerCommandName . 'Command');
245 }
246 return $this->commandMethodReflection;
247 }
248 }
249 ?>