Columns::getRow()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.8666
c 0
b 0
f 0
cc 4
nc 3
nop 2
crap 4
1
<?php
2
3
namespace League\CLImate\TerminalObject\Basic;
4
5
use League\CLImate\TerminalObject\Helper\StringLength;
6
7
class Columns extends BasicTerminalObject
8
{
9
    use StringLength;
10
11
    /**
12
     * Number of columns
13
     *
14
     * @var integer $column_count
15
     */
16
    protected $column_count;
17
18
    /**
19
     * Data to columnize
20
     *
21
     * @var array $data
22
     */
23
    protected $data;
24
25 32
    public function __construct($data, $column_count = null)
26
    {
27 32
        $this->data  = $data;
28 32
        $this->column_count = $column_count;
29 32
    }
30
31
    /**
32
     * Calculate the number of columns organize data
33
     *
34
     * @return array
35
     */
36 32
    public function result()
37
    {
38 32
        $keys      = array_keys($this->data);
39 32
        $first_key = reset($keys);
40
41 32
        return (!is_int($first_key)) ? $this->associativeColumns() : $this->columns();
42
    }
43
44
    /**
45
     * Get columns for a regular array
46
     *
47
     * @return array
48
     */
49 28
    protected function columns()
50
    {
51 28
        $this->data    = $this->setData();
52 28
        $column_widths = $this->getColumnWidths();
53 28
        $output        = [];
54 28
        $count         = count(reset($this->data));
55
56 28
        for ($i = 0; $i < $count; $i++) {
57 28
            $output[] = $this->getRow($i, $column_widths);
58 28
        }
59
60 28
        return $output;
61
    }
62
63
    /**
64
     * Re-configure the data into it's final form
65
     */
66 28
    protected function setData()
67
    {
68
        // If it's already an array of arrays, we're good to go
69 28
        if (is_array(reset($this->data))) {
70 8
            return $this->setArrayOfArraysData();
71
        }
72
73 20
        $column_width = $this->getColumnWidth($this->data);
74 20
        $row_count    = $this->getMaxRows($column_width);
75
76 20
        return array_chunk($this->data, $row_count);
77
    }
78
79
    /**
80
     * Re-configure an array of arrays into column arrays
81
     */
82 8
    protected function setArrayOfArraysData()
83
    {
84 8
        $this->setColumnCountViaArray($this->data);
85
86 8
        $new_data = array_fill(0, $this->column_count, []);
87
88 8
        foreach ($this->data as $items) {
89 8
            for ($i = 0; $i < $this->column_count; $i++) {
90 8
                $new_data[$i][] = (array_key_exists($i, $items)) ? $items[$i] : null;
91 8
            }
92 8
        }
93
94 8
        return $new_data;
95
    }
96
97
    /**
98
     * Get columns for an associative array
99
     *
100
     * @return array
101
     */
102 4
    protected function associativeColumns()
103
    {
104 4
        $column_width = $this->getColumnWidth(array_keys($this->data));
105 4
        $output       = [];
106
107 4
        foreach ($this->data as $key => $value) {
108 4
            $output[] = $this->pad($key, $column_width) . $value;
109 4
        }
110
111 4
        return $output;
112
    }
113
114
    /**
115
     * Get the row of data
116
     *
117
     * @param integer $key
118
     * @param array $column_widths
119
     *
120
     * @return string
121
     */
122 28
    protected function getRow($key, $column_widths)
123
    {
124 28
        $row = [];
125
126 28
        for ($j = 0; $j < $this->column_count; $j++) {
127 28
            if (isset($this->data[$j]) && array_key_exists($key, $this->data[$j])) {
128 28
                $row[] = $this->pad($this->data[$j][$key], $column_widths[$j]);
129 28
            }
130 28
        }
131
132 28
        return trim(implode('', $row));
133
    }
134
135
    /**
136
     * Get the standard column width
137
     *
138
     * @param array $data
139
     *
140
     * @return integer
141
     */
142 32
    protected function getColumnWidth($data)
143
    {
144
        // Return the maximum width plus a buffer
145 32
        return $this->maxStrLen($data) + 5;
146
    }
147
148
    /**
149
     * Get an array of each column's width
150
     *
151
     * @return array
152
     */
153 28
    protected function getColumnWidths()
154
    {
155 28
        $column_widths = [];
156
157 28
        for ($i = 0; $i < $this->column_count; $i++) {
158 28
            if (!isset($this->data[$i])) {
159 4
                $column_widths[] = 0;
160 4
                continue;
161
            }
162 28
            $column_widths[] = $this->getColumnWidth($this->data[$i]);
163 28
        }
164
165 28
        return $column_widths;
166
    }
167
168
    /**
169
     * Set the count property
170
     *
171
     * @param integer $column_width
172
     */
173 8
    protected function setColumnCount($column_width)
174
    {
175 8
        $this->column_count = (int) floor($this->util->width() / $column_width);
176 8
    }
177
178
    /**
179
     * Set the count property via an array
180
     *
181
     * @param array $items
182
     */
183
    protected function setColumnCountViaArray($items)
184
    {
185 8
        $counts = array_map(function ($arr) {
186 8
            return count($arr);
187 8
        }, $items);
188
189 8
        $this->column_count = max($counts);
190 8
    }
191
192
    /**
193
     * Get the number of rows per column
194
     *
195
     * @param integer $column_width
196
     *
197
     * @return integer
198
     */
199 20
    protected function getMaxRows($column_width)
200
    {
201 20
        if (!$this->column_count) {
202 8
            $this->setColumnCount($column_width);
203 8
        }
204
205 20
        return ceil(count($this->data) / $this->column_count);
206
    }
207
}
208