mirror of
https://github.com/torrentpier/torrentpier-lts.git
synced 2025-03-01 15:21:02 +03:00
562 lines
15 KiB
PHP
562 lines
15 KiB
PHP
<?php
|
|
/**
|
|
* Zend Framework (http://framework.zend.com/)
|
|
*
|
|
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
|
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
*/
|
|
|
|
namespace Zend\Console\Adapter;
|
|
|
|
use Zend\Console\Charset;
|
|
use Zend\Console\Exception;
|
|
use Zend\Stdlib\StringUtils;
|
|
|
|
/**
|
|
* Common console adapter codebase
|
|
*/
|
|
abstract class AbstractAdapter implements AdapterInterface
|
|
{
|
|
/**
|
|
* Whether or not mbstring is enabled
|
|
*
|
|
* @var null|bool
|
|
*/
|
|
protected static $hasMBString;
|
|
|
|
/**
|
|
* @var Charset\CharsetInterface
|
|
*/
|
|
protected $charset;
|
|
|
|
/**
|
|
* Current cursor X position
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $posX;
|
|
|
|
/**
|
|
* Current cursor Y position
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $posY;
|
|
|
|
/**
|
|
* Write a chunk of text to console.
|
|
*
|
|
* @param string $text
|
|
* @param null|int $color
|
|
* @param null|int $bgColor
|
|
*/
|
|
public function write($text, $color = null, $bgColor = null)
|
|
{
|
|
//Encode text to match console encoding
|
|
$text = $this->encodeText($text);
|
|
|
|
if ($color !== null || $bgColor !== null) {
|
|
echo $this->colorize($text, $color, $bgColor);
|
|
} else {
|
|
echo $text;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Alias for write()
|
|
*
|
|
* @param string $text
|
|
* @param null|int $color
|
|
* @param null|int $bgColor
|
|
*/
|
|
public function writeText($text, $color = null, $bgColor = null)
|
|
{
|
|
return $this->write($text, $color, $bgColor);
|
|
}
|
|
|
|
/**
|
|
* Write a single line of text to console and advance cursor to the next line.
|
|
*
|
|
* @param string $text
|
|
* @param null|int $color
|
|
* @param null|int $bgColor
|
|
*/
|
|
public function writeLine($text = "", $color = null, $bgColor = null)
|
|
{
|
|
$this->write($text . PHP_EOL, $color, $bgColor);
|
|
}
|
|
|
|
/**
|
|
* Write a piece of text at the coordinates of $x and $y
|
|
*
|
|
*
|
|
* @param string $text Text to write
|
|
* @param int $x Console X coordinate (column)
|
|
* @param int $y Console Y coordinate (row)
|
|
* @param null|int $color
|
|
* @param null|int $bgColor
|
|
*/
|
|
public function writeAt($text, $x, $y, $color = null, $bgColor = null)
|
|
{
|
|
$this->setPos($x, $y);
|
|
$this->write($text, $color, $bgColor);
|
|
}
|
|
|
|
/**
|
|
* Write a box at the specified coordinates.
|
|
* If X or Y coordinate value is negative, it will be calculated as the distance from far right or bottom edge
|
|
* of the console (respectively).
|
|
*
|
|
* @param int $x1 Top-left corner X coordinate (column)
|
|
* @param int $y1 Top-left corner Y coordinate (row)
|
|
* @param int $x2 Bottom-right corner X coordinate (column)
|
|
* @param int $y2 Bottom-right corner Y coordinate (row)
|
|
* @param int $lineStyle (optional) Box border style.
|
|
* @param int $fillStyle (optional) Box fill style or a single character to fill it with.
|
|
* @param int $color (optional) Foreground color
|
|
* @param int $bgColor (optional) Background color
|
|
* @param null|int $fillColor (optional) Foreground color of box fill
|
|
* @param null|int $fillBgColor (optional) Background color of box fill
|
|
* @throws Exception\BadMethodCallException if coordinates are invalid
|
|
*/
|
|
public function writeBox(
|
|
$x1,
|
|
$y1,
|
|
$x2,
|
|
$y2,
|
|
$lineStyle = self::LINE_SINGLE,
|
|
$fillStyle = self::FILL_NONE,
|
|
$color = null,
|
|
$bgColor = null,
|
|
$fillColor = null,
|
|
$fillBgColor = null
|
|
) {
|
|
// Sanitize coordinates
|
|
$x1 = (int) $x1;
|
|
$y1 = (int) $y1;
|
|
$x2 = (int) $x2;
|
|
$y2 = (int) $y2;
|
|
|
|
// Translate negative coordinates
|
|
if ($x2 < 0) {
|
|
$x2 = $this->getWidth() - $x2;
|
|
}
|
|
|
|
if ($y2 < 0) {
|
|
$y2 = $this->getHeight() - $y2;
|
|
}
|
|
|
|
// Validate coordinates
|
|
if ($x1 < 0
|
|
|| $y1 < 0
|
|
|| $x2 < $x1
|
|
|| $y2 < $y1
|
|
) {
|
|
throw new Exception\BadMethodCallException('Supplied X,Y coordinates are invalid.');
|
|
}
|
|
|
|
// Determine charset and dimensions
|
|
$charset = $this->getCharset();
|
|
$width = $x2 - $x1 + 1;
|
|
$height = $y2 - $y1 + 1;
|
|
|
|
if ($width <= 2) {
|
|
$lineStyle = static::LINE_NONE;
|
|
}
|
|
|
|
// Activate line drawing
|
|
$this->write($charset::ACTIVATE);
|
|
|
|
// Draw horizontal lines
|
|
if ($lineStyle !== static::LINE_NONE) {
|
|
switch ($lineStyle) {
|
|
case static::LINE_SINGLE:
|
|
$lineChar = $charset::LINE_SINGLE_EW;
|
|
break;
|
|
|
|
case static::LINE_DOUBLE:
|
|
$lineChar = $charset::LINE_DOUBLE_EW;
|
|
break;
|
|
|
|
case static::LINE_BLOCK:
|
|
default:
|
|
$lineChar = $charset::LINE_BLOCK_EW;
|
|
break;
|
|
}
|
|
|
|
$this->setPos($x1 + 1, $y1);
|
|
$this->write(str_repeat($lineChar, $width - 2), $color, $bgColor);
|
|
$this->setPos($x1 + 1, $y2);
|
|
$this->write(str_repeat($lineChar, $width - 2), $color, $bgColor);
|
|
}
|
|
|
|
// Draw vertical lines and fill
|
|
if (is_numeric($fillStyle)
|
|
&& $fillStyle !== static::FILL_NONE) {
|
|
switch ($fillStyle) {
|
|
case static::FILL_SHADE_LIGHT:
|
|
$fillChar = $charset::SHADE_LIGHT;
|
|
break;
|
|
case static::FILL_SHADE_MEDIUM:
|
|
$fillChar = $charset::SHADE_MEDIUM;
|
|
break;
|
|
case static::FILL_SHADE_DARK:
|
|
$fillChar = $charset::SHADE_DARK;
|
|
break;
|
|
case static::FILL_BLOCK:
|
|
default:
|
|
$fillChar = $charset::BLOCK;
|
|
break;
|
|
}
|
|
} elseif ($fillStyle) {
|
|
$fillChar = StringUtils::getWrapper()->substr($fillStyle, 0, 1);
|
|
} else {
|
|
$fillChar = ' ';
|
|
}
|
|
|
|
if ($lineStyle === static::LINE_NONE) {
|
|
for ($y = $y1; $y <= $y2; $y++) {
|
|
$this->setPos($x1, $y);
|
|
$this->write(str_repeat($fillChar, $width), $fillColor, $fillBgColor);
|
|
}
|
|
} else {
|
|
switch ($lineStyle) {
|
|
case static::LINE_DOUBLE:
|
|
$lineChar = $charset::LINE_DOUBLE_NS;
|
|
break;
|
|
case static::LINE_BLOCK:
|
|
$lineChar = $charset::LINE_BLOCK_NS;
|
|
break;
|
|
case static::LINE_SINGLE:
|
|
default:
|
|
$lineChar = $charset::LINE_SINGLE_NS;
|
|
break;
|
|
}
|
|
|
|
for ($y = $y1 + 1; $y < $y2; $y++) {
|
|
$this->setPos($x1, $y);
|
|
$this->write($lineChar, $color, $bgColor);
|
|
$this->write(str_repeat($fillChar, $width - 2), $fillColor, $fillBgColor);
|
|
$this->write($lineChar, $color, $bgColor);
|
|
}
|
|
}
|
|
|
|
// Draw corners
|
|
if ($lineStyle !== static::LINE_NONE) {
|
|
if ($color !== null) {
|
|
$this->setColor($color);
|
|
}
|
|
if ($bgColor !== null) {
|
|
$this->setBgColor($bgColor);
|
|
}
|
|
if ($lineStyle === static::LINE_SINGLE) {
|
|
$this->writeAt($charset::LINE_SINGLE_NW, $x1, $y1);
|
|
$this->writeAt($charset::LINE_SINGLE_NE, $x2, $y1);
|
|
$this->writeAt($charset::LINE_SINGLE_SE, $x2, $y2);
|
|
$this->writeAt($charset::LINE_SINGLE_SW, $x1, $y2);
|
|
} elseif ($lineStyle === static::LINE_DOUBLE) {
|
|
$this->writeAt($charset::LINE_DOUBLE_NW, $x1, $y1);
|
|
$this->writeAt($charset::LINE_DOUBLE_NE, $x2, $y1);
|
|
$this->writeAt($charset::LINE_DOUBLE_SE, $x2, $y2);
|
|
$this->writeAt($charset::LINE_DOUBLE_SW, $x1, $y2);
|
|
} elseif ($lineStyle === static::LINE_BLOCK) {
|
|
$this->writeAt($charset::LINE_BLOCK_NW, $x1, $y1);
|
|
$this->writeAt($charset::LINE_BLOCK_NE, $x2, $y1);
|
|
$this->writeAt($charset::LINE_BLOCK_SE, $x2, $y2);
|
|
$this->writeAt($charset::LINE_BLOCK_SW, $x1, $y2);
|
|
}
|
|
}
|
|
|
|
// Deactivate line drawing and reset colors
|
|
$this->write($charset::DEACTIVATE);
|
|
$this->resetColor();
|
|
}
|
|
|
|
/**
|
|
* Write a block of text at the given coordinates, matching the supplied width and height.
|
|
* In case a line of text does not fit desired width, it will be wrapped to the next line.
|
|
* In case the whole text does not fit in desired height, it will be truncated.
|
|
*
|
|
* @param string $text Text to write
|
|
* @param int $width Maximum block width. Negative value means distance from right edge.
|
|
* @param int|null $height Maximum block height. Negative value means distance from bottom edge.
|
|
* @param int $x Block X coordinate (column)
|
|
* @param int $y Block Y coordinate (row)
|
|
* @param null|int $color (optional) Text color
|
|
* @param null|int $bgColor (optional) Text background color
|
|
* @throws Exception\InvalidArgumentException
|
|
*/
|
|
public function writeTextBlock(
|
|
$text,
|
|
$width,
|
|
$height = null,
|
|
$x = 0,
|
|
$y = 0,
|
|
$color = null,
|
|
$bgColor = null
|
|
) {
|
|
if ($x < 0 || $y < 0) {
|
|
throw new Exception\InvalidArgumentException('Supplied X,Y coordinates are invalid.');
|
|
}
|
|
|
|
if ($width < 1) {
|
|
throw new Exception\InvalidArgumentException('Invalid width supplied.');
|
|
}
|
|
|
|
if (null !== $height && $height < 1) {
|
|
throw new Exception\InvalidArgumentException('Invalid height supplied.');
|
|
}
|
|
|
|
// ensure the text is not wider than the width
|
|
if (strlen($text) <= $width) {
|
|
// just write the line at the spec'd position
|
|
$this->setPos($x, $y);
|
|
$this->write($text, $color, $bgColor);
|
|
return;
|
|
}
|
|
|
|
$text = wordwrap($text, $width, PHP_EOL, true);
|
|
|
|
// convert to array of lines
|
|
$lines = explode(PHP_EOL, $text);
|
|
|
|
// truncate if height was specified
|
|
if (null !== $height && count($lines) > $height) {
|
|
$lines = array_slice($lines, 0, $height);
|
|
}
|
|
|
|
// write each line
|
|
$curY = $y;
|
|
foreach ($lines as $line) {
|
|
$this->setPos($x, $curY);
|
|
$this->write($line, $color, $bgColor);
|
|
$curY++;//next line
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determine and return current console width.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getWidth()
|
|
{
|
|
return 80;
|
|
}
|
|
|
|
/**
|
|
* Determine and return current console height.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getHeight()
|
|
{
|
|
return 25;
|
|
}
|
|
|
|
/**
|
|
* Determine and return current console width and height.
|
|
*
|
|
* @return int[] array($width, $height)
|
|
*/
|
|
public function getSize()
|
|
{
|
|
return array(
|
|
$this->getWidth(),
|
|
$this->getHeight(),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if console is UTF-8 compatible
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isUtf8()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set cursor position
|
|
*
|
|
* @param int $x
|
|
* @param int $y
|
|
*/
|
|
public function setPos($x, $y)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Show console cursor
|
|
*/
|
|
public function showCursor()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Hide console cursor
|
|
*/
|
|
public function hideCursor()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Return current console window title.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getTitle()
|
|
{
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Prepare a string that will be rendered in color.
|
|
*
|
|
* @param string $string
|
|
* @param int $color
|
|
* @param null|int $bgColor
|
|
* @return string
|
|
*/
|
|
public function colorize($string, $color = null, $bgColor = null)
|
|
{
|
|
return $string;
|
|
}
|
|
|
|
/**
|
|
* Change current drawing color.
|
|
*
|
|
* @param int $color
|
|
*/
|
|
public function setColor($color)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Change current drawing background color
|
|
*
|
|
* @param int $color
|
|
*/
|
|
public function setBgColor($color)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Reset color to console default.
|
|
*/
|
|
public function resetColor()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Set Console charset to use.
|
|
*
|
|
* @param Charset\CharsetInterface $charset
|
|
*/
|
|
public function setCharset(Charset\CharsetInterface $charset)
|
|
{
|
|
$this->charset = $charset;
|
|
}
|
|
|
|
/**
|
|
* Get charset currently in use by this adapter.
|
|
*
|
|
* @return Charset\CharsetInterface $charset
|
|
*/
|
|
public function getCharset()
|
|
{
|
|
if ($this->charset === null) {
|
|
$this->charset = $this->getDefaultCharset();
|
|
}
|
|
|
|
return $this->charset;
|
|
}
|
|
|
|
/**
|
|
* @return Charset\Utf8
|
|
*/
|
|
public function getDefaultCharset()
|
|
{
|
|
return new Charset\Utf8;
|
|
}
|
|
|
|
/**
|
|
* Clear console screen
|
|
*/
|
|
public function clear()
|
|
{
|
|
echo "\f";
|
|
}
|
|
|
|
/**
|
|
* Clear line at cursor position
|
|
*/
|
|
public function clearLine()
|
|
{
|
|
echo "\r" . str_repeat(" ", $this->getWidth()) . "\r";
|
|
}
|
|
|
|
/**
|
|
* Clear console screen
|
|
*/
|
|
public function clearScreen()
|
|
{
|
|
return $this->clear();
|
|
}
|
|
|
|
/**
|
|
* Read a single line from the console input
|
|
*
|
|
* @param int $maxLength Maximum response length
|
|
* @return string
|
|
*/
|
|
public function readLine($maxLength = 2048)
|
|
{
|
|
$f = fopen('php://stdin', 'r');
|
|
$line = stream_get_line($f, $maxLength, PHP_EOL);
|
|
fclose($f);
|
|
return rtrim($line, "\n\r");
|
|
}
|
|
|
|
/**
|
|
* Read a single character from the console input
|
|
*
|
|
* @param string|null $mask A list of allowed chars
|
|
* @return string
|
|
*/
|
|
public function readChar($mask = null)
|
|
{
|
|
$f = fopen('php://stdin', 'r');
|
|
do {
|
|
$char = fread($f, 1);
|
|
} while ("" === $char || ($mask !== null && false === strstr($mask, $char)));
|
|
fclose($f);
|
|
return $char;
|
|
}
|
|
|
|
/**
|
|
* Encode a text to match console encoding
|
|
*
|
|
* @param string $text
|
|
* @return string the encoding text
|
|
*/
|
|
public function encodeText($text)
|
|
{
|
|
if ($this->isUtf8()) {
|
|
if (StringUtils::isValidUtf8($text)) {
|
|
return $text;
|
|
}
|
|
|
|
return utf8_encode($text);
|
|
}
|
|
|
|
if (StringUtils::isValidUtf8($text)) {
|
|
return utf8_decode($text);
|
|
}
|
|
|
|
return $text;
|
|
}
|
|
}
|