PluginProbe
Depicter — Popup & Slider Builder / 1.3.2
Depicter — Popup & Slider Builder v1.3.2
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 1.3.2, at vendor/symfony/console/Terminal.php

175 lines 4.9 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(): bool
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(): ?array
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 private static function getSttyColumns(): ?string
147 {
148 return self::readFromProcess('stty -a | grep columns');
149 }
150
151 private static function readFromProcess(string $command): ?string
152 {
153 if (!\function_exists('proc_open')) {
154 return null;
155 }
156
157 $descriptorspec = [
158 1 => ['pipe', 'w'],
159 2 => ['pipe', 'w'],
160 ];
161
162 $process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
163 if (!\is_resource($process)) {
164 return null;
165 }
166
167 $info = stream_get_contents($pipes[1]);
168 fclose($pipes[1]);
169 fclose($pipes[2]);
170 proc_close($process);
171
172 return $info;
173 }
174 }
175