Table   A
last analyzed

↳ Parent: Project

Coupling/Cohesion

Components 1
Dependencies 3

Complexity

Total Complexity 19

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 0
loc 219
ccs 64
cts 64
cp 1
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A result() 0 15 2
A getWidth() 0 7 1
A getBorder() 0 4 1
A buildHeaderRow() 0 12 2
A buildRow() 0 12 2
A buildCell() 0 4 1
A getHeaderRow() 0 18 3
A getColumnWidths() 0 19 4
A getDefaultColumnWidths() 0 6 1
A getCellWidth() 0 4 1
1
<?php
2
3
namespace League\CLImate\TerminalObject\Basic;
4
5
use League\CLImate\TerminalObject\Helper\StringLength;
6
7
class Table extends BasicTerminalObject
8
{
9
    use StringLength;
10
11
    /**
12
     * The data for the table, an array of (arrays|objects)
13
     *
14
     * @var array $data
15
     */
16
    protected $data           = [];
17
18
    /**
19
     * An array of the widths of each column in the table
20
     *
21
     * @var array $column_widths
22
     */
23
    protected $column_widths  = [];
24
25
    /**
26
     * The width of the table
27
     *
28
     * @var integer $table_width
29
     */
30
    protected $table_width    = 0;
31
32
    /**
33
     * The divider between table cells
34
     *
35
     * @var string $column_divider
36
     */
37
    protected $column_divider = ' | ';
38
39
    /**
40
     * The border to divide each row of the table
41
     *
42
     * @var string $border
43
     */
44
    protected $border;
45
46
    /**
47
     * The array of rows that will ultimately be returned
48
     *
49
     * @var array $rows
50
     */
51
    protected $rows           = [];
52
53 28
    public function __construct(array $data)
54
    {
55 28
        $this->data = $data;
56 28
    }
57
58
    /**
59
     * Return the built rows
60
     *
61
     * @return array
62
     */
63 28
    public function result()
64
    {
65 28
        $this->column_widths = $this->getColumnWidths();
66 28
        $this->table_width   = $this->getWidth();
67 28
        $this->border        = $this->getBorder();
68
69 28
        $this->buildHeaderRow();
70
71 28
        foreach ($this->data as $key => $columns) {
72 28
            $this->rows[] = $this->buildRow($columns);
73 28
            $this->rows[] = $this->border;
74 28
        }
75
76 28
        return $this->rows;
77
    }
78
79
    /**
80
     * Determine the width of the table
81
     *
82
     * @return integer
83
     */
84 28
    protected function getWidth()
85
    {
86 28
        $first_row = reset($this->data);
87 28
        $first_row = $this->buildRow($first_row);
88
89 28
        return $this->lengthWithoutTags($first_row);
90
    }
91
92
    /**
93
     * Get the border for each row based on the table width
94
     */
95 28
    protected function getBorder()
96
    {
97 28
        return (new Border())->length($this->table_width)->result();
98
    }
99
100
    /**
101
     * Check for a header row (if it's an array of associative arrays or objects),
102
     * if there is one, tack it onto the front of the rows array
103
     */
104 28
    protected function buildHeaderRow()
105
    {
106 28
        $header_row = $this->getHeaderRow();
107
108 28
        if ($header_row) {
109 24
            $this->rows[] = $this->border;
110 24
            $this->rows[] = $this->buildRow($header_row);
111 24
            $this->rows[] = (new Border())->char('=')->length($this->table_width)->result();
112 24
        } else {
113 4
            $this->rows[] = $this->border;
114
        }
115 28
    }
116
117
    /**
118
     * Get table row
119
     *
120
     * @param  mixed  $columns
121
     *
122
     * @return string
123
     */
124 28
    protected function buildRow($columns)
125
    {
126 28
        $row = [];
127
128 28
        foreach ($columns as $key => $column) {
129 28
            $row[] = $this->buildCell($key, $column);
130 28
        }
131
132 28
        $row = implode($this->column_divider, $row);
133
134 28
        return trim($this->column_divider . $row . $this->column_divider);
135
    }
136
137
    /**
138
     * Build the string for this particular table cell
139
     *
140
     * @param  mixed  $key
141
     * @param  string $column
142
     *
143
     * @return string
144
     */
145 28
    protected function buildCell($key, $column)
146
    {
147 28
        return  $this->pad($column, $this->column_widths[$key]);
148
    }
149
150
    /**
151
     * Get the header row for the table if it's an associative array or object
152
     *
153
     * @return mixed
154
     */
155 28
    protected function getHeaderRow()
156
    {
157 28
        $first_item = reset($this->data);
158
159 28
        if (is_object($first_item)) {
160 4
            $first_item = get_object_vars($first_item);
161 4
        }
162
163 28
        $keys       = array_keys($first_item);
164 28
        $first_key  = reset($keys);
165
166
        // We have an associative array (probably), let's have a header row
167 28
        if (!is_int($first_key)) {
168 24
            return array_combine($keys, $keys);
169
        }
170
171 4
        return false;
172
    }
173
174
    /**
175
     * Determine the width of each column
176
     *
177
     * @return array
178
     */
179 28
    protected function getColumnWidths()
180
    {
181 28
        $first_row = reset($this->data);
182
183 28
        if (is_object($first_row)) {
184 4
            $first_row = get_object_vars($first_row);
185 4
        }
186
187
        // Create an array with the columns as keys and values of zero
188 28
        $column_widths = $this->getDefaultColumnWidths($first_row);
189
190 28
        foreach ($this->data as $columns) {
191 28
            foreach ($columns as $key => $column) {
192 28
                $column_widths[$key] = $this->getCellWidth($column_widths[$key], $column);
193 28
            }
194 28
        }
195
196 28
        return $column_widths;
197
    }
198
199
    /**
200
     * Set up an array of default column widths
201
     *
202
     * @param array $columns
203
     *
204
     * @return array
205
     */
206 28
    protected function getDefaultColumnWidths(array $columns)
207
    {
208 28
        $widths = $this->arrayOfStrLens(array_keys($columns));
209
210 28
        return array_combine(array_keys($columns), $widths);
211
    }
212
213
    /**
214
     * Determine the width of the columns without tags
215
     *
216
     * @param array  $current_width
217
     * @param string $str
218
     *
219
     * @return integer
220
     */
221 28
    protected function getCellWidth($current_width, $str)
222
    {
223 28
        return max($current_width, $this->lengthWithoutTags($str));
224
    }
225
}
226