[TASK] Use fully qualified name resolution in PHP 5.5
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Cli / CommandManager.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 * A helper for CLI commands
18 *
19 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
20 */
21 class CommandManager implements \TYPO3\CMS\Core\SingletonInterface {
22
23 /**
24 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
25 * @inject
26 */
27 protected $objectManager;
28
29 /**
30 * @var array<\TYPO3\CMS\Extbase\Mvc\Cli\Command>
31 */
32 protected $availableCommands = NULL;
33
34 /**
35 * @var array
36 */
37 protected $shortCommandIdentifiers = NULL;
38
39 /**
40 * Returns an array of all commands
41 *
42 * @return Command[]
43 * @api
44 */
45 public function getAvailableCommands() {
46 if ($this->availableCommands === NULL) {
47 $this->availableCommands = array();
48 $commandControllerClassNames = is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers']) ? $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'] : array();
49 foreach ($commandControllerClassNames as $className) {
50 if (!class_exists($className)) {
51 continue;
52 }
53 foreach (get_class_methods($className) as $methodName) {
54 if (substr($methodName, -7, 7) === 'Command') {
55 $this->availableCommands[] = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\Cli\Command::class, $className, substr($methodName, 0, -7));
56 }
57 }
58 }
59 }
60 return $this->availableCommands;
61 }
62
63 /**
64 * Returns a Command that matches the given identifier.
65 * If no Command could be found a CommandNotFoundException is thrown
66 * If more than one Command matches an AmbiguousCommandIdentifierException is thrown that contains the matched Commands
67 *
68 * @param string $commandIdentifier command identifier in the format foo:bar:baz
69 * @return Command
70 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException if no matching command is available
71 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\AmbiguousCommandIdentifierException if more than one Command matches the identifier (the exception contains the matched commands)
72 * @api
73 */
74 public function getCommandByIdentifier($commandIdentifier) {
75 $commandIdentifier = strtolower(trim($commandIdentifier));
76 if ($commandIdentifier === 'help') {
77 $commandIdentifier = 'extbase:help:help';
78 }
79 $matchedCommands = array();
80 $availableCommands = $this->getAvailableCommands();
81 foreach ($availableCommands as $command) {
82 if ($this->commandMatchesIdentifier($command, $commandIdentifier)) {
83 $matchedCommands[] = $command;
84 }
85 }
86 if (count($matchedCommands) === 0) {
87 throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchCommandException('No command could be found that matches the command identifier "' . $commandIdentifier . '".', 1310556663);
88 }
89 if (count($matchedCommands) > 1) {
90 throw new \TYPO3\CMS\Extbase\Mvc\Exception\AmbiguousCommandIdentifierException('More than one command matches the command identifier "' . $commandIdentifier . '"', 1310557169, NULL, $matchedCommands);
91 }
92 return current($matchedCommands);
93 }
94
95 /**
96 * Returns the shortest, non-ambiguous command identifier for the given command
97 *
98 * @param Command $command The command
99 * @return string The shortest possible command identifier
100 * @api
101 */
102 public function getShortestIdentifierForCommand(Command $command) {
103 if ($command->getCommandIdentifier() === 'extbase:help:help') {
104 return 'help';
105 }
106 $shortCommandIdentifiers = $this->getShortCommandIdentifiers();
107 if (!isset($shortCommandIdentifiers[$command->getCommandIdentifier()])) {
108 $command->getCommandIdentifier();
109 }
110 return $shortCommandIdentifiers[$command->getCommandIdentifier()];
111 }
112
113 /**
114 * Returns an array that contains all available command identifiers and their shortest non-ambiguous alias
115 *
116 * @return array in the format array('full.command:identifier1' => 'alias1', 'full.command:identifier2' => 'alias2')
117 */
118 protected function getShortCommandIdentifiers() {
119 if ($this->shortCommandIdentifiers === NULL) {
120 $commandsByCommandName = array();
121 foreach ($this->getAvailableCommands() as $availableCommand) {
122 list($extensionKey, $controllerName, $commandName) = explode(':', $availableCommand->getCommandIdentifier());
123 if (!isset($commandsByCommandName[$commandName])) {
124 $commandsByCommandName[$commandName] = array();
125 }
126 if (!isset($commandsByCommandName[$commandName][$controllerName])) {
127 $commandsByCommandName[$commandName][$controllerName] = array();
128 }
129 $commandsByCommandName[$commandName][$controllerName][] = $extensionKey;
130 }
131 foreach ($this->getAvailableCommands() as $availableCommand) {
132 list($extensionKey, $controllerName, $commandName) = explode(':', $availableCommand->getCommandIdentifier());
133 if (count($commandsByCommandName[$commandName][$controllerName]) > 1) {
134 $this->shortCommandIdentifiers[$availableCommand->getCommandIdentifier()] = sprintf('%s:%s:%s', $extensionKey, $controllerName, $commandName);
135 } else {
136 $this->shortCommandIdentifiers[$availableCommand->getCommandIdentifier()] = sprintf('%s:%s', $controllerName, $commandName);
137 }
138 }
139 }
140 return $this->shortCommandIdentifiers;
141 }
142
143 /**
144 * Returns TRUE if the specified command identifier matches the identifier of the specified command.
145 * This is the case, if the identifiers are the same or if at least the last two command parts match (case sensitive).
146 *
147 * @param Command $command
148 * @param string $commandIdentifier command identifier in the format foo:bar:baz (all lower case)
149 * @return bool TRUE if the specified command identifier matches this commands identifier
150 */
151 protected function commandMatchesIdentifier(Command $command, $commandIdentifier) {
152 $commandIdentifierParts = explode(':', $command->getCommandIdentifier());
153 $searchedCommandIdentifierParts = explode(':', $commandIdentifier);
154 $extensionKey = array_shift($commandIdentifierParts);
155 if (count($searchedCommandIdentifierParts) === 3) {
156 $searchedExtensionKey = array_shift($searchedCommandIdentifierParts);
157 if ($searchedExtensionKey !== $extensionKey) {
158 return FALSE;
159 }
160 }
161 if (count($searchedCommandIdentifierParts) !== 2) {
162 return FALSE;
163 }
164 return $searchedCommandIdentifierParts === $commandIdentifierParts;
165 }
166 }