[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/symfony/console/Symfony/Component/Console/Helper/ -> ProgressHelper.php (source)

   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\Output\ConsoleOutputInterface;
  15  use Symfony\Component\Console\Output\OutputInterface;
  16  
  17  /**
  18   * The Progress class provides helpers to display progress output.
  19   *
  20   * @author Chris Jones <leeked@gmail.com>
  21   * @author Fabien Potencier <fabien@symfony.com>
  22   */
  23  class ProgressHelper extends Helper
  24  {
  25      const FORMAT_QUIET = ' %percent%%';
  26      const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%';
  27      const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%';
  28      const FORMAT_QUIET_NOMAX = ' %current%';
  29      const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]';
  30      const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%';
  31  
  32      // options
  33      private $barWidth = 28;
  34      private $barChar = '=';
  35      private $emptyBarChar = '-';
  36      private $progressChar = '>';
  37      private $format = null;
  38      private $redrawFreq = 1;
  39  
  40      private $lastMessagesLength;
  41      private $barCharOriginal;
  42  
  43      /**
  44       * @var OutputInterface
  45       */
  46      private $output;
  47  
  48      /**
  49       * Current step.
  50       *
  51       * @var int
  52       */
  53      private $current;
  54  
  55      /**
  56       * Maximum number of steps.
  57       *
  58       * @var int
  59       */
  60      private $max;
  61  
  62      /**
  63       * Start time of the progress bar.
  64       *
  65       * @var int
  66       */
  67      private $startTime;
  68  
  69      /**
  70       * List of formatting variables.
  71       *
  72       * @var array
  73       */
  74      private $defaultFormatVars = array(
  75          'current',
  76          'max',
  77          'bar',
  78          'percent',
  79          'elapsed',
  80      );
  81  
  82      /**
  83       * Available formatting variables.
  84       *
  85       * @var array
  86       */
  87      private $formatVars;
  88  
  89      /**
  90       * Stored format part widths (used for padding).
  91       *
  92       * @var array
  93       */
  94      private $widths = array(
  95          'current' => 4,
  96          'max' => 4,
  97          'percent' => 3,
  98          'elapsed' => 6,
  99      );
 100  
 101      /**
 102       * Various time formats.
 103       *
 104       * @var array
 105       */
 106      private $timeFormats = array(
 107          array(0, '???'),
 108          array(2, '1 sec'),
 109          array(59, 'secs', 1),
 110          array(60, '1 min'),
 111          array(3600, 'mins', 60),
 112          array(5400, '1 hr'),
 113          array(86400, 'hrs', 3600),
 114          array(129600, '1 day'),
 115          array(604800, 'days', 86400),
 116      );
 117  
 118      /**
 119       * Sets the progress bar width.
 120       *
 121       * @param int $size The progress bar size
 122       */
 123      public function setBarWidth($size)
 124      {
 125          $this->barWidth = (int) $size;
 126      }
 127  
 128      /**
 129       * Sets the bar character.
 130       *
 131       * @param string $char A character
 132       */
 133      public function setBarCharacter($char)
 134      {
 135          $this->barChar = $char;
 136      }
 137  
 138      /**
 139       * Sets the empty bar character.
 140       *
 141       * @param string $char A character
 142       */
 143      public function setEmptyBarCharacter($char)
 144      {
 145          $this->emptyBarChar = $char;
 146      }
 147  
 148      /**
 149       * Sets the progress bar character.
 150       *
 151       * @param string $char A character
 152       */
 153      public function setProgressCharacter($char)
 154      {
 155          $this->progressChar = $char;
 156      }
 157  
 158      /**
 159       * Sets the progress bar format.
 160       *
 161       * @param string $format The format
 162       */
 163      public function setFormat($format)
 164      {
 165          $this->format = $format;
 166      }
 167  
 168      /**
 169       * Sets the redraw frequency.
 170       *
 171       * @param int $freq The frequency in steps
 172       */
 173      public function setRedrawFrequency($freq)
 174      {
 175          $this->redrawFreq = (int) $freq;
 176      }
 177  
 178      /**
 179       * Starts the progress output.
 180       *
 181       * @param OutputInterface $output An Output instance
 182       * @param int|null        $max    Maximum steps
 183       */
 184      public function start(OutputInterface $output, $max = null)
 185      {
 186          if ($output instanceof ConsoleOutputInterface) {
 187              $output = $output->getErrorOutput();
 188          }
 189  
 190          $this->startTime = time();
 191          $this->current = 0;
 192          $this->max = (int) $max;
 193          $this->output = $output;
 194          $this->lastMessagesLength = 0;
 195          $this->barCharOriginal = '';
 196  
 197          if (null === $this->format) {
 198              switch ($output->getVerbosity()) {
 199                  case OutputInterface::VERBOSITY_QUIET:
 200                      $this->format = self::FORMAT_QUIET_NOMAX;
 201                      if ($this->max > 0) {
 202                          $this->format = self::FORMAT_QUIET;
 203                      }
 204                      break;
 205                  case OutputInterface::VERBOSITY_VERBOSE:
 206                  case OutputInterface::VERBOSITY_VERY_VERBOSE:
 207                  case OutputInterface::VERBOSITY_DEBUG:
 208                      $this->format = self::FORMAT_VERBOSE_NOMAX;
 209                      if ($this->max > 0) {
 210                          $this->format = self::FORMAT_VERBOSE;
 211                      }
 212                      break;
 213                  default:
 214                      $this->format = self::FORMAT_NORMAL_NOMAX;
 215                      if ($this->max > 0) {
 216                          $this->format = self::FORMAT_NORMAL;
 217                      }
 218                      break;
 219              }
 220          }
 221  
 222          $this->initialize();
 223      }
 224  
 225      /**
 226       * Advances the progress output X steps.
 227       *
 228       * @param int  $step   Number of steps to advance
 229       * @param bool $redraw Whether to redraw or not
 230       *
 231       * @throws \LogicException
 232       */
 233      public function advance($step = 1, $redraw = false)
 234      {
 235          if (null === $this->startTime) {
 236              throw new \LogicException('You must start the progress bar before calling advance().');
 237          }
 238  
 239          if (0 === $this->current) {
 240              $redraw = true;
 241          }
 242  
 243          $prevPeriod = (int) ($this->current / $this->redrawFreq);
 244  
 245          $this->current += $step;
 246  
 247          $currPeriod = (int) ($this->current / $this->redrawFreq);
 248          if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
 249              $this->display();
 250          }
 251      }
 252  
 253      /**
 254       * Sets the current progress.
 255       *
 256       * @param int  $current The current progress
 257       * @param bool $redraw  Whether to redraw or not
 258       *
 259       * @throws \LogicException
 260       */
 261      public function setCurrent($current, $redraw = false)
 262      {
 263          if (null === $this->startTime) {
 264              throw new \LogicException('You must start the progress bar before calling setCurrent().');
 265          }
 266  
 267          $current = (int) $current;
 268  
 269          if ($current < $this->current) {
 270              throw new \LogicException('You can\'t regress the progress bar');
 271          }
 272  
 273          if (0 === $this->current) {
 274              $redraw = true;
 275          }
 276  
 277          $prevPeriod = (int) ($this->current / $this->redrawFreq);
 278  
 279          $this->current = $current;
 280  
 281          $currPeriod = (int) ($this->current / $this->redrawFreq);
 282          if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
 283              $this->display();
 284          }
 285      }
 286  
 287      /**
 288       * Outputs the current progress string.
 289       *
 290       * @param bool $finish Forces the end result
 291       *
 292       * @throws \LogicException
 293       */
 294      public function display($finish = false)
 295      {
 296          if (null === $this->startTime) {
 297              throw new \LogicException('You must start the progress bar before calling display().');
 298          }
 299  
 300          $message = $this->format;
 301          foreach ($this->generate($finish) as $name => $value) {
 302              $message = str_replace("%{$name}%", $value, $message);
 303          }
 304          $this->overwrite($this->output, $message);
 305      }
 306  
 307      /**
 308       * Finishes the progress output.
 309       */
 310      public function finish()
 311      {
 312          if (null === $this->startTime) {
 313              throw new \LogicException('You must start the progress bar before calling finish().');
 314          }
 315  
 316          if (null !== $this->startTime) {
 317              if (!$this->max) {
 318                  $this->barChar = $this->barCharOriginal;
 319                  $this->display(true);
 320              }
 321              $this->startTime = null;
 322              $this->output->writeln('');
 323              $this->output = null;
 324          }
 325      }
 326  
 327      /**
 328       * Initializes the progress helper.
 329       */
 330      private function initialize()
 331      {
 332          $this->formatVars = array();
 333          foreach ($this->defaultFormatVars as $var) {
 334              if (false !== strpos($this->format, "%{$var}%")) {
 335                  $this->formatVars[$var] = true;
 336              }
 337          }
 338  
 339          if ($this->max > 0) {
 340              $this->widths['max'] = $this->strlen($this->max);
 341              $this->widths['current'] = $this->widths['max'];
 342          } else {
 343              $this->barCharOriginal = $this->barChar;
 344              $this->barChar = $this->emptyBarChar;
 345          }
 346      }
 347  
 348      /**
 349       * Generates the array map of format variables to values.
 350       *
 351       * @param bool $finish Forces the end result
 352       *
 353       * @return array Array of format vars and values
 354       */
 355      private function generate($finish = false)
 356      {
 357          $vars = array();
 358          $percent = 0;
 359          if ($this->max > 0) {
 360              $percent = (float) $this->current / $this->max;
 361          }
 362  
 363          if (isset($this->formatVars['bar'])) {
 364              $completeBars = 0;
 365  
 366              if ($this->max > 0) {
 367                  $completeBars = floor($percent * $this->barWidth);
 368              } else {
 369                  if (!$finish) {
 370                      $completeBars = floor($this->current % $this->barWidth);
 371                  } else {
 372                      $completeBars = $this->barWidth;
 373                  }
 374              }
 375  
 376              $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar);
 377              $bar = str_repeat($this->barChar, $completeBars);
 378              if ($completeBars < $this->barWidth) {
 379                  $bar .= $this->progressChar;
 380                  $bar .= str_repeat($this->emptyBarChar, $emptyBars);
 381              }
 382  
 383              $vars['bar'] = $bar;
 384          }
 385  
 386          if (isset($this->formatVars['elapsed'])) {
 387              $elapsed = time() - $this->startTime;
 388              $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT);
 389          }
 390  
 391          if (isset($this->formatVars['current'])) {
 392              $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT);
 393          }
 394  
 395          if (isset($this->formatVars['max'])) {
 396              $vars['max'] = $this->max;
 397          }
 398  
 399          if (isset($this->formatVars['percent'])) {
 400              $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT);
 401          }
 402  
 403          return $vars;
 404      }
 405  
 406      /**
 407       * Converts seconds into human-readable format.
 408       *
 409       * @param int $secs Number of seconds
 410       *
 411       * @return string Time in readable format
 412       */
 413      private function humaneTime($secs)
 414      {
 415          $text = '';
 416          foreach ($this->timeFormats as $format) {
 417              if ($secs < $format[0]) {
 418                  if (count($format) == 2) {
 419                      $text = $format[1];
 420                      break;
 421                  } else {
 422                      $text = ceil($secs / $format[2]).' '.$format[1];
 423                      break;
 424                  }
 425              }
 426          }
 427  
 428          return $text;
 429      }
 430  
 431      /**
 432       * Overwrites a previous message to the output.
 433       *
 434       * @param OutputInterface $output  An Output instance
 435       * @param string          $message The message
 436       */
 437      private function overwrite(OutputInterface $output, $message)
 438      {
 439          $length = $this->strlen($message);
 440  
 441          // append whitespace to match the last line's length
 442          if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) {
 443              $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
 444          }
 445  
 446          // carriage return
 447          $output->write("\x0D");
 448          $output->write($message);
 449  
 450          $this->lastMessagesLength = $this->strlen($message);
 451      }
 452  
 453      /**
 454       * {@inheritdoc}
 455       */
 456      public function getName()
 457      {
 458          return 'progress';
 459      }
 460  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1