PluginProbe
Depicter — Popup & Slider Builder / trunk
Depicter — Popup & Slider Builder vtrunk
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / vendor / symfony / console / Terminal.php

Terminal.php in Depicter — Popup & Slider Builder trunk, at vendor/symfony/console/Terminal.php

177 lines 5.1 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 <[email protected]>
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 public static function hasSttyAvailable(): bool
62 {
63 if (null !== self::$stty) {
64 return self::$stty;
65 }
66
67 // skip check if shell_exec function is disabled
68 if (!\function_exists('shell_exec')) {
69 return false;
70 }
71
72 return self::$stty = (bool) shell_exec('stty 2> '.('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null'));
73 }
74
75 private static function initDimensions()
76 {
77 if ('\\' === \DIRECTORY_SEPARATOR) {
78 $ansicon = getenv('ANSICON');
79 if (false !== $ansicon && preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim($ansicon), $matches)) {
80 // extract [w, H] from "wxh (WxH)"
81 // or [w, h] from "wxh"
82 self::$width = (int) $matches[1];
83 self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
84 } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) {
85 // only use stty on Windows if the terminal does not support vt100 (e.g. Windows 7 + git-bash)
86 // testing for stty in a Windows 10 vt100-enabled console will implicitly disable vt100 support on STDOUT
87 self::initDimensionsUsingStty();
88 } elseif (null !== $dimensions = self::getConsoleMode()) {
89 // extract [w, h] from "wxh"
90 self::$width = (int) $dimensions[0];
91 self::$height = (int) $dimensions[1];
92 }
93 } else {
94 self::initDimensionsUsingStty();
95 }
96 }
97
98 /**
99 * Returns whether STDOUT has vt100 support (some Windows 10+ configurations).
100 */
101 private static function hasVt100Support(): bool
102 {
103 return \function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(fopen('php://stdout', 'w'));
104 }
105
106 /**
107 * Initializes dimensions using the output of an stty columns line.
108 */
109 private static function initDimensionsUsingStty()
110 {
111 if ($sttyString = self::getSttyColumns()) {
112 if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
113 // extract [w, h] from "rows h; columns w;"
114 self::$width = (int) $matches[2];
115 self::$height = (int) $matches[1];
116 } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
117 // extract [w, h] from "; h rows; w columns"
118 self::$width = (int) $matches[2];
119 self::$height = (int) $matches[1];
120 }
121 }
122 }
123
124 /**
125 * Runs and parses mode CON if it's available, suppressing any error output.
126 *
127 * @return int[]|null An array composed of the width and the height or null if it could not be parsed
128 */
129 private static function getConsoleMode(): ?array
130 {
131 $info = self::readFromProcess('mode CON');
132
133 if (null === $info || !preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
134 return null;
135 }
136
137 return [(int) $matches[2], (int) $matches[1]];
138 }
139
140 /**
141 * Runs and parses stty -a if it's available, suppressing any error output.
142 */
143 private static function getSttyColumns(): ?string
144 {
145 return self::readFromProcess('stty -a | grep columns');
146 }
147
148 private static function readFromProcess(string $command): ?string
149 {
150 if (!\function_exists('proc_open')) {
151 return null;
152 }
153
154 $descriptorspec = [
155 1 => ['pipe', 'w'],
156 2 => ['pipe', 'w'],
157 ];
158
159 $cp = \function_exists('sapi_windows_cp_set') ? sapi_windows_cp_get() : 0;
160
161 if (!$process = @proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true])) {
162 return null;
163 }
164
165 $info = stream_get_contents($pipes[1]);
166 fclose($pipes[1]);
167 fclose($pipes[2]);
168 proc_close($process);
169
170 if ($cp) {
171 sapi_windows_cp_set($cp);
172 }
173
174 return $info;
175 }
176 }
177