Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
ProgressHelper.php
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\OutputInterface;
015
016 /**
017 * The Progress class provides helpers to display progress output.
018 *
019 * @author Chris Jones <leeked@gmail.com>
020 * @author Fabien Potencier <fabien@symfony.com>
021 */
022 class ProgressHelper extends Helper
023 {
024 const FORMAT_QUIET = ' %percent%%';
025 const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%';
026 const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%';
027 const FORMAT_QUIET_NOMAX = ' %current%';
028 const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]';
029 const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%';
030
031 // options
032 private $barWidth = 28;
033 private $barChar = '=';
034 private $emptyBarChar = '-';
035 private $progressChar = '>';
036 private $format = null;
037 private $redrawFreq = 1;
038
039 private $lastMessagesLength;
040 private $barCharOriginal;
041
042 /**
043 * @var OutputInterface
044 */
045 private $output;
046
047 /**
048 * Current step
049 *
050 * @var int
051 */
052 private $current;
053
054 /**
055 * Maximum number of steps
056 *
057 * @var int
058 */
059 private $max;
060
061 /**
062 * Start time of the progress bar
063 *
064 * @var int
065 */
066 private $startTime;
067
068 /**
069 * List of formatting variables
070 *
071 * @var array
072 */
073 private $defaultFormatVars = array(
074 'current',
075 'max',
076 'bar',
077 'percent',
078 'elapsed',
079 );
080
081 /**
082 * Available formatting variables
083 *
084 * @var array
085 */
086 private $formatVars;
087
088 /**
089 * Stored format part widths (used for padding)
090 *
091 * @var array
092 */
093 private $widths = array(
094 'current' => 4,
095 'max' => 4,
096 'percent' => 3,
097 'elapsed' => 6,
098 );
099
100 /**
101 * Various time formats
102 *
103 * @var array
104 */
105 private $timeFormats = array(
106 array(0, '???'),
107 array(2, '1 sec'),
108 array(59, 'secs', 1),
109 array(60, '1 min'),
110 array(3600, 'mins', 60),
111 array(5400, '1 hr'),
112 array(86400, 'hrs', 3600),
113 array(129600, '1 day'),
114 array(604800, 'days', 86400),
115 );
116
117 /**
118 * Sets the progress bar width.
119 *
120 * @param int $size The progress bar size
121 */
122 public function setBarWidth($size)
123 {
124 $this->barWidth = (int) $size;
125 }
126
127 /**
128 * Sets the bar character.
129 *
130 * @param string $char A character
131 */
132 public function setBarCharacter($char)
133 {
134 $this->barChar = $char;
135 }
136
137 /**
138 * Sets the empty bar character.
139 *
140 * @param string $char A character
141 */
142 public function setEmptyBarCharacter($char)
143 {
144 $this->emptyBarChar = $char;
145 }
146
147 /**
148 * Sets the progress bar character.
149 *
150 * @param string $char A character
151 */
152 public function setProgressCharacter($char)
153 {
154 $this->progressChar = $char;
155 }
156
157 /**
158 * Sets the progress bar format.
159 *
160 * @param string $format The format
161 */
162 public function setFormat($format)
163 {
164 $this->format = $format;
165 }
166
167 /**
168 * Sets the redraw frequency.
169 *
170 * @param int $freq The frequency in steps
171 */
172 public function setRedrawFrequency($freq)
173 {
174 $this->redrawFreq = (int) $freq;
175 }
176
177 /**
178 * Starts the progress output.
179 *
180 * @param OutputInterface $output An Output instance
181 * @param int|null $max Maximum steps
182 */
183 public function start(OutputInterface $output, $max = null)
184 {
185 $this->startTime = time();
186 $this->current = 0;
187 $this->max = (int) $max;
188 $this->output = $output;
189 $this->lastMessagesLength = 0;
190 $this->barCharOriginal = '';
191
192 if (null === $this->format) {
193 switch ($output->getVerbosity()) {
194 case OutputInterface::VERBOSITY_QUIET:
195 $this->format = self::FORMAT_QUIET_NOMAX;
196 if ($this->max > 0) {
197 $this->format = self::FORMAT_QUIET;
198 }
199 break;
200 case OutputInterface::VERBOSITY_VERBOSE:
201 case OutputInterface::VERBOSITY_VERY_VERBOSE:
202 case OutputInterface::VERBOSITY_DEBUG:
203 $this->format = self::FORMAT_VERBOSE_NOMAX;
204 if ($this->max > 0) {
205 $this->format = self::FORMAT_VERBOSE;
206 }
207 break;
208 default:
209 $this->format = self::FORMAT_NORMAL_NOMAX;
210 if ($this->max > 0) {
211 $this->format = self::FORMAT_NORMAL;
212 }
213 break;
214 }
215 }
216
217 $this->initialize();
218 }
219
220 /**
221 * Advances the progress output X steps.
222 *
223 * @param int $step Number of steps to advance
224 * @param bool $redraw Whether to redraw or not
225 *
226 * @throws \LogicException
227 */
228 public function advance($step = 1, $redraw = false)
229 {
230 if (null === $this->startTime) {
231 throw new \LogicException('You must start the progress bar before calling advance().');
232 }
233
234 if (0 === $this->current) {
235 $redraw = true;
236 }
237
238 $prevPeriod = intval($this->current / $this->redrawFreq);
239
240 $this->current += $step;
241
242 $currPeriod = intval($this->current / $this->redrawFreq);
243 if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
244 $this->display();
245 }
246 }
247
248 /**
249 * Sets the current progress.
250 *
251 * @param int $current The current progress
252 * @param bool $redraw Whether to redraw or not
253 *
254 * @throws \LogicException
255 */
256 public function setCurrent($current, $redraw = false)
257 {
258 if (null === $this->startTime) {
259 throw new \LogicException('You must start the progress bar before calling setCurrent().');
260 }
261
262 $current = (int) $current;
263
264 if ($current < $this->current) {
265 throw new \LogicException('You can\'t regress the progress bar');
266 }
267
268 if (0 === $this->current) {
269 $redraw = true;
270 }
271
272 $prevPeriod = intval($this->current / $this->redrawFreq);
273
274 $this->current = $current;
275
276 $currPeriod = intval($this->current / $this->redrawFreq);
277 if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
278 $this->display();
279 }
280 }
281
282 /**
283 * Outputs the current progress string.
284 *
285 * @param bool $finish Forces the end result
286 *
287 * @throws \LogicException
288 */
289 public function display($finish = false)
290 {
291 if (null === $this->startTime) {
292 throw new \LogicException('You must start the progress bar before calling display().');
293 }
294
295 $message = $this->format;
296 foreach ($this->generate($finish) as $name => $value) {
297 $message = str_replace("%{$name}%", $value, $message);
298 }
299 $this->overwrite($this->output, $message);
300 }
301
302 /**
303 * Finishes the progress output.
304 */
305 public function finish()
306 {
307 if (null === $this->startTime) {
308 throw new \LogicException('You must start the progress bar before calling finish().');
309 }
310
311 if (null !== $this->startTime) {
312 if (!$this->max) {
313 $this->barChar = $this->barCharOriginal;
314 $this->display(true);
315 }
316 $this->startTime = null;
317 $this->output->writeln('');
318 $this->output = null;
319 }
320 }
321
322 /**
323 * Initializes the progress helper.
324 */
325 private function initialize()
326 {
327 $this->formatVars = array();
328 foreach ($this->defaultFormatVars as $var) {
329 if (false !== strpos($this->format, "%{$var}%")) {
330 $this->formatVars[$var] = true;
331 }
332 }
333
334 if ($this->max > 0) {
335 $this->widths['max'] = $this->strlen($this->max);
336 $this->widths['current'] = $this->widths['max'];
337 } else {
338 $this->barCharOriginal = $this->barChar;
339 $this->barChar = $this->emptyBarChar;
340 }
341 }
342
343 /**
344 * Generates the array map of format variables to values.
345 *
346 * @param bool $finish Forces the end result
347 *
348 * @return array Array of format vars and values
349 */
350 private function generate($finish = false)
351 {
352 $vars = array();
353 $percent = 0;
354 if ($this->max > 0) {
355 $percent = (float) $this->current / $this->max;
356 }
357
358 if (isset($this->formatVars['bar'])) {
359 $completeBars = 0;
360
361 if ($this->max > 0) {
362 $completeBars = floor($percent * $this->barWidth);
363 } else {
364 if (!$finish) {
365 $completeBars = floor($this->current % $this->barWidth);
366 } else {
367 $completeBars = $this->barWidth;
368 }
369 }
370
371 $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar);
372 $bar = str_repeat($this->barChar, $completeBars);
373 if ($completeBars < $this->barWidth) {
374 $bar .= $this->progressChar;
375 $bar .= str_repeat($this->emptyBarChar, $emptyBars);
376 }
377
378 $vars['bar'] = $bar;
379 }
380
381 if (isset($this->formatVars['elapsed'])) {
382 $elapsed = time() - $this->startTime;
383 $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT);
384 }
385
386 if (isset($this->formatVars['current'])) {
387 $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT);
388 }
389
390 if (isset($this->formatVars['max'])) {
391 $vars['max'] = $this->max;
392 }
393
394 if (isset($this->formatVars['percent'])) {
395 $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT);
396 }
397
398 return $vars;
399 }
400
401 /**
402 * Converts seconds into human-readable format.
403 *
404 * @param int $secs Number of seconds
405 *
406 * @return string Time in readable format
407 */
408 private function humaneTime($secs)
409 {
410 $text = '';
411 foreach ($this->timeFormats as $format) {
412 if ($secs < $format[0]) {
413 if (count($format) == 2) {
414 $text = $format[1];
415 break;
416 } else {
417 $text = ceil($secs / $format[2]).' '.$format[1];
418 break;
419 }
420 }
421 }
422
423 return $text;
424 }
425
426 /**
427 * Overwrites a previous message to the output.
428 *
429 * @param OutputInterface $output An Output instance
430 * @param string $message The message
431 */
432 private function overwrite(OutputInterface $output, $message)
433 {
434 $length = $this->strlen($message);
435
436 // append whitespace to match the last line's length
437 if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) {
438 $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
439 }
440
441 // carriage return
442 $output->write("\x0D");
443 $output->write($message);
444
445 $this->lastMessagesLength = $this->strlen($message);
446 }
447
448 /**
449 * {@inheritdoc}
450 */
451 public function getName()
452 {
453 return 'progress';
454 }
455 }
456