|
1
|
|
|
<?php |
|
2
|
|
|
namespace PHPDaemon\Utils; |
|
3
|
|
|
|
|
4
|
|
|
/** |
|
5
|
|
|
* Terminal |
|
6
|
|
|
* @package PHPDaemon\Utils |
|
7
|
|
|
* @author Vasily Zorin <[email protected]> |
|
8
|
|
|
*/ |
|
9
|
|
|
class Terminal |
|
10
|
|
|
{ |
|
11
|
|
|
use \PHPDaemon\Traits\ClassWatchdog; |
|
12
|
|
|
use \PHPDaemon\Traits\StaticObjectWatchdog; |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* @var boolean Is color allowed in terminal? |
|
16
|
|
|
*/ |
|
17
|
|
|
protected $enableColor = false; |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* @var integer Maximum terminal width |
|
21
|
|
|
*/ |
|
22
|
|
|
protected $columns = 80; |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* Constructor |
|
26
|
|
|
*/ |
|
27
|
|
|
public function __construct() |
|
28
|
|
|
{ |
|
29
|
|
|
$this->columns = $this->getMaxColumns(); |
|
|
|
|
|
|
30
|
|
|
} |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* Counting terminal char width |
|
34
|
|
|
* @return integer |
|
|
|
|
|
|
35
|
|
|
*/ |
|
36
|
|
|
protected function getMaxColumns() |
|
37
|
|
|
{ |
|
38
|
|
|
if (preg_match_all("/columns.([0-9]+);/", strtolower(@exec('stty -a | grep columns')), $output) |
|
39
|
|
|
&& sizeof($output) === 2 |
|
40
|
|
|
) { |
|
41
|
|
|
return $output[1][0]; |
|
42
|
|
|
} |
|
43
|
|
|
|
|
44
|
|
|
return 80; |
|
45
|
|
|
} |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* Read a line from STDIN |
|
49
|
|
|
* @return string Line |
|
50
|
|
|
*/ |
|
51
|
|
|
public function readln() |
|
52
|
|
|
{ |
|
53
|
|
|
return fgets(STDIN); |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* Enables/disable color |
|
58
|
|
|
* @param boolean $bool Enable? |
|
59
|
|
|
* @return void |
|
60
|
|
|
*/ |
|
61
|
|
|
public function enableColor($bool = true) |
|
62
|
|
|
{ |
|
63
|
|
|
$this->enableColor = $bool; |
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
|
|
/** |
|
67
|
|
|
* Clear the terminal with CLR |
|
68
|
|
|
* @return void |
|
69
|
|
|
*/ |
|
70
|
|
|
public function clearScreen() |
|
71
|
|
|
{ |
|
72
|
|
|
echo "\x0c"; |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
/** |
|
76
|
|
|
* Draw param (like in man) |
|
77
|
|
|
* @param string $name Param name |
|
78
|
|
|
* @param string $description Param description |
|
79
|
|
|
* @param array $values Param allowed values |
|
|
|
|
|
|
80
|
|
|
* @return void |
|
81
|
|
|
*/ |
|
82
|
|
|
public function drawParam($name, $description, $values = '') |
|
83
|
|
|
{ |
|
84
|
|
|
$paramw = round($this->columns / 3); |
|
85
|
|
|
|
|
86
|
|
|
echo "\n"; |
|
87
|
|
|
|
|
88
|
|
|
$leftcolumn = []; |
|
89
|
|
|
|
|
90
|
|
|
$valstr = is_array($values) ? implode('|', array_keys($values)) : $values; |
|
91
|
|
|
|
|
92
|
|
|
if ('' !== $valstr) { |
|
93
|
|
|
$valstr = '=[' . $valstr . ']'; |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
$paramstr = " \033[1m--" . $name . $valstr . "\033[0m"; |
|
97
|
|
|
|
|
98
|
|
|
$pl = mb_orig_strlen($paramstr); |
|
99
|
|
|
if ($pl + 2 >= $paramw) { |
|
100
|
|
|
$paramw = $pl + 3; |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
$descw = $this->columns - $paramw; |
|
104
|
|
|
|
|
105
|
|
|
$leftcolumn[] = $paramstr; |
|
106
|
|
|
|
|
107
|
|
|
if (is_array($values)) { |
|
108
|
|
|
foreach ($values as $key => $value) { |
|
109
|
|
|
$leftcolumn[] = ' ' . $key . ' - ' . $value; |
|
110
|
|
|
} |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
if (strlen($description) <= $descw) { |
|
114
|
|
|
$rightcolumn[] = $description; |
|
|
|
|
|
|
115
|
|
|
} else { |
|
116
|
|
|
$m = explode(' ', $description); |
|
117
|
|
|
|
|
118
|
|
|
$descstr = ''; |
|
119
|
|
|
|
|
120
|
|
|
while (sizeof($m) > 0) { |
|
121
|
|
|
$el = array_shift($m); |
|
122
|
|
|
|
|
123
|
|
|
if (strlen($descstr) + mb_orig_strlen($el) >= $descw) { |
|
124
|
|
|
$rightcolumn[] = $descstr; |
|
|
|
|
|
|
125
|
|
|
$descstr = ''; |
|
126
|
|
|
} else { |
|
127
|
|
|
$descstr .= ' '; |
|
128
|
|
|
} |
|
129
|
|
|
|
|
130
|
|
|
$descstr .= $el; |
|
131
|
|
|
} |
|
132
|
|
|
|
|
133
|
|
|
if ('' !== $descstr) { |
|
134
|
|
|
$rightcolumn[] = $descstr; |
|
|
|
|
|
|
135
|
|
|
} |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
while (sizeof($leftcolumn) > 0 || sizeof($rightcolumn) > 0) { |
|
139
|
|
|
if ($l = array_shift($leftcolumn)) { |
|
140
|
|
|
echo str_pad($l, $paramw, ' '); |
|
141
|
|
|
} else { |
|
142
|
|
|
echo str_repeat(' ', $paramw - 7); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
if ($r = array_shift($rightcolumn)) { |
|
146
|
|
|
echo $r; |
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
echo "\n"; |
|
150
|
|
|
} |
|
151
|
|
|
} |
|
152
|
|
|
|
|
153
|
|
|
/** |
|
154
|
|
|
* Draw a table |
|
155
|
|
|
* @param array Array of table's rows |
|
156
|
|
|
* @return void |
|
157
|
|
|
*/ |
|
158
|
|
|
public function drawTable($rows) |
|
159
|
|
|
{ |
|
160
|
|
|
$pad = []; |
|
161
|
|
|
|
|
162
|
|
|
foreach ($rows as $row) { |
|
163
|
|
|
foreach ($row as $k => $v) { |
|
164
|
|
|
if (substr($k, 0, 1) === '_') { |
|
165
|
|
|
continue; |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
if (!isset($pad[$k]) || (strlen($v) > $pad[$k])) { |
|
169
|
|
|
$pad[$k] = mb_orig_strlen($v); |
|
170
|
|
|
} |
|
171
|
|
|
} |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
foreach ($rows as $row) { |
|
175
|
|
|
if (isset($row['_color'])) { |
|
176
|
|
|
$this->setStyle($row['_color']); |
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
if (isset($row['_bold'])) { |
|
180
|
|
|
$this->setStyle('1'); |
|
181
|
|
|
} |
|
182
|
|
|
|
|
183
|
|
|
if (isset($row['_'])) { |
|
184
|
|
|
echo $row['_']; |
|
185
|
|
|
} else { |
|
186
|
|
|
$i = 0; |
|
187
|
|
|
|
|
188
|
|
|
foreach ($row as $k => $v) { |
|
189
|
|
|
if (substr($k, 0, 1) === '_') { |
|
190
|
|
|
continue; |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
if ($i > 0) { |
|
194
|
|
|
echo "\t"; |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
echo str_pad($v, $pad[$k]); |
|
198
|
|
|
++$i; |
|
199
|
|
|
} |
|
200
|
|
|
} |
|
201
|
|
|
|
|
202
|
|
|
$this->resetStyle(); |
|
203
|
|
|
echo "\n"; |
|
204
|
|
|
} |
|
205
|
|
|
} |
|
206
|
|
|
|
|
207
|
|
|
/** |
|
208
|
|
|
* Set text style |
|
209
|
|
|
* @param string $c Style |
|
210
|
|
|
* @return void |
|
211
|
|
|
*/ |
|
212
|
|
|
public function setStyle($c) |
|
213
|
|
|
{ |
|
214
|
|
|
if ($this->enableColor) { |
|
215
|
|
|
echo "\033[" . $c . 'm'; |
|
216
|
|
|
} |
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
|
|
/** |
|
220
|
|
|
* Reset style to default |
|
221
|
|
|
* @return void |
|
222
|
|
|
*/ |
|
223
|
|
|
public function resetStyle() |
|
224
|
|
|
{ |
|
225
|
|
|
if ($this->enableColor) { |
|
226
|
|
|
echo "\033[0m"; |
|
227
|
|
|
} |
|
228
|
|
|
} |
|
229
|
|
|
} |
|
230
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.