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