Passed
Pull Request — master (#192)
by Sergei
02:44
created

AbstractField::renderEnd()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 0
dl 0
loc 14
ccs 6
cts 7
cp 0.8571
crap 3.0261
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field\Base;
6
7
use InvalidArgumentException;
8
use Yiisoft\Html\Tag\CustomTag;
9
use Yiisoft\Widget\Widget;
10
11
abstract class AbstractField extends Widget
12
{
13
    /**
14
     * @psalm-var non-empty-string
15
     */
16
    protected string $containerTag = 'div';
17
    protected array $containerTagAttributes = [];
18
    protected bool $useContainer = true;
19
20
    protected string $templateBegin = "{label}\n{input}";
21
    protected string $templateEnd = "{input}\n{hint}\n{error}";
22
    protected string $template = "{label}\n{input}\n{hint}\n{error}";
23
    protected ?bool $hideLabel = null;
24
25
    protected array $labelConfig = [];
26
    protected array $hintConfig = [];
27
    protected array $errorConfig = [];
28
29
    private bool $isStartedByBegin = false;
30
31 4
    final public function containerTag(string $tag): static
32
    {
33 4
        if ($tag === '') {
34 1
            throw new InvalidArgumentException('Tag name cannot be empty.');
35
        }
36
37 3
        $new = clone $this;
38 3
        $new->containerTag = $tag;
39 3
        return $new;
40
    }
41
42 3
    final public function containerTagAttributes(array $attributes): static
43
    {
44 3
        $new = clone $this;
45 3
        $new->containerTagAttributes = $attributes;
46 3
        return $new;
47
    }
48
49 10
    final public function useContainer(bool $use): static
50
    {
51 10
        $new = clone $this;
52 10
        $new->useContainer = $use;
53 10
        return $new;
54
    }
55
56
    /**
57
     * Set layout template for render a field.
58
     */
59 2
    final public function template(string $template): static
60
    {
61 2
        $new = clone $this;
62 2
        $new->template = $template;
63 2
        return $new;
64
    }
65
66 2
    final public function hideLabel(?bool $hide = true): static
67
    {
68 2
        $new = clone $this;
69 2
        $new->hideLabel = $hide;
70 2
        return $new;
71
    }
72
73 3
    final public function labelConfig(array $config): static
74
    {
75 3
        $new = clone $this;
76 3
        $new->labelConfig = $config;
77 3
        return $new;
78
    }
79
80 2
    final public function label(?string $content): static
81
    {
82 2
        $new = clone $this;
83 2
        $new->labelConfig['content()'] = [$content];
84 2
        return $new;
85
    }
86
87 2
    final public function hintConfig(array $config): static
88
    {
89 2
        $new = clone $this;
90 2
        $new->hintConfig = $config;
91 2
        return $new;
92
    }
93
94 2
    final public function hint(?string $content): static
95
    {
96 2
        $new = clone $this;
97 2
        $new->hintConfig['content()'] = [$content];
98 2
        return $new;
99
    }
100
101 2
    final public function errorConfig(array $config): static
102
    {
103 2
        $new = clone $this;
104 2
        $new->errorConfig = $config;
105 2
        return $new;
106
    }
107
108 1
    final public function error(?string $message): static
109
    {
110 1
        $new = clone $this;
111 1
        $new->errorConfig['message()'] = [$message];
112 1
        return $new;
113
    }
114
115 1
    final public function begin(): ?string
116
    {
117 1
        parent::begin();
118 1
        $this->isStartedByBegin = true;
119
120 1
        $content = $this->generateBeginContent();
121
122 1
        if (!$this->useContainer) {
123
            return $content;
124
        }
125
126 1
        $containerTag = CustomTag::name($this->containerTag);
127 1
        if ($this->containerTagAttributes !== []) {
128
            $containerTag = $containerTag->attributes($this->containerTagAttributes);
129
        }
130
131 1
        return $containerTag->open()
132 1
            . ($content === '' ? '' : (PHP_EOL . $content))
133
            . PHP_EOL;
134
    }
135
136 96
    final protected function run(): string
137
    {
138 96
        if ($this->isStartedByBegin) {
139 1
            $this->isStartedByBegin = false;
140 1
            return $this->renderEnd();
141
        }
142
143 96
        $content = $this->generateContent();
144
145 95
        if (!$this->useContainer) {
146 11
            return $content;
147
        }
148
149 85
        $containerTag = CustomTag::name($this->containerTag);
150 85
        if ($this->containerTagAttributes !== []) {
151 3
            $containerTag = $containerTag->attributes($this->containerTagAttributes);
152
        }
153
154 85
        return $containerTag->open()
155 85
            . ($content === '' ? '' : (PHP_EOL . $content))
156
            . PHP_EOL
157 85
            . $containerTag->close();
158
    }
159
160 75
    protected function shouldHideLabel(): bool
161
    {
162 75
        return false;
163
    }
164
165 1
    private function renderEnd(): string
166
    {
167 1
        $content = $this->generateEndContent();
168
169 1
        if (!$this->useContainer) {
170
            return $content;
171
        }
172
173 1
        $containerTag = CustomTag::name($this->containerTag);
174
175
        return
176
            "\n" .
177 1
            ($content !== '' ? $content . "\n" : '')
178 1
            . $containerTag->close();
179
    }
180
181
    protected function generateInput(): string
182
    {
183
        return '';
184
    }
185
186
    protected function generateBeginInput(): string
187
    {
188
        return '';
189
    }
190
191
    protected function generateEndInput(): string
192
    {
193
        return '';
194
    }
195
196
    abstract protected function generateLabel(): string;
197
198
    abstract protected function generateHint(): string;
199
200
    abstract protected function generateError(): string;
201
202 96
    private function generateContent(): string
203
    {
204 95
        $parts = [
205 96
            '{input}' => $this->generateInput(),
206 95
            '{label}' => ($this->hideLabel ?? $this->shouldHideLabel()) ? '' : $this->generateLabel(),
207 95
            '{hint}' => $this->generateHint(),
208 95
            '{error}' => $this->generateError(),
209
        ];
210
211 95
        return preg_replace('/^\h*\v+/m', '', trim(strtr($this->template, $parts)));
212
    }
213
214 1
    private function generateBeginContent(): string
215
    {
216 1
        $parts = [
217 1
            '{input}' => $this->generateBeginInput(),
218 1
            '{label}' => ($this->hideLabel ?? $this->shouldHideLabel()) ? '' : $this->generateLabel(),
219 1
            '{hint}' => $this->generateHint(),
220 1
            '{error}' => $this->generateError(),
221
        ];
222
223 1
        return preg_replace('/^\h*\v+/m', '', trim(strtr($this->templateBegin, $parts)));
224
    }
225
226 1
    private function generateEndContent(): string
227
    {
228 1
        $parts = [
229 1
            '{input}' => $this->generateEndInput(),
230 1
            '{label}' => ($this->hideLabel ?? $this->shouldHideLabel()) ? '' : $this->generateLabel(),
231 1
            '{hint}' => $this->generateHint(),
232 1
            '{error}' => $this->generateError(),
233
        ];
234
235 1
        return preg_replace('/^\h*\v+/m', '', trim(strtr($this->templateEnd, $parts)));
236
    }
237
}
238