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