Version 1
[yaffs-website] / vendor / symfony / console / Helper / ProgressIndicator.php
diff --git a/vendor/symfony/console/Helper/ProgressIndicator.php b/vendor/symfony/console/Helper/ProgressIndicator.php
new file mode 100644 (file)
index 0000000..2e43bc3
--- /dev/null
@@ -0,0 +1,307 @@
+<?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\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @author Kevin Bond <kevinbond@gmail.com>
+ */
+class ProgressIndicator
+{
+    private $output;
+    private $startTime;
+    private $format;
+    private $message;
+    private $indicatorValues;
+    private $indicatorCurrent;
+    private $indicatorChangeInterval;
+    private $indicatorUpdateTime;
+    private $started = false;
+
+    private static $formatters;
+    private static $formats;
+
+    /**
+     * @param OutputInterface $output
+     * @param string|null     $format                  Indicator format
+     * @param int             $indicatorChangeInterval Change interval in milliseconds
+     * @param array|null      $indicatorValues         Animated indicator characters
+     */
+    public function __construct(OutputInterface $output, $format = null, $indicatorChangeInterval = 100, $indicatorValues = null)
+    {
+        $this->output = $output;
+
+        if (null === $format) {
+            $format = $this->determineBestFormat();
+        }
+
+        if (null === $indicatorValues) {
+            $indicatorValues = array('-', '\\', '|', '/');
+        }
+
+        $indicatorValues = array_values($indicatorValues);
+
+        if (2 > count($indicatorValues)) {
+            throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
+        }
+
+        $this->format = self::getFormatDefinition($format);
+        $this->indicatorChangeInterval = $indicatorChangeInterval;
+        $this->indicatorValues = $indicatorValues;
+        $this->startTime = time();
+    }
+
+    /**
+     * Sets the current indicator message.
+     *
+     * @param string|null $message
+     */
+    public function setMessage($message)
+    {
+        $this->message = $message;
+
+        $this->display();
+    }
+
+    /**
+     * Gets the current indicator message.
+     *
+     * @return string|null
+     *
+     * @internal for PHP 5.3 compatibility
+     */
+    public function getMessage()
+    {
+        return $this->message;
+    }
+
+    /**
+     * Gets the progress bar start time.
+     *
+     * @return int The progress bar start time
+     *
+     * @internal for PHP 5.3 compatibility
+     */
+    public function getStartTime()
+    {
+        return $this->startTime;
+    }
+
+    /**
+     * Gets the current animated indicator character.
+     *
+     * @return string
+     *
+     * @internal for PHP 5.3 compatibility
+     */
+    public function getCurrentValue()
+    {
+        return $this->indicatorValues[$this->indicatorCurrent % count($this->indicatorValues)];
+    }
+
+    /**
+     * Starts the indicator output.
+     *
+     * @param $message
+     */
+    public function start($message)
+    {
+        if ($this->started) {
+            throw new LogicException('Progress indicator already started.');
+        }
+
+        $this->message = $message;
+        $this->started = true;
+        $this->startTime = time();
+        $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
+        $this->indicatorCurrent = 0;
+
+        $this->display();
+    }
+
+    /**
+     * Advances the indicator.
+     */
+    public function advance()
+    {
+        if (!$this->started) {
+            throw new LogicException('Progress indicator has not yet been started.');
+        }
+
+        if (!$this->output->isDecorated()) {
+            return;
+        }
+
+        $currentTime = $this->getCurrentTimeInMilliseconds();
+
+        if ($currentTime < $this->indicatorUpdateTime) {
+            return;
+        }
+
+        $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
+        ++$this->indicatorCurrent;
+
+        $this->display();
+    }
+
+    /**
+     * Finish the indicator with message.
+     *
+     * @param $message
+     */
+    public function finish($message)
+    {
+        if (!$this->started) {
+            throw new LogicException('Progress indicator has not yet been started.');
+        }
+
+        $this->message = $message;
+        $this->display();
+        $this->output->writeln('');
+        $this->started = false;
+    }
+
+    /**
+     * Gets the format for a given name.
+     *
+     * @param string $name The format name
+     *
+     * @return string|null A format string
+     */
+    public static function getFormatDefinition($name)
+    {
+        if (!self::$formats) {
+            self::$formats = self::initFormats();
+        }
+
+        return isset(self::$formats[$name]) ? self::$formats[$name] : null;
+    }
+
+    /**
+     * Sets a placeholder formatter for a given name.
+     *
+     * This method also allow you to override an existing placeholder.
+     *
+     * @param string   $name     The placeholder name (including the delimiter char like %)
+     * @param callable $callable A PHP callable
+     */
+    public static function setPlaceholderFormatterDefinition($name, $callable)
+    {
+        if (!self::$formatters) {
+            self::$formatters = self::initPlaceholderFormatters();
+        }
+
+        self::$formatters[$name] = $callable;
+    }
+
+    /**
+     * Gets the placeholder formatter for a given name.
+     *
+     * @param string $name The placeholder name (including the delimiter char like %)
+     *
+     * @return callable|null A PHP callable
+     */
+    public static function getPlaceholderFormatterDefinition($name)
+    {
+        if (!self::$formatters) {
+            self::$formatters = self::initPlaceholderFormatters();
+        }
+
+        return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
+    }
+
+    private function display()
+    {
+        if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
+            return;
+        }
+
+        $self = $this;
+
+        $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
+            if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
+                return call_user_func($formatter, $self);
+            }
+
+            return $matches[0];
+        }, $this->format));
+    }
+
+    private function determineBestFormat()
+    {
+        switch ($this->output->getVerbosity()) {
+            // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
+            case OutputInterface::VERBOSITY_VERBOSE:
+                return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
+            case OutputInterface::VERBOSITY_VERY_VERBOSE:
+            case OutputInterface::VERBOSITY_DEBUG:
+                return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
+            default:
+                return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
+        }
+    }
+
+    /**
+     * Overwrites a previous message to the output.
+     *
+     * @param string $message The message
+     */
+    private function overwrite($message)
+    {
+        if ($this->output->isDecorated()) {
+            $this->output->write("\x0D\x1B[2K");
+            $this->output->write($message);
+        } else {
+            $this->output->writeln($message);
+        }
+    }
+
+    private function getCurrentTimeInMilliseconds()
+    {
+        return round(microtime(true) * 1000);
+    }
+
+    private static function initPlaceholderFormatters()
+    {
+        return array(
+            'indicator' => function (ProgressIndicator $indicator) {
+                return $indicator->getCurrentValue();
+            },
+            'message' => function (ProgressIndicator $indicator) {
+                return $indicator->getMessage();
+            },
+            'elapsed' => function (ProgressIndicator $indicator) {
+                return Helper::formatTime(time() - $indicator->getStartTime());
+            },
+            'memory' => function () {
+                return Helper::formatMemory(memory_get_usage(true));
+            },
+        );
+    }
+
+    private static function initFormats()
+    {
+        return array(
+            'normal' => ' %indicator% %message%',
+            'normal_no_ansi' => ' %message%',
+
+            'verbose' => ' %indicator% %message% (%elapsed:6s%)',
+            'verbose_no_ansi' => ' %message% (%elapsed:6s%)',
+
+            'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)',
+            'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
+        );
+    }
+}