Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ProgressBar.php

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 17.53 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\Console\Helper;
 013   
 014  use Symfony\Component\Console\Output\ConsoleOutputInterface;
 015  use Symfony\Component\Console\Output\OutputInterface;
 016  use Symfony\Component\Console\Exception\LogicException;
 017   
 018  /**
 019   * The ProgressBar provides helpers to display progress output.
 020   *
 021   * @author Fabien Potencier <fabien@symfony.com>
 022   * @author Chris Jones <leeked@gmail.com>
 023   */
 024  class ProgressBar
 025  {
 026      // options
 027      private $barWidth = 28;
 028      private $barChar;
 029      private $emptyBarChar = '-';
 030      private $progressChar = '>';
 031      private $format;
 032      private $internalFormat;
 033      private $redrawFreq = 1;
 034   
 035      /**
 036       * @var OutputInterface
 037       */
 038      private $output;
 039      private $step = 0;
 040      private $max;
 041      private $startTime;
 042      private $stepWidth;
 043      private $percent = 0.0;
 044      private $formatLineCount;
 045      private $messages = array();
 046      private $overwrite = true;
 047      private $firstRun = true;
 048   
 049      private static $formatters;
 050      private static $formats;
 051   
 052      /**
 053       * Constructor.
 054       *
 055       * @param OutputInterface $output An OutputInterface instance
 056       * @param int             $max    Maximum steps (0 if unknown)
 057       */
 058      public function __construct(OutputInterface $output, $max = 0)
 059      {
 060          if ($output instanceof ConsoleOutputInterface) {
 061              $output = $output->getErrorOutput();
 062          }
 063   
 064          $this->output = $output;
 065          $this->setMaxSteps($max);
 066   
 067          if (!$this->output->isDecorated()) {
 068              // disable overwrite when output does not support ANSI codes.
 069              $this->overwrite = false;
 070   
 071              // set a reasonable redraw frequency so output isn't flooded
 072              $this->setRedrawFrequency($max / 10);
 073          }
 074   
 075          $this->startTime = time();
 076      }
 077   
 078      /**
 079       * Sets a placeholder formatter for a given name.
 080       *
 081       * This method also allow you to override an existing placeholder.
 082       *
 083       * @param string   $name     The placeholder name (including the delimiter char like %)
 084       * @param callable $callable A PHP callable
 085       */
 086      public static function setPlaceholderFormatterDefinition($name, $callable)
 087      {
 088          if (!self::$formatters) {
 089              self::$formatters = self::initPlaceholderFormatters();
 090          }
 091   
 092          self::$formatters[$name] = $callable;
 093      }
 094   
 095      /**
 096       * Gets the placeholder formatter for a given name.
 097       *
 098       * @param string $name The placeholder name (including the delimiter char like %)
 099       *
 100       * @return callable|null A PHP callable
 101       */
 102      public static function getPlaceholderFormatterDefinition($name)
 103      {
 104          if (!self::$formatters) {
 105              self::$formatters = self::initPlaceholderFormatters();
 106          }
 107   
 108          return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
 109      }
 110   
 111      /**
 112       * Sets a format for a given name.
 113       *
 114       * This method also allow you to override an existing format.
 115       *
 116       * @param string $name   The format name
 117       * @param string $format A format string
 118       */
 119      public static function setFormatDefinition($name, $format)
 120      {
 121          if (!self::$formats) {
 122              self::$formats = self::initFormats();
 123          }
 124   
 125          self::$formats[$name] = $format;
 126      }
 127   
 128      /**
 129       * Gets the format for a given name.
 130       *
 131       * @param string $name The format name
 132       *
 133       * @return string|null A format string
 134       */
 135      public static function getFormatDefinition($name)
 136      {
 137          if (!self::$formats) {
 138              self::$formats = self::initFormats();
 139          }
 140   
 141          return isset(self::$formats[$name]) ? self::$formats[$name] : null;
 142      }
 143   
 144      /**
 145       * Associates a text with a named placeholder.
 146       *
 147       * The text is displayed when the progress bar is rendered but only
 148       * when the corresponding placeholder is part of the custom format line
 149       * (by wrapping the name with %).
 150       *
 151       * @param string $message The text to associate with the placeholder
 152       * @param string $name    The name of the placeholder
 153       */
 154      public function setMessage($message, $name = 'message')
 155      {
 156          $this->messages[$name] = $message;
 157      }
 158   
 159      public function getMessage($name = 'message')
 160      {
 161          return $this->messages[$name];
 162      }
 163   
 164      /**
 165       * Gets the progress bar start time.
 166       *
 167       * @return int The progress bar start time
 168       */
 169      public function getStartTime()
 170      {
 171          return $this->startTime;
 172      }
 173   
 174      /**
 175       * Gets the progress bar maximal steps.
 176       *
 177       * @return int The progress bar max steps
 178       */
 179      public function getMaxSteps()
 180      {
 181          return $this->max;
 182      }
 183   
 184      /**
 185       * Gets the progress bar step.
 186       *
 187       * @deprecated since version 2.6, to be removed in 3.0. Use {@link getProgress()} instead.
 188       *
 189       * @return int The progress bar step
 190       */
 191      public function getStep()
 192      {
 193          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the getProgress() method instead.', E_USER_DEPRECATED);
 194   
 195          return $this->getProgress();
 196      }
 197   
 198      /**
 199       * Gets the current step position.
 200       *
 201       * @return int The progress bar step
 202       */
 203      public function getProgress()
 204      {
 205          return $this->step;
 206      }
 207   
 208      /**
 209       * Gets the progress bar step width.
 210       *
 211       * @internal This method is public for PHP 5.3 compatibility, it should not be used.
 212       *
 213       * @return int The progress bar step width
 214       */
 215      public function getStepWidth()
 216      {
 217          return $this->stepWidth;
 218      }
 219   
 220      /**
 221       * Gets the current progress bar percent.
 222       *
 223       * @return float The current progress bar percent
 224       */
 225      public function getProgressPercent()
 226      {
 227          return $this->percent;
 228      }
 229   
 230      /**
 231       * Sets the progress bar width.
 232       *
 233       * @param int $size The progress bar size
 234       */
 235      public function setBarWidth($size)
 236      {
 237          $this->barWidth = (int) $size;
 238      }
 239   
 240      /**
 241       * Gets the progress bar width.
 242       *
 243       * @return int The progress bar size
 244       */
 245      public function getBarWidth()
 246      {
 247          return $this->barWidth;
 248      }
 249   
 250      /**
 251       * Sets the bar character.
 252       *
 253       * @param string $char A character
 254       */
 255      public function setBarCharacter($char)
 256      {
 257          $this->barChar = $char;
 258      }
 259   
 260      /**
 261       * Gets the bar character.
 262       *
 263       * @return string A character
 264       */
 265      public function getBarCharacter()
 266      {
 267          if (null === $this->barChar) {
 268              return $this->max ? '=' : $this->emptyBarChar;
 269          }
 270   
 271          return $this->barChar;
 272      }
 273   
 274      /**
 275       * Sets the empty bar character.
 276       *
 277       * @param string $char A character
 278       */
 279      public function setEmptyBarCharacter($char)
 280      {
 281          $this->emptyBarChar = $char;
 282      }
 283   
 284      /**
 285       * Gets the empty bar character.
 286       *
 287       * @return string A character
 288       */
 289      public function getEmptyBarCharacter()
 290      {
 291          return $this->emptyBarChar;
 292      }
 293   
 294      /**
 295       * Sets the progress bar character.
 296       *
 297       * @param string $char A character
 298       */
 299      public function setProgressCharacter($char)
 300      {
 301          $this->progressChar = $char;
 302      }
 303   
 304      /**
 305       * Gets the progress bar character.
 306       *
 307       * @return string A character
 308       */
 309      public function getProgressCharacter()
 310      {
 311          return $this->progressChar;
 312      }
 313   
 314      /**
 315       * Sets the progress bar format.
 316       *
 317       * @param string $format The format
 318       */
 319      public function setFormat($format)
 320      {
 321          $this->format = null;
 322          $this->internalFormat = $format;
 323      }
 324   
 325      /**
 326       * Sets the redraw frequency.
 327       *
 328       * @param int|float $freq The frequency in steps
 329       */
 330      public function setRedrawFrequency($freq)
 331      {
 332          $this->redrawFreq = max((int) $freq, 1);
 333      }
 334   
 335      /**
 336       * Starts the progress output.
 337       *
 338       * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
 339       */
 340      public function start($max = null)
 341      {
 342          $this->startTime = time();
 343          $this->step = 0;
 344          $this->percent = 0.0;
 345   
 346          if (null !== $max) {
 347              $this->setMaxSteps($max);
 348          }
 349   
 350          $this->display();
 351      }
 352   
 353      /**
 354       * Advances the progress output X steps.
 355       *
 356       * @param int $step Number of steps to advance
 357       *
 358       * @throws LogicException
 359       */
 360      public function advance($step = 1)
 361      {
 362          $this->setProgress($this->step + $step);
 363      }
 364   
 365      /**
 366       * Sets the current progress.
 367       *
 368       * @deprecated since version 2.6, to be removed in 3.0. Use {@link setProgress()} instead.
 369       *
 370       * @param int $step The current progress
 371       *
 372       * @throws LogicException
 373       */
 374      public function setCurrent($step)
 375      {
 376          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the setProgress() method instead.', E_USER_DEPRECATED);
 377   
 378          $this->setProgress($step);
 379      }
 380   
 381      /**
 382       * Sets whether to overwrite the progressbar, false for new line.
 383       *
 384       * @param bool $overwrite
 385       */
 386      public function setOverwrite($overwrite)
 387      {
 388          $this->overwrite = (bool) $overwrite;
 389      }
 390   
 391      /**
 392       * Sets the current progress.
 393       *
 394       * @param int $step The current progress
 395       *
 396       * @throws LogicException
 397       */
 398      public function setProgress($step)
 399      {
 400          $step = (int) $step;
 401          if ($step < $this->step) {
 402              throw new LogicException('You can\'t regress the progress bar.');
 403          }
 404   
 405          if ($this->max && $step > $this->max) {
 406              $this->max = $step;
 407          }
 408   
 409          $prevPeriod = (int) ($this->step / $this->redrawFreq);
 410          $currPeriod = (int) ($step / $this->redrawFreq);
 411          $this->step = $step;
 412          $this->percent = $this->max ? (float) $this->step / $this->max : 0;
 413          if ($prevPeriod !== $currPeriod || $this->max === $step) {
 414              $this->display();
 415          }
 416      }
 417   
 418      /**
 419       * Finishes the progress output.
 420       */
 421      public function finish()
 422      {
 423          if (!$this->max) {
 424              $this->max = $this->step;
 425          }
 426   
 427          if ($this->step === $this->max && !$this->overwrite) {
 428              // prevent double 100% output
 429              return;
 430          }
 431   
 432          $this->setProgress($this->max);
 433      }
 434   
 435      /**
 436       * Outputs the current progress string.
 437       */
 438      public function display()
 439      {
 440          if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
 441              return;
 442          }
 443   
 444          if (null === $this->format) {
 445              $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
 446          }
 447   
 448          // these 3 variables can be removed in favor of using $this in the closure when support for PHP 5.3 will be dropped.
 449          $self = $this;
 450          $output = $this->output;
 451          $messages = $this->messages;
 452          $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self, $output, $messages) {
 453              if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
 454                  $text = call_user_func($formatter, $self, $output);
 455              } elseif (isset($messages[$matches[1]])) {
 456                  $text = $messages[$matches[1]];
 457              } else {
 458                  return $matches[0];
 459              }
 460   
 461              if (isset($matches[2])) {
 462                  $text = sprintf('%'.$matches[2], $text);
 463              }
 464   
 465              return $text;
 466          }, $this->format));
 467      }
 468   
 469      /**
 470       * Removes the progress bar from the current line.
 471       *
 472       * This is useful if you wish to write some output
 473       * while a progress bar is running.
 474       * Call display() to show the progress bar again.
 475       */
 476      public function clear()
 477      {
 478          if (!$this->overwrite) {
 479              return;
 480          }
 481   
 482          if (null === $this->format) {
 483              $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
 484          }
 485   
 486          $this->overwrite('');
 487      }
 488   
 489      /**
 490       * Sets the progress bar format.
 491       *
 492       * @param string $format The format
 493       */
 494      private function setRealFormat($format)
 495      {
 496          // try to use the _nomax variant if available
 497          if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
 498              $this->format = self::getFormatDefinition($format.'_nomax');
 499          } elseif (null !== self::getFormatDefinition($format)) {
 500              $this->format = self::getFormatDefinition($format);
 501          } else {
 502              $this->format = $format;
 503          }
 504   
 505          $this->formatLineCount = substr_count($this->format, "\n");
 506      }
 507   
 508      /**
 509       * Sets the progress bar maximal steps.
 510       *
 511       * @param int $max The progress bar max steps
 512       */
 513      private function setMaxSteps($max)
 514      {
 515          $this->max = max(0, (int) $max);
 516          $this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
 517      }
 518   
 519      /**
 520       * Overwrites a previous message to the output.
 521       *
 522       * @param string $message The message
 523       */
 524      private function overwrite($message)
 525      {
 526          if ($this->overwrite) {
 527              if (!$this->firstRun) {
 528                  // Move the cursor to the beginning of the line
 529                  $this->output->write("\x0D");
 530   
 531                  // Erase the line
 532                  $this->output->write("\x1B[2K");
 533   
 534                  // Erase previous lines
 535                  if ($this->formatLineCount > 0) {
 536                      $this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
 537                  }
 538              }
 539          } elseif ($this->step > 0) {
 540              $this->output->writeln('');
 541          }
 542   
 543          $this->firstRun = false;
 544   
 545          $this->output->write($message);
 546      }
 547   
 548      private function determineBestFormat()
 549      {
 550          switch ($this->output->getVerbosity()) {
 551              // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
 552              case OutputInterface::VERBOSITY_VERBOSE:
 553                  return $this->max ? 'verbose' : 'verbose_nomax';
 554              case OutputInterface::VERBOSITY_VERY_VERBOSE:
 555                  return $this->max ? 'very_verbose' : 'very_verbose_nomax';
 556              case OutputInterface::VERBOSITY_DEBUG:
 557                  return $this->max ? 'debug' : 'debug_nomax';
 558              default:
 559                  return $this->max ? 'normal' : 'normal_nomax';
 560          }
 561      }
 562   
 563      private static function initPlaceholderFormatters()
 564      {
 565          return array(
 566              'bar' => function (ProgressBar $bar, OutputInterface $output) {
 567                  $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
 568                  $display = str_repeat($bar->getBarCharacter(), $completeBars);
 569                  if ($completeBars < $bar->getBarWidth()) {
 570                      $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
 571                      $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
 572                  }
 573   
 574                  return $display;
 575              },
 576              'elapsed' => function (ProgressBar $bar) {
 577                  return Helper::formatTime(time() - $bar->getStartTime());
 578              },
 579              'remaining' => function (ProgressBar $bar) {
 580                  if (!$bar->getMaxSteps()) {
 581                      throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
 582                  }
 583   
 584                  if (!$bar->getProgress()) {
 585                      $remaining = 0;
 586                  } else {
 587                      $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
 588                  }
 589   
 590                  return Helper::formatTime($remaining);
 591              },
 592              'estimated' => function (ProgressBar $bar) {
 593                  if (!$bar->getMaxSteps()) {
 594                      throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
 595                  }
 596   
 597                  if (!$bar->getProgress()) {
 598                      $estimated = 0;
 599                  } else {
 600                      $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
 601                  }
 602   
 603                  return Helper::formatTime($estimated);
 604              },
 605              'memory' => function (ProgressBar $bar) {
 606                  return Helper::formatMemory(memory_get_usage(true));
 607              },
 608              'current' => function (ProgressBar $bar) {
 609                  return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
 610              },
 611              'max' => function (ProgressBar $bar) {
 612                  return $bar->getMaxSteps();
 613              },
 614              'percent' => function (ProgressBar $bar) {
 615                  return floor($bar->getProgressPercent() * 100);
 616              },
 617          );
 618      }
 619   
 620      private static function initFormats()
 621      {
 622          return array(
 623              'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
 624              'normal_nomax' => ' %current% [%bar%]',
 625   
 626              'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
 627              'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
 628   
 629              'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
 630              'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
 631   
 632              'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
 633              'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
 634          );
 635      }
 636  }
 637