Passed
Pull Request — master (#192)
by Alexander
05:47 queued 02:55
created

BaseField::run()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 11
c 0
b 0
f 0
nc 4
nop 0
dl 0
loc 21
ccs 12
cts 12
cp 1
crap 4
rs 9.9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field\Base;
6
7
use InvalidArgumentException;
8
use Yiisoft\Html\Html;
9
use Yiisoft\Html\Tag\CustomTag;
10
use Yiisoft\Widget\Widget;
11
12
abstract class BaseField extends Widget
13
{
14
    /**
15
     * @psalm-var non-empty-string
16
     */
17
    protected string $containerTag = 'div';
18
    protected array $containerTagAttributes = [];
19
    protected bool $useContainer = true;
20
21
    private bool $isStartedByBegin = false;
22
23 4
    final public function containerTag(string $tag): static
24
    {
25 4
        if ($tag === '') {
26 1
            throw new InvalidArgumentException('Tag name cannot be empty.');
27
        }
28
29 3
        $new = clone $this;
30 3
        $new->containerTag = $tag;
31 3
        return $new;
32
    }
33
34 5
    final public function containerTagAttributes(array $attributes): static
35
    {
36 5
        $new = clone $this;
37 5
        $new->containerTagAttributes = $attributes;
38 5
        return $new;
39
    }
40
41 19
    final public function useContainer(bool $use): static
42
    {
43 19
        $new = clone $this;
44 19
        $new->useContainer = $use;
45 19
        return $new;
46
    }
47
48 1
    final public function begin(): ?string
49
    {
50 1
        parent::begin();
51 1
        $this->isStartedByBegin = true;
52
53 1
        $this->beforeRender();
54
55 1
        $content = $this->generateBeginContent();
56
57 1
        return $this->renderOpenContainerAndContent($content) . "\n";
58
    }
59
60 117
    final protected function run(): string
61
    {
62 117
        if ($this->isStartedByBegin) {
63 1
            $this->isStartedByBegin = false;
64 1
            return $this->renderEnd();
65
        }
66
67 117
        $this->beforeRender();
68
69 117
        $content = $this->generateContent();
70 116
        if ($content === null) {
71 1
            return '';
72
        }
73
74 115
        $result = $this->renderOpenContainerAndContent($content);
75
76 115
        if ($this->useContainer) {
77 96
            $result .= "\n" . Html::closeTag($this->containerTag);
78
        }
79
80 115
        return $result;
81
    }
82
83
    protected function beforeRender(): void
84
    {
85
    }
86
87
    abstract protected function generateContent(): ?string;
88
89
    protected function generateBeginContent(): string
90
    {
91
        return '';
92
    }
93
94
    protected function generateEndContent(): string
95
    {
96
        return '';
97
    }
98
99
    protected function prepareContainerTagAttributes(array &$attributes): void
100
    {
101
    }
102
103 1
    private function renderEnd(): string
104
    {
105 1
        $content = $this->generateEndContent();
106
107 1
        if (!$this->useContainer) {
108
            return $content;
109
        }
110
111 1
        $containerTag = CustomTag::name($this->containerTag);
112
113
        return
114
            "\n"
115 1
            . ($content !== '' ? $content . "\n" : '')
116 1
            . $containerTag->close();
117
    }
118
119 115
    private function renderOpenContainerAndContent(string $content): string
120
    {
121 115
        if (!$this->useContainer) {
122 20
            return $content;
123
        }
124
125 97
        $containerTag = CustomTag::name($this->containerTag);
126
127 97
        $attributes = $this->containerTagAttributes;
128 97
        $this->prepareContainerTagAttributes($attributes);
129 97
        if ($attributes !== []) {
130 7
            $containerTag = $containerTag->attributes($attributes);
131
        }
132
133 97
        return $containerTag->open()
134 97
            . ($content === '' ? '' : ("\n" . $content));
135
    }
136
}
137