Virtual.php 3.76 KB
Newer Older
reynaldi adriantama's avatar
reynaldi adriantama committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
<?php

/**
 * @see       https://github.com/laminas/laminas-console for the canonical source repository
 * @copyright https://github.com/laminas/laminas-console/blob/master/COPYRIGHT.md
 * @license   https://github.com/laminas/laminas-console/blob/master/LICENSE.md New BSD License
 */

namespace Laminas\Console\Adapter;

use Laminas\Console\Charset;

/**
 * Virtual buffer adapter
 */
class Virtual extends AbstractAdapter
{
    /**
     * Whether or not mbstring is enabled
     *
     * @var null|bool
     */
    protected static $hasMBString;

    /**
     * Results of mode system command
     *
     * @var mixed
     */
    protected $modeResult;

    /**
     * Determine and return current console width.
     *
     * @return int
     */
    public function getWidth()
    {
        static $width;
        if ($width > 0) {
            return $width;
        }

        // Try to read console size from "mode" command
        if ($this->modeResult === null) {
            $this->runProbeCommand();
        }

        if (preg_match('/Columns\:\s+(\d+)/', $this->modeResult, $matches)) {
            $width = $matches[1];
        } else {
            $width = parent::getWidth();
        }

        return $width;
    }

    /**
     * Determine and return current console height.
     *
     * @return false|int
     */
    public function getHeight()
    {
        static $height;
        if ($height > 0) {
            return $height;
        }

        // Try to read console size from "mode" command
        if ($this->modeResult === null) {
            $this->runProbeCommand();
        }

        if (preg_match('/Rows\:\s+(\d+)/', $this->modeResult, $matches)) {
            $height = $matches[1];
        } else {
            $height = parent::getHeight();
        }

        return $height;
    }

    /**
     * Run and store the results of mode command
     *
     * @return void
     */
    protected function runProbeCommand()
    {
        exec('mode', $output, $return);
        if ($return || ! count($output)) {
            $this->modeResult = '';
        } else {
            $this->modeResult = trim(implode('', $output));
        }
    }

    /**
     * Check if console is UTF-8 compatible
     *
     * @return bool
     */
    public function isUtf8()
    {
        // Try to read code page info from "mode" command
        if ($this->modeResult === null) {
            $this->runProbeCommand();
        }

        if (preg_match('/Code page\:\s+(\d+)/', $this->modeResult, $matches)) {
            return (int) $matches[1] == 65001;
        }

        return false;
    }

    /**
     * Return current console window title.
     *
     * @return string
     */
    public function getTitle()
    {
        // Try to use powershell to retrieve console window title
        exec('powershell -command "write $Host.UI.RawUI.WindowTitle"', $output, $result);
        if ($result || ! $output) {
            return '';
        }

        return trim($output, "\r\n");
    }

    /**
     * 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\AsciiExtended
     */
    public function getDefaultCharset()
    {
        return new Charset\AsciiExtended;
    }

    /**
     * Switch to UTF mode
     *
     * @return void
     */
    protected function switchToUtf8()
    {
        shell_exec('mode con cp select=65001');
    }
}