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