PluginProbe
UpStream: a Project Management Plugin for WordPress / trunk
UpStream: a Project Management Plugin for WordPress vtrunk
trunk 1.39.0 1.39.1 1.39.2 1.39.3 2.0.7 2.1.0
upstream / vendor / symfony / console / Terminal.php

Terminal.php in UpStream: a Project Management Plugin for WordPress trunk, at vendor/symfony/console/Terminal.php

182 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Symfony\Component\Console;
13
14 class Terminal
15 {
16 private static $width;
17 private static $height;
18 private static $stty;
19
20 /**
21 * Gets the terminal width.
22 *
23 * @return int
24 */
25 public function getWidth()
26 {
27 $width = getenv('COLUMNS');
28 if (false !== $width) {
29 return (int) trim($width);
30 }
31
32 if (null === self::$width) {
33 self::initDimensions();
34 }
35
36 return self::$width ?: 80;
37 }
38
39 /**
40 * Gets the terminal height.
41 *
42 * @return int
43 */
44 public function getHeight()
45 {
46 $height = getenv('LINES');
47 if (false !== $height) {
48 return (int) trim($height);
49 }
50
51 if (null === self::$height) {
52 self::initDimensions();
53 }
54
55 return self::$height ?: 50;
56 }
57
58 /**
59 * @internal
60 *
61 * @return bool
62 */
63 public static function hasSttyAvailable()
64 {
65 if (null !== self::$stty) {
66 return self::$stty;
67 }
68
69 // skip check if exec function is disabled
70 if (!\function_exists('exec')) {
71 return false;
72 }
73
74 exec('stty 2>&1', $output, $exitcode);
75
76 return self::$stty = 0 === $exitcode;
77 }
78
79 private static function initDimensions()
80 {
81 if ('\\' === \DIRECTORY_SEPARATOR) {
82 if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) {
83 // extract [w, H] from "wxh (WxH)"
84 // or [w, h] from "wxh"
85 self::$width = (int) $matches[1];
86 self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
87 } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) {
88 // only use stty on Windows if the terminal does not support vt100 (e.g. Windows 7 + git-bash)
89 // testing for stty in a Windows 10 vt100-enabled console will implicitly disable vt100 support on STDOUT
90 self::initDimensionsUsingStty();
91 } elseif (null !== $dimensions = self::getConsoleMode()) {
92 // extract [w, h] from "wxh"
93 self::$width = (int) $dimensions[0];
94 self::$height = (int) $dimensions[1];
95 }
96 } else {
97 self::initDimensionsUsingStty();
98 }
99 }
100
101 /**
102 * Returns whether STDOUT has vt100 support (some Windows 10+ configurations).
103 */
104 private static function hasVt100Support()
105 {
106 return \function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(fopen('php://stdout', 'w'));
107 }
108
109 /**
110 * Initializes dimensions using the output of an stty columns line.
111 */
112 private static function initDimensionsUsingStty()
113 {
114 if ($sttyString = self::getSttyColumns()) {
115 if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
116 // extract [w, h] from "rows h; columns w;"
117 self::$width = (int) $matches[2];
118 self::$height = (int) $matches[1];
119 } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
120 // extract [w, h] from "; h rows; w columns"
121 self::$width = (int) $matches[2];
122 self::$height = (int) $matches[1];
123 }
124 }
125 }
126
127 /**
128 * Runs and parses mode CON if it's available, suppressing any error output.
129 *
130 * @return int[]|null An array composed of the width and the height or null if it could not be parsed
131 */
132 private static function getConsoleMode()
133 {
134 $info = self::readFromProcess('mode CON');
135
136 if (null === $info || !preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
137 return null;
138 }
139
140 return [(int) $matches[2], (int) $matches[1]];
141 }
142
143 /**
144 * Runs and parses stty -a if it's available, suppressing any error output.
145 *
146 * @return string|null
147 */
148 private static function getSttyColumns()
149 {
150 return self::readFromProcess('stty -a | grep columns');
151 }
152
153 /**
154 * @param string $command
155 *
156 * @return string|null
157 */
158 private static function readFromProcess($command)
159 {
160 if (!\function_exists('proc_open')) {
161 return null;
162 }
163
164 $descriptorspec = [
165 1 => ['pipe', 'w'],
166 2 => ['pipe', 'w'],
167 ];
168
169 $process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
170 if (!\is_resource($process)) {
171 return null;
172 }
173
174 $info = stream_get_contents($pipes[1]);
175 fclose($pipes[1]);
176 fclose($pipes[2]);
177 proc_close($process);
178
179 return $info;
180 }
181 }
182