| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- <?php
- namespace App\Support\Traits;
- use DOMElement;
- /*
- * Трейт: построение результирующего массива (fields + blade) для плоской
- * структуры и для repeater-структуры.
- * Используется классом BlockLayoutParser.
- */
- trait BlockLayoutBuilderTrait
- {
- // ── Плоская структура ─────────────────────────────────────────────────
- private function buildFlat(DOMElement $wrapper): array
- {
- $raw = [];
- foreach ($this->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];
- }
- }
|