elementChildren($wrapper) as $child) { $this->extractFields($child, $raw, '$data'); } $this->applyTokens($raw); $blade = $this->serializeChildren($wrapper); $blade = $this->replaceTokens($blade); $fields = $this->publicFields($raw); return ['fields' => $fields, 'blade' => $blade, 'is_repeater' => false]; } // ── Repeater ────────────────────────────────────────────────────────── private function buildRepeater(DOMElement $wrapper, DOMElement $container, array $items): array { // Sub-fields извлекаем из первого элемента-образца $rawSub = []; $this->extractFields($items[0], $rawSub, '$item'); $this->applyTokens($rawSub); // Blade для одного item $itemBlade = $this->dom->saveHTML($items[0]); $itemBlade = $this->replaceTokens($itemBlade); // Блок @foreach $foreachBlock = "@foreach(\$data['items'] as \$item)\n " . str_replace("\n", "\n ", trim($itemBlade)) . "\n@endforeach"; if ($container === $wrapper) { $blade = $foreachBlock; } else { // container — один из потомков wrapper; // удаляем лишние item-дублёры, оставляем placeholder @foreach foreach (array_slice($items, 1) as $item) { $container->removeChild($item); } $foreachToken = 'BLADEFOREACHBLOCK'; $this->tokens[$foreachToken] = $foreachBlock; $container->replaceChild( $this->dom->createTextNode($foreachToken), $items[0] ); // Также ищем плоские поля в частях wrapper вне container $outerRaw = []; foreach ($this->elementChildren($wrapper) as $child) { if ($child !== $container) { $this->extractFields($child, $outerRaw, '$data'); } } $this->applyTokens($outerRaw); $blade = $this->serializeChildren($wrapper); $blade = $this->replaceTokens($blade); $outerFields = $this->publicFields($outerRaw); $fields = array_merge($outerFields, [[ 'name' => 'items', 'label' => 'Элементы', 'type' => 'repeater', 'sub_fields' => $this->publicFields($rawSub), ]]); return ['fields' => $fields, 'blade' => $blade, 'is_repeater' => true]; } $fields = [[ 'name' => 'items', 'label' => 'Элементы', 'type' => 'repeater', 'sub_fields' => $this->publicFields($rawSub), ]]; return ['fields' => $fields, 'blade' => $blade, 'is_repeater' => true]; } }