torrentpier-lts/library/Zend/Console/Adapter/AbstractAdapter.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;
}
}