1 | <?php |
||
46 | class Table extends Widget |
||
47 | { |
||
48 | const CHAR_TOP = 'top'; |
||
49 | const CHAR_TOP_MID = 'top-mid'; |
||
50 | const CHAR_TOP_LEFT = 'top-left'; |
||
51 | const CHAR_TOP_RIGHT = 'top-right'; |
||
52 | const CHAR_BOTTOM = 'bottom'; |
||
53 | const CHAR_BOTTOM_MID = 'bottom-mid'; |
||
54 | const CHAR_BOTTOM_LEFT = 'bottom-left'; |
||
55 | const CHAR_BOTTOM_RIGHT = 'bottom-right'; |
||
56 | const CHAR_LEFT = 'left'; |
||
57 | const CHAR_LEFT_MID = 'left-mid'; |
||
58 | const CHAR_MID = 'mid'; |
||
59 | const CHAR_MID_MID = 'mid-mid'; |
||
60 | const CHAR_RIGHT = 'right'; |
||
61 | const CHAR_RIGHT_MID = 'right-mid'; |
||
62 | const CHAR_MIDDLE = 'middle'; |
||
63 | |||
64 | /** |
||
65 | * @var array table headers |
||
66 | */ |
||
67 | private $_headers = []; |
||
68 | /** |
||
69 | * @var array table rows |
||
70 | */ |
||
71 | private $_rows = []; |
||
72 | /** |
||
73 | * @var array table chars |
||
74 | */ |
||
75 | private $_chars = [ |
||
76 | self::CHAR_TOP => '═', |
||
77 | self::CHAR_TOP_MID => '╤', |
||
78 | self::CHAR_TOP_LEFT => '╔', |
||
79 | self::CHAR_TOP_RIGHT => '╗', |
||
80 | self::CHAR_BOTTOM => '═', |
||
81 | self::CHAR_BOTTOM_MID => '╧', |
||
82 | self::CHAR_BOTTOM_LEFT => '╚', |
||
83 | self::CHAR_BOTTOM_RIGHT => '╝', |
||
84 | self::CHAR_LEFT => '║', |
||
85 | self::CHAR_LEFT_MID => '╟', |
||
86 | self::CHAR_MID => '─', |
||
87 | self::CHAR_MID_MID => '┼', |
||
88 | self::CHAR_RIGHT => '║', |
||
89 | self::CHAR_RIGHT_MID => '╢', |
||
90 | self::CHAR_MIDDLE => '│', |
||
91 | ]; |
||
92 | /** |
||
93 | * @var array table column widths |
||
94 | */ |
||
95 | private $_columnWidths = []; |
||
96 | /** |
||
97 | * @var int screen width |
||
98 | */ |
||
99 | private $_screenWidth; |
||
100 | /** |
||
101 | * @var string list prefix |
||
102 | */ |
||
103 | private $_listPrefix = '• '; |
||
104 | |||
105 | /** |
||
106 | * Set table headers |
||
107 | * |
||
108 | * @param array $headers table headers |
||
109 | * @return $this |
||
110 | */ |
||
111 | 6 | public function setHeaders(array $headers) |
|
116 | |||
117 | /** |
||
118 | * Set table rows |
||
119 | * |
||
120 | * @param array $rows table rows |
||
121 | * @return $this |
||
122 | */ |
||
123 | 6 | public function setRows(array $rows) |
|
128 | |||
129 | /** |
||
130 | * Set table chars |
||
131 | * |
||
132 | * @param array $chars table chars |
||
133 | * @return $this |
||
134 | */ |
||
135 | 1 | public function setChars(array $chars) |
|
140 | |||
141 | /** |
||
142 | * Set screen width |
||
143 | * |
||
144 | * @param int $width screen width |
||
145 | * @return $this |
||
146 | */ |
||
147 | 6 | public function setScreenWidth($width) |
|
152 | |||
153 | /** |
||
154 | * Set list prefix |
||
155 | * |
||
156 | * @param string $listPrefix list prefix |
||
157 | * @return $this |
||
158 | */ |
||
159 | 1 | public function setListPrefix($listPrefix) |
|
164 | |||
165 | /** |
||
166 | * @return string the rendered table |
||
167 | */ |
||
168 | 6 | public function run() |
|
207 | |||
208 | /** |
||
209 | * Renders a row of data into a string |
||
210 | * |
||
211 | * @param array $row row of data |
||
212 | * @param string $spanLeft character for left border |
||
213 | * @param string $spanMiddle character for middle border |
||
214 | * @param string $spanRight character for right border |
||
215 | * @return string |
||
216 | * @see \yii\console\widgets\Table::render() |
||
217 | */ |
||
218 | 6 | protected function renderRow(array $row, $spanLeft, $spanMiddle, $spanRight) |
|
263 | |||
264 | /** |
||
265 | * Renders separator |
||
266 | * |
||
267 | * @param string $spanLeft character for left border |
||
268 | * @param string $spanMid character for middle border |
||
269 | * @param string $spanMidMid character for middle-middle border |
||
270 | * @param string $spanRight character for right border |
||
271 | * @return string the generated separator row |
||
272 | * @see \yii\console\widgets\Table::render() |
||
273 | */ |
||
274 | 6 | protected function renderSeparator($spanLeft, $spanMid, $spanMidMid, $spanRight) |
|
286 | |||
287 | /** |
||
288 | * Calculate the size of rows to draw anchor of columns in console |
||
289 | * |
||
290 | * @see \yii\console\widgets\Table::render() |
||
291 | */ |
||
292 | 6 | protected function calculateRowsSize() |
|
293 | { |
||
294 | 6 | $this->_columnWidths = $columns = []; |
|
295 | 6 | $totalWidth = 0; |
|
296 | 6 | $screenWidth = $this->getScreenWidth() - 3; |
|
297 | |||
298 | 6 | for ($i = 0, $count = count($this->_headers); $i < $count; $i++) { |
|
299 | 6 | $columns[] = ArrayHelper::getColumn($this->_rows, $i); |
|
300 | 6 | $columns[$i][] = $this->_headers[$i]; |
|
301 | } |
||
302 | |||
303 | 6 | foreach ($columns as $column) { |
|
304 | 6 | $columnWidth = max(array_map(function ($val) { |
|
305 | 6 | if (is_array($val)) { |
|
306 | 2 | $encodings = array_fill(0, count($val), Yii::$app->charset); |
|
307 | 2 | return max(array_map('mb_strwidth', $val, $encodings)) + mb_strwidth($this->_listPrefix, Yii::$app->charset); |
|
308 | } |
||
309 | 6 | return mb_strwidth($val, Yii::$app->charset); |
|
310 | 6 | }, $column)) + 2; |
|
311 | 6 | $this->_columnWidths[] = $columnWidth; |
|
312 | 6 | $totalWidth += $columnWidth; |
|
313 | } |
||
314 | |||
315 | 6 | $relativeWidth = $screenWidth / $totalWidth; |
|
316 | |||
317 | 6 | if ($totalWidth > $screenWidth) { |
|
318 | foreach ($this->_columnWidths as $j => $width) { |
||
319 | $this->_columnWidths[$j] = (int) ($width * $relativeWidth); |
||
320 | if ($j === count($this->_columnWidths)) { |
||
321 | $this->_columnWidths = $totalWidth; |
||
322 | } |
||
323 | $totalWidth -= $this->_columnWidths[$j]; |
||
324 | } |
||
325 | } |
||
326 | 6 | } |
|
327 | |||
328 | /** |
||
329 | * Calculate the height of a row |
||
330 | * |
||
331 | * @param array $row |
||
332 | * @return int maximum row per cell |
||
333 | * @see \yii\console\widgets\Table::render() |
||
334 | */ |
||
335 | protected function calculateRowHeight($row) |
||
336 | { |
||
337 | 6 | $rowsPerCell = array_map(function ($size, $columnWidth) { |
|
338 | 6 | if (is_array($columnWidth)) { |
|
339 | 2 | $rows = 0; |
|
340 | 2 | foreach ($columnWidth as $width) { |
|
341 | 2 | $rows += ceil($width / ($size - 2)); |
|
342 | } |
||
343 | 2 | return $rows; |
|
344 | } |
||
345 | 6 | return ceil($columnWidth / ($size - 2)); |
|
346 | }, $this->_columnWidths, array_map(function ($val) { |
||
347 | 6 | if (is_array($val)) { |
|
348 | 2 | $encodings = array_fill(0, count($val), Yii::$app->charset); |
|
349 | 2 | return array_map('mb_strwidth', $val, $encodings); |
|
350 | } |
||
351 | 6 | return mb_strwidth($val, Yii::$app->charset); |
|
352 | 6 | }, $row) |
|
353 | ); |
||
354 | |||
355 | 6 | return max($rowsPerCell); |
|
356 | } |
||
357 | |||
358 | /** |
||
359 | * Getting screen width |
||
360 | * |
||
361 | * @return int screen width |
||
362 | */ |
||
363 | 6 | protected function getScreenWidth() |
|
373 | } |
||
374 |
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.
Let’s take a look at an example:
As you can see in this example, the array
$myArray
is initialized the first time when the foreach loop is entered. You can also see that the value of thebar
key is only written conditionally; thus, its value might result from a previous iteration.This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.