Table   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 46
c 1
b 0
f 1
dl 0
loc 86
rs 10
wmc 13

3 Methods

Rating   Name   Duplication   Size   Complexity  
A render() 0 36 5
A normalize() 0 26 5
A normalizeStyles() 0 16 3
1
<?php
2
3
/*
4
 * This file is part of the PHP-CLI package.
5
 *
6
 * (c) Jitendra Adhikari <[email protected]>
7
 *     <https://github.com/adhocore>
8
 *
9
 * Licensed under MIT license.
10
 */
11
12
namespace Ahc\Cli\Output;
13
14
use Ahc\Cli\Exception\InvalidArgumentException;
15
use Ahc\Cli\Helper\InflectsString;
16
17
class Table
18
{
19
    use InflectsString;
20
21
    public function render(array $rows, array $styles = []): string
22
    {
23
        if ([] === $table = $this->normalize($rows)) {
24
            return '';
25
        }
26
27
        list($head, $rows) = $table;
28
29
        $styles = $this->normalizeStyles($styles);
30
        $title  = $body = $dash = [];
31
32
        list($start, $end) = $styles['head'];
33
        foreach ($head as $col => $size) {
34
            $dash[]  = \str_repeat('-', $size + 2);
35
            $title[] = \str_pad($this->toWords($col), $size, ' ');
36
        }
37
38
        $title = "|$start " . \implode(" $end|$start ", $title) . " $end|" . \PHP_EOL;
39
40
        $odd = true;
41
        foreach ($rows as $row) {
42
            $parts = [];
43
44
            list($start, $end) = $styles[['even', 'odd'][(int) $odd]];
45
            foreach ($head as $col => $size) {
46
                $parts[] = \str_pad($row[$col] ?? '', $size, ' ');
47
            }
48
49
            $odd    = !$odd;
0 ignored issues
show
introduced by
The condition $odd is always true.
Loading history...
50
            $body[] = "|$start " . \implode(" $end|$start ", $parts) . " $end|";
51
        }
52
53
        $dash  = '+' . \implode('+', $dash) . '+' . \PHP_EOL;
54
        $body  = \implode(\PHP_EOL, $body) . \PHP_EOL;
55
56
        return "$dash$title$dash$body$dash";
57
    }
58
59
    protected function normalize(array $rows): array
60
    {
61
        $head = \reset($rows);
62
        if (empty($head)) {
63
            return [];
64
        }
65
66
        if (!\is_array($head)) {
67
            throw new InvalidArgumentException(
68
                \sprintf('Rows must be array of assoc arrays, %s given', \gettype($head))
69
            );
70
        }
71
72
        $head = \array_fill_keys(\array_keys($head), null);
73
        foreach ($rows as $i => &$row) {
74
            $row = \array_merge($head, $row);
75
        }
76
77
        foreach ($head as $col => &$value) {
78
            $cols   = \array_column($rows, $col);
79
            $span   = \array_map('strlen', $cols);
80
            $span[] = \strlen($col);
81
            $value  = \max($span);
82
        }
83
84
        return [$head, $rows];
85
    }
86
87
    protected function normalizeStyles(array $styles)
88
    {
89
        $default = [
90
            // styleFor => ['styleStartFn', 'end']
91
            'head' => ['', ''],
92
            'odd'  => ['', ''],
93
            'even' => ['', ''],
94
        ];
95
96
        foreach ($styles as $for => $style) {
97
            if (isset($default[$for])) {
98
                $default[$for] = ['<' . \trim($style, '<> ') . '>', '</end>'];
99
            }
100
        }
101
102
        return $default;
103
    }
104
}
105