Initial commit
This commit is contained in:
		
							
								
								
									
										362
									
								
								content/vendor/splitbrain/php-cli/src/CLI.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										362
									
								
								content/vendor/splitbrain/php-cli/src/CLI.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,362 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace splitbrain\phpcli;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class CLI
 | 
			
		||||
 *
 | 
			
		||||
 * Your commandline script should inherit from this class and implement the abstract methods.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Andreas Gohr <andi@splitbrain.org>
 | 
			
		||||
 * @license MIT
 | 
			
		||||
 */
 | 
			
		||||
abstract class CLI
 | 
			
		||||
{
 | 
			
		||||
    /** @var string the executed script itself */
 | 
			
		||||
    protected $bin;
 | 
			
		||||
    /** @var  Options the option parser */
 | 
			
		||||
    protected $options;
 | 
			
		||||
    /** @var  Colors */
 | 
			
		||||
    public $colors;
 | 
			
		||||
 | 
			
		||||
    /** @var array PSR-3 compatible loglevels and their prefix, color, output channel */
 | 
			
		||||
    protected $loglevel = array(
 | 
			
		||||
        'debug' => array('', Colors::C_RESET, STDOUT),
 | 
			
		||||
        'info' => array('ℹ ', Colors::C_CYAN, STDOUT),
 | 
			
		||||
        'notice' => array('☛ ', Colors::C_CYAN, STDOUT),
 | 
			
		||||
        'success' => array('✓ ', Colors::C_GREEN, STDOUT),
 | 
			
		||||
        'warning' => array('⚠ ', Colors::C_BROWN, STDERR),
 | 
			
		||||
        'error' => array('✗ ', Colors::C_RED, STDERR),
 | 
			
		||||
        'critical' => array('☠ ', Colors::C_LIGHTRED, STDERR),
 | 
			
		||||
        'alert' => array('✖ ', Colors::C_LIGHTRED, STDERR),
 | 
			
		||||
        'emergency' => array('✘ ', Colors::C_LIGHTRED, STDERR),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    protected $logdefault = 'info';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * constructor
 | 
			
		||||
     *
 | 
			
		||||
     * Initialize the arguments, set up helper classes and set up the CLI environment
 | 
			
		||||
     *
 | 
			
		||||
     * @param bool $autocatch should exceptions be catched and handled automatically?
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($autocatch = true)
 | 
			
		||||
    {
 | 
			
		||||
        if ($autocatch) {
 | 
			
		||||
            set_exception_handler(array($this, 'fatal'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->colors = new Colors();
 | 
			
		||||
        $this->options = new Options($this->colors);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register options and arguments on the given $options object
 | 
			
		||||
     *
 | 
			
		||||
     * @param Options $options
 | 
			
		||||
     * @return void
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    abstract protected function setup(Options $options);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Your main program
 | 
			
		||||
     *
 | 
			
		||||
     * Arguments and options have been parsed when this is run
 | 
			
		||||
     *
 | 
			
		||||
     * @param Options $options
 | 
			
		||||
     * @return void
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    abstract protected function main(Options $options);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the CLI program
 | 
			
		||||
     *
 | 
			
		||||
     * Executes the setup() routine, adds default options, initiate the options parsing and argument checking
 | 
			
		||||
     * and finally executes main() - Each part is split into their own protected function below, so behaviour
 | 
			
		||||
     * can easily be overwritten
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function run()
 | 
			
		||||
    {
 | 
			
		||||
        if ('cli' != php_sapi_name()) {
 | 
			
		||||
            throw new Exception('This has to be run from the command line');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->setup($this->options);
 | 
			
		||||
        $this->registerDefaultOptions();
 | 
			
		||||
        $this->parseOptions();
 | 
			
		||||
        $this->handleDefaultOptions();
 | 
			
		||||
        $this->setupLogging();
 | 
			
		||||
        $this->checkArgments();
 | 
			
		||||
        $this->execute();
 | 
			
		||||
 | 
			
		||||
        exit(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // region run handlers - for easier overriding
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add the default help, color and log options
 | 
			
		||||
     */
 | 
			
		||||
    protected function registerDefaultOptions()
 | 
			
		||||
    {
 | 
			
		||||
        $this->options->registerOption(
 | 
			
		||||
            'help',
 | 
			
		||||
            'Display this help screen and exit immediately.',
 | 
			
		||||
            'h'
 | 
			
		||||
        );
 | 
			
		||||
        $this->options->registerOption(
 | 
			
		||||
            'no-colors',
 | 
			
		||||
            'Do not use any colors in output. Useful when piping output to other tools or files.'
 | 
			
		||||
        );
 | 
			
		||||
        $this->options->registerOption(
 | 
			
		||||
            'loglevel',
 | 
			
		||||
            'Minimum level of messages to display. Default is ' . $this->colors->wrap($this->logdefault, Colors::C_CYAN) . '. ' .
 | 
			
		||||
            'Valid levels are: debug, info, notice, success, warning, error, critical, alert, emergency.',
 | 
			
		||||
            null,
 | 
			
		||||
            'level'
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle the default options
 | 
			
		||||
     */
 | 
			
		||||
    protected function handleDefaultOptions()
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->options->getOpt('no-colors')) {
 | 
			
		||||
            $this->colors->disable();
 | 
			
		||||
        }
 | 
			
		||||
        if ($this->options->getOpt('help')) {
 | 
			
		||||
            echo $this->options->help();
 | 
			
		||||
            exit(0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle the logging options
 | 
			
		||||
     */
 | 
			
		||||
    protected function setupLogging()
 | 
			
		||||
    {
 | 
			
		||||
        $level = $this->options->getOpt('loglevel', $this->logdefault);
 | 
			
		||||
        if (!isset($this->loglevel[$level])) $this->fatal('Unknown log level');
 | 
			
		||||
        foreach (array_keys($this->loglevel) as $l) {
 | 
			
		||||
            if ($l == $level) break;
 | 
			
		||||
            unset($this->loglevel[$l]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Wrapper around the option parsing
 | 
			
		||||
     */
 | 
			
		||||
    protected function parseOptions()
 | 
			
		||||
    {
 | 
			
		||||
        $this->options->parseOptions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Wrapper around the argument checking
 | 
			
		||||
     */
 | 
			
		||||
    protected function checkArgments()
 | 
			
		||||
    {
 | 
			
		||||
        $this->options->checkArguments();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Wrapper around main
 | 
			
		||||
     */
 | 
			
		||||
    protected function execute()
 | 
			
		||||
    {
 | 
			
		||||
        $this->main($this->options);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // endregion
 | 
			
		||||
 | 
			
		||||
    // region logging
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Exits the program on a fatal error
 | 
			
		||||
     *
 | 
			
		||||
     * @param \Exception|string $error either an exception or an error message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function fatal($error, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $code = 0;
 | 
			
		||||
        if (is_object($error) && is_a($error, 'Exception')) {
 | 
			
		||||
            /** @var Exception $error */
 | 
			
		||||
            $this->debug(get_class($error) . ' caught in ' . $error->getFile() . ':' . $error->getLine());
 | 
			
		||||
            $this->debug($error->getTraceAsString());
 | 
			
		||||
            $code = $error->getCode();
 | 
			
		||||
            $error = $error->getMessage();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        if (!$code) {
 | 
			
		||||
            $code = Exception::E_ANY;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->critical($error, $context);
 | 
			
		||||
        exit($code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * System is unusable.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function emergency($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('emergency', $message, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Action must be taken immediately.
 | 
			
		||||
     *
 | 
			
		||||
     * Example: Entire website down, database unavailable, etc. This should
 | 
			
		||||
     * trigger the SMS alerts and wake you up.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function alert($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('alert', $message, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Critical conditions.
 | 
			
		||||
     *
 | 
			
		||||
     * Example: Application component unavailable, unexpected exception.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function critical($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('critical', $message, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Runtime errors that do not require immediate action but should typically
 | 
			
		||||
     * be logged and monitored.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function error($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('error', $message, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Exceptional occurrences that are not errors.
 | 
			
		||||
     *
 | 
			
		||||
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
 | 
			
		||||
     * that are not necessarily wrong.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function warning($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('warning', $message, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normal, positive outcome
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $string
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function success($string, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('success', $string, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normal but significant events.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function notice($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('notice', $message, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Interesting events.
 | 
			
		||||
     *
 | 
			
		||||
     * Example: User logs in, SQL logs.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function info($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('info', $message, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Detailed debug information.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function debug($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->log('debug', $message, $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $level
 | 
			
		||||
     * @param string $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     */
 | 
			
		||||
    public function log($level, $message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        // is this log level wanted?
 | 
			
		||||
        if (!isset($this->loglevel[$level])) return;
 | 
			
		||||
 | 
			
		||||
        /** @var string $prefix */
 | 
			
		||||
        /** @var string $color */
 | 
			
		||||
        /** @var resource $channel */
 | 
			
		||||
        list($prefix, $color, $channel) = $this->loglevel[$level];
 | 
			
		||||
        if (!$this->colors->isEnabled()) $prefix = '';
 | 
			
		||||
 | 
			
		||||
        $message = $this->interpolate($message, $context);
 | 
			
		||||
        $this->colors->ptln($prefix . $message, $color, $channel);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Interpolates context values into the message placeholders.
 | 
			
		||||
     *
 | 
			
		||||
     * @param $message
 | 
			
		||||
     * @param array $context
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    function interpolate($message, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        // build a replacement array with braces around the context keys
 | 
			
		||||
        $replace = array();
 | 
			
		||||
        foreach ($context as $key => $val) {
 | 
			
		||||
            // check that the value can be casted to string
 | 
			
		||||
            if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
 | 
			
		||||
                $replace['{' . $key . '}'] = $val;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // interpolate replacement values into the message and return
 | 
			
		||||
        return strtr($message, $replace);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // endregion
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										170
									
								
								content/vendor/splitbrain/php-cli/src/Colors.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								content/vendor/splitbrain/php-cli/src/Colors.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace splitbrain\phpcli;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class Colors
 | 
			
		||||
 *
 | 
			
		||||
 * Handles color output on (Linux) terminals
 | 
			
		||||
 *
 | 
			
		||||
 * @author Andreas Gohr <andi@splitbrain.org>
 | 
			
		||||
 * @license MIT
 | 
			
		||||
 */
 | 
			
		||||
class Colors
 | 
			
		||||
{
 | 
			
		||||
    // these constants make IDE autocompletion easier, but color names can also be passed as strings
 | 
			
		||||
    const C_RESET = 'reset';
 | 
			
		||||
    const C_BLACK = 'black';
 | 
			
		||||
    const C_DARKGRAY = 'darkgray';
 | 
			
		||||
    const C_BLUE = 'blue';
 | 
			
		||||
    const C_LIGHTBLUE = 'lightblue';
 | 
			
		||||
    const C_GREEN = 'green';
 | 
			
		||||
    const C_LIGHTGREEN = 'lightgreen';
 | 
			
		||||
    const C_CYAN = 'cyan';
 | 
			
		||||
    const C_LIGHTCYAN = 'lightcyan';
 | 
			
		||||
    const C_RED = 'red';
 | 
			
		||||
    const C_LIGHTRED = 'lightred';
 | 
			
		||||
    const C_PURPLE = 'purple';
 | 
			
		||||
    const C_LIGHTPURPLE = 'lightpurple';
 | 
			
		||||
    const C_BROWN = 'brown';
 | 
			
		||||
    const C_YELLOW = 'yellow';
 | 
			
		||||
    const C_LIGHTGRAY = 'lightgray';
 | 
			
		||||
    const C_WHITE = 'white';
 | 
			
		||||
 | 
			
		||||
    /** @var array known color names */
 | 
			
		||||
    protected $colors = array(
 | 
			
		||||
        self::C_RESET => "\33[0m",
 | 
			
		||||
        self::C_BLACK => "\33[0;30m",
 | 
			
		||||
        self::C_DARKGRAY => "\33[1;30m",
 | 
			
		||||
        self::C_BLUE => "\33[0;34m",
 | 
			
		||||
        self::C_LIGHTBLUE => "\33[1;34m",
 | 
			
		||||
        self::C_GREEN => "\33[0;32m",
 | 
			
		||||
        self::C_LIGHTGREEN => "\33[1;32m",
 | 
			
		||||
        self::C_CYAN => "\33[0;36m",
 | 
			
		||||
        self::C_LIGHTCYAN => "\33[1;36m",
 | 
			
		||||
        self::C_RED => "\33[0;31m",
 | 
			
		||||
        self::C_LIGHTRED => "\33[1;31m",
 | 
			
		||||
        self::C_PURPLE => "\33[0;35m",
 | 
			
		||||
        self::C_LIGHTPURPLE => "\33[1;35m",
 | 
			
		||||
        self::C_BROWN => "\33[0;33m",
 | 
			
		||||
        self::C_YELLOW => "\33[1;33m",
 | 
			
		||||
        self::C_LIGHTGRAY => "\33[0;37m",
 | 
			
		||||
        self::C_WHITE => "\33[1;37m",
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /** @var bool should colors be used? */
 | 
			
		||||
    protected $enabled = true;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
     * Tries to disable colors for non-terminals
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        if (function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
 | 
			
		||||
            $this->enabled = false;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (!getenv('TERM')) {
 | 
			
		||||
            $this->enabled = false;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * enable color output
 | 
			
		||||
     */
 | 
			
		||||
    public function enable()
 | 
			
		||||
    {
 | 
			
		||||
        $this->enabled = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * disable color output
 | 
			
		||||
     */
 | 
			
		||||
    public function disable()
 | 
			
		||||
    {
 | 
			
		||||
        $this->enabled = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return bool is color support enabled?
 | 
			
		||||
     */
 | 
			
		||||
    public function isEnabled()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->enabled;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convenience function to print a line in a given color
 | 
			
		||||
     *
 | 
			
		||||
     * @param string   $line    the line to print, a new line is added automatically
 | 
			
		||||
     * @param string   $color   one of the available color names
 | 
			
		||||
     * @param resource $channel file descriptor to write to
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function ptln($line, $color, $channel = STDOUT)
 | 
			
		||||
    {
 | 
			
		||||
        $this->set($color);
 | 
			
		||||
        fwrite($channel, rtrim($line) . "\n");
 | 
			
		||||
        $this->reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the given text wrapped in the appropriate color and reset code
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $text string to wrap
 | 
			
		||||
     * @param string $color one of the available color names
 | 
			
		||||
     * @return string the wrapped string
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function wrap($text, $color)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->getColorCode($color) . $text . $this->getColorCode('reset');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the appropriate terminal code for the given color
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $color one of the available color names
 | 
			
		||||
     * @return string color code
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function getColorCode($color)
 | 
			
		||||
    {
 | 
			
		||||
        if (!$this->enabled) {
 | 
			
		||||
            return '';
 | 
			
		||||
        }
 | 
			
		||||
        if (!isset($this->colors[$color])) {
 | 
			
		||||
            throw new Exception("No such color $color");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->colors[$color];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the given color for consecutive output
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $color one of the supported color names
 | 
			
		||||
     * @param resource $channel file descriptor to write to
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function set($color, $channel = STDOUT)
 | 
			
		||||
    {
 | 
			
		||||
        fwrite($channel, $this->getColorCode($color));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * reset the terminal color
 | 
			
		||||
     *
 | 
			
		||||
     * @param resource $channel file descriptor to write to
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function reset($channel = STDOUT)
 | 
			
		||||
    {
 | 
			
		||||
        $this->set('reset', $channel);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								content/vendor/splitbrain/php-cli/src/Exception.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								content/vendor/splitbrain/php-cli/src/Exception.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace splitbrain\phpcli;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class Exception
 | 
			
		||||
 *
 | 
			
		||||
 * The code is used as exit code for the CLI tool. This should probably be extended. Many cases just fall back to the
 | 
			
		||||
 * E_ANY code.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Andreas Gohr <andi@splitbrain.org>
 | 
			
		||||
 * @license MIT
 | 
			
		||||
 */
 | 
			
		||||
class Exception extends \RuntimeException
 | 
			
		||||
{
 | 
			
		||||
    const E_ANY = -1; // no error code specified
 | 
			
		||||
    const E_UNKNOWN_OPT = 1; //Unrecognized option
 | 
			
		||||
    const E_OPT_ARG_REQUIRED = 2; //Option requires argument
 | 
			
		||||
    const E_OPT_ARG_DENIED = 3; //Option not allowed argument
 | 
			
		||||
    const E_OPT_ABIGUOUS = 4; //Option abiguous
 | 
			
		||||
    const E_ARG_READ = 5; //Could not read argv
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $message The Exception message to throw.
 | 
			
		||||
     * @param int $code The Exception code
 | 
			
		||||
     * @param \Exception $previous The previous exception used for the exception chaining.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($message = "", $code = 0, \Exception $previous = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (!$code) {
 | 
			
		||||
            $code = self::E_ANY;
 | 
			
		||||
        }
 | 
			
		||||
        parent::__construct($message, $code, $previous);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										478
									
								
								content/vendor/splitbrain/php-cli/src/Options.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										478
									
								
								content/vendor/splitbrain/php-cli/src/Options.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,478 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace splitbrain\phpcli;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class Options
 | 
			
		||||
 *
 | 
			
		||||
 * Parses command line options passed to the CLI script. Allows CLI scripts to easily register all accepted options and
 | 
			
		||||
 * commands and even generates a help text from this setup.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Andreas Gohr <andi@splitbrain.org>
 | 
			
		||||
 * @license MIT
 | 
			
		||||
 */
 | 
			
		||||
class Options
 | 
			
		||||
{
 | 
			
		||||
    /** @var  array keeps the list of options to parse */
 | 
			
		||||
    protected $setup;
 | 
			
		||||
 | 
			
		||||
    /** @var  array store parsed options */
 | 
			
		||||
    protected $options = array();
 | 
			
		||||
 | 
			
		||||
    /** @var string current parsed command if any */
 | 
			
		||||
    protected $command = '';
 | 
			
		||||
 | 
			
		||||
    /** @var  array passed non-option arguments */
 | 
			
		||||
    protected $args = array();
 | 
			
		||||
 | 
			
		||||
    /** @var  string the executed script */
 | 
			
		||||
    protected $bin;
 | 
			
		||||
 | 
			
		||||
    /** @var  Colors for colored help output */
 | 
			
		||||
    protected $colors;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
     * @param Colors $colors optional configured color object
 | 
			
		||||
     * @throws Exception when arguments can't be read
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Colors $colors = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (!is_null($colors)) {
 | 
			
		||||
            $this->colors = $colors;
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->colors = new Colors();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->setup = array(
 | 
			
		||||
            '' => array(
 | 
			
		||||
                'opts' => array(),
 | 
			
		||||
                'args' => array(),
 | 
			
		||||
                'help' => ''
 | 
			
		||||
            )
 | 
			
		||||
        ); // default command
 | 
			
		||||
 | 
			
		||||
        $this->args = $this->readPHPArgv();
 | 
			
		||||
        $this->bin = basename(array_shift($this->args));
 | 
			
		||||
 | 
			
		||||
        $this->options = array();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the bin value
 | 
			
		||||
     */
 | 
			
		||||
    public function getBin()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->bin;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the help text for the tool itself
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $help
 | 
			
		||||
     */
 | 
			
		||||
    public function setHelp($help)
 | 
			
		||||
    {
 | 
			
		||||
        $this->setup['']['help'] = $help;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register the names of arguments for help generation and number checking
 | 
			
		||||
     *
 | 
			
		||||
     * This has to be called in the order arguments are expected
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $arg argument name (just for help)
 | 
			
		||||
     * @param string $help help text
 | 
			
		||||
     * @param bool $required is this a required argument
 | 
			
		||||
     * @param string $command if theses apply to a sub command only
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function registerArgument($arg, $help, $required = true, $command = '')
 | 
			
		||||
    {
 | 
			
		||||
        if (!isset($this->setup[$command])) {
 | 
			
		||||
            throw new Exception("Command $command not registered");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->setup[$command]['args'][] = array(
 | 
			
		||||
            'name' => $arg,
 | 
			
		||||
            'help' => $help,
 | 
			
		||||
            'required' => $required
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This registers a sub command
 | 
			
		||||
     *
 | 
			
		||||
     * Sub commands have their own options and use their own function (not main()).
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $command
 | 
			
		||||
     * @param string $help
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function registerCommand($command, $help)
 | 
			
		||||
    {
 | 
			
		||||
        if (isset($this->setup[$command])) {
 | 
			
		||||
            throw new Exception("Command $command already registered");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->setup[$command] = array(
 | 
			
		||||
            'opts' => array(),
 | 
			
		||||
            'args' => array(),
 | 
			
		||||
            'help' => $help
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register an option for option parsing and help generation
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $long multi character option (specified with --)
 | 
			
		||||
     * @param string $help help text for this option
 | 
			
		||||
     * @param string|null $short one character option (specified with -)
 | 
			
		||||
     * @param bool|string $needsarg does this option require an argument? give it a name here
 | 
			
		||||
     * @param string $command what command does this option apply to
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function registerOption($long, $help, $short = null, $needsarg = false, $command = '')
 | 
			
		||||
    {
 | 
			
		||||
        if (!isset($this->setup[$command])) {
 | 
			
		||||
            throw new Exception("Command $command not registered");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->setup[$command]['opts'][$long] = array(
 | 
			
		||||
            'needsarg' => $needsarg,
 | 
			
		||||
            'help' => $help,
 | 
			
		||||
            'short' => $short
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if ($short) {
 | 
			
		||||
            if (strlen($short) > 1) {
 | 
			
		||||
                throw new Exception("Short options should be exactly one ASCII character");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $this->setup[$command]['short'][$short] = $long;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks the actual number of arguments against the required number
 | 
			
		||||
     *
 | 
			
		||||
     * Throws an exception if arguments are missing.
 | 
			
		||||
     *
 | 
			
		||||
     * This is run from CLI automatically and usually does not need to be called directly
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function checkArguments()
 | 
			
		||||
    {
 | 
			
		||||
        $argc = count($this->args);
 | 
			
		||||
 | 
			
		||||
        $req = 0;
 | 
			
		||||
        foreach ($this->setup[$this->command]['args'] as $arg) {
 | 
			
		||||
            if (!$arg['required']) {
 | 
			
		||||
                break;
 | 
			
		||||
            } // last required arguments seen
 | 
			
		||||
            $req++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($req > $argc) {
 | 
			
		||||
            throw new Exception("Not enough arguments", Exception::E_OPT_ARG_REQUIRED);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses the given arguments for known options and command
 | 
			
		||||
     *
 | 
			
		||||
     * The given $args array should NOT contain the executed file as first item anymore! The $args
 | 
			
		||||
     * array is stripped from any options and possible command. All found otions can be accessed via the
 | 
			
		||||
     * getOpt() function
 | 
			
		||||
     *
 | 
			
		||||
     * Note that command options will overwrite any global options with the same name
 | 
			
		||||
     *
 | 
			
		||||
     * This is run from CLI automatically and usually does not need to be called directly
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function parseOptions()
 | 
			
		||||
    {
 | 
			
		||||
        $non_opts = array();
 | 
			
		||||
 | 
			
		||||
        $argc = count($this->args);
 | 
			
		||||
        for ($i = 0; $i < $argc; $i++) {
 | 
			
		||||
            $arg = $this->args[$i];
 | 
			
		||||
 | 
			
		||||
            // The special element '--' means explicit end of options. Treat the rest of the arguments as non-options
 | 
			
		||||
            // and end the loop.
 | 
			
		||||
            if ($arg == '--') {
 | 
			
		||||
                $non_opts = array_merge($non_opts, array_slice($this->args, $i + 1));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // '-' is stdin - a normal argument
 | 
			
		||||
            if ($arg == '-') {
 | 
			
		||||
                $non_opts = array_merge($non_opts, array_slice($this->args, $i));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // first non-option
 | 
			
		||||
            if ($arg[0] != '-') {
 | 
			
		||||
                $non_opts = array_merge($non_opts, array_slice($this->args, $i));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // long option
 | 
			
		||||
            if (strlen($arg) > 1 && $arg[1] === '-') {
 | 
			
		||||
                $arg = explode('=', substr($arg, 2), 2);
 | 
			
		||||
                $opt = array_shift($arg);
 | 
			
		||||
                $val = array_shift($arg);
 | 
			
		||||
 | 
			
		||||
                if (!isset($this->setup[$this->command]['opts'][$opt])) {
 | 
			
		||||
                    throw new Exception("No such option '$opt'", Exception::E_UNKNOWN_OPT);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // argument required?
 | 
			
		||||
                if ($this->setup[$this->command]['opts'][$opt]['needsarg']) {
 | 
			
		||||
                    if (is_null($val) && $i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
 | 
			
		||||
                        $val = $this->args[++$i];
 | 
			
		||||
                    }
 | 
			
		||||
                    if (is_null($val)) {
 | 
			
		||||
                        throw new Exception("Option $opt requires an argument",
 | 
			
		||||
                            Exception::E_OPT_ARG_REQUIRED);
 | 
			
		||||
                    }
 | 
			
		||||
                    $this->options[$opt] = $val;
 | 
			
		||||
                } else {
 | 
			
		||||
                    $this->options[$opt] = true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // short option
 | 
			
		||||
            $opt = substr($arg, 1);
 | 
			
		||||
            if (!isset($this->setup[$this->command]['short'][$opt])) {
 | 
			
		||||
                throw new Exception("No such option $arg", Exception::E_UNKNOWN_OPT);
 | 
			
		||||
            } else {
 | 
			
		||||
                $opt = $this->setup[$this->command]['short'][$opt]; // store it under long name
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // argument required?
 | 
			
		||||
            if ($this->setup[$this->command]['opts'][$opt]['needsarg']) {
 | 
			
		||||
                $val = null;
 | 
			
		||||
                if ($i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
 | 
			
		||||
                    $val = $this->args[++$i];
 | 
			
		||||
                }
 | 
			
		||||
                if (is_null($val)) {
 | 
			
		||||
                    throw new Exception("Option $arg requires an argument",
 | 
			
		||||
                        Exception::E_OPT_ARG_REQUIRED);
 | 
			
		||||
                }
 | 
			
		||||
                $this->options[$opt] = $val;
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->options[$opt] = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // parsing is now done, update args array
 | 
			
		||||
        $this->args = $non_opts;
 | 
			
		||||
 | 
			
		||||
        // if not done yet, check if first argument is a command and reexecute argument parsing if it is
 | 
			
		||||
        if (!$this->command && $this->args && isset($this->setup[$this->args[0]])) {
 | 
			
		||||
            // it is a command!
 | 
			
		||||
            $this->command = array_shift($this->args);
 | 
			
		||||
            $this->parseOptions(); // second pass
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the value of the given option
 | 
			
		||||
     *
 | 
			
		||||
     * Please note that all options are accessed by their long option names regardless of how they were
 | 
			
		||||
     * specified on commandline.
 | 
			
		||||
     *
 | 
			
		||||
     * Can only be used after parseOptions() has been run
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $option
 | 
			
		||||
     * @param bool|string $default what to return if the option was not set
 | 
			
		||||
     * @return bool|string|string[]
 | 
			
		||||
     */
 | 
			
		||||
    public function getOpt($option = null, $default = false)
 | 
			
		||||
    {
 | 
			
		||||
        if ($option === null) {
 | 
			
		||||
            return $this->options;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isset($this->options[$option])) {
 | 
			
		||||
            return $this->options[$option];
 | 
			
		||||
        }
 | 
			
		||||
        return $default;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return the found command if any
 | 
			
		||||
     *
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getCmd()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->command;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all the arguments passed to the script
 | 
			
		||||
     *
 | 
			
		||||
     * This will not contain any recognized options or the script name itself
 | 
			
		||||
     *
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    public function getArgs()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->args;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Builds a help screen from the available options. You may want to call it from -h or on error
 | 
			
		||||
     *
 | 
			
		||||
     * @return string
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function help()
 | 
			
		||||
    {
 | 
			
		||||
        $tf = new TableFormatter($this->colors);
 | 
			
		||||
        $text = '';
 | 
			
		||||
 | 
			
		||||
        $hascommands = (count($this->setup) > 1);
 | 
			
		||||
        foreach ($this->setup as $command => $config) {
 | 
			
		||||
            $hasopts = (bool)$this->setup[$command]['opts'];
 | 
			
		||||
            $hasargs = (bool)$this->setup[$command]['args'];
 | 
			
		||||
 | 
			
		||||
            // usage or command syntax line
 | 
			
		||||
            if (!$command) {
 | 
			
		||||
                $text .= $this->colors->wrap('USAGE:', Colors::C_BROWN);
 | 
			
		||||
                $text .= "\n";
 | 
			
		||||
                $text .= '   ' . $this->bin;
 | 
			
		||||
                $mv = 2;
 | 
			
		||||
            } else {
 | 
			
		||||
                $text .= "\n";
 | 
			
		||||
                $text .= $this->colors->wrap('   ' . $command, Colors::C_PURPLE);
 | 
			
		||||
                $mv = 4;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($hasopts) {
 | 
			
		||||
                $text .= ' ' . $this->colors->wrap('<OPTIONS>', Colors::C_GREEN);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!$command && $hascommands) {
 | 
			
		||||
                $text .= ' ' . $this->colors->wrap('<COMMAND> ...', Colors::C_PURPLE);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach ($this->setup[$command]['args'] as $arg) {
 | 
			
		||||
                $out = $this->colors->wrap('<' . $arg['name'] . '>', Colors::C_CYAN);
 | 
			
		||||
 | 
			
		||||
                if (!$arg['required']) {
 | 
			
		||||
                    $out = '[' . $out . ']';
 | 
			
		||||
                }
 | 
			
		||||
                $text .= ' ' . $out;
 | 
			
		||||
            }
 | 
			
		||||
            $text .= "\n";
 | 
			
		||||
 | 
			
		||||
            // usage or command intro
 | 
			
		||||
            if ($this->setup[$command]['help']) {
 | 
			
		||||
                $text .= "\n";
 | 
			
		||||
                $text .= $tf->format(
 | 
			
		||||
                    array($mv, '*'),
 | 
			
		||||
                    array('', $this->setup[$command]['help'] . "\n")
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // option description
 | 
			
		||||
            if ($hasopts) {
 | 
			
		||||
                if (!$command) {
 | 
			
		||||
                    $text .= "\n";
 | 
			
		||||
                    $text .= $this->colors->wrap('OPTIONS:', Colors::C_BROWN);
 | 
			
		||||
                }
 | 
			
		||||
                $text .= "\n";
 | 
			
		||||
                foreach ($this->setup[$command]['opts'] as $long => $opt) {
 | 
			
		||||
 | 
			
		||||
                    $name = '';
 | 
			
		||||
                    if ($opt['short']) {
 | 
			
		||||
                        $name .= '-' . $opt['short'];
 | 
			
		||||
                        if ($opt['needsarg']) {
 | 
			
		||||
                            $name .= ' <' . $opt['needsarg'] . '>';
 | 
			
		||||
                        }
 | 
			
		||||
                        $name .= ', ';
 | 
			
		||||
                    }
 | 
			
		||||
                    $name .= "--$long";
 | 
			
		||||
                    if ($opt['needsarg']) {
 | 
			
		||||
                        $name .= ' <' . $opt['needsarg'] . '>';
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    $text .= $tf->format(
 | 
			
		||||
                        array($mv, '30%', '*'),
 | 
			
		||||
                        array('', $name, $opt['help']),
 | 
			
		||||
                        array('', 'green', '')
 | 
			
		||||
                    );
 | 
			
		||||
                    $text .= "\n";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // argument description
 | 
			
		||||
            if ($hasargs) {
 | 
			
		||||
                if (!$command) {
 | 
			
		||||
                    $text .= "\n";
 | 
			
		||||
                    $text .= $this->colors->wrap('ARGUMENTS:', Colors::C_BROWN);
 | 
			
		||||
                }
 | 
			
		||||
                $text .= "\n";
 | 
			
		||||
                foreach ($this->setup[$command]['args'] as $arg) {
 | 
			
		||||
                    $name = '<' . $arg['name'] . '>';
 | 
			
		||||
 | 
			
		||||
                    $text .= $tf->format(
 | 
			
		||||
                        array($mv, '30%', '*'),
 | 
			
		||||
                        array('', $name, $arg['help']),
 | 
			
		||||
                        array('', 'cyan', '')
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // head line and intro for following command documentation
 | 
			
		||||
            if (!$command && $hascommands) {
 | 
			
		||||
                $text .= "\n";
 | 
			
		||||
                $text .= $this->colors->wrap('COMMANDS:', Colors::C_BROWN);
 | 
			
		||||
                $text .= "\n";
 | 
			
		||||
                $text .= $tf->format(
 | 
			
		||||
                    array($mv, '*'),
 | 
			
		||||
                    array('', 'This tool accepts a command as first parameter as outlined below:')
 | 
			
		||||
                );
 | 
			
		||||
                $text .= "\n";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Safely read the $argv PHP array across different PHP configurations.
 | 
			
		||||
     * Will take care on register_globals and register_argc_argv ini directives
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     * @return array the $argv PHP array or PEAR error if not registered
 | 
			
		||||
     */
 | 
			
		||||
    private function readPHPArgv()
 | 
			
		||||
    {
 | 
			
		||||
        global $argv;
 | 
			
		||||
        if (!is_array($argv)) {
 | 
			
		||||
            if (!@is_array($_SERVER['argv'])) {
 | 
			
		||||
                if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
 | 
			
		||||
                    throw new Exception(
 | 
			
		||||
                        "Could not read cmd args (register_argc_argv=Off?)",
 | 
			
		||||
                        Exception::E_ARG_READ
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                return $GLOBALS['HTTP_SERVER_VARS']['argv'];
 | 
			
		||||
            }
 | 
			
		||||
            return $_SERVER['argv'];
 | 
			
		||||
        }
 | 
			
		||||
        return $argv;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								content/vendor/splitbrain/php-cli/src/PSR3CLI.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								content/vendor/splitbrain/php-cli/src/PSR3CLI.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace splitbrain\phpcli;
 | 
			
		||||
 | 
			
		||||
use Psr\Log\LoggerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class PSR3CLI
 | 
			
		||||
 *
 | 
			
		||||
 * The same as CLI, but implements the PSR-3 logger interface
 | 
			
		||||
 */
 | 
			
		||||
abstract class PSR3CLI extends CLI implements LoggerInterface {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										325
									
								
								content/vendor/splitbrain/php-cli/src/TableFormatter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								content/vendor/splitbrain/php-cli/src/TableFormatter.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,325 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace splitbrain\phpcli;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class TableFormatter
 | 
			
		||||
 *
 | 
			
		||||
 * Output text in multiple columns
 | 
			
		||||
 *
 | 
			
		||||
 * @author Andreas Gohr <andi@splitbrain.org>
 | 
			
		||||
 * @license MIT
 | 
			
		||||
 */
 | 
			
		||||
class TableFormatter
 | 
			
		||||
{
 | 
			
		||||
    /** @var string border between columns */
 | 
			
		||||
    protected $border = ' ';
 | 
			
		||||
 | 
			
		||||
    /** @var int the terminal width */
 | 
			
		||||
    protected $max = 74;
 | 
			
		||||
 | 
			
		||||
    /** @var Colors for coloring output */
 | 
			
		||||
    protected $colors;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * TableFormatter constructor.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Colors|null $colors
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Colors $colors = null)
 | 
			
		||||
    {
 | 
			
		||||
        // try to get terminal width
 | 
			
		||||
        $width = $this->getTerminalWidth();
 | 
			
		||||
        if ($width) {
 | 
			
		||||
            $this->max = $width - 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($colors) {
 | 
			
		||||
            $this->colors = $colors;
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->colors = new Colors();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The currently set border (defaults to ' ')
 | 
			
		||||
     *
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getBorder()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->border;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the border. The border is set between each column. Its width is
 | 
			
		||||
     * added to the column widths.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $border
 | 
			
		||||
     */
 | 
			
		||||
    public function setBorder($border)
 | 
			
		||||
    {
 | 
			
		||||
        $this->border = $border;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Width of the terminal in characters
 | 
			
		||||
     *
 | 
			
		||||
     * initially autodetected
 | 
			
		||||
     *
 | 
			
		||||
     * @return int
 | 
			
		||||
     */
 | 
			
		||||
    public function getMaxWidth()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->max;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the width of the terminal to assume (in characters)
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $max
 | 
			
		||||
     */
 | 
			
		||||
    public function setMaxWidth($max)
 | 
			
		||||
    {
 | 
			
		||||
        $this->max = $max;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Tries to figure out the width of the terminal
 | 
			
		||||
     *
 | 
			
		||||
     * @return int terminal width, 0 if unknown
 | 
			
		||||
     */
 | 
			
		||||
    protected function getTerminalWidth()
 | 
			
		||||
    {
 | 
			
		||||
        // from environment
 | 
			
		||||
        if (isset($_SERVER['COLUMNS'])) return (int)$_SERVER['COLUMNS'];
 | 
			
		||||
 | 
			
		||||
        // via tput
 | 
			
		||||
        $process = proc_open('tput cols', array(
 | 
			
		||||
            1 => array('pipe', 'w'),
 | 
			
		||||
            2 => array('pipe', 'w'),
 | 
			
		||||
        ), $pipes);
 | 
			
		||||
        $width = (int)stream_get_contents($pipes[1]);
 | 
			
		||||
        proc_close($process);
 | 
			
		||||
 | 
			
		||||
        return $width;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Takes an array with dynamic column width and calculates the correct width
 | 
			
		||||
     *
 | 
			
		||||
     * Column width can be given as fixed char widths, percentages and a single * width can be given
 | 
			
		||||
     * for taking the remaining available space. When mixing percentages and fixed widths, percentages
 | 
			
		||||
     * refer to the remaining space after allocating the fixed width
 | 
			
		||||
     *
 | 
			
		||||
     * @param array $columns
 | 
			
		||||
     * @return int[]
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    protected function calculateColLengths($columns)
 | 
			
		||||
    {
 | 
			
		||||
        $idx = 0;
 | 
			
		||||
        $border = $this->strlen($this->border);
 | 
			
		||||
        $fixed = (count($columns) - 1) * $border; // borders are used already
 | 
			
		||||
        $fluid = -1;
 | 
			
		||||
 | 
			
		||||
        // first pass for format check and fixed columns
 | 
			
		||||
        foreach ($columns as $idx => $col) {
 | 
			
		||||
            // handle fixed columns
 | 
			
		||||
            if ((string)intval($col) === (string)$col) {
 | 
			
		||||
                $fixed += $col;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            // check if other colums are using proper units
 | 
			
		||||
            if (substr($col, -1) == '%') {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if ($col == '*') {
 | 
			
		||||
                // only one fluid
 | 
			
		||||
                if ($fluid < 0) {
 | 
			
		||||
                    $fluid = $idx;
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw new Exception('Only one fluid column allowed!');
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("unknown column format $col");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $alloc = $fixed;
 | 
			
		||||
        $remain = $this->max - $alloc;
 | 
			
		||||
 | 
			
		||||
        // second pass to handle percentages
 | 
			
		||||
        foreach ($columns as $idx => $col) {
 | 
			
		||||
            if (substr($col, -1) != '%') {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $perc = floatval($col);
 | 
			
		||||
 | 
			
		||||
            $real = (int)floor(($perc * $remain) / 100);
 | 
			
		||||
 | 
			
		||||
            $columns[$idx] = $real;
 | 
			
		||||
            $alloc += $real;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $remain = $this->max - $alloc;
 | 
			
		||||
        if ($remain < 0) {
 | 
			
		||||
            throw new Exception("Wanted column widths exceed available space");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // assign remaining space
 | 
			
		||||
        if ($fluid < 0) {
 | 
			
		||||
            $columns[$idx] += ($remain); // add to last column
 | 
			
		||||
        } else {
 | 
			
		||||
            $columns[$fluid] = $remain;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $columns;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Displays text in multiple word wrapped columns
 | 
			
		||||
     *
 | 
			
		||||
     * @param int[] $columns list of column widths (in characters, percent or '*')
 | 
			
		||||
     * @param string[] $texts list of texts for each column
 | 
			
		||||
     * @param array $colors A list of color names to use for each column. use empty string for default
 | 
			
		||||
     * @return string
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public function format($columns, $texts, $colors = array())
 | 
			
		||||
    {
 | 
			
		||||
        $columns = $this->calculateColLengths($columns);
 | 
			
		||||
 | 
			
		||||
        $wrapped = array();
 | 
			
		||||
        $maxlen = 0;
 | 
			
		||||
 | 
			
		||||
        foreach ($columns as $col => $width) {
 | 
			
		||||
            $wrapped[$col] = explode("\n", $this->wordwrap($texts[$col], $width, "\n", true));
 | 
			
		||||
            $len = count($wrapped[$col]);
 | 
			
		||||
            if ($len > $maxlen) {
 | 
			
		||||
                $maxlen = $len;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $last = count($columns) - 1;
 | 
			
		||||
        $out = '';
 | 
			
		||||
        for ($i = 0; $i < $maxlen; $i++) {
 | 
			
		||||
            foreach ($columns as $col => $width) {
 | 
			
		||||
                if (isset($wrapped[$col][$i])) {
 | 
			
		||||
                    $val = $wrapped[$col][$i];
 | 
			
		||||
                } else {
 | 
			
		||||
                    $val = '';
 | 
			
		||||
                }
 | 
			
		||||
                $chunk = $this->pad($val, $width);
 | 
			
		||||
                if (isset($colors[$col]) && $colors[$col]) {
 | 
			
		||||
                    $chunk = $this->colors->wrap($chunk, $colors[$col]);
 | 
			
		||||
                }
 | 
			
		||||
                $out .= $chunk;
 | 
			
		||||
 | 
			
		||||
                // border
 | 
			
		||||
                if ($col != $last) {
 | 
			
		||||
                    $out .= $this->border;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $out .= "\n";
 | 
			
		||||
        }
 | 
			
		||||
        return $out;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pad the given string to the correct length
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $string
 | 
			
		||||
     * @param int $len
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    protected function pad($string, $len)
 | 
			
		||||
    {
 | 
			
		||||
        $strlen = $this->strlen($string);
 | 
			
		||||
        if ($strlen > $len) return $string;
 | 
			
		||||
 | 
			
		||||
        $pad = $len - $strlen;
 | 
			
		||||
        return $string . str_pad('', $pad, ' ');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Measures char length in UTF-8 when possible
 | 
			
		||||
     *
 | 
			
		||||
     * @param $string
 | 
			
		||||
     * @return int
 | 
			
		||||
     */
 | 
			
		||||
    protected function strlen($string)
 | 
			
		||||
    {
 | 
			
		||||
        // don't count color codes
 | 
			
		||||
        $string = preg_replace("/\33\\[\\d+(;\\d+)?m/", '', $string);
 | 
			
		||||
 | 
			
		||||
        if (function_exists('mb_strlen')) {
 | 
			
		||||
            return mb_strlen($string, 'utf-8');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return strlen($string);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $string
 | 
			
		||||
     * @param int $start
 | 
			
		||||
     * @param int|null $length
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    protected function substr($string, $start = 0, $length = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (function_exists('mb_substr')) {
 | 
			
		||||
            return mb_substr($string, $start, $length);
 | 
			
		||||
        } else {
 | 
			
		||||
            // mb_substr() treats $length differently than substr()
 | 
			
		||||
            if ($length) {
 | 
			
		||||
                return substr($string, $start, $length);
 | 
			
		||||
            } else {
 | 
			
		||||
                return substr($string, $start);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $str
 | 
			
		||||
     * @param int $width
 | 
			
		||||
     * @param string $break
 | 
			
		||||
     * @param bool $cut
 | 
			
		||||
     * @return string
 | 
			
		||||
     * @link http://stackoverflow.com/a/4988494
 | 
			
		||||
     */
 | 
			
		||||
    protected function wordwrap($str, $width = 75, $break = "\n", $cut = false)
 | 
			
		||||
    {
 | 
			
		||||
        $lines = explode($break, $str);
 | 
			
		||||
        foreach ($lines as &$line) {
 | 
			
		||||
            $line = rtrim($line);
 | 
			
		||||
            if ($this->strlen($line) <= $width) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $words = explode(' ', $line);
 | 
			
		||||
            $line = '';
 | 
			
		||||
            $actual = '';
 | 
			
		||||
            foreach ($words as $word) {
 | 
			
		||||
                if ($this->strlen($actual . $word) <= $width) {
 | 
			
		||||
                    $actual .= $word . ' ';
 | 
			
		||||
                } else {
 | 
			
		||||
                    if ($actual != '') {
 | 
			
		||||
                        $line .= rtrim($actual) . $break;
 | 
			
		||||
                    }
 | 
			
		||||
                    $actual = $word;
 | 
			
		||||
                    if ($cut) {
 | 
			
		||||
                        while ($this->strlen($actual) > $width) {
 | 
			
		||||
                            $line .= $this->substr($actual, 0, $width) . $break;
 | 
			
		||||
                            $actual = $this->substr($actual, $width);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    $actual .= ' ';
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $line .= trim($actual);
 | 
			
		||||
        }
 | 
			
		||||
        return implode($break, $lines);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user