|
27 | 27 |
|
28 | 28 | class LazyTreeBuilder extends DOMTreeBuilder |
29 | 29 | { |
| 30 | + public static \WeakMap|null $idMap = null; |
30 | 31 | private static int $id = 0; |
31 | | - |
32 | 32 | /** |
33 | 33 | * @var array<CompiledComponent> |
34 | 34 | */ |
35 | 35 | private array $componentStack = []; |
36 | | - |
37 | 36 | private readonly StateProviderInterface $stateProvider; |
38 | 37 | private readonly AuthenticationServiceInterface|null $authenticationService; |
39 | 38 | /** |
40 | 39 | * @var array<DOMNode> |
41 | 40 | */ |
42 | 41 | private array $childParents = []; |
43 | | - |
44 | 42 | /** |
45 | 43 | * @var array<array<CompiledComponent>> |
46 | 44 | */ |
47 | 45 | private array $delayStack = []; |
48 | | - |
49 | 46 | /** |
50 | 47 | * @var array<CompiledComponent> |
51 | 48 | */ |
52 | 49 | private array|null $delayStackPointer = null; |
53 | | - |
54 | 50 | /** |
55 | 51 | * @var array<DataProvider> |
56 | 52 | */ |
@@ -82,6 +78,7 @@ public function __construct( |
82 | 78 | } catch (NotFoundExceptionInterface|ContainerExceptionInterface) { |
83 | 79 | $this->authenticationService = null; |
84 | 80 | } |
| 81 | + self::$idMap ??= new \WeakMap(); |
85 | 82 | } |
86 | 83 |
|
87 | 84 | /** |
@@ -137,8 +134,12 @@ private function pushComponent(string $name, array $attributes): void |
137 | 134 | $attributes |
138 | 135 | ); |
139 | 136 |
|
| 137 | + if ($attributes['id'] ?? null) { |
| 138 | + self::$idMap[$this->componentStack[$name]] = $attributes['id']; |
| 139 | + } |
| 140 | + |
140 | 141 | // only count children we are actually rendering |
141 | | - if(count($this->componentStack) === 1) { |
| 142 | + if (count($this->componentStack) === 1) { |
142 | 143 | // in a weird quirk of php, this results in appending a new array to the delay stack and they are the same variable. |
143 | 144 | $this->delayStackPointer = &$this->delayStack[]; |
144 | 145 | $this->delayStackPointer = []; |
@@ -207,17 +208,15 @@ private function decorateForm(string $name, array $attributes): void |
207 | 208 | $idElement = $this->doc->createElement('input'); |
208 | 209 | $idElement->setAttribute('type', 'hidden'); |
209 | 210 | $idElement->setAttribute('name', 'target_id'); |
210 | | - $idElement->setAttribute('value', $this->calculateId(self::$id)); |
| 211 | + $idElement->setAttribute( |
| 212 | + 'value', |
| 213 | + self::$idMap[$this->parentComponent ?? reset($this->componentStack)] ?? 'null' |
| 214 | + ); |
211 | 215 | $this->current->appendChild($idElement); |
212 | 216 | } |
213 | 217 | } |
214 | 218 | } |
215 | 219 |
|
216 | | - private function calculateId(int $id): string |
217 | | - { |
218 | | - return substr('c' . md5((string)$id), 0, 8); |
219 | | - } |
220 | | - |
221 | 220 | /** |
222 | 221 | * @param string $name |
223 | 222 | * @return void |
@@ -304,10 +303,18 @@ private function decorateComponent(CompiledComponent|false $component): void |
304 | 303 | } |
305 | 304 | $id = $this->calculateId(++self::$id); |
306 | 305 | if ($this->current instanceof DOMElement && !$this->current->hasAttribute('id')) { |
| 306 | + if ($component = end($this->componentStack)) { |
| 307 | + self::$idMap[$component] = $id; |
| 308 | + } |
307 | 309 | $this->current->setAttribute('id', $id); |
308 | 310 | } |
309 | 311 | } |
310 | 312 |
|
| 313 | + private function calculateId(int $id): string |
| 314 | + { |
| 315 | + return substr('c' . md5((string)$id), 0, 8); |
| 316 | + } |
| 317 | + |
311 | 318 | /** |
312 | 319 | * @param array<DOMNode> $children |
313 | 320 | * @param false $renderedChildren |
|
0 commit comments