forked from wp-cli/php-cli-tools
/
Table.php
210 lines (185 loc) · 5.08 KB
/
Table.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<?php
/**
* PHP Command Line Tools
*
* This source file is subject to the MIT license that is bundled
* with this package in the file LICENSE.
*
* @author James Logsdon <dwarf@girsbrain.org>
* @copyright 2010 James Logsdom (http://girsbrain.org)
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace cli;
use cli\Shell;
use cli\Streams;
use cli\table\Ascii;
use cli\table\Renderer;
use cli\table\Tabular;
/**
* The `Table` class is used to display data in a tabular format.
*/
class Table {
protected $_renderer;
protected $_headers = array();
protected $_footers = array();
protected $_width = array();
protected $_rows = array();
/**
* Initializes the `Table` class.
*
* There are 3 ways to instantiate this class:
*
* 1. Pass an array of strings as the first paramater for the column headers
* and a 2-dimensional array as the second parameter for the data rows.
* 2. Pass an array of hash tables (string indexes instead of numerical)
* where each hash table is a row and the indexes of the *first* hash
* table are used as the header values.
* 3. Pass nothing and use `setHeaders()` and `addRow()` or `setRows()`.
*
* @param array $headers Headers used in this table. Optional.
* @param array $rows The rows of data for this table. Optional.
* @param array $footers Footers used in this table. Optional.
*/
public function __construct(array $headers = null, array $rows = null, array $footers = null) {
if (!empty($headers)) {
// If all the rows is given in $headers we use the keys from the
// first row for the header values
if (empty($rows)) {
$rows = $headers;
$keys = array_keys(array_shift($headers));
$headers = array();
foreach ($keys as $header) {
$headers[$header] = $header;
}
}
$this->setHeaders($headers);
$this->setRows($rows);
}
if (!empty($footers)) {
$this->setFooters($footers);
}
if (Shell::isPiped()) {
$this->setRenderer(new Tabular());
} else {
$this->setRenderer(new Ascii());
}
}
public function resetTable()
{
$this->_headers = array();
$this->_width = array();
$this->_rows = array();
$this->_footers = array();
return $this;
}
/**
* Sets the renderer used by this table.
*
* @param table\Renderer $renderer The renderer to use for output.
* @see table\Renderer
* @see table\Ascii
* @see table\Tabular
*/
public function setRenderer(Renderer $renderer) {
$this->_renderer = $renderer;
}
/**
* Loops through the row and sets the maximum width for each column.
*
* @param array $row The table row.
* @return array $row
*/
protected function checkRow(array $row) {
foreach ($row as $column => $str) {
$width = Colors::length($str);
if (!isset($this->_width[$column]) || $width > $this->_width[$column]) {
$this->_width[$column] = $width;
}
}
return $row;
}
/**
* Output the table to `STDOUT` using `cli\line()`.
*
* If STDOUT is a pipe or redirected to a file, should output simple
* tab-separated text. Otherwise, renders table with ASCII table borders
*
* @uses cli\Shell::isPiped() Determine what format to output
*
* @see cli\Table::renderRow()
*/
public function display() {
$this->_renderer->setWidths($this->_width);
$border = $this->_renderer->border();
if (isset($border)) {
Streams::line($border);
}
Streams::line($this->_renderer->row($this->_headers));
if (isset($border)) {
Streams::line($border);
}
foreach ($this->_rows as $row) {
Streams::line($this->_renderer->row($row));
}
if (isset($border)) {
Streams::line($border);
}
if ($this->_footers) {
Streams::line($this->_renderer->row($this->_footers));
if (isset($border)) {
Streams::line($border);
}
}
}
/**
* Sort the table by a column. Must be called before `cli\Table::display()`.
*
* @param int $column The index of the column to sort by.
*/
public function sort($column) {
if (!isset($this->_headers[$column])) {
trigger_error('No column with index ' . $column, E_USER_NOTICE);
return;
}
usort($this->_rows, function($a, $b) use ($column) {
return strcmp($a[$column], $b[$column]);
});
}
/**
* Set the headers of the table.
*
* @param array $headers An array of strings containing column header names.
*/
public function setHeaders(array $headers) {
$this->_headers = $this->checkRow($headers);
}
/**
* Set the footers of the table.
*
* @param array $footers An array of strings containing column footers names.
*/
public function setFooters(array $footers) {
$this->_footers = $this->checkRow($footers);
}
/**
* Add a row to the table.
*
* @param array $row The row data.
* @see cli\Table::checkRow()
*/
public function addRow(array $row) {
$this->_rows[] = $this->checkRow($row);
}
/**
* Clears all previous rows and adds the given rows.
*
* @param array $rows A 2-dimensional array of row data.
* @see cli\Table::addRow()
*/
public function setRows(array $rows) {
$this->_rows = array();
foreach ($rows as $row) {
$this->addRow($row);
}
}
}