4af59e0a2a062e908f92e404cf0f0f0e03b74af6
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Cli / CommandManager.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc\Cli;
3
4 /***************************************************************
5 * Copyright notice
6 * All rights reserved
7 *
8 * This class is a backport of the corresponding class of TYPO3 Flow.
9 * All credits go to the TYPO3 Flow team.
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * A helper for CLI commands
29 *
30 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
31 */
32 class CommandManager implements \TYPO3\CMS\Core\SingletonInterface {
33
34 /**
35 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
36 */
37 protected $objectManager;
38
39 /**
40 * @var array<\TYPO3\CMS\Extbase\Mvc\Cli\Command>
41 */
42 protected $availableCommands = NULL;
43
44 /**
45 * @var array
46 */
47 protected $shortCommandIdentifiers = NULL;
48
49 /**
50 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager A reference to the object manager
51 * @return void
52 */
53 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
54 $this->objectManager = $objectManager;
55 }
56
57 /**
58 * Returns an array of all commands
59 *
60 * @return array<\TYPO3\CMS\Extbase\Mvc\Cli\Command>
61 * @api
62 */
63 public function getAvailableCommands() {
64 if ($this->availableCommands === NULL) {
65 $this->availableCommands = array();
66 $commandControllerClassNames = is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers']) ? $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'] : array();
67 foreach ($commandControllerClassNames as $className) {
68 if (!class_exists($className)) {
69 continue;
70 }
71 foreach (get_class_methods($className) as $methodName) {
72 if (substr($methodName, -7, 7) === 'Command') {
73 $this->availableCommands[] = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Mvc\\Cli\\Command', $className, substr($methodName, 0, -7));
74 }
75 }
76 }
77 }
78 return $this->availableCommands;
79 }
80
81 /**
82 * Returns a Command that matches the given identifier.
83 * If no Command could be found a CommandNotFoundException is thrown
84 * If more than one Command matches an AmbiguousCommandIdentifierException is thrown that contains the matched Commands
85 *
86 * @param string $commandIdentifier command identifier in the format foo:bar:baz
87 * @return \TYPO3\CMS\Extbase\Mvc\Cli\Command
88 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException if no matching command is available
89 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\AmbiguousCommandIdentifierException if more than one Command matches the identifier (the exception contains the matched commands)
90 * @api
91 */
92 public function getCommandByIdentifier($commandIdentifier) {
93 $commandIdentifier = strtolower(trim($commandIdentifier));
94 if ($commandIdentifier === 'help') {
95 $commandIdentifier = 'extbase:help:help';
96 }
97 $matchedCommands = array();
98 $availableCommands = $this->getAvailableCommands();
99 foreach ($availableCommands as $command) {
100 if ($this->commandMatchesIdentifier($command, $commandIdentifier)) {
101 $matchedCommands[] = $command;
102 }
103 }
104 if (count($matchedCommands) === 0) {
105 throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException('No command could be found that matches the command identifier "' . $commandIdentifier . '".', 1310556663);
106 }
107 if (count($matchedCommands) > 1) {
108 throw new \TYPO3\CMS\Extbase\Mvc\Exception\AmbiguousCommandIdentifierException('More than one command matches the command identifier "' . $commandIdentifier . '"', 1310557169, NULL, $matchedCommands);
109 }
110 return current($matchedCommands);
111 }
112
113 /**
114 * Returns the shortest, non-ambiguous command identifier for the given command
115 *
116 * @param \TYPO3\CMS\Extbase\Mvc\Cli\Command $command The command
117 * @return string The shortest possible command identifier
118 * @api
119 */
120 public function getShortestIdentifierForCommand(\TYPO3\CMS\Extbase\Mvc\Cli\Command $command) {
121 if ($command->getCommandIdentifier() === 'extbase:help:help') {
122 return 'help';
123 }
124 $shortCommandIdentifiers = $this->getShortCommandIdentifiers();
125 if (!isset($shortCommandIdentifiers[$command->getCommandIdentifier()])) {
126 $command->getCommandIdentifier();
127 }
128 return $shortCommandIdentifiers[$command->getCommandIdentifier()];
129 }
130
131 /**
132 * Returns an array that contains all available command identifiers and their shortest non-ambiguous alias
133 *
134 * @return array in the format array('full.command:identifier1' => 'alias1', 'full.command:identifier2' => 'alias2')
135 */
136 protected function getShortCommandIdentifiers() {
137 if ($this->shortCommandIdentifiers === NULL) {
138 $commandsByCommandName = array();
139 foreach ($this->getAvailableCommands() as $availableCommand) {
140 list($extensionKey, $controllerName, $commandName) = explode(':', $availableCommand->getCommandIdentifier());
141 if (!isset($commandsByCommandName[$commandName])) {
142 $commandsByCommandName[$commandName] = array();
143 }
144 if (!isset($commandsByCommandName[$commandName][$controllerName])) {
145 $commandsByCommandName[$commandName][$controllerName] = array();
146 }
147 $commandsByCommandName[$commandName][$controllerName][] = $extensionKey;
148 }
149 foreach ($this->getAvailableCommands() as $availableCommand) {
150 list($extensionKey, $controllerName, $commandName) = explode(':', $availableCommand->getCommandIdentifier());
151 if (count($commandsByCommandName[$commandName][$controllerName]) > 1) {
152 $this->shortCommandIdentifiers[$availableCommand->getCommandIdentifier()] = sprintf('%s:%s:%s', $extensionKey, $controllerName, $commandName);
153 } else {
154 $this->shortCommandIdentifiers[$availableCommand->getCommandIdentifier()] = sprintf('%s:%s', $controllerName, $commandName);
155 }
156 }
157 }
158 return $this->shortCommandIdentifiers;
159 }
160
161 /**
162 * Returns TRUE if the specified command identifier matches the identifier of the specified command.
163 * This is the case, if the identifiers are the same or if at least the last two command parts match (case sensitive).
164 *
165 * @param \TYPO3\CMS\Extbase\Mvc\Cli\Command $command
166 * @param string $commandIdentifier command identifier in the format foo:bar:baz (all lower case)
167 * @return boolean TRUE if the specified command identifier matches this commands identifier
168 */
169 protected function commandMatchesIdentifier(\TYPO3\CMS\Extbase\Mvc\Cli\Command $command, $commandIdentifier) {
170 $commandIdentifierParts = explode(':', $command->getCommandIdentifier());
171 $searchedCommandIdentifierParts = explode(':', $commandIdentifier);
172 $extensionKey = array_shift($commandIdentifierParts);
173 if (count($searchedCommandIdentifierParts) === 3) {
174 $searchedExtensionKey = array_shift($searchedCommandIdentifierParts);
175 if ($searchedExtensionKey !== $extensionKey) {
176 return FALSE;
177 }
178 }
179 if (count($searchedCommandIdentifierParts) !== 2) {
180 return FALSE;
181 }
182 return $searchedCommandIdentifierParts === $commandIdentifierParts;
183 }
184 }
185
186 ?>