RSI helpers  0.1
RSI helpers
Console.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Rsi;
4 
5 /**
6  * Console helpers.
7  */
8 class Console{
9 
10  /**
11  * Read an input line.
12  * @return string User input (excluding the last return).
13  */
14  public static function readLine(){
15  $line = fgets(STDIN);
16  return rtrim($line,"\r\n");
17  }
18  /**
19  * Ask a question.
20  * @param string $message Message to show.
21  * @param array|string $options Array with allowed options (key = input, value = explanation) or regex for the answer.
22  * @param string $default Default answer (when user presses enter).
23  * @return string Answer.
24  */
25  public static function prompt($message,$options = null,$default = null){
26  do{
27  print($message . (is_array($options) ? ' [' . Record::implode($options,',','=') . ']' : '') . ($default ? " ($default)" : '') . ': ');
28  if(($result = self::readLine()) === '') $result = $default;
29  }
30  while($options && !(is_array($options) ? array_key_exists($result,$options) : preg_match($options,$result)));
31  return $result;
32  }
33  /**
34  * Large header text.
35  * @param string $header Header.
36  * @param int $width Maximum width of header.
37  * @param int $font Maximum font size (1..5).
38  * @param int $pad Padding type (STR_PAD_* constants).
39  * @return string Large header (multi line string) or simply $header if too wide.
40  */
41  public static function header($header,$width = 80,$font = null,$pad = null){
42  $length = strlen($header);
43  $image = imagecreate($width * 2,$width);
44  $background = imagecolorallocate($image,0,0,0);
45  $color = imagecolorallocate($image,0,0,255);
46  $check = imagecolorallocate($image,0,255,0);
47  for($font = $font ?: 5; $font; $font--){
48  $size= imagefontwidth($font);
49  imagefilledrectangle($image,0,0,$width * 2,$height = imagefontheight($font),$background);
50  $x = $max = 0;
51  for($i = 0; $i < $length; $i++) if(trim($c = $header[$i])){
52  if($i && trim($header[$i - 1])){
53  do{
54  imagestring($image,$font,--$x,0,$c,$check);
55  $touch = false;
56  for($cx = max(0,$x - $size); $cx < min($width * 2,$x + $size); $cx++) for($cy = 0; $cy < $height; $cy++)
57  if($touch = (!$cx || (imagecolorat($image,$cx - 1,$cy) == $color)) && (
58  (($cy > 0) && (($cx && (imagecolorat($image,$cx - 1,$cy - 1) == $check)) || (imagecolorat($image,$cx,$cy - 1) == $check))) ||
59  (imagecolorat($image,$cx,$cy) == $check) ||
60  (($cy < $height - 1) && (($cx && (imagecolorat($image,$cx - 1,$cy + 1) == $check)) || (imagecolorat($image,$cx,$cy + 1) == $check)))
61  )) break 2; //cx + cy loop
62  imagestring($image,$font,$x,0,$c,$background);
63  }
64  while(!$touch);
65  $x++;
66  }
67  imagestring($image,$font,$x,0,$c,$color);
68  if(($x += $size) > $width * 2) break;
69  }
70  else $x += round($size / 2); //space
71  $lines = [];
72  for($y = 0; $y < $height; $y++){
73  $line = '';
74  for($x = 0; $x < $width * 2; $x++) $line .= imagecolorat($image,$x,$y) ? '#' : ' ';
75  if($line = rtrim($line)) $max = max($max,strlen($lines[] = $line));
76  }
77  if($max <= $width) break;
78  }
79  imagedestroy($image);
80  if($max > $width){
81  $lines = [$header];
82  $max = $length;
83  }
84  switch($pad){
85  case STR_PAD_RIGHT: $lines = Record::prefix($lines,str_repeat(' ',$width - $max)); break;
86  case STR_PAD_BOTH: $lines = Record::prefix($lines,str_repeat(' ',round(($width - $max) / 2))); break;
87  }
88  return implode("\n",$lines);
89  }
90  /**
91  * Text block.
92  * @param string $str Text.
93  * @param int $width Width of block.
94  * @param int $pad Padding type (STR_PAD_* constants).
95  * @return string Block with text.
96  */
97  public static function block($str,$width = 80,$pad = null){
98  $text = $border = str_repeat('*',$width);
99  foreach(Str::wrap($str,$width -= 8) as $line) $text .= "\n** " . Str::pad($line,$width,' ',$pad ?: STR_PAD_RIGHT) . " **";
100  return $text . "\n" . $border;
101  }
102  /**
103  * Text style gauge.
104  * @param float $perc Percentage done (0..100).
105  * @param int $width Total width of gauche.
106  * @return string
107  */
108  public static function gauge($perc = 0,$width = 80){
109  $done = round($perc * $width / 100);
110  $text = str_repeat('#',$done) . str_repeat('-',$width - $done);
111  $start = round(($width - ($length = strlen($perc = ' ' . round($perc) . '% '))) / 2);
112  return substr($text,0,$start) . $perc . substr($text,$start + $length);
113  }
114 
115  protected static function tableRow($record,$columns){
116  $text = null;
117  $max_lines = 1;
118  foreach($columns as $key => $column) $max_lines = max($max_lines,count($columns[$key]['lines'] = Str::wrap($record[$key] ?? null,$column['width'])));
119  $last = Record::key($columns,-1);
120  for($i = 0; $i < $max_lines; $i++){
121  $text .= ['|','/',':','\\'][$border = $max_lines <= 1 ? 0 : ($i ? ($i == $max_lines - 1 ? 3 : 2) : 1)];
122  foreach($columns as $key => $column)
123  $text .= ' ' . \Rsi\Str::pad($column['lines'][$i] ?? null,$column['width'],' ',$column['pad'] ?? STR_PAD_RIGHT) . ' ' . ($key == $last ? ['|','\\',':','/'][$border] : '|');
124  $text .= "\n";
125  }
126  return $text;
127  }
128  /**
129  * Text style table.
130  * @param array $data Array of records.
131  * @param array $columns Key = same as records, value = array with (optional) 'header' (defaults to key), 'width' (defaults
132  * to null = auto), 'pad' = STR_PAD_RIGHT (default), STR_PAD_LEFT, or STR_PAD_BOTH. Empty = take keys of first record.
133  * @param int $width Maximum width of complete table (including borders).
134  * @return string
135  */
136  public static function table($data,$columns = null,$width = 80){
137  $text = null;
138  if($count = count($data = array_values($data))){
139  if(!$columns) $columns = array_fill_keys(array_keys($data[0]),[]);
140  $headers = $footers = $max_length = [];
141  foreach($columns as $key => $column) $max_length[$key] = max(mb_strlen($headers[$key] = $column['header'] ?? $key),mb_strlen($footers[$key] = $column['footer'] ?? null));
142  $average_length = $max_length;
143  foreach($data as $record) foreach($columns as $key => $column){
144  $length = mb_strlen($record[$key] ?? null);
145  if($column['width'] ?? null) $length = min($length,$column['width']);
146  $average_length[$key] += $length;
147  $max_length[$key] = max($max_length[$key],$length);
148  }
149  $total_width = 1; //left border
150  foreach($columns as $key => $column){
151  $average_length[$key] /= $count;
152  $total_width += ($columns[$key]['width'] = $max_length[$key]) + 3; //spaces + right border
153  }
154  if($total_width > $width){
155  $factor = ($width - 1 - count($columns) * 3) / array_sum($average_length);
156  $total_width = 1;
157  foreach($columns as $key => $column) $total_width += ($columns[$key]['width'] = min($max_length[$key],max(1,floor($factor * $average_length[$key])))) + 3;
158  while($total_width < $width){
159  $min_key = $min_width = null;
160  foreach($columns as $key => $column) if((!$min_key || ($column['width'] < $min_width)) && ($column['width'] < $max_length[$key])){
161  $min_key = $key;
162  $min_width = $column['width'];
163  }
164  $columns[$min_key]['width']++;
165  $total_width++;
166  }
167  }
168  $border = '+';
169  foreach($columns as $key => $column) $border .= str_repeat('-',$column['width'] + 2) . '+';
170  $text = $border . "\n" . self::tableRow($headers,$columns) . $border . "\n";
171  foreach($data as $record) $text .= self::tableRow($record,$columns);
172  $text .= $border;
173  if(array_filter($footers)) $text .= "\n" . self::tableRow($footers,$columns) . $border;
174  }
175  return $text;
176  }
177 
178 }
static prompt($message, $options=null, $default=null)
Ask a question.
Definition: Console.php:25
static readLine()
Read an input line.
Definition: Console.php:14
static header($header, $width=80, $font=null, $pad=null)
Large header text.
Definition: Console.php:41
static tableRow($record, $columns)
Definition: Console.php:115
static gauge($perc=0, $width=80)
Text style gauge.
Definition: Console.php:108
static block($str, $width=80, $pad=null)
Text block.
Definition: Console.php:97
Definition: Color.php:3
static table($data, $columns=null, $width=80)
Text style table.
Definition: Console.php:136
Console helpers.
Definition: Console.php:8