HtmlComponent::addHtml()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Lagdo\UiBuilder\Component;
4
5
use Lagdo\UiBuilder\Builder\Engine\Engine;
6
use Lagdo\UiBuilder\Component\Html\Element;
7
use Lagdo\UiBuilder\Component\Html\Html;
8
use Lagdo\UiBuilder\Component\Html\Text;
9
use Closure;
10
11
use function is_array;
12
use function is_string;
13
14
/**
15
 * @method static setId(string $id, bool $escape = true)
16
 * @method static setClass(string $class, bool $escape = true)
17
 * @method static setFor(string $for, bool $escape = true)
18
 * @method static setName(string $name, bool $escape = true)
19
 * @method static setValue(string $value, bool $escape = true)
20
 * @method static setType(string $type, bool $escape = true)
21
 * @method static setTitle(string $type, bool $escape = true)
22
 * @method static setStyle(string $type, bool $escape = true)
23
 */
24
class HtmlComponent extends Component
25
{
26
    /**
27
     * @var HtmlElement
28
     */
29
    private $element;
30
31
    /**
32
     * @var array<HtmlElement>|null
33
     */
34
    private $wrappers = null;
35
36
    /**
37
     * @var array<HtmlElement>|null
38
     */
39
    private $siblings = null;
40
41
    /**
42
     * @var array<Element|Component>
43
     */
44
    private $children = [];
45
46
    /**
47
     * @var array So empty arrays aren't created anytime an element doesn't exist.
48
     */
49
    private const EMPTY_ARRAY = [];
50
51
    /**
52
     * The constructor
53
     *
54
     * @param Engine $engine
55
     * @param string $name
56
     * @param array $arguments
57
     */
58
    public function __construct(private Engine $engine, string $name, array $arguments = [])
59
    {
60
        $this->element = new HtmlElement($engine, $name);
61
62
        // Resolve arguments
63
        $this->contents(...$arguments);
64
65
        $this->onCreate();
66
    }
67
68
    /**
69
     * Called for each child after a parent is expanded.
70
     *
71
     * @param HtmlComponent $parent
72
     *
73
     * @return static
74
     */
75
    final public function expanded(HtmlComponent $parent): static
76
    {
77
        $this->onBuild($parent);
78
        return $this;
79
    }
80
81
    /**
82
     * @return bool
83
     */
84
    protected function inForm(): bool
85
    {
86
        return $this->engine->inForm();
87
    }
88
89
    /**
90
     * @return static
91
     */
92
    public function contents(...$arguments): static
93
    {
94
        // Resolve arguments
95
        foreach ($arguments as $argument) {
96
            switch (true) {
97
            case is_array($argument):
98
                $this->element->setAttributes($argument);
99
                break;
100
            case is_string($argument):
101
                $this->children[] = new Html($argument);
102
                break;
103
            case is_a($argument, Element::class):
104
            case is_a($argument, Component::class):
105
                $this->children[] = $argument;
106
            }
107
        }
108
        return $this;
109
    }
110
111
    /**
112
     * @return HtmlElement
113
     */
114
    public function element(): HtmlElement
115
    {
116
        return $this->element;
117
    }
118
119
    /**
120
     * @return array<HtmlElement>
121
     */
122
    public function wrappers(): array
123
    {
124
        return $this->wrappers ?? self::EMPTY_ARRAY;
125
    }
126
127
    /**
128
     * @param string $position "prev" or "next"
129
     *
130
     * @return array<HtmlElement>
131
     */
132
    public function siblings(string $position): array
133
    {
134
        return $this->siblings[$position] ?? self::EMPTY_ARRAY;
135
    }
136
137
    /**
138
     * @return array<Element|Component>
139
     */
140
    public function children(): array
141
    {
142
        return $this->children;
143
    }
144
145
    /**
146
     * @param string $text
147
     *
148
     * @return static
149
     */
150
    protected function addText(string $text): static
151
    {
152
        $this->children[] = new Text($text);
153
        return $this;
154
    }
155
156
    /**
157
     * @param string $html
158
     *
159
     * @return static
160
     */
161
    protected function addHtml(string $html): static
162
    {
163
        $this->children[] = new Html($html);
164
        return $this;
165
    }
166
167
    /**
168
     * @param string $method
169
     * @param array $arguments
170
     *
171
     * @return static
172
     */
173
    public function __call(string $method, array $arguments): static
174
    {
175
        $this->engine->callComponentHelper($this, $method, $arguments);
176
        return $this;
177
    }
178
179
    /**
180
     * @param string $class
181
     *
182
     * @return static
183
     */
184
    public function addClass(string $class): static
185
    {
186
        $this->element->addClass($class);
187
        return $this;
188
    }
189
190
    /**
191
     * @param string $class
192
     *
193
     * @return static
194
     */
195
    public function setClass(string $class): static
196
    {
197
        // Actually appends the class.
198
        return $this->addClass($class);
199
    }
200
201
    /**
202
     * @param string $class
203
     *
204
     * @return static
205
     */
206
    public function removeClass(string $class): static
207
    {
208
        $this->element->removeClass($class);
209
        return $this;
210
    }
211
212
    /**
213
     * @param string $class
214
     *
215
     * @return bool
216
     */
217
    public function hasClass(string $class): bool
218
    {
219
        return $this->element->hasClass($class);
220
    }
221
222
    /**
223
     * @param string $name
224
     * @param string|bool $value
225
     * @param bool $escape
226
     *
227
     * @return static
228
     */
229
    public function setAttribute(string $name, string|bool $value = true, bool $escape = true): static
230
    {
231
        $this->element->setAttribute($name, $value, $escape);
232
        return $this;
233
    }
234
235
    /**
236
     * @param array $attributes
237
     * @param bool $escape
238
     *
239
     * @return static
240
     */
241
    public function setAttributes(array $attributes, bool $escape = true): static
242
    {
243
        $this->element->setAttributes($attributes, $escape);
244
        return $this;
245
    }
246
247
    /**
248
     * @param string $name
249
     *
250
     * @return bool
251
     */
252
    public function hasAttribute(string $name): bool
253
    {
254
        return $this->element->hasAttribute($name);
255
    }
256
257
    /**
258
     * @param string $name
259
     *
260
     * @return string|bool
261
     */
262
    public function getAttribute(string $name): string|bool
263
    {
264
        return $this->element->getAttribute($name);
265
    }
266
267
    /**
268
     * @param string $name
269
     *
270
     * @return static
271
     */
272
    public function removeAttribute(string $name): static
273
    {
274
        $this->element->removeAttribute($name);
275
        return $this;
276
    }
277
278
    /**
279
     * @param string $name
280
     * @param array $arguments
281
     *
282
     * @return HtmlElement
283
     */
284
    protected function addWrapper(string $name, array $arguments = []): HtmlElement
285
    {
286
        $element = new HtmlElement($this->engine, $name, $arguments);
287
        $this->wrappers ??= [];
288
        $this->wrappers[] = $element;
289
        return $element;
290
    }
291
292
    /**
293
     * @param int $index
294
     *
295
     * @return HtmlElement|null
296
     */
297
    protected function wrapper(int $index): HtmlElement|null
298
    {
299
        return $this->wrappers[$index] ?? null;
300
    }
301
302
    /**
303
     * @param string $name
304
     * @param array $arguments
305
     *
306
     * @return HtmlElement
307
     */
308
    protected function addSiblingPrev(string $name, array $arguments = []): HtmlElement
309
    {
310
        $element = new HtmlElement($this->engine, $name, $arguments);
311
        $this->siblings ??= [];
312
        $this->siblings['prev'] ??= [];
313
        $this->siblings['prev'][] = $element;
314
        return $element;
315
    }
316
317
    /**
318
     * @param int $index
319
     *
320
     * @return HtmlElement|null
321
     */
322
    protected function siblingPrev(int $index): HtmlElement|null
323
    {
324
        return $this->siblings['prev'][$index] ?? null;
325
    }
326
327
    /**
328
     * @param string $name
329
     * @param array $arguments
330
     *
331
     * @return HtmlElement
332
     */
333
    protected function addSiblingNext(string $name, array $arguments = []): HtmlElement
334
    {
335
        $element = new HtmlElement($this->engine, $name, $arguments);
336
        $this->siblings ??= [];
337
        $this->siblings['next'] ??= [];
338
        $this->siblings['next'][] = $element;
339
        return $element;
340
    }
341
342
    /**
343
     * @param int $index
344
     *
345
     * @return HtmlElement|null
346
     */
347
    protected function siblingNext(int $index): HtmlElement|null
348
    {
349
        return $this->siblings['next'][$index] ?? null;
350
    }
351
352
    /**
353
     * @param bool $condition
354
     * @param Closure $closure
355
     *
356
     * @return static
357
     */
358
    public function when(bool $condition, Closure $closure): static
359
    {
360
        $condition && $closure($this);
361
        return $this;
362
    }
363
364
    /**
365
     * @param Closure $closure
366
     *
367
     * @return static
368
     */
369
    public function with(Closure $closure): static
370
    {
371
        $closure($this);
372
        return $this;
373
    }
374
}
375