PageRenderTime 24ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/Front_End/vendor/symfony/console/Helper/ProgressIndicator.php

https://gitlab.com/Sigpot/AirSpot
PHP | 288 lines | 254 code | 17 blank | 17 comment | 7 complexity | bb156eb4191bcdee824f6279f83e37d3 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Console\Helper;
  11. use Symfony\Component\Console\Exception\InvalidArgumentException;
  12. use Symfony\Component\Console\Exception\LogicException;
  13. use Symfony\Component\Console\Output\OutputInterface;
  14. /**
  15. * @author Kevin Bond <kevinbond@gmail.com>
  16. */
  17. class ProgressIndicator
  18. {
  19. private $output;
  20. private $startTime;
  21. private $format;
  22. private $message;
  23. private $indicatorValues;
  24. private $indicatorCurrent;
  25. private $indicatorChangeInterval;
  26. private $indicatorUpdateTime;
  27. private $lastMessagesLength;
  28. private $started = false;
  29. private static $formatters;
  30. private static $formats;
  31. /**
  32. * @param OutputInterface $output
  33. * @param string|null $format Indicator format
  34. * @param int $indicatorChangeInterval Change interval in milliseconds
  35. * @param array|null $indicatorValues Animated indicator characters
  36. */
  37. public function __construct(OutputInterface $output, $format = null, $indicatorChangeInterval = 100, $indicatorValues = null)
  38. {
  39. $this->output = $output;
  40. if (null === $format) {
  41. $format = $this->determineBestFormat();
  42. }
  43. if (null === $indicatorValues) {
  44. $indicatorValues = array('-', '\\', '|', '/');
  45. }
  46. $indicatorValues = array_values($indicatorValues);
  47. if (2 > count($indicatorValues)) {
  48. throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
  49. }
  50. $this->format = self::getFormatDefinition($format);
  51. $this->indicatorChangeInterval = $indicatorChangeInterval;
  52. $this->indicatorValues = $indicatorValues;
  53. $this->startTime = time();
  54. }
  55. /**
  56. * Sets the current indicator message.
  57. *
  58. * @param string|null $message
  59. */
  60. public function setMessage($message)
  61. {
  62. $this->message = $message;
  63. $this->display();
  64. }
  65. /**
  66. * Starts the indicator output.
  67. *
  68. * @param $message
  69. */
  70. public function start($message)
  71. {
  72. if ($this->started) {
  73. throw new LogicException('Progress indicator already started.');
  74. }
  75. $this->message = $message;
  76. $this->started = true;
  77. $this->lastMessagesLength = 0;
  78. $this->startTime = time();
  79. $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
  80. $this->indicatorCurrent = 0;
  81. $this->display();
  82. }
  83. /**
  84. * Advances the indicator.
  85. */
  86. public function advance()
  87. {
  88. if (!$this->started) {
  89. throw new LogicException('Progress indicator has not yet been started.');
  90. }
  91. if (!$this->output->isDecorated()) {
  92. return;
  93. }
  94. $currentTime = $this->getCurrentTimeInMilliseconds();
  95. if ($currentTime < $this->indicatorUpdateTime) {
  96. return;
  97. }
  98. $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
  99. ++$this->indicatorCurrent;
  100. $this->display();
  101. }
  102. /**
  103. * Finish the indicator with message.
  104. *
  105. * @param $message
  106. */
  107. public function finish($message)
  108. {
  109. if (!$this->started) {
  110. throw new LogicException('Progress indicator has not yet been started.');
  111. }
  112. $this->message = $message;
  113. $this->display();
  114. $this->output->writeln('');
  115. $this->started = false;
  116. }
  117. /**
  118. * Gets the format for a given name.
  119. *
  120. * @param string $name The format name
  121. *
  122. * @return string|null A format string
  123. */
  124. public static function getFormatDefinition($name)
  125. {
  126. if (!self::$formats) {
  127. self::$formats = self::initFormats();
  128. }
  129. return isset(self::$formats[$name]) ? self::$formats[$name] : null;
  130. }
  131. /**
  132. * Sets a placeholder formatter for a given name.
  133. *
  134. * This method also allow you to override an existing placeholder.
  135. *
  136. * @param string $name The placeholder name (including the delimiter char like %)
  137. * @param callable $callable A PHP callable
  138. */
  139. public static function setPlaceholderFormatterDefinition($name, $callable)
  140. {
  141. if (!self::$formatters) {
  142. self::$formatters = self::initPlaceholderFormatters();
  143. }
  144. self::$formatters[$name] = $callable;
  145. }
  146. /**
  147. * Gets the placeholder formatter for a given name.
  148. *
  149. * @param string $name The placeholder name (including the delimiter char like %)
  150. *
  151. * @return callable|null A PHP callable
  152. */
  153. public static function getPlaceholderFormatterDefinition($name)
  154. {
  155. if (!self::$formatters) {
  156. self::$formatters = self::initPlaceholderFormatters();
  157. }
  158. return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
  159. }
  160. private function display()
  161. {
  162. if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
  163. return;
  164. }
  165. $self = $this;
  166. $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
  167. if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
  168. return call_user_func($formatter, $self);
  169. }
  170. return $matches[0];
  171. }, $this->format));
  172. }
  173. private function determineBestFormat()
  174. {
  175. switch ($this->output->getVerbosity()) {
  176. // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
  177. case OutputInterface::VERBOSITY_VERBOSE:
  178. return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
  179. case OutputInterface::VERBOSITY_VERY_VERBOSE:
  180. case OutputInterface::VERBOSITY_DEBUG:
  181. return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
  182. default:
  183. return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
  184. }
  185. }
  186. /**
  187. * Overwrites a previous message to the output.
  188. *
  189. * @param string $message The message
  190. */
  191. private function overwrite($message)
  192. {
  193. // append whitespace to match the line's length
  194. if (null !== $this->lastMessagesLength) {
  195. if ($this->lastMessagesLength > Helper::strlenWithoutDecoration($this->output->getFormatter(), $message)) {
  196. $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
  197. }
  198. }
  199. if ($this->output->isDecorated()) {
  200. $this->output->write("\x0D");
  201. $this->output->write($message);
  202. } else {
  203. $this->output->writeln($message);
  204. }
  205. $this->lastMessagesLength = 0;
  206. $len = Helper::strlenWithoutDecoration($this->output->getFormatter(), $message);
  207. if ($len > $this->lastMessagesLength) {
  208. $this->lastMessagesLength = $len;
  209. }
  210. }
  211. private function getCurrentTimeInMilliseconds()
  212. {
  213. return round(microtime(true) * 1000);
  214. }
  215. private static function initPlaceholderFormatters()
  216. {
  217. return array(
  218. 'indicator' => function (ProgressIndicator $indicator) {
  219. return $indicator->indicatorValues[$indicator->indicatorCurrent % count($indicator->indicatorValues)];
  220. },
  221. 'message' => function (ProgressIndicator $indicator) {
  222. return $indicator->message;
  223. },
  224. 'elapsed' => function (ProgressIndicator $indicator) {
  225. return Helper::formatTime(time() - $indicator->startTime);
  226. },
  227. 'memory' => function () {
  228. return Helper::formatMemory(memory_get_usage(true));
  229. },
  230. );
  231. }
  232. private static function initFormats()
  233. {
  234. return array(
  235. 'normal' => ' %indicator% %message%',
  236. 'normal_no_ansi' => ' %message%',
  237. 'verbose' => ' %indicator% %message% (%elapsed:6s%)',
  238. 'verbose_no_ansi' => ' %message% (%elapsed:6s%)',
  239. 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)',
  240. 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
  241. );
  242. }
  243. }