Passed
Push — main ( f41333...337636 )
by ANDREY
02:27
created

Table1D::getHeader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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