Passed
Pull Request — master (#244)
by Sergei
02:56
created

BaseField   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 63
dl 0
loc 171
ccs 77
cts 77
cp 1
rs 10
c 1
b 0
f 0
wmc 25

16 Methods

Rating   Name   Duplication   Size   Complexity  
A prepareContainerAttributes() 0 2 1
A beforeRender() 0 2 1
A containerAttributes() 0 5 1
A renderEnd() 0 11 3
A containerClass() 0 5 1
A addContainerClass() 0 8 1
A containerId() 0 5 1
A useContainer() 0 5 1
A render() 0 21 4
A containerTag() 0 9 2
A getThemeConfig() 0 3 1
A addContainerAttributes() 0 5 1
A generateBeginContent() 0 3 1
A generateEndContent() 0 3 1
A renderOpenContainerAndContent() 0 16 4
A begin() 0 10 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field\Base;
6
7
use InvalidArgumentException;
8
use Yiisoft\Form\ThemeContainer;
9
use Yiisoft\Html\Html;
10
use Yiisoft\Html\Tag\CustomTag;
11
use Yiisoft\Widget\Widget;
12
13
abstract class BaseField extends Widget
14
{
15
    /**
16
     * @psalm-var non-empty-string
17
     */
18
    protected string $containerTag = 'div';
19
    protected array $containerAttributes = [];
20
    protected bool $useContainer = true;
21
22
    private bool $isStartedByBegin = false;
23
24 5
    final public function containerTag(string $tag): static
25
    {
26 5
        if ($tag === '') {
27 1
            throw new InvalidArgumentException('Tag name cannot be empty.');
28
        }
29
30 4
        $new = clone $this;
31 4
        $new->containerTag = $tag;
32 4
        return $new;
33
    }
34
35 8
    final public function containerAttributes(array $attributes): static
36
    {
37 8
        $new = clone $this;
38 8
        $new->containerAttributes = $attributes;
39 8
        return $new;
40
    }
41
42 1
    final public function addContainerAttributes(array $attributes): static
43
    {
44 1
        $new = clone $this;
45 1
        $new->containerAttributes = array_merge($new->containerAttributes, $attributes);
46 1
        return $new;
47
    }
48
49
    /**
50
     * Set container tag ID.
51
     *
52
     * @param string|null $id Container tag ID.
53
     */
54 3
    final public function containerId(?string $id): static
55
    {
56 3
        $new = clone $this;
57 3
        $new->containerAttributes['id'] = $id;
58 3
        return $new;
59
    }
60
61
    /**
62
     * Replace container tag CSS classes with a new set of classes.
63
     *
64
     * @param string|null ...$class One or many CSS classes.
65
     */
66 10
    final public function containerClass(?string ...$class): static
67
    {
68 10
        $new = clone $this;
69 10
        $new->containerAttributes['class'] = array_filter($class, static fn ($c) => $c !== null);
70 10
        return $new;
71
    }
72
73
    /**
74
     * Add one or more CSS classes to the container tag.
75
     *
76
     * @param string|null ...$class One or many CSS classes.
77
     */
78 9
    final public function addContainerClass(?string ...$class): static
79
    {
80 9
        $new = clone $this;
81 9
        Html::addCssClass(
82 9
            $new->containerAttributes,
83 9
            array_filter($class, static fn ($c) => $c !== null),
84 9
        );
85 9
        return $new;
86
    }
87
88 181
    final public function useContainer(bool $use): static
89
    {
90 181
        $new = clone $this;
91 181
        $new->useContainer = $use;
92 181
        return $new;
93
    }
94
95 5
    final public function begin(): ?string
96
    {
97 5
        parent::begin();
98 5
        $this->isStartedByBegin = true;
99
100 5
        $this->beforeRender();
101
102 5
        $content = $this->generateBeginContent();
103
104 5
        return $this->renderOpenContainerAndContent($content);
105
    }
106
107 536
    final public function render(): string
108
    {
109 536
        if ($this->isStartedByBegin) {
110 5
            $this->isStartedByBegin = false;
111 5
            return $this->renderEnd();
112
        }
113
114 532
        $this->beforeRender();
115
116 532
        $content = $this->generateContent();
117 514
        if ($content === null) {
118 1
            return '';
119
        }
120
121 513
        $result = $this->renderOpenContainerAndContent($content);
122
123 513
        if ($this->useContainer) {
124 332
            $result .= "\n" . Html::closeTag($this->containerTag);
125
        }
126
127 513
        return $result;
128
    }
129
130 536
    protected function beforeRender(): void
131
    {
132 536
    }
133
134
    abstract protected function generateContent(): ?string;
135
136 2
    protected function generateBeginContent(): string
137
    {
138 2
        return '';
139
    }
140
141 2
    protected function generateEndContent(): string
142
    {
143 2
        return '';
144
    }
145
146 151
    protected function prepareContainerAttributes(array &$attributes): void
147
    {
148 151
    }
149
150 564
    final protected static function getThemeConfig(?string $theme): array
151
    {
152 564
        return ThemeContainer::getTheme($theme)?->getFieldConfig(static::class) ?? [];
153
    }
154
155 5
    private function renderEnd(): string
156
    {
157 5
        $content = $this->generateEndContent();
158
159 5
        if (!$this->useContainer) {
160 1
            return $content;
161
        }
162
163 4
        $containerTag = CustomTag::name($this->containerTag);
164
165 4
        return ($content !== '' ? $content . "\n" : '') . $containerTag->close();
166
    }
167
168 517
    private function renderOpenContainerAndContent(string $content): string
169
    {
170 517
        if (!$this->useContainer) {
171 183
            return $content;
172
        }
173
174 336
        $containerTag = CustomTag::name($this->containerTag);
175
176 336
        $attributes = $this->containerAttributes;
177 336
        $this->prepareContainerAttributes($attributes);
178 336
        if ($attributes !== []) {
179 28
            $containerTag = $containerTag->addAttributes($attributes);
180
        }
181
182 336
        return $containerTag->open()
183 336
            . ($content === '' ? '' : ("\n" . $content));
184
    }
185
}
186