Passed
Branch test (96f424)
by Roman
03:22
created

AbstractFormatter::addHeader()   B

Complexity

Conditions 6
Paths 24

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 14
cts 14
cp 1
rs 8.5125
c 0
b 0
f 0
cc 6
eloc 18
nc 24
nop 0
crap 6
1
<?php
2
3
namespace ToolkitLab\ASCII;
4
5
use ToolkitLab\ASCII\Table;
6
7
abstract class AbstractFormatter implements FormatterInterface {
8
    
9
    const
10
        DEFAULT_MODE              = 0x0,
11
12
        HEADER_FIRST_ROW_MODE     = 0X1,
13
        HEADER_NUMERIC_MODE       = 0x2,
14
        HEADER_ABC_MODE           = 0X4,
15
            
16
        SIDEBAR_FIRST_COLUMN_MODE = 0X8,
17
        SIDEBAR_NUMERIC_MODE      = 0X10,
18
        SIDEBAR_ABC_MODE          = 0x20,
19
            
20
        SPREADSHEET_MODE          = 0X14;
21
22
    /**
23
     * @var Table
24
     */
25
    protected $table;
26
27
    /**
28
     * @var array
29
     */
30
    protected $metadata = [];
31
32
    /**
33
     * @var string
34
     */
35
    protected $output = '';
36
37
    /**
38
     * The data to be formatted
39
     * @var array
40
     */
41
    protected $data = [];
42
43
    /**
44 22
     * Formatting parameters
45 22
     * @var array
46 20
     */
47
    protected $params = [
48
        'mode' => self::DEFAULT_MODE,
49
        'rotate' => false,
50
        'max_cell_length' => 100,
51
        'max_cell_ending' => '...',
52
    ];
53
54 20
    /**
55 20
     * Constructor
56 20
     * @param array $params
57 20
     */
58 20
    public function __construct($params = []) {
59 20
        $this->setParams($params);
60 20
    }
61
62
    /**
63
     * Converts an array into ASCII-formatted string (table)
64
     * @param Table $table
65
     * @param array $params
66
     * @return string
67
     */
68
    public function format($table, $params = []) {
69 20
        if (is_array($table)) {
0 ignored issues
show
introduced by
The condition is_array($table) can never be true.
Loading history...
70 20
            $table = new Table($table);
71 20
        }
72 20
        $this->init($table, $params);
73 20
        $this->addTopBorder();
74 20
        $this->addHeader();
75 20
        $this->addRows();
76 20
        $this->addBottomBorder();
77 20
        return $this->output;
78
    }
79
80
    /**
81
     * Initializes the data/parameters before formatting
82
     * @param Table $table
83
     * @param array $params
84 22
     * @return void
85 22
     */
86 22
    protected function init(Table $table, $params = []) {
87 2
        $this->output = '';
88
        $this->setParams($params);
89 20
        $this->table = $table;
90 20
        if ($this->getParam('rotate') !== false) {
91
            $this->table->rotate($this->getParam('rotate'));
92
        }
93
        $maxLength = $this->getParam('max_cell_length');
94
        $ending = $this->getParam('max_cell_ending');
95
        $this->table->truncate($maxLength, $ending);
96
    }
97 20
    
98 20
    /**
99
     * Updates the parameters with new values
100
     * @param array $params
101
     * @throws \InvalidArgumentException
102
     */
103
    protected function setParams($params) {
104
        $unknownParams = array_diff(array_keys($params), array_keys($this->params));
105 20
        if (count($unknownParams)) {
106 20
            throw new \InvalidArgumentException('Unknown parameter(-s): ' . implode(', ', $unknownParams));
107 16
        }
108 16
        $this->params = array_merge($this->params, $params);
109 8
    }
110 8
111 20
    /**
112
     * Get the specified parameter
113
     * @param string $key
114
     * @return mixed
115
     */
116
    protected function getParam($key) {
117 20
        return $this->params[$key];
118 20
    }
119 10
120 10
    /**
121 5
     * Adds the top border to the output
122 20
     * @return void
123
     */
124
    protected function addTopBorder() {
125
        if ($this->metadata['top_border']) {
126
            $this->addRow(
127 20
                $this->metadata['top_border']['left'],
128 20
                $this->metadata['top_border']['middle'],
129 20
                $this->metadata['top_border']['right'],
130
                $this->metadata['top_border']['pad']
131
            );
132
        }
133
    }
134
135
    /**
136 20
     * Adds the header row to the output
137 20
     * @return void
138 20
     */
139 20
    protected function addHeader() {
140 20
        $headerCount = 0;
141 20
        $mode = $this->getParam('mode');
142 10
        $data = $this->table->getData();
143 10
        $dimensionX = $this->table->getDimensionX();
144 20
        $dimensionY = $this->table->getDimensionY();
145
        if (($mode & self::HEADER_FIRST_ROW_MODE) === self::HEADER_FIRST_ROW_MODE) {
146
            $headerCount++;
147
        }
148
        if (($mode & self::HEADER_ABC_MODE) === self::HEADER_ABC_MODE) {
149
            // $data = array_merge($this->getAbcRange($dimensionX), $data);
150 10
            $headerCount++;
151 10
        }
152 10
        if (($mode & self::HEADER_NUMERIC_MODE) === self::HEADER_NUMERIC_MODE) {
153 10
            $data = array_merge([range(1, $dimensionX)], $data);
154 10
            $headerCount++;
155 10
        }
156 5
        if ($headerCount > 1) {
157 10
            throw new \LogicException('There should be only one header.');
158
        }
159
        if ($headerCount) {
160
            $this->addDataRow(array_shift($data));
161
            $this->addHeaderBorder();
162
            $this->table->setData($data, $dimensionX, $dimensionY);
163 20
        }
164 20
    }
165 16
166 16
    /**
167 16
     * Adds the rows to the output
168 16
     */
169 16
    protected function addRows() {
170 8
        $data = $this->table->getData();
171 8
        array_walk($data, [$this, 'addDataRow']);
172 20
    }
173
174
    /**
175
     * Adds the row with the specified data to the output
176
     * @param array $row
177
     * @return void
178
     */
179
    protected function addDataRow($row) {
180
        $this->addRow(
181
            $this->metadata['content']['left'],
182
            $this->metadata['content']['middle'],
183 20
            $this->metadata['content']['right'],
184 20
            $this->metadata['content']['pad'],
185 20
            $row
186 20
        );
187 20
    }
188 20
189 20
    /**
190 20
     * Adds the bottom border of the header to the output
191 10
     * @return void
192 18
     */
193
    protected function addHeaderBorder() {
194 20
        $this->addRow(
195 10
            $this->metadata['header']['left'],
196 20
            $this->metadata['header']['middle'],
197 20
            $this->metadata['header']['right'],
198
            $this->metadata['header']['pad']
199
        );
200
    }
201
202
    /**
203
     * Adds the bottom border to the output
204
     * @return void
205
     */
206
    protected function addBottomBorder() {
207
        if ($this->metadata['bottom_border']) {
208
            $this->addRow(
209
                $this->metadata['bottom_border']['left'],
210
                $this->metadata['bottom_border']['middle'],
211
                $this->metadata['bottom_border']['right'],
212
                $this->metadata['bottom_border']['pad']
213
            );
214
        }
215
    }
216
217
    /**
218
     * Adds the row to the output
219
     * @param string $lb
220
     * @param string $bm
221
     * @param string $br
222
     * @param string $pad
223
     * @param array $row
224
     * @return void
225
     */
226
    protected function addRow($lb, $bm, $br, $pad, $row = []) {
227
        $delimiter = $lb;
228
        for ($i = 0; $i < $this->table->getDimensionX(); $i++) {
229
            $maxLength = $this->table->getColumnsMaxLength($i);
230
            $this->output .= $delimiter;
231
            if (count($row)) {
232
                $spaces = str_repeat($pad, $maxLength - strlen($row[$i]));
233
                $this->output .= " {$row[$i]}{$spaces} ";
234
            } else {
235
                $this->output .= str_repeat($pad, $maxLength + 2);
236
            }
237
            $delimiter = $bm;
238
        }
239
        $this->output .= $br . PHP_EOL;
240
    }
241
242
}
243