| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 | <?php/* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */namespace Symfony\Component\Console\Helper;use Symfony\Component\Console\Output\NullOutput;use Symfony\Component\Console\Output\OutputInterface;/** * The Progress class provides helpers to display progress output. * * @author Chris Jones <leeked@gmail.com> * @author Fabien Potencier <fabien@symfony.com> * * @deprecated since version 2.5, to be removed in 3.0 *             Use {@link ProgressBar} instead. */class ProgressHelper extends Helper{    const FORMAT_QUIET = ' %percent%%';    const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%';    const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%';    const FORMAT_QUIET_NOMAX = ' %current%';    const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]';    const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%';    // options    private $barWidth = 28;    private $barChar = '=';    private $emptyBarChar = '-';    private $progressChar = '>';    private $format = null;    private $redrawFreq = 1;    private $lastMessagesLength;    private $barCharOriginal;    /**     * @var OutputInterface     */    private $output;    /**     * Current step.     *     * @var int     */    private $current;    /**     * Maximum number of steps.     *     * @var int     */    private $max;    /**     * Start time of the progress bar.     *     * @var int     */    private $startTime;    /**     * List of formatting variables.     *     * @var array     */    private $defaultFormatVars = array(        'current',        'max',        'bar',        'percent',        'elapsed',    );    /**     * Available formatting variables.     *     * @var array     */    private $formatVars;    /**     * Stored format part widths (used for padding).     *     * @var array     */    private $widths = array(        'current' => 4,        'max' => 4,        'percent' => 3,        'elapsed' => 6,    );    /**     * Various time formats.     *     * @var array     */    private $timeFormats = array(        array(0, '???'),        array(2, '1 sec'),        array(59, 'secs', 1),        array(60, '1 min'),        array(3600, 'mins', 60),        array(5400, '1 hr'),        array(86400, 'hrs', 3600),        array(129600, '1 day'),        array(604800, 'days', 86400),    );    public function __construct($triggerDeprecationError = true)    {        if ($triggerDeprecationError) {            @trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\ProgressBar class instead.', E_USER_DEPRECATED);        }    }    /**     * Sets the progress bar width.     *     * @param int $size The progress bar size     */    public function setBarWidth($size)    {        $this->barWidth = (int) $size;    }    /**     * Sets the bar character.     *     * @param string $char A character     */    public function setBarCharacter($char)    {        $this->barChar = $char;    }    /**     * Sets the empty bar character.     *     * @param string $char A character     */    public function setEmptyBarCharacter($char)    {        $this->emptyBarChar = $char;    }    /**     * Sets the progress bar character.     *     * @param string $char A character     */    public function setProgressCharacter($char)    {        $this->progressChar = $char;    }    /**     * Sets the progress bar format.     *     * @param string $format The format     */    public function setFormat($format)    {        $this->format = $format;    }    /**     * Sets the redraw frequency.     *     * @param int $freq The frequency in steps     */    public function setRedrawFrequency($freq)    {        $this->redrawFreq = (int) $freq;    }    /**     * Starts the progress output.     *     * @param OutputInterface $output An Output instance     * @param int|null        $max    Maximum steps     */    public function start(OutputInterface $output, $max = null)    {        $this->startTime = time();        $this->current = 0;        $this->max = (int) $max;        // Disabling output when it does not support ANSI codes as it would result in a broken display anyway.        $this->output = $output->isDecorated() ? $output : new NullOutput();        $this->lastMessagesLength = 0;        $this->barCharOriginal = '';        if (null === $this->format) {            switch ($output->getVerbosity()) {                case OutputInterface::VERBOSITY_QUIET:                    $this->format = self::FORMAT_QUIET_NOMAX;                    if ($this->max > 0) {                        $this->format = self::FORMAT_QUIET;                    }                    break;                case OutputInterface::VERBOSITY_VERBOSE:                case OutputInterface::VERBOSITY_VERY_VERBOSE:                case OutputInterface::VERBOSITY_DEBUG:                    $this->format = self::FORMAT_VERBOSE_NOMAX;                    if ($this->max > 0) {                        $this->format = self::FORMAT_VERBOSE;                    }                    break;                default:                    $this->format = self::FORMAT_NORMAL_NOMAX;                    if ($this->max > 0) {                        $this->format = self::FORMAT_NORMAL;                    }                    break;            }        }        $this->initialize();    }    /**     * Advances the progress output X steps.     *     * @param int  $step   Number of steps to advance     * @param bool $redraw Whether to redraw or not     *     * @throws \LogicException     */    public function advance($step = 1, $redraw = false)    {        $this->setCurrent($this->current + $step, $redraw);    }    /**     * Sets the current progress.     *     * @param int  $current The current progress     * @param bool $redraw  Whether to redraw or not     *     * @throws \LogicException     */    public function setCurrent($current, $redraw = false)    {        if (null === $this->startTime) {            throw new \LogicException('You must start the progress bar before calling setCurrent().');        }        $current = (int) $current;        if ($current < $this->current) {            throw new \LogicException('You can\'t regress the progress bar');        }        if (0 === $this->current) {            $redraw = true;        }        $prevPeriod = (int) ($this->current / $this->redrawFreq);        $this->current = $current;        $currPeriod = (int) ($this->current / $this->redrawFreq);        if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {            $this->display();        }    }    /**     * Outputs the current progress string.     *     * @param bool $finish Forces the end result     *     * @throws \LogicException     */    public function display($finish = false)    {        if (null === $this->startTime) {            throw new \LogicException('You must start the progress bar before calling display().');        }        $message = $this->format;        foreach ($this->generate($finish) as $name => $value) {            $message = str_replace("%{$name}%", $value, $message);        }        $this->overwrite($this->output, $message);    }    /**     * Removes the progress bar from the current line.     *     * This is useful if you wish to write some output     * while a progress bar is running.     * Call display() to show the progress bar again.     */    public function clear()    {        $this->overwrite($this->output, '');    }    /**     * Finishes the progress output.     */    public function finish()    {        if (null === $this->startTime) {            throw new \LogicException('You must start the progress bar before calling finish().');        }        if (null !== $this->startTime) {            if (!$this->max) {                $this->barChar = $this->barCharOriginal;                $this->display(true);            }            $this->startTime = null;            $this->output->writeln('');            $this->output = null;        }    }    /**     * Initializes the progress helper.     */    private function initialize()    {        $this->formatVars = array();        foreach ($this->defaultFormatVars as $var) {            if (false !== strpos($this->format, "%{$var}%")) {                $this->formatVars[$var] = true;            }        }        if ($this->max > 0) {            $this->widths['max'] = $this->strlen($this->max);            $this->widths['current'] = $this->widths['max'];        } else {            $this->barCharOriginal = $this->barChar;            $this->barChar = $this->emptyBarChar;        }    }    /**     * Generates the array map of format variables to values.     *     * @param bool $finish Forces the end result     *     * @return array Array of format vars and values     */    private function generate($finish = false)    {        $vars = array();        $percent = 0;        if ($this->max > 0) {            $percent = (float) $this->current / $this->max;        }        if (isset($this->formatVars['bar'])) {            $completeBars = 0;            if ($this->max > 0) {                $completeBars = floor($percent * $this->barWidth);            } else {                if (!$finish) {                    $completeBars = floor($this->current % $this->barWidth);                } else {                    $completeBars = $this->barWidth;                }            }            $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar);            $bar = str_repeat($this->barChar, $completeBars);            if ($completeBars < $this->barWidth) {                $bar .= $this->progressChar;                $bar .= str_repeat($this->emptyBarChar, $emptyBars);            }            $vars['bar'] = $bar;        }        if (isset($this->formatVars['elapsed'])) {            $elapsed = time() - $this->startTime;            $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT);        }        if (isset($this->formatVars['current'])) {            $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT);        }        if (isset($this->formatVars['max'])) {            $vars['max'] = $this->max;        }        if (isset($this->formatVars['percent'])) {            $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT);        }        return $vars;    }    /**     * Converts seconds into human-readable format.     *     * @param int $secs Number of seconds     *     * @return string Time in readable format     */    private function humaneTime($secs)    {        $text = '';        foreach ($this->timeFormats as $format) {            if ($secs < $format[0]) {                if (count($format) == 2) {                    $text = $format[1];                    break;                } else {                    $text = ceil($secs / $format[2]).' '.$format[1];                    break;                }            }        }        return $text;    }    /**     * Overwrites a previous message to the output.     *     * @param OutputInterface $output  An Output instance     * @param string          $message The message     */    private function overwrite(OutputInterface $output, $message)    {        $length = $this->strlen($message);        // append whitespace to match the last line's length        if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) {            $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);        }        // carriage return        $output->write("\x0D");        $output->write($message);        $this->lastMessagesLength = $this->strlen($message);    }    /**     * {@inheritdoc}     */    public function getName()    {        return 'progress';    }}
 |