/caspar/core/CliCommand.class.php

https://github.com/zegenie/caspar · PHP · 260 lines · 195 code · 45 blank · 20 comment · 25 complexity · 40b93ee2390275c78757a94d8e31812f MD5 · raw file

  1. <?php
  2. namespace caspar\core;
  3. /**
  4. * CLI command class
  5. *
  6. * @author Daniel Andre Eikeland <zegenie@gmail.com>
  7. * @version 1.0
  8. * @license http://www.opensource.org/licenses/mozilla1.1.php Mozilla Public License 1.1 (MPL 1.1)
  9. * @package caspar
  10. * @subpackage core
  11. */
  12. /**
  13. * CLI command class
  14. *
  15. * @package caspar
  16. * @subpackage core
  17. */
  18. abstract class CliCommand
  19. {
  20. protected static $_available_commands = null;
  21. protected static $_provided_arguments = null;
  22. protected static $_named_arguments = array();
  23. protected $_command_name = null;
  24. protected $_description = '';
  25. protected $_required_arguments = array();
  26. protected $_optional_arguments = array();
  27. protected $_namespace = null;
  28. abstract protected function do_execute();
  29. final public function __construct($namespace = null)
  30. {
  31. $this->_namespace = $namespace;
  32. $this->_setup();
  33. }
  34. final public function execute()
  35. {
  36. $this->_processArguments();
  37. $this->_prepare();
  38. $this->do_execute();
  39. }
  40. /**
  41. * Return the associated namespace for this command, this will likely correlate to a module
  42. *
  43. * @return string
  44. */
  45. final protected function getNamespace()
  46. {
  47. return $this->_namespace;
  48. }
  49. public function getDescription()
  50. {
  51. return $this->_description;
  52. }
  53. public static function setAvailableCommands($available_commands)
  54. {
  55. if (self::$_available_commands !== null)
  56. {
  57. throw new \Exception('You cannot change available commands');
  58. }
  59. self::$_available_commands = $available_commands;
  60. }
  61. public static function getAvailableCommands()
  62. {
  63. return self::$_available_commands;
  64. }
  65. public static function processArguments()
  66. {
  67. if (self::$_provided_arguments == null)
  68. {
  69. self::$_provided_arguments = array();
  70. foreach ($GLOBALS['argv'] as $cc => $argument)
  71. {
  72. self::$_provided_arguments[$cc] = $argument;
  73. $argument_parts = explode('=', $argument, 2);
  74. if (count($argument_parts) == 2)
  75. {
  76. $key = mb_substr($argument_parts[0], 2);
  77. self::$_provided_arguments[$key] = $argument_parts[1];
  78. if (!is_numeric($key))
  79. {
  80. self::$_named_arguments[$key] = $argument_parts[1];
  81. }
  82. }
  83. }
  84. }
  85. }
  86. protected function _setup() { }
  87. final protected function _processArguments()
  88. {
  89. $cc = 1;
  90. foreach ($this->_required_arguments as $key => $argument)
  91. {
  92. $cc++;
  93. if ($this->hasProvidedArgument($key)) continue;
  94. if ($this->hasProvidedArgument($cc))
  95. {
  96. if (mb_substr(self::$_provided_arguments[$cc], 0, 2) == '--' && mb_substr(self::$_provided_arguments[$cc], 2, mb_strpos(self::$_provided_arguments[$cc], '=') - 1) != $key) continue;
  97. self::$_provided_arguments[$key] = self::$_provided_arguments[$cc];
  98. if (!is_numeric($key))
  99. {
  100. self::$_named_arguments[$key] = self::$_provided_arguments[$cc];
  101. }
  102. continue;
  103. }
  104. }
  105. foreach (self::$_provided_arguments as $key => $value)
  106. {
  107. $this->$key = $value;
  108. }
  109. $diff = array_diff(array_keys($this->_required_arguments), array_keys(self::$_named_arguments));
  110. if (count($diff))
  111. {
  112. throw new \Exception('Please include all required arguments. Missing arguments: '.join(', ', $diff));
  113. }
  114. foreach ($this->_optional_arguments as $key => $argument)
  115. {
  116. $cc++;
  117. if ($this->hasProvidedArgument($key)) continue;
  118. if ($this->hasProvidedArgument($cc))
  119. {
  120. if (mb_substr(self::$_provided_arguments[$cc], 0, 2) == '--' && mb_substr(self::$_provided_arguments[$cc], 2, mb_strpos(self::$_provided_arguments[$cc], '=') - 1) != $key) continue;
  121. self::$_provided_arguments[$key] = self::$_provided_arguments[$cc];
  122. if (!is_numeric($key))
  123. {
  124. self::$_named_arguments[$key] = self::$_provided_arguments[$cc];
  125. }
  126. continue;
  127. }
  128. }
  129. }
  130. protected function _prepare() { }
  131. public function getCommandName()
  132. {
  133. return $this->_command_name;
  134. }
  135. public function getProvidedArgument($key, $default_value = null)
  136. {
  137. return (array_key_exists($key, self::$_provided_arguments)) ? self::$_provided_arguments[$key] : $default_value;
  138. }
  139. public function hasProvidedArgument($key)
  140. {
  141. return array_key_exists($key, self::$_provided_arguments);
  142. }
  143. protected function addRequiredArgument($argument, $description = null)
  144. {
  145. $this->_required_arguments[$argument] = $description;
  146. }
  147. public function getRequiredArguments()
  148. {
  149. return $this->_required_arguments;
  150. }
  151. protected function addOptionalArgument($argument, $description = null)
  152. {
  153. $this->_optional_arguments[$argument] = $description;
  154. }
  155. public function getOptionalArguments()
  156. {
  157. return $this->_optional_arguments;
  158. }
  159. public function getProvidedArguments()
  160. {
  161. return self::$_provided_arguments;
  162. }
  163. public function getNamedArguments()
  164. {
  165. return self::$_named_arguments;
  166. }
  167. public static function getCommandLineName()
  168. {
  169. return $GLOBALS['argv'][0];
  170. }
  171. public function getCommandAliases()
  172. {
  173. return array();
  174. }
  175. protected function _getCliInput()
  176. {
  177. return trim(fgets(STDIN));
  178. }
  179. public function getInputConfirmation()
  180. {
  181. $retval = $this->_getCliInput();
  182. return (bool) (mb_strtolower(trim($retval)) == 'yes');
  183. }
  184. public function askToAccept()
  185. {
  186. return $this->getInputConfirmation();
  187. }
  188. public function askToDecline()
  189. {
  190. $retval = $this->_getCliInput();
  191. return !(bool) (mb_strtolower(trim($retval)) == 'no');
  192. }
  193. public function getInput($default = '')
  194. {
  195. $retval = $this->_getCliInput();
  196. return ($retval == '') ? $default : $retval;
  197. }
  198. public function pressEnterToContinue()
  199. {
  200. fgets(STDIN);
  201. }
  202. public static function cli_echo($text, $color = 'white', $style = null)
  203. {
  204. $fg_colors = array('black' => 29, 'red' => 31, 'green' => 32, 'yellow' => 33, 'blue' => 34, 'magenta' => 35, 'cyan' => 36, 'white' => 37);
  205. $op_format = array('bold' => 1, 'underline' => 4, 'blink' => 5, 'reverse' => 7, 'conceal' => 8);
  206. $return_text = "\033[" . $fg_colors[$color];
  207. $return_text .= ($style !== null && array_key_exists($style, $op_format)) ? ";" . $op_format[$style] : '';
  208. $return_text .= "m" . $text . "\033[0m";
  209. echo $return_text;
  210. }
  211. public function cliEcho($text, $color = 'white', $style = null)
  212. {
  213. self::cli_echo($text, $color, $style);
  214. }
  215. }