PluginProbe
Depicter — Popup & Slider Builder / 1.3.2
Depicter — Popup & Slider Builder v1.3.2
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / vendor / symfony / console / Helper / ProgressIndicator.php

ProgressIndicator.php in Depicter — Popup & Slider Builder 1.3.2, at vendor/symfony/console/Helper/ProgressIndicator.php

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