Completed
Pull Request — master (#1)
by Insolita
01:15
created

ArrayToTextTable::calcColumnsList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace dekor;
4
5
use function array_keys;
6
7
/**
8
 * @author Denis Koronets
9
 */
10
class ArrayToTextTable
11
{
12
    /**
13
     * @var array
14
     */
15
    private $data;
16
    
17
    /**
18
     * @var array
19
     */
20
    private $columnsList = [];
21
    
22
    /**
23
     * @var int
24
     */
25
    private $maxLineLength = 40;
26
    
27
    /**
28
     * @var array
29
     */
30
    private $columnsLength = [];
31
    
32
    /**
33
     * @var array
34
     */
35
    private $result = [];
36
    
37
    /**
38
     * @var string
39
     */
40
    private $charset = 'UTF-8';
41
    
42
    /**
43
     * @var bool
44
     */
45
    private $renderHeader = true;
46
    
47
    public function __construct(array $data)
48
    {
49
        $this->data = $data;
50
    }
51
    
52
    /**
53
     * Set custom charset for columns values
54
     *
55
     * @param $charset
56
     *
57
     * @return \dekor\ArrayToTextTable
58
     * @throws \Exception
59
     */
60
    public function charset($charset)
61
    {
62
        if (!in_array($charset, mb_list_encodings())) {
63
            throw new \Exception(
64
                'This charset `' . $charset . '` is not supported by mbstring.' .
65
                'Please check it: http://php.net/manual/ru/function.mb-list-encodings.php'
66
            );
67
        }
68
        
69
        $this->charset = $charset;
70
        
71
        return $this;
72
    }
73
    
74
    /**
75
     * Set mode to print no header in the table
76
     *
77
     * @return self
78
     */
79
    public function noHeader()
80
    {
81
        $this->renderHeader = false;
82
        
83
        return $this;
84
    }
85
    
86
    /**
87
     * @param int $length
88
     *
89
     * @return self
90
     * @throws \Exception
91
     */
92
    public function maxLineLength($length)
93
    {
94
        if ($length < 3) {
95
            throw new \Exception('Minimum length for cropper is 3 sumbols');
96
        }
97
        
98
        $this->maxLineLength = $length;
99
        
100
        return $this;
101
    }
102
    
103
    /**
104
     * Build your ascii table and return the result
105
     *
106
     * @return string
107
     */
108
    public function render()
109
    {
110
        if (empty($this->data)) {
111
            return 'Empty';
112
        }
113
        
114
        $this->calcColumnsList();
115
        $this->calcColumnsLength();
116
        
117
        /** render section **/
118
        $this->renderHeader();
119
        $this->renderBody();
120
        $this->lineSeparator();
121
        /** end render section **/
122
        
123
        return str_replace(
124
            ['++', '||'],
125
            ['+', '|'],
126
            implode(PHP_EOL, $this->result)
127
        );
128
    }
129
    
130
    /**
131
     * Calculates list of columns in data
132
     */
133
    protected function calcColumnsList()
134
    {
135
        
136
        $this->columnsList = array_keys(reset($this->data));
137
    }
138
    
139
    /**
140
     * Calculates length for string
141
     *
142
     * @param $str
143
     *
144
     * @return int
145
     */
146
    protected function length($str)
147
    {
148
        return mb_strlen($str, $this->charset);
149
    }
150
    
151
    /**
152
     * Calculate maximum string length for each column
153
     */
154
    private function calcColumnsLength()
155
    {
156
        foreach ($this->data as $row) {
157
            if ($row === '---') {
158
                continue;
159
            }
160
            foreach ($this->columnsList as $column) {
161
                $this->columnsLength[$column] = max(
162
                    isset($this->columnsLength[$column])
163
                        ? $this->columnsLength[$column]
164
                        : 0,
165
                    $this->length($row[$column]),
166
                    $this->length($column)
167
                );
168
            }
169
        }
170
    }
171
    
172
    /**
173
     * Append a line separator to result
174
     */
175
    private function lineSeparator()
176
    {
177
        $tmp = '';
178
        
179
        foreach ($this->columnsList as $column) {
180
            $tmp .= '+' . str_repeat('-', $this->columnsLength[$column] + 2) . '+';
181
        }
182
        
183
        $this->result[] = $tmp;
184
    }
185
    
186
    /**
187
     * @param $columnKey
188
     * @param $value
189
     *
190
     * @return string
191
     */
192
    private function column($columnKey, $value)
193
    {
194
        return '| ' . $value . ' ' . str_repeat(' ', $this->columnsLength[$columnKey] - $this->length($value)) . '|';
195
    }
196
    
197
    /**
198
     * Render header part
199
     *
200
     * @return void
201
     */
202
    private function renderHeader()
203
    {
204
        $this->lineSeparator();
205
        
206
        if (!$this->renderHeader) {
207
            return;
208
        }
209
        
210
        $tmp = '';
211
        
212
        foreach ($this->columnsList as $column) {
213
            $tmp .= $this->column($column, $column);
214
        }
215
        
216
        $this->result[] = $tmp;
217
        
218
        $this->lineSeparator();
219
    }
220
    
221
    /**
222
     * Render body section of table
223
     *
224
     * @return void
225
     */
226
    private function renderBody()
227
    {
228
        foreach ($this->data as $row) {
229
            if ($row === '---') {
230
                $this->lineSeparator();
231
                continue;
232
            }
233
            
234
            $tmp = '';
235
            
236
            foreach ($this->columnsList as $column) {
237
                $tmp .= $this->column($column, $row[$column]);
238
            }
239
            
240
            $this->result[] = $tmp;
241
        }
242
    }
243
}
0 ignored issues
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
244