PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/Classes/TYPO3/FLOW3/Cli/Command.php

https://github.com/christianjul/FLOW3-Composer
PHP | 217 lines | 170 code | 11 blank | 36 comment | 1 complexity | 7e1332200b7e8da35c508292ebef0778 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-3.0
  1. <?php
  2. namespace TYPO3\FLOW3\Cli;
  3. /* *
  4. * This script belongs to the FLOW3 framework. *
  5. * *
  6. * It is free software; you can redistribute it and/or modify it under *
  7. * the terms of the GNU Lesser General Public License, either version 3 *
  8. * of the License, or (at your option) any later version. *
  9. * *
  10. * The TYPO3 project - inspiring people to share! *
  11. * */
  12. use TYPO3\FLOW3\Annotations as FLOW3;
  13. /**
  14. * Represents a Command
  15. *
  16. */
  17. class Command {
  18. /**
  19. * @var string
  20. */
  21. protected $controllerClassName;
  22. /**
  23. * @var string
  24. */
  25. protected $controllerCommandName;
  26. /**
  27. * @var string
  28. */
  29. protected $commandIdentifier;
  30. /**
  31. * @var \TYPO3\FLOW3\Reflection\MethodReflection
  32. */
  33. protected $commandMethodReflection;
  34. /**
  35. * Reflection service
  36. * @var \TYPO3\FLOW3\Reflection\ReflectionService
  37. */
  38. private $reflectionService;
  39. /**
  40. * Constructor
  41. *
  42. * @param string $controllerClassName Class name of the controller providing the command
  43. * @param string $controllerCommandName Command name, i.e. the method name of the command, without the "Command" suffix
  44. * @throws \InvalidArgumentException
  45. */
  46. public function __construct($controllerClassName, $controllerCommandName) {
  47. $this->controllerClassName = $controllerClassName;
  48. $this->controllerCommandName = $controllerCommandName;
  49. $matchCount = preg_match('/^(?P<PackageNamespace>\w+(?:\\\\\w+)*)\\\\Command\\\\(?P<ControllerName>\w+)CommandController$/', $controllerClassName, $matches);
  50. if ($matchCount !== 1) {
  51. throw new \InvalidArgumentException('Invalid controller class name "' . $controllerClassName . '". Make sure your controller is in a folder named "Command" and it\'s name ends in "CommandController"', 1305100019);
  52. }
  53. $this->commandIdentifier = strtolower(str_replace('\\', '.', $matches['PackageNamespace']) . ':' . $matches['ControllerName'] . ':' . $controllerCommandName);
  54. }
  55. /**
  56. * @param \TYPO3\FLOW3\Reflection\ReflectionService $reflectionService Reflection service
  57. */
  58. public function injectReflectionService(\TYPO3\FLOW3\Reflection\ReflectionService $reflectionService) {
  59. $this->reflectionService = $reflectionService;
  60. }
  61. /**
  62. * @return string
  63. */
  64. public function getControllerClassName() {
  65. return $this->controllerClassName;
  66. }
  67. /**
  68. * @return string
  69. */
  70. public function getControllerCommandName() {
  71. return $this->controllerCommandName;
  72. }
  73. /**
  74. * Returns the command identifier for this command
  75. *
  76. * @return string The command identifier for this command, following the pattern packagekey:controllername:commandname
  77. */
  78. public function getCommandIdentifier() {
  79. return $this->commandIdentifier;
  80. }
  81. /**
  82. * Returns a short description of this command
  83. *
  84. * @return string A short description
  85. */
  86. public function getShortDescription() {
  87. $lines = explode(chr(10), $this->getCommandMethodReflection()->getDescription());
  88. return (count($lines) > 0) ? trim($lines[0]) : '<no description available>';
  89. }
  90. /**
  91. * Returns a longer description of this command
  92. * This is the complete method description except for the first line which can be retrieved via getShortDescription()
  93. * If The command description only consists of one line, an empty string is returned
  94. *
  95. * @return string A longer description of this command
  96. */
  97. public function getDescription() {
  98. $lines = explode(chr(10), $this->getCommandMethodReflection()->getDescription());
  99. array_shift($lines);
  100. $descriptionLines = array();
  101. foreach ($lines as $line) {
  102. $trimmedLine = trim($line);
  103. if ($descriptionLines !== array() || $trimmedLine !== '') {
  104. $descriptionLines[] = $trimmedLine;
  105. }
  106. }
  107. return implode(chr(10), $descriptionLines);
  108. }
  109. /**
  110. * Returns TRUE if this command expects required and/or optional arguments, otherwise FALSE
  111. *
  112. * @return boolean
  113. */
  114. public function hasArguments() {
  115. return count($this->getCommandMethodReflection()->getParameters()) > 0;
  116. }
  117. /**
  118. * Returns an array of \TYPO3\FLOW3\Cli\CommandArgumentDefinition that contains
  119. * information about required/optional arguments of this command.
  120. * If the command does not expect any arguments, an empty array is returned
  121. *
  122. * @return array<\TYPO3\FLOW3\Cli\CommandArgumentDefinition>
  123. */
  124. public function getArgumentDefinitions() {
  125. if (!$this->hasArguments()) {
  126. return array();
  127. }
  128. $commandArgumentDefinitions = array();
  129. $commandMethodReflection = $this->getCommandMethodReflection();
  130. $annotations = $commandMethodReflection->getTagsValues();
  131. $commandParameters = $this->reflectionService->getMethodParameters($this->controllerClassName, $this->controllerCommandName . 'Command');
  132. $i = 0;
  133. foreach ($commandParameters as $commandParameterName => $commandParameterDefinition) {
  134. $explodedAnnotation = explode(' ', $annotations['param'][$i]);
  135. array_shift($explodedAnnotation);
  136. array_shift($explodedAnnotation);
  137. $description = implode(' ', $explodedAnnotation);
  138. $required = $commandParameterDefinition['optional'] !== TRUE;
  139. $commandArgumentDefinitions[] = new CommandArgumentDefinition($commandParameterName, $required, $description);
  140. $i ++;
  141. }
  142. return $commandArgumentDefinitions;
  143. }
  144. /**
  145. * Tells if this command is internal and thus should not be exposed through help texts, user documentation etc.
  146. * Internal commands are still accessible through the regular command line interface, but should not be used
  147. * by users.
  148. *
  149. * @return boolean
  150. */
  151. public function isInternal() {
  152. return $this->getCommandMethodReflection()->isTaggedWith('internal');
  153. }
  154. /**
  155. * Tells if this command flushes all caches and thus needs special attention in the interactive shell.
  156. *
  157. * Note that neither this method nor the @FLOW3\FlushesCaches annotation is currently part of the official API.
  158. *
  159. * @return boolean
  160. */
  161. public function isFlushingCaches() {
  162. return $this->getCommandMethodReflection()->isTaggedWith('flushescaches');
  163. }
  164. /**
  165. * Returns an array of command identifiers which were specified in the "@see"
  166. * annotation of a command method.
  167. *
  168. * @return array
  169. */
  170. public function getRelatedCommandIdentifiers() {
  171. $commandMethodReflection = $this->getCommandMethodReflection();
  172. if (!$commandMethodReflection->isTaggedWith('see')) {
  173. return array();
  174. }
  175. $relatedCommandIdentifiers = array();
  176. foreach ($commandMethodReflection->getTagValues('see') as $tagValue) {
  177. if (preg_match('/^[\w\d\.]+:[\w\d]+:[\w\d]+$/', $tagValue) === 1) {
  178. $relatedCommandIdentifiers[] = $tagValue;
  179. }
  180. }
  181. return $relatedCommandIdentifiers;
  182. }
  183. /**
  184. * @return \TYPO3\FLOW3\Reflection\MethodReflection
  185. */
  186. protected function getCommandMethodReflection() {
  187. if ($this->commandMethodReflection === NULL) {
  188. $this->commandMethodReflection = new \TYPO3\FLOW3\Reflection\MethodReflection($this->controllerClassName, $this->controllerCommandName . 'Command');
  189. }
  190. return $this->commandMethodReflection;
  191. }
  192. }
  193. ?>