[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
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\LogicException; 15 use Symfony\Component\Console\Output\ConsoleOutputInterface; 16 use Symfony\Component\Console\Output\OutputInterface; 17 18 /** 19 * The ProgressBar provides helpers to display progress output. 20 * 21 * @author Fabien Potencier <fabien@symfony.com> 22 * @author Chris Jones <leeked@gmail.com> 23 */ 24 class ProgressBar 25 { 26 private $barWidth = 28; 27 private $barChar; 28 private $emptyBarChar = '-'; 29 private $progressChar = '>'; 30 private $format; 31 private $internalFormat; 32 private $redrawFreq = 1; 33 private $output; 34 private $step = 0; 35 private $max; 36 private $startTime; 37 private $stepWidth; 38 private $percent = 0.0; 39 private $formatLineCount; 40 private $messages = array(); 41 private $overwrite = true; 42 private $firstRun = true; 43 44 private static $formatters; 45 private static $formats; 46 47 /** 48 * @param OutputInterface $output An OutputInterface instance 49 * @param int $max Maximum steps (0 if unknown) 50 */ 51 public function __construct(OutputInterface $output, $max = 0) 52 { 53 if ($output instanceof ConsoleOutputInterface) { 54 $output = $output->getErrorOutput(); 55 } 56 57 $this->output = $output; 58 $this->setMaxSteps($max); 59 60 if (!$this->output->isDecorated()) { 61 // disable overwrite when output does not support ANSI codes. 62 $this->overwrite = false; 63 64 // set a reasonable redraw frequency so output isn't flooded 65 $this->setRedrawFrequency($max / 10); 66 } 67 68 $this->startTime = time(); 69 } 70 71 /** 72 * Sets a placeholder formatter for a given name. 73 * 74 * This method also allow you to override an existing placeholder. 75 * 76 * @param string $name The placeholder name (including the delimiter char like %) 77 * @param callable $callable A PHP callable 78 */ 79 public static function setPlaceholderFormatterDefinition($name, $callable) 80 { 81 if (!self::$formatters) { 82 self::$formatters = self::initPlaceholderFormatters(); 83 } 84 85 self::$formatters[$name] = $callable; 86 } 87 88 /** 89 * Gets the placeholder formatter for a given name. 90 * 91 * @param string $name The placeholder name (including the delimiter char like %) 92 * 93 * @return callable|null A PHP callable 94 */ 95 public static function getPlaceholderFormatterDefinition($name) 96 { 97 if (!self::$formatters) { 98 self::$formatters = self::initPlaceholderFormatters(); 99 } 100 101 return isset(self::$formatters[$name]) ? self::$formatters[$name] : null; 102 } 103 104 /** 105 * Sets a format for a given name. 106 * 107 * This method also allow you to override an existing format. 108 * 109 * @param string $name The format name 110 * @param string $format A format string 111 */ 112 public static function setFormatDefinition($name, $format) 113 { 114 if (!self::$formats) { 115 self::$formats = self::initFormats(); 116 } 117 118 self::$formats[$name] = $format; 119 } 120 121 /** 122 * Gets the format for a given name. 123 * 124 * @param string $name The format name 125 * 126 * @return string|null A format string 127 */ 128 public static function getFormatDefinition($name) 129 { 130 if (!self::$formats) { 131 self::$formats = self::initFormats(); 132 } 133 134 return isset(self::$formats[$name]) ? self::$formats[$name] : null; 135 } 136 137 /** 138 * Associates a text with a named placeholder. 139 * 140 * The text is displayed when the progress bar is rendered but only 141 * when the corresponding placeholder is part of the custom format line 142 * (by wrapping the name with %). 143 * 144 * @param string $message The text to associate with the placeholder 145 * @param string $name The name of the placeholder 146 */ 147 public function setMessage($message, $name = 'message') 148 { 149 $this->messages[$name] = $message; 150 } 151 152 public function getMessage($name = 'message') 153 { 154 return $this->messages[$name]; 155 } 156 157 /** 158 * Gets the progress bar start time. 159 * 160 * @return int The progress bar start time 161 */ 162 public function getStartTime() 163 { 164 return $this->startTime; 165 } 166 167 /** 168 * Gets the progress bar maximal steps. 169 * 170 * @return int The progress bar max steps 171 */ 172 public function getMaxSteps() 173 { 174 return $this->max; 175 } 176 177 /** 178 * Gets the progress bar step. 179 * 180 * @deprecated since version 2.6, to be removed in 3.0. Use {@link getProgress()} instead. 181 * 182 * @return int The progress bar step 183 */ 184 public function getStep() 185 { 186 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the getProgress() method instead.', E_USER_DEPRECATED); 187 188 return $this->getProgress(); 189 } 190 191 /** 192 * Gets the current step position. 193 * 194 * @return int The progress bar step 195 */ 196 public function getProgress() 197 { 198 return $this->step; 199 } 200 201 /** 202 * Gets the progress bar step width. 203 * 204 * @internal This method is public for PHP 5.3 compatibility, it should not be used. 205 * 206 * @return int The progress bar step width 207 */ 208 public function getStepWidth() 209 { 210 return $this->stepWidth; 211 } 212 213 /** 214 * Gets the current progress bar percent. 215 * 216 * @return float The current progress bar percent 217 */ 218 public function getProgressPercent() 219 { 220 return $this->percent; 221 } 222 223 /** 224 * Sets the progress bar width. 225 * 226 * @param int $size The progress bar size 227 */ 228 public function setBarWidth($size) 229 { 230 $this->barWidth = (int) $size; 231 } 232 233 /** 234 * Gets the progress bar width. 235 * 236 * @return int The progress bar size 237 */ 238 public function getBarWidth() 239 { 240 return $this->barWidth; 241 } 242 243 /** 244 * Sets the bar character. 245 * 246 * @param string $char A character 247 */ 248 public function setBarCharacter($char) 249 { 250 $this->barChar = $char; 251 } 252 253 /** 254 * Gets the bar character. 255 * 256 * @return string A character 257 */ 258 public function getBarCharacter() 259 { 260 if (null === $this->barChar) { 261 return $this->max ? '=' : $this->emptyBarChar; 262 } 263 264 return $this->barChar; 265 } 266 267 /** 268 * Sets the empty bar character. 269 * 270 * @param string $char A character 271 */ 272 public function setEmptyBarCharacter($char) 273 { 274 $this->emptyBarChar = $char; 275 } 276 277 /** 278 * Gets the empty bar character. 279 * 280 * @return string A character 281 */ 282 public function getEmptyBarCharacter() 283 { 284 return $this->emptyBarChar; 285 } 286 287 /** 288 * Sets the progress bar character. 289 * 290 * @param string $char A character 291 */ 292 public function setProgressCharacter($char) 293 { 294 $this->progressChar = $char; 295 } 296 297 /** 298 * Gets the progress bar character. 299 * 300 * @return string A character 301 */ 302 public function getProgressCharacter() 303 { 304 return $this->progressChar; 305 } 306 307 /** 308 * Sets the progress bar format. 309 * 310 * @param string $format The format 311 */ 312 public function setFormat($format) 313 { 314 $this->format = null; 315 $this->internalFormat = $format; 316 } 317 318 /** 319 * Sets the redraw frequency. 320 * 321 * @param int|float $freq The frequency in steps 322 */ 323 public function setRedrawFrequency($freq) 324 { 325 $this->redrawFreq = max((int) $freq, 1); 326 } 327 328 /** 329 * Starts the progress output. 330 * 331 * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged 332 */ 333 public function start($max = null) 334 { 335 $this->startTime = time(); 336 $this->step = 0; 337 $this->percent = 0.0; 338 339 if (null !== $max) { 340 $this->setMaxSteps($max); 341 } 342 343 $this->display(); 344 } 345 346 /** 347 * Advances the progress output X steps. 348 * 349 * @param int $step Number of steps to advance 350 * 351 * @throws LogicException 352 */ 353 public function advance($step = 1) 354 { 355 $this->setProgress($this->step + $step); 356 } 357 358 /** 359 * Sets the current progress. 360 * 361 * @deprecated since version 2.6, to be removed in 3.0. Use {@link setProgress()} instead. 362 * 363 * @param int $step The current progress 364 * 365 * @throws LogicException 366 */ 367 public function setCurrent($step) 368 { 369 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the setProgress() method instead.', E_USER_DEPRECATED); 370 371 $this->setProgress($step); 372 } 373 374 /** 375 * Sets whether to overwrite the progressbar, false for new line. 376 * 377 * @param bool $overwrite 378 */ 379 public function setOverwrite($overwrite) 380 { 381 $this->overwrite = (bool) $overwrite; 382 } 383 384 /** 385 * Sets the current progress. 386 * 387 * @param int $step The current progress 388 * 389 * @throws LogicException 390 */ 391 public function setProgress($step) 392 { 393 $step = (int) $step; 394 if ($step < $this->step) { 395 throw new LogicException('You can\'t regress the progress bar.'); 396 } 397 398 if ($this->max && $step > $this->max) { 399 $this->max = $step; 400 } 401 402 $prevPeriod = (int) ($this->step / $this->redrawFreq); 403 $currPeriod = (int) ($step / $this->redrawFreq); 404 $this->step = $step; 405 $this->percent = $this->max ? (float) $this->step / $this->max : 0; 406 if ($prevPeriod !== $currPeriod || $this->max === $step) { 407 $this->display(); 408 } 409 } 410 411 /** 412 * Finishes the progress output. 413 */ 414 public function finish() 415 { 416 if (!$this->max) { 417 $this->max = $this->step; 418 } 419 420 if ($this->step === $this->max && !$this->overwrite) { 421 // prevent double 100% output 422 return; 423 } 424 425 $this->setProgress($this->max); 426 } 427 428 /** 429 * Outputs the current progress string. 430 */ 431 public function display() 432 { 433 if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { 434 return; 435 } 436 437 if (null === $this->format) { 438 $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); 439 } 440 441 // these 3 variables can be removed in favor of using $this in the closure when support for PHP 5.3 will be dropped. 442 $self = $this; 443 $output = $this->output; 444 $messages = $this->messages; 445 $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self, $output, $messages) { 446 if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) { 447 $text = \call_user_func($formatter, $self, $output); 448 } elseif (isset($messages[$matches[1]])) { 449 $text = $messages[$matches[1]]; 450 } else { 451 return $matches[0]; 452 } 453 454 if (isset($matches[2])) { 455 $text = sprintf('%'.$matches[2], $text); 456 } 457 458 return $text; 459 }, $this->format)); 460 } 461 462 /** 463 * Removes the progress bar from the current line. 464 * 465 * This is useful if you wish to write some output 466 * while a progress bar is running. 467 * Call display() to show the progress bar again. 468 */ 469 public function clear() 470 { 471 if (!$this->overwrite) { 472 return; 473 } 474 475 if (null === $this->format) { 476 $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); 477 } 478 479 $this->overwrite(''); 480 } 481 482 /** 483 * Sets the progress bar format. 484 * 485 * @param string $format The format 486 */ 487 private function setRealFormat($format) 488 { 489 // try to use the _nomax variant if available 490 if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) { 491 $this->format = self::getFormatDefinition($format.'_nomax'); 492 } elseif (null !== self::getFormatDefinition($format)) { 493 $this->format = self::getFormatDefinition($format); 494 } else { 495 $this->format = $format; 496 } 497 498 $this->formatLineCount = substr_count($this->format, "\n"); 499 } 500 501 /** 502 * Sets the progress bar maximal steps. 503 * 504 * @param int $max The progress bar max steps 505 */ 506 private function setMaxSteps($max) 507 { 508 $this->max = max(0, (int) $max); 509 $this->stepWidth = $this->max ? Helper::strlen($this->max) : 4; 510 } 511 512 /** 513 * Overwrites a previous message to the output. 514 * 515 * @param string $message The message 516 */ 517 private function overwrite($message) 518 { 519 if ($this->overwrite) { 520 if (!$this->firstRun) { 521 // Move the cursor to the beginning of the line 522 $this->output->write("\x0D"); 523 524 // Erase the line 525 $this->output->write("\x1B[2K"); 526 527 // Erase previous lines 528 if ($this->formatLineCount > 0) { 529 $this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount)); 530 } 531 } 532 } elseif ($this->step > 0) { 533 $this->output->writeln(''); 534 } 535 536 $this->firstRun = false; 537 538 $this->output->write($message); 539 } 540 541 private function determineBestFormat() 542 { 543 switch ($this->output->getVerbosity()) { 544 // OutputInterface::VERBOSITY_QUIET: display is disabled anyway 545 case OutputInterface::VERBOSITY_VERBOSE: 546 return $this->max ? 'verbose' : 'verbose_nomax'; 547 case OutputInterface::VERBOSITY_VERY_VERBOSE: 548 return $this->max ? 'very_verbose' : 'very_verbose_nomax'; 549 case OutputInterface::VERBOSITY_DEBUG: 550 return $this->max ? 'debug' : 'debug_nomax'; 551 default: 552 return $this->max ? 'normal' : 'normal_nomax'; 553 } 554 } 555 556 private static function initPlaceholderFormatters() 557 { 558 return array( 559 'bar' => function (ProgressBar $bar, OutputInterface $output) { 560 $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth()); 561 $display = str_repeat($bar->getBarCharacter(), $completeBars); 562 if ($completeBars < $bar->getBarWidth()) { 563 $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter()); 564 $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars); 565 } 566 567 return $display; 568 }, 569 'elapsed' => function (ProgressBar $bar) { 570 return Helper::formatTime(time() - $bar->getStartTime()); 571 }, 572 'remaining' => function (ProgressBar $bar) { 573 if (!$bar->getMaxSteps()) { 574 throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.'); 575 } 576 577 if (!$bar->getProgress()) { 578 $remaining = 0; 579 } else { 580 $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress())); 581 } 582 583 return Helper::formatTime($remaining); 584 }, 585 'estimated' => function (ProgressBar $bar) { 586 if (!$bar->getMaxSteps()) { 587 throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.'); 588 } 589 590 if (!$bar->getProgress()) { 591 $estimated = 0; 592 } else { 593 $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps()); 594 } 595 596 return Helper::formatTime($estimated); 597 }, 598 'memory' => function (ProgressBar $bar) { 599 return Helper::formatMemory(memory_get_usage(true)); 600 }, 601 'current' => function (ProgressBar $bar) { 602 return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT); 603 }, 604 'max' => function (ProgressBar $bar) { 605 return $bar->getMaxSteps(); 606 }, 607 'percent' => function (ProgressBar $bar) { 608 return floor($bar->getProgressPercent() * 100); 609 }, 610 ); 611 } 612 613 private static function initFormats() 614 { 615 return array( 616 'normal' => ' %current%/%max% [%bar%] %percent:3s%%', 617 'normal_nomax' => ' %current% [%bar%]', 618 619 'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%', 620 'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%', 621 622 'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%', 623 'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%', 624 625 'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%', 626 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%', 627 ); 628 } 629 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |