Passed
Push — main ( 4059b3...f7ff17 )
by ANDREY
02:27
created

Table1D   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Test Coverage

Coverage 98.88%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 103
dl 0
loc 158
ccs 88
cts 89
cp 0.9888
rs 10
c 1
b 0
f 0
wmc 22

7 Methods

Rating   Name   Duplication   Size   Complexity  
A addCells() 0 22 6
A getHeader() 0 3 1
A getAutoColumnsNum() 0 26 2
B setData() 0 43 8
A setHeader() 0 11 3
A __construct() 0 15 1
A output() 0 5 1
1
<?php
2
3
namespace VPA\Console\Components;
4
5
use VPA\Console\FrameConfigInterface;
6
use VPA\Console\Glyphs\Glyph;
7
use VPA\Console\Glyphs\GlyphBlock;
8
use VPA\Console\Glyphs\Row;
9
use VPA\Console\SymbolMode;
10
use VPA\Console\TableDisplayMode;
11
12
class Table1D extends GlyphBlock
13
{
14
    private string $firstColumnTitle;
15
    private string $secondColumnTitle;
16
    private bool $haveHeader = false;
17
    private int|string $firstWidth;
18
    private int|string $secondWidth;
19
    private int|string $firstMaxWidth;
20
    private int|string $secondMaxWidth;
21
    private array $data = [];
22
    private int $columns = 1;
23
    private const PADDING_X = 1;
24 8
25
    public function __construct(protected FrameConfigInterface $globalConfig)
26 8
    {
27 8
        parent::__construct($globalConfig);
28 8
        $this->config = array_merge(
29
            parent::getConfig(),
30 8
            [
31
                'type' => TableDisplayMode::Slim,
32
                'columns' => '1',
33
                'firstColumnWidth' => 'auto',
34
                'firstColumnMaxWidth' => 'auto',
35
                'secondColumnWidth' => 'auto',
36
                'secondColumnMaxWidth' => 'auto',
37
            ]
38 8
        );
39
        $this->documentWidth = $this->gc('shell')->getDocumentWidthFromOS();
40
    }
41
42
    /**
43
     * Add header info to Table1D.
44
     * Can get names of columns as array setHeader([titleFirst, titleSecond])
45
     * or as 2 string params:setHeader(titleFirst, titleSecond)
46
     * @param string|array $firstTitle
47
     * @param string|null $secondTitle
48
     * @return Glyph
49 2
     */
50
    public function setHeader(string|array $firstTitle, ?string $secondTitle = ''): Glyph
51 2
    {
52 2
        $this->haveHeader = true;
53 1
        if (is_array($firstTitle) && count($firstTitle) == 2) {
54 1
            $this->firstColumnTitle = reset($firstTitle);
55 1
            $this->secondColumnTitle = end($firstTitle);
56
            return $this;
57 2
        }
58 2
        $this->firstColumnTitle = $firstTitle ?? '';
59 2
        $this->secondColumnTitle = $secondTitle ?? '';
60
        return $this;
61
    }
62 1
63
    public function getHeader(): array
64 1
    {
65
        return [$this->firstColumnTitle, $this->secondColumnTitle];
66
    }
67 7
68
    private function getAutoColumnsNum(): int
69 7
    {
70 7
        $columns = intval($this->__get('columns'));
71 7
        $this->firstWidth = $this->__get('firstColumnWidth');
72 7
        $this->firstMaxWidth = $this->__get('firstColumnMaxWidth');
73 7
        $this->secondWidth = $this->__get('secondColumnWidth');
74 7
        $this->secondMaxWidth = $this->__get('secondColumnMaxWidth');
75 7
        $type = $this->__get('type');
76
        $deltaWidth = self::PADDING_X * 4;
77 7
        $deltaWidth += match ($type) {
78 1
            TableDisplayMode::Slim, TableDisplayMode::Frame => 3,
79
            default => 0,
80 7
        };
81 1
        if ($columns == 0) {
82 1
            $valueWidth = max(array_map(function ($it) {
83 1
                return strlen($it);
84 1
            }, $this->data));
85 1
            $keyWidth = max(array_map(function ($it) {
86 1
                return strlen($it);
87 1
            }, array_keys($this->data)));
88 1
            $keyRealWidth = min([$keyWidth, $this->firstWidth, $this->firstMaxWidth]);
89 1
            $valueRealWidth = min([$valueWidth, $this->secondWidth, $this->secondMaxWidth]);
90 1
            $width = $keyRealWidth + $valueRealWidth + $deltaWidth;
91
            return intval(floor($this->getDocumentWidth() / $width));
92 6
        }
93
        return $columns;
94
    }
95 7
96
    public function setData($data): Glyph
97 7
    {
98 7
        $this->data = $data;
99 7
        $table = $this->addTable();
100 7
        $type = $this->__get('type');
101
        $this->columns = $this->getAutoColumnsNum();
102 7
103
        $borderHead = $borderV = $borderH = 0;
104 7
        switch ($type) {
105 5
            case TableDisplayMode::Slim:
106 5
                $borderV = 1;
107 5
                $borderHead = 1;
108 5
                $table->setBorder(1, 1, 1, 1);
109 2
                break;
110 1
            case TableDisplayMode::Frame:
111 1
                $borderV = 1;
112 1
                $borderH = 1;
113 1
                $borderHead = 1;
114 1
                $table->setBorder(1, 1, 1, 0);
115
                break;
116
        }
117 7
118 1
        if ($this->haveHeader) {
119 1
            $header = $table->addRow(['mode'=>SymbolMode::BOLD]);
120 1
            for ($i = 0; $i < $this->columns; $i++) {
121
                $this->addCells($header, $this->firstColumnTitle, $this->secondColumnTitle, $borderHead, $borderV, $i);
122
            }
123 7
        }
124 7
        $value = current($data);
125
        $key = key($data);
126 7
        do {
127 7
            $row = $table->addRow();
128 7
            for ($i = 0; $i < $this->columns; $i++) {
129 7
                if ($key) {
130 7
                    $this->addCells($row, $key, $value, $borderH, $borderV, $i);
131 7
                    $value = next($data);
132
                    $key = key($data);
133
                } else {
134
                    $this->addCells($row, '', '', $borderH, $borderV, $i);
135
                }
136
            }
137 7
        } while ($value);
138
        return $this;
139
    }
140 1
141
    public function output($data): Glyph
142 1
    {
143 1
        $this->setData($data);
144 1
        $this->display();
145
        return $this;
146
    }
147 7
148
    private function addCells(
149
        Row $row,
150
        string $first,
151
        string $second,
152
        int $borderBottom = 0,
153
        int $borderV = 1,
154
        int $column = 1
155 7
    ): array {
156 7
        $firstCell = $row->addCell()
157 7
            ->setPadding(self::PADDING_X, self::PADDING_X, 0, 0)->setBorder(0, $borderV, 0, $borderBottom);
158 7
        $this->firstWidth !== 'auto' && $firstCell = $firstCell->setWidth(intval($this->firstWidth));
159 7
        $firstText = $firstCell->addText();
160 7
        $this->firstMaxWidth != 'auto' && $firstText = $firstText->setConfig(['maxWidth' => $this->firstMaxWidth]);
161 7
        $firstText->setValue($first);
162 7
        $secondCell = $row->addCell()
163 7
            ->setPadding(self::PADDING_X, self::PADDING_X, 0, 0)
164 7
            ->setBorder(0, $this->columns - 1 == $column ? 0 : $borderV, 0, $borderBottom);
165 7
        $this->secondWidth !== 'auto' && $firstCell = $secondCell->setWidth(intval($this->secondWidth));
166 7
        $secondText = $secondCell->addText();
167 7
        $this->secondMaxWidth != 'auto' && $secondText = $secondText->setConfig(['maxWidth' => $this->secondMaxWidth]);
168 7
        $secondText->setValue($second);
169
        return [&$firstCell, &$secondCell];
170
    }
171
}
172