Test Failed
Pull Request — master (#244)
by Sergei
03:29
created

BaseField::getThemeConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 1
cts 1
cp 1
crap 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 5
24
    final public function containerTag(string $tag): static
25 5
    {
26 1
        if ($tag === '') {
27
            throw new InvalidArgumentException('Tag name cannot be empty.');
28
        }
29 4
30 4
        $new = clone $this;
31 4
        $new->containerTag = $tag;
32
        return $new;
33
    }
34 8
35
    final public function containerAttributes(array $attributes): static
36 8
    {
37 8
        $new = clone $this;
38 8
        $new->containerAttributes = $attributes;
39
        return $new;
40
    }
41 1
42
    final public function addContainerAttributes(array $attributes): static
43 1
    {
44 1
        $new = clone $this;
45 1
        $new->containerAttributes = array_merge($new->containerAttributes, $attributes);
46
        return $new;
47
    }
48
49
    /**
50
     * Set container tag ID.
51
     *
52
     * @param string|null $id Container tag ID.
53 3
     */
54
    final public function containerId(?string $id): static
55 3
    {
56 3
        $new = clone $this;
57 3
        $new->containerAttributes['id'] = $id;
58
        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 9
     */
66
    final public function containerClass(?string ...$class): static
67 9
    {
68 9
        $new = clone $this;
69 9
        $new->containerAttributes['class'] = array_filter($class, static fn ($c) => $c !== null);
70
        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 9
     */
78
    final public function addContainerClass(?string ...$class): static
79 9
    {
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
        return $new;
86
    }
87 181
88
    final public function useContainer(bool $use): static
89 181
    {
90 181
        $new = clone $this;
91 181
        $new->useContainer = $use;
92
        return $new;
93
    }
94 5
95
    final public function begin(): ?string
96 5
    {
97 5
        parent::begin();
98
        $this->isStartedByBegin = true;
99 5
100
        $this->beforeRender();
101 5
102
        $content = $this->generateBeginContent();
103 5
104
        return $this->renderOpenContainerAndContent($content);
105
    }
106 534
107
    final public function render(): string
108 534
    {
109 5
        if ($this->isStartedByBegin) {
110 5
            $this->isStartedByBegin = false;
111
            return $this->renderEnd();
112
        }
113 530
114
        $this->beforeRender();
115 530
116 512
        $content = $this->generateContent();
117 1
        if ($content === null) {
118
            return '';
119
        }
120 511
121
        $result = $this->renderOpenContainerAndContent($content);
122 511
123 330
        if ($this->useContainer) {
124
            $result .= "\n" . Html::closeTag($this->containerTag);
125
        }
126 511
127
        return $result;
128
    }
129 534
130
    protected function beforeRender(): void
131 534
    {
132
    }
133
134
    abstract protected function generateContent(): ?string;
135 2
136
    protected function generateBeginContent(): string
137 2
    {
138
        return '';
139
    }
140 2
141
    protected function generateEndContent(): string
142 2
    {
143
        return '';
144
    }
145 151
146
    protected function prepareContainerAttributes(array &$attributes): void
147 151
    {
148
    }
149 5
150
    final protected static function getThemeConfig(?string $theme): array
151 5
    {
152
        return ThemeContainer::getTheme($theme)?->getFieldConfig(static::class) ?? [];
153 5
    }
154 1
155
    private function renderEnd(): string
156
    {
157 4
        $content = $this->generateEndContent();
158
159 4
        if (!$this->useContainer) {
160
            return $content;
161
        }
162 515
163
        $containerTag = CustomTag::name($this->containerTag);
164 515
165 183
        return ($content !== '' ? $content . "\n" : '') . $containerTag->close();
166
    }
167
168 334
    private function renderOpenContainerAndContent(string $content): string
169
    {
170 334
        if (!$this->useContainer) {
171 334
            return $content;
172 334
        }
173 27
174
        $containerTag = CustomTag::name($this->containerTag);
175
176 334
        $attributes = $this->containerAttributes;
177 334
        $this->prepareContainerAttributes($attributes);
178
        if ($attributes !== []) {
179
            $containerTag = $containerTag->addAttributes($attributes);
180
        }
181
182
        return $containerTag->open()
183
            . ($content === '' ? '' : ("\n" . $content));
184
    }
185
}
186