maj+ header

This commit is contained in:
2018-08-22 14:46:33 +02:00
parent 28c9e9d76f
commit 3fc62ab1f1
443 changed files with 24198 additions and 6201 deletions
+83
View File
@@ -1,3 +1,86 @@
Changelog
=========
## 3.4.1 - 2018-04-29
### Fixed
* [Json] Don't escape slashes when outputting JSON. [#121](https://github.com/thephpleague/climate/pull/121)
--------
## 3.4.0 - 2018-04-28
### Added
* [Logger] Added a Logger class to use CLImate as a PSR-3 logger.
--------
## 3.3.0 - 2018-04-20
### Fixed
* Ensure multibyte strings are supported everywhere.
* Improved support for IDE assistance when using method chaining. [#102](https://github.com/thephpleague/climate/pull/102)
* [Art] Improve handling of missing files. [#114](https://github.com/thephpleague/climate/issues/114)
* [Input] Correct the usage of `defaultTo()` with `accept()`. [#104](https://github.com/thephpleague/climate/pull/104)
* [Windows] Fixed the terminal width detection. [#64](https://github.com/thephpleague/climate/pull/64)
### Added
* [Table] Add support for a prefix argument for each row. [#51](https://github.com/thephpleague/climate/issues/51)
* [Progress] Added an `each()` method. [#112](https://github.com/thephpleague/climate/pull/112)
### Changed
* [Support] Add support for PHP 7.2
* [Support] Drop support for PHP 5.4
* [Support] Drop support for PHP 5.5
* [Support] Drop support for HHVM.
* Suggest the symfony polyfill library is `ext-mbstring` is not available. [#110](https://github.com/thephpleague/climate/pull/110)
--------
## 3.2.4 - 2016-10-30
### Fixed
* [Progres] Allow labels to be shown/hidden on each iteration. [#98](https://github.com/thephpleague/climate/pull/98)
--------
## 3.2.3 - 2016-10-17
### Added
* [Support] Added support for PHP 7.1
--------
## 3.2.2 - 2016-07-18
### Fixed
* [Art] Allow code to be used in a phar. [#86](https://github.com/thephpleague/climate/pull/86)
--------
## 3.2.1 - 2016-04-05
### Added
* [Arguments] Add a `trailing()` method to get any trailing arguments.
* [Progress] Added a `forceRedraw()` method. [#72](https://github.com/thephpleague/climate/issues/72)
### Fixed
* [Checkbox] Don't cancel out the formatting for the first checkbox. [#77](https://github.com/thephpleague/climate/issues/77)
* [Padding] Ensure formatting is handled. [#78](https://github.com/thephpleague/climate/issues/78)
* [Columns] Prevent error when less items than columns are passed. [#75](https://github.com/thephpleague/climate/pull/75)
--------
## 3.2.0 - 2015-08-13
### Added
+11 -19
View File
@@ -1,4 +1,4 @@
<p align="center"><img src="http://climate.thephpleague.com/img/CLImate_Blink-100k.gif" width="300" alt="CLImate" /></p>
<p align="center"><img src="http://climate.thephpleague.com/img/CLImate_Blink.gif" width="300" alt="CLImate" /></p>
[![Latest Version](https://img.shields.io/github/tag/thephpleague/climate.svg?style=flat&label=release)](https://github.com/thephpleague/climate/tags)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](LICENSE.md)
@@ -11,36 +11,28 @@ Running PHP from the command line? CLImate is your new best bud.
CLImate allows you to easily output colored text, special formats, and more.
## Table of Contents
+ [Installation](#installation)
+ [Requirements](#requirements)
+ [Documentation](#documentation)
+ [Credits](#credits)
## Installation
Using [composer](https://packagist.org/packages/league/climate):
```bash
$ composer require league/climate
```
## Requirements
The following versions of PHP are supported by this version.
## Quick Example
```php
require_once __DIR__ . "vendor/autoload.php";
+ PHP 5.4
+ PHP 5.5
+ PHP 5.6
+ HHVM
$climate = new \League\CLImate\CLImate;
## Documentation
$climate->red('Whoa now this text is red.');
$climate->blue('Blue? Wow!');
```
CLImate has [full documentation](http://climate.thephpleague.com), powered by [Jekyll](http://jekyllrb.com/).
_Read more at https://climate.thephpleague.com/_
Contribute to this documentation in the [gh-pages branch](https://github.com/thephpleague/climate/tree/gh-pages/).
## Credits
Much love to [Damian Makki](https://dribbble.com/damianmakki) for the logo.
This library was created by [Joe Tannenbaum](https://joe.codes/).
Much love to [Damian Makki](https://dribbble.com/damianmakki) for the logo.
+1 -1
View File
@@ -178,6 +178,6 @@ class Filter
*/
protected function prefixCompareString(Argument $argument)
{
return strtolower($argument->longPrefix() ?: $argument->prefix() ?: '');
return mb_strtolower($argument->longPrefix() ?: $argument->prefix() ?: '');
}
}
+2 -2
View File
@@ -121,7 +121,7 @@ class Summary
public function argument(Argument $argument)
{
$summary = $this->prefixedArguments($argument);
$printedName = strstr($summary, ' ' . $argument->name());
$printedName = mb_strstr($summary, ' ' . $argument->name());
// Print the argument name if it's not printed yet.
if (!$printedName && !$argument->noValue()) {
@@ -169,7 +169,7 @@ class Summary
return;
}
$this->climate->br()->out(ucwords($type) . ' Arguments:');
$this->climate->br()->out(mb_convert_case($type, MB_CASE_TITLE) . ' Arguments:');
foreach ($arguments as $argument) {
$this->climate->tab()->out($this->argument($argument));
+43 -43
View File
@@ -11,52 +11,52 @@ use League\CLImate\Util\Output;
use League\CLImate\Util\UtilFactory;
/**
* @method mixed black(string $str = null)
* @method mixed red(string $str = null)
* @method mixed green(string $str = null)
* @method mixed yellow(string $str = null)
* @method mixed blue(string $str = null)
* @method mixed magenta(string $str = null)
* @method mixed cyan(string $str = null)
* @method mixed lightGray(string $str = null)
* @method mixed darkGray(string $str = null)
* @method mixed lightRed(string $str = null)
* @method mixed lightGreen(string $str = null)
* @method mixed lightYellow(string $str = null)
* @method mixed lightBlue(string $str = null)
* @method mixed lightMagenta(string $str = null)
* @method mixed lightCyan(string $str = null)
* @method mixed white(string $str = null)
* @method CLImate black(string $str = null)
* @method CLImate red(string $str = null)
* @method CLImate green(string $str = null)
* @method CLImate yellow(string $str = null)
* @method CLImate blue(string $str = null)
* @method CLImate magenta(string $str = null)
* @method CLImate cyan(string $str = null)
* @method CLImate lightGray(string $str = null)
* @method CLImate darkGray(string $str = null)
* @method CLImate lightRed(string $str = null)
* @method CLImate lightGreen(string $str = null)
* @method CLImate lightYellow(string $str = null)
* @method CLImate lightBlue(string $str = null)
* @method CLImate lightMagenta(string $str = null)
* @method CLImate lightCyan(string $str = null)
* @method CLImate white(string $str = null)
*
* @method mixed backgroundBlack(string $str = null)
* @method mixed backgroundRed(string $str = null)
* @method mixed backgroundGreen(string $str = null)
* @method mixed backgroundYellow(string $str = null)
* @method mixed backgroundBlue(string $str = null)
* @method mixed backgroundMagenta(string $str = null)
* @method mixed backgroundCyan(string $str = null)
* @method mixed backgroundLightGray(string $str = null)
* @method mixed backgroundDarkGray(string $str = null)
* @method mixed backgroundLightRed(string $str = null)
* @method mixed backgroundLightGreen(string $str = null)
* @method mixed backgroundLightYellow(string $str = null)
* @method mixed backgroundLightBlue(string $str = null)
* @method mixed backgroundLightMagenta(string $str = null)
* @method mixed backgroundLightCyan(string $str = null)
* @method mixed backgroundWhite(string $str = null)
* @method CLImate backgroundBlack(string $str = null)
* @method CLImate backgroundRed(string $str = null)
* @method CLImate backgroundGreen(string $str = null)
* @method CLImate backgroundYellow(string $str = null)
* @method CLImate backgroundBlue(string $str = null)
* @method CLImate backgroundMagenta(string $str = null)
* @method CLImate backgroundCyan(string $str = null)
* @method CLImate backgroundLightGray(string $str = null)
* @method CLImate backgroundDarkGray(string $str = null)
* @method CLImate backgroundLightRed(string $str = null)
* @method CLImate backgroundLightGreen(string $str = null)
* @method CLImate backgroundLightYellow(string $str = null)
* @method CLImate backgroundLightBlue(string $str = null)
* @method CLImate backgroundLightMagenta(string $str = null)
* @method CLImate backgroundLightCyan(string $str = null)
* @method CLImate backgroundWhite(string $str = null)
*
* @method mixed bold(string $str = null)
* @method mixed dim(string $str = null)
* @method mixed underline(string $str = null)
* @method mixed blink(string $str = null)
* @method mixed invert(string $str = null)
* @method mixed hidden(string $str = null)
* @method CLImate bold(string $str = null)
* @method CLImate dim(string $str = null)
* @method CLImate underline(string $str = null)
* @method CLImate blink(string $str = null)
* @method CLImate invert(string $str = null)
* @method CLImate hidden(string $str = null)
*
* @method mixed info(string $str = null)
* @method mixed comment(string $str = null)
* @method mixed whisper(string $str = null)
* @method mixed shout(string $str = null)
* @method mixed error(string $str = null)
* @method CLImate info(string $str = null)
* @method CLImate comment(string $str = null)
* @method CLImate whisper(string $str = null)
* @method CLImate shout(string $str = null)
* @method CLImate error(string $str = null)
*
* @method mixed out(string $str)
* @method mixed inline(string $str)
+2 -2
View File
@@ -125,7 +125,7 @@ class Ansi extends Parser
// We will be replacing tags one at a time, can't pass this by reference
$replace_count = 1;
if (strstr($tag, '/')) {
if (strpos($tag, '/')) {
// We are closing out the tag, pop off the last element and get the codes that are left
array_pop($history);
$replace = $this->end($history);
@@ -149,7 +149,7 @@ class Ansi extends Parser
protected function codeStr($codes)
{
// If we get something that is already a code string, just pass it back
if (!is_array($codes) && strstr($codes, ';')) {
if (!is_array($codes) && strpos($codes, ';')) {
return $codes;
}
+174
View File
@@ -0,0 +1,174 @@
<?php
namespace League\CLImate;
use Psr\Log\AbstractLogger;
use Psr\Log\InvalidArgumentException;
use Psr\Log\LogLevel;
use function array_key_exists;
use function is_array;
use function str_replace;
use function strpos;
/**
* A PSR-3 compatible logger that uses CLImate for output.
*/
class Logger extends AbstractLogger
{
/**
* @var array $levels Conversion of the level strings to their numeric representations.
*/
private $levels = [
LogLevel::EMERGENCY => 1,
LogLevel::ALERT => 2,
LogLevel::CRITICAL => 3,
LogLevel::ERROR => 4,
LogLevel::WARNING => 5,
LogLevel::NOTICE => 6,
LogLevel::INFO => 7,
LogLevel::DEBUG => 8,
];
/**
* @var int $level Ignore logging attempts at a level less than this.
*/
private $level;
/**
* @var CLImate $climate The underlying climate instance we are using for output.
*/
private $climate;
/**
* Create a new Logger instance.
*
* @param string $level One of the LogLevel constants
* @param CLImate $climate An existing CLImate instance to use for output
*/
public function __construct($level = LogLevel::INFO, CLImate $climate = null)
{
$this->level = $this->convertLevel($level);
if ($climate === null) {
$climate = new CLImate;
}
$this->climate = $climate;
# Define some default styles to use for the output
$commands = [
"emergency" => ["white", "bold", "background_red"],
"alert" => ["white", "background_yellow"],
"critical" => ["red", "bold"],
"error" => ["red"],
"warning" => "yellow",
"notice" => "light_cyan",
"info" => "green",
"debug" => "dark_gray",
];
# If any of the required styles are not defined then define them now
foreach ($commands as $command => $style) {
if (!$this->climate->style->get($command)) {
$this->climate->style->addCommand($command, $style);
}
}
}
/**
* Get a numeric log level for the passed parameter.
*
* @param string $level One of the LogLevel constants
*
* @return int
*/
private function convertLevel($level)
{
# If this is one of the defined string log levels then return it's numeric value
if (!array_key_exists($level, $this->levels)) {
throw new InvalidArgumentException("Unknown log level: {$level}");
}
return $this->levels[$level];
}
/**
* Get a new instance logging at a different level
*
* @param string $level One of the LogLevel constants
*
* @return Logger
*/
public function withLogLevel($level)
{
$logger = clone $this;
$logger->level = $this->convertLevel($level);
return $logger;
}
/**
* Log messages to a CLImate instance.
*
* @param string $level One of the LogLevel constants
* @param string|object $message If an object is passed it must implement __toString()
* @param array $context Placeholders to be substituted in the message
*
* @return void
*/
public function log($level, $message, array $context = [])
{
if ($this->convertLevel($level) > $this->level) {
return;
}
# Handle objects implementing __toString
$message = (string)$message;
# Handle any placeholders in the $context array
foreach ($context as $key => $val) {
$placeholder = "{" . $key . "}";
# If this context key is used as a placeholder, then replace it, and remove it from the $context array
if (strpos($message, $placeholder) !== false) {
$val = (string)$val;
$message = str_replace($placeholder, $val, $message);
unset($context[$key]);
}
}
# Send the message to the climate instance
$this->climate->{$level}($message);
# Append any context information not used as placeholders
$this->outputRecursiveContext($level, $context, 1);
}
/**
* Handle recursive arrays in the logging context.
*
* @param string $level One of the LogLevel constants
* @param array $context The array of context to output
* @param int $indent The current level of indentation to be used
*
* @return void
*/
private function outputRecursiveContext($level, array $context, $indent)
{
foreach ($context as $key => $val) {
$this->climate->tab($indent);
$this->climate->{$level}()->inline("{$key}: ");
if (is_array($val)) {
$this->climate->{$level}("[");
$this->outputRecursiveContext($level, $val, $indent + 1);
$this->climate->tab($indent)->{$level}("]");
} else {
$this->climate->{$level}((string)$val);
}
}
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ class Draw extends BasicTerminalObject
*/
public function result()
{
$file = $this->artFile($this->art) ?: $this->artFile($this->default_art);
$file = $this->artFile($this->art);
return $this->parse($file);
}
+1 -1
View File
@@ -23,6 +23,6 @@ class Json extends BasicTerminalObject
*/
public function result()
{
return json_encode($this->data, JSON_PRETTY_PRINT);
return json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
}
+27 -9
View File
@@ -50,9 +50,16 @@ class Table extends BasicTerminalObject
*/
protected $rows = [];
public function __construct(array $data)
/**
* @var string $pregix A string to be output before each row is output.
*/
private $prefix = "";
public function __construct(array $data, $prefix = "")
{
$this->data = $data;
$this->prefix = $prefix;
}
/**
@@ -69,13 +76,26 @@ class Table extends BasicTerminalObject
$this->buildHeaderRow();
foreach ($this->data as $key => $columns) {
$this->rows[] = $this->buildRow($columns);
$this->rows[] = $this->border;
$this->addLine($this->buildRow($columns));
$this->addLine($this->border);
}
return $this->rows;
}
/**
* Append a line to the output.
*
* @param string $line The line to output
*
* @return void
*/
private function addLine($line)
{
$this->rows[] = $this->prefix . $line;
}
/**
* Determine the width of the table
*
@@ -103,14 +123,12 @@ class Table extends BasicTerminalObject
*/
protected function buildHeaderRow()
{
$header_row = $this->getHeaderRow();
$this->addLine($this->border);
$header_row = $this->getHeaderRow();
if ($header_row) {
$this->rows[] = $this->border;
$this->rows[] = $this->buildRow($header_row);
$this->rows[] = (new Border())->char('=')->length($this->table_width)->result();
} else {
$this->rows[] = $this->border;
$this->addLine($this->buildRow($header_row));
$this->addLine((new Border)->char('=')->length($this->table_width)->result());
}
}
@@ -153,7 +153,7 @@ class Keyframe
protected function exitHorizontalFrames(array $lines, $line_method)
{
$keyframes = [];
$length = strlen($lines[0]);
$length = mb_strlen($lines[0]);
for ($i = $length; $i > 0; $i--) {
$keyframes[] = $this->getHorizontalKeyframe($lines, $i, $line_method, $length);
@@ -213,7 +213,7 @@ class Keyframe
*/
protected function currentLeftLine($line, $frame_number)
{
return substr($line, -$frame_number);
return mb_substr($line, -$frame_number);
}
@@ -228,7 +228,7 @@ class Keyframe
*/
protected function currentRightLine($line, $frame_number, $length)
{
return str_repeat(' ', $length - $frame_number) . substr($line, 0, $frame_number);
return str_repeat(' ', $length - $frame_number) . mb_substr($line, 0, $frame_number);
}
/**
@@ -62,7 +62,7 @@ class CheckboxGroup
*/
public function toggleCurrent()
{
list($option, $key) = $this->getCurrent();
list($option) = $this->getCurrent();
$option->setChecked(!$option->isChecked());
}
+3 -3
View File
@@ -174,9 +174,9 @@ class Input extends InputAbstract
return '';
}
$this->acceptable = array_map([$this, 'acceptableItemFormatted'], $this->acceptable);
$acceptable = array_map([$this, 'acceptableItemFormatted'], $this->acceptable);
return '[' . implode('/', $this->acceptable) . ']';
return '[' . implode('/', $acceptable) . ']';
}
/**
@@ -219,7 +219,7 @@ class Input extends InputAbstract
*/
protected function levelPlayingField($var)
{
$levelers = ['trim', 'strtolower'];
$levelers = ['trim', 'mb_strtolower'];
foreach ($levelers as $leveler) {
if (is_array($var)) {
@@ -89,10 +89,10 @@ class Padding extends DynamicTerminalObject
{
if (strlen($this->char) > 0) {
$length = $this->getLength();
$padding_length = ceil($length / strlen($this->char));
$padding_length = ceil($length / mb_strlen($this->char));
$padding = str_repeat($this->char, $padding_length);
$content .= substr($padding, 0, $length - strlen($content));
$content .= mb_substr($padding, 0, $length - mb_strlen($content));
}
return $content;
@@ -108,7 +108,12 @@ class Padding extends DynamicTerminalObject
public function label($content)
{
// Handle long labels by splitting them across several lines
$lines = str_split($content, $this->util->width());
$lines = [];
$stop = mb_strlen($content);
$width = $this->util->width();
for ($i = 0; $i < $stop; $i += $width) {
$lines[] = mb_substr($content, $i, $width);
}
$content = array_pop($lines);
foreach ($lines as $line) {
@@ -134,6 +134,37 @@ class Progress extends DynamicTerminalObject
return $this;
}
/**
* Update a progress bar using an iterable.
*
* @param iterable $items Array or any other iterable object
* @param callable $callback A handler to run on each item
*/
public function each($items, callable $callback = null)
{
if ($items instanceof \Traversable) {
$items = iterator_to_array($items);
}
$total = count($items);
if (!$total) {
return;
}
$this->total($total);
foreach ($items as $key => $item) {
if ($callback) {
$label = $callback($item, $key);
} else {
$label = null;
}
$this->advance(1, $label);
}
}
/**
* Draw the progress bar, if necessary
*
@@ -87,6 +87,15 @@ trait Art
{
$files = $this->fileSearch($art, '.*');
if (count($files) === 0) {
$this->addDir(__DIR__ . '/../../ASCII');
$files = $this->fileSearch($this->default_art, '.*');
}
if (count($files) === 0) {
throw new \UnexpectedValueException("Unable to find an art file with the name '{$art}'");
}
return reset($files);
}
+1 -1
View File
@@ -47,7 +47,7 @@ class Windows extends System
*/
protected function getDimensions()
{
$output = $this->exec('mode', true);
$output = $this->exec('mode CON', true);
if (!is_array($output)) {
return [];