Completed
Push — feature/logger ( 1c2c4d...c4d378 )
by Todd
03:49 queued 02:00
created

Table::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 5
ccs 5
cts 5
cp 1
rs 9.4286
cc 1
eloc 4
nc 1
nop 0
crap 1
1
<?php
2
namespace Garden\Cli;
3
4
/**
5
 * Used to write a formatted table to the console.
6
 */
7
class Table {
8
    /// Properties ///
9
10
    /**
11
     * @var array An array of column widths.
12
     */
13
    protected $columnWidths;
14
15
    /**
16
     * @var bool Whether or not to format the console commands.
17
     */
18
    public $format = true;
19
20
    /**
21
     * @var array An array of the row data.
22
     */
23
    protected $rows;
24
25
    /**
26
     * @var array|null A pointer to the current row.
27
     */
28
    protected $currentRow;
29
30
    /**
31
     * @var int The maximum width of the table.
32
     */
33
    public $maxWidth = 80;
34
35
    /**
36
     * @var int The left padding on each cell.
37
     */
38
    public $padding = 3;
39
40
    /**
41
     * @var int The left indent on the table.
42
     */
43
    public $indent = 2;
44
45
46
    /// Methods ///
47
48
    /**
49
     * Initialize an instance of the {@link Table} class.
50
     */
51 4
    public function __construct() {
52
        $this->reset();
53 4
    }
54
55
    /**
56
     * Add a cell to the table.
57
     *
58
     * @param string $text The text of the cell.
59
     * @param array $wrap A two element array used to wrap the text in the cell.
60
     * @return $this Returns this object for fluent calls.
61
     */
62
    protected function addCell($text, $wrap = ['', '']) {
63
        if ($this->currentRow === null) {
64
            $this->row();
65
        }
66
67
        $i = count($this->currentRow);
68
        $this->columnWidths[$i] = max(strlen($text), Cli::val($i, $this->columnWidths, 0)); // max column width
69
70
        $this->currentRow[$i] = [$text, $wrap];
71
        return $this;
72
    }
73
74
    /**
75
     * Adds a cell.
76
     *
77
     * @param string $text The text of the cell.
78
     * @return $this Returns this object for fluent calls.
79
     */
80
    public function cell($text) {
81
        return $this->addCell($text);
82
    }
83
84
    /**
85
     * Adds a bold cell.
86
     *
87
     * @param string $text The text of the cell.
88
     * @return $this Returns this object for fluent calls.
89
     */
90
    public function bold($text) {
91
        return $this->addCell($text, ["\033[1m", "\033[0m"]);
92
    }
93
94
    /**
95
     * Adds a red cell.
96
     *
97
     * @param string $text The text of the cell.
98
     * @return $this Returns this object for fluent calls.
99
     */
100
    public function red($text) {
101
        return $this->addCell($text, ["\033[1;31m", "\033[0m"]);
102
    }
103
104
    /**
105
     * Adds a green cell.
106
     *
107
     * @param string $text The text of the cell.
108
     * @return $this Returns this object for fluent calls.
109
     */
110
    public function green($text) {
111
        return $this->addCell($text, ["\033[1;32m", "\033[0m"]);
112
    }
113
114
    /**
115
     * Adds a blue cell.
116
     *
117
     * @param string $text The text of the cell.
118
     * @return $this Returns this object for fluent calls.
119
     */
120
    public function blue($text) {
121
        return $this->addCell($text, ["\033[1;34m", "\033[0m"]);
122
    }
123
124
    /**
125
     * Adds a purple cell.
126
     * 
127
     * @param string $text The text of the cell.
128
     * @return $this Returns this object for fluent calls.
129
     */
130
    public function purple($text) {
131
        return $this->addCell($text, ["\033[0;35m", "\033[0m"]);
132
    }
133
134
    /**
135
     * Reset the table so another one can be written with the same object.
136
     */
137 4
    public function reset() {
138 4
        $this->columnWidths = [];
139 4
        $this->rows = [];
140 4
        $this->currentRow = null;
141 4
    }
142
143
    /**
144
     * Start a new row.
145
     * 
146
     * @return $this Returns this object for fluent calls.
147
     */
148 1
    public function row() {
149 1
        $this->rows[] = [];
150
        $this->currentRow =& $this->rows[count($this->rows) - 1];
151 1
        return $this;
152
    }
153
154
    /**
155
     * Writes the final table.
156
     */
157 4
    public function write() {
158
        // Determine the width of the last column.
159
        $columnWidths = array_sum($this->columnWidths);
160
        $totalWidth = $this->indent + $columnWidths + $this->padding * (count($this->columnWidths) - 1);
161
162
        $lastWidth = end($this->columnWidths) + $this->maxWidth - $totalWidth;
163
        $lastWidth = max($lastWidth, 10); // min width of 10
164
        $this->columnWidths[count($this->columnWidths) - 1] = $lastWidth;
165
166
        // Loop through each row and write it.
167 4
        foreach ($this->rows as $row) {
168 1
            $rowLines = [];
169 1
            $lineCount = 0;
170
171
            // Split the cells into lines.
172
            foreach ($row as $i => $cell) {
173
                list($text,) = $cell;
174
                $width = $this->columnWidths[$i];
175
176
                $lines = Cli::breakLines($text, $width, $i < count($this->columnWidths) - 1);
177
                $rowLines[] = $lines;
178
                $lineCount = max($lineCount, count($lines));
179
            }
180
181
            // Write all of the lines.
182
            for ($i = 0; $i < $lineCount; $i++) {
183
                foreach ($rowLines as $j => $lines) {
184
                    $padding = $j === 0 ? $this->indent : $this->padding;
185
186
                    if (isset($lines[$i])) {
187
                        if(isset($row[$i])) {
188
                            $wrap = $row[$i][1];
189
                        } else {
190
                            // if we're out of array, use the latest wraps
191
                            $wrap = $row[count($row)-1][1];
192
                        }
193
194
                        if ($this->format) {
195
                            echo str_repeat(' ', $padding).$wrap[0].$lines[$i].$wrap[1];
196
                        } else {
197
                            echo str_repeat(' ', $padding).$lines[$i];
198
                        }
199
                    } elseif ($j < count($this->columnWidths) - 1) {
200
                        // This is an empty line. Write the spaces.
201
                        echo str_repeat(' ', $padding + $this->columnWidths[$j]);
202
                    }
203
                }
204
                echo PHP_EOL;
205
            }
206
        }
207 4
    }
208
}
209