1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Ui\HtmlTemplate;
6:
7: use Atk4\Core\WarnDynamicPropertyTrait;
8: use Atk4\Ui\Exception;
9: use Atk4\Ui\HtmlTemplate;
10:
11: /**
12: * @phpstan-consistent-constructor
13: */
14: class TagTree
15: {
16: use WarnDynamicPropertyTrait;
17:
18: private HtmlTemplate $parentTemplate;
19:
20: private string $tag;
21:
22: /** @var array<int, Value|string|HtmlTemplate> */
23: private array $children = [];
24:
25: public function __construct(HtmlTemplate $parentTemplate, string $tag)
26: {
27: $this->parentTemplate = $parentTemplate;
28: $this->tag = $tag;
29: }
30:
31: private function __clone()
32: {
33: // prevent cloning
34: }
35:
36: /**
37: * @return static
38: */
39: public function clone(HtmlTemplate $newParentTemplate): self
40: {
41: $res = new static($newParentTemplate, $this->tag);
42: foreach ($this->children as $k => $v) {
43: $res->children[$k] = is_string($v) ? $v : clone $v;
44: }
45:
46: return $res;
47: }
48:
49: public function getParentTemplate(): HtmlTemplate
50: {
51: return $this->parentTemplate;
52: }
53:
54: public function getTag(): string
55: {
56: return $this->tag;
57: }
58:
59: /**
60: * @return array<int, Value|self|HtmlTemplate>
61: */
62: public function getChildren(): array
63: {
64: $res = [];
65: $parentTemplate = $this->getParentTemplate();
66: foreach ($this->children as $k => $v) {
67: $res[$k] = is_string($v) ? $parentTemplate->getTagTree($v) : $v;
68: }
69:
70: return $res;
71: }
72:
73: /**
74: * @param Value|HtmlTemplate $value
75: *
76: * @return $this
77: */
78: public function add(object $value): self
79: {
80: if (!$value instanceof Value && !$value instanceof HtmlTemplate) { // @phpstan-ignore-line
81: if ($value instanceof self) { // @phpstan-ignore-line
82: throw new Exception('Tag tree cannot be added directly');
83: }
84:
85: throw new Exception('Value must be of type HtmlTemplate\Value or HtmlTemplate');
86: }
87:
88: $this->children[] = $value;
89:
90: return $this;
91: }
92:
93: /**
94: * @return $this
95: */
96: public function addTag(string $tag): self
97: {
98: $this->getParentTemplate()->getTagTree($tag); // check if exists
99:
100: $this->children[] = $tag;
101:
102: return $this;
103: }
104: }
105: