From 49ecfadcdb20d984729bf20894600de3fd078c51 Mon Sep 17 00:00:00 2001 From: Tofandel Date: Thu, 29 Feb 2024 10:38:27 +0100 Subject: [PATCH] Fix all BC breaks --- frontend/js/utils/getFormData.js | 53 ++++++------ src/Repositories/Behaviors/HandleBlocks.php | 45 ++++------ .../Behaviors/HandleRepeaters.php | 18 ---- .../integration/Blocks/BlockChildrenTest.php | 85 ++----------------- 4 files changed, 47 insertions(+), 154 deletions(-) diff --git a/frontend/js/utils/getFormData.js b/frontend/js/utils/getFormData.js index 23a0a8298..f08636813 100755 --- a/frontend/js/utils/getFormData.js +++ b/frontend/js/utils/getFormData.js @@ -31,17 +31,17 @@ export const stripOutBlockNamespace = (name, id) => { return nameWithoutBlock.match(/]/gi).length > 1 ? nameWithoutBlock.replace(']', '') : nameWithoutBlock.slice(0, -1) } -export const buildBlock = (block, rootState, isRepeater = false, childKey) => { - const parentRepeaters = rootState.repeaters.repeaters; - const repeaterIds = Object.keys(parentRepeaters); +export const buildBlock = (block, rootState, isRepeater = false, isInsideRepeater = isRepeater) => { + const repeaterIds = Object.keys(rootState.repeaters.repeaters); const prefix = 'blocks-' + block.id + '|'; const repeaters = repeaterIds.filter(repeaterKey => { return repeaterKey.startsWith(prefix) }) .reduce((acc, repeaterKey) => { - acc[repeaterKey.replace(prefix, '')] = parentRepeaters[repeaterKey].map(repeaterItem => { - return buildBlock(repeaterItem, rootState, true) - }) + acc[repeaterKey.replace(prefix, '')] = rootState.repeaters.repeaters[repeaterKey] + .map(repeaterItem => { + return buildBlock(repeaterItem, rootState, true, isRepeater) + }) return acc }, {}) @@ -50,41 +50,38 @@ export const buildBlock = (block, rootState, isRepeater = false, childKey) => { const blocks = blockIds.filter(blockKey => { return blockKey.startsWith(prefix) }).reduce((acc, blockKey) => { - acc.push(...rootState.blocks.blocks[blockKey].map(repeaterItem => { - if (isRepeater) { - repeaterItem = {...repeaterItem, name: repeaterItem.name.replace(prefix, '')} + const key = blockKey.replace(prefix, ''); + rootState.blocks.blocks[blockKey].forEach(blockItem => { + const block = buildBlock(blockItem, rootState, false); + if (isInsideRepeater) { + acc.push(block); + } else { + if (!acc[key]) { + acc[key] = []; + } + acc[key].push(block) } - return buildBlock(repeaterItem, rootState, false, blockKey.replace(prefix, '')) - })); + }) return acc; - }, []) + }, isInsideRepeater ? [] : {}) // retrieve all fields for this block and clean up field names const content = rootState.form.fields.filter((field) => { return isBlockField(field.name, block.id) - }).map((field) => { - return { - name: stripOutBlockNamespace(field.name, block.id), - value: field.value - } - }).reduce((content, field) => { - content[field.name] = field.value - return content - }, {}); + }).reduce((acc, field) => { + acc[stripOutBlockNamespace(field.name, block.id)] = field.value; + return acc; + }, {}) const base = { id: block.id, - type: block.type, medias: gatherSelected(rootState.mediaLibrary.selected, block), browsers: gatherSelected(rootState.browser.selected, block), - content, // gather repeater blocks from the repeater store module - blocks, - repeaters, } - return isRepeater - ? { ...base, is_repeater: true, repeater_target_id: block.repeater_target_id} - : { ...base, editor_name: block.name, child_key: childKey } + return isInsideRepeater + ? { ...content, ...base, repeater_target_id: block.repeater_target_id, blocks, repeaters} + : { ...base, content, is_repeater: isRepeater, type: block.type, editor_name: block.name, blocks: {...blocks, ...repeaters} } } export const isBlockEmpty = (blockData) => { diff --git a/src/Repositories/Behaviors/HandleBlocks.php b/src/Repositories/Behaviors/HandleBlocks.php index f38d9b386..73e7e4110 100644 --- a/src/Repositories/Behaviors/HandleBlocks.php +++ b/src/Repositories/Behaviors/HandleBlocks.php @@ -273,39 +273,22 @@ private function getChildBlocks($object, $parentBlockFields) { $childBlocksList = Collection::make(); - if (!empty($parentBlockFields['blocks'])) { - // Fallback if frontend or revision is still on the old schema - if (is_int(key(current($parentBlockFields['blocks'])))) { - foreach ($parentBlockFields['blocks'] as $childKey => $childBlocks) { - foreach ($childBlocks as $childBlock) { - $childBlock['child_key'] = $childKey; - $parentBlockFields['blocks'][] = $childBlock; - } - unset($parentBlockFields['blocks'][$childKey]); - } + foreach ($parentBlockFields['blocks'] ?? [] as $childKey => $childBlocks) { + if (str_contains($childKey, '|')) { + continue; } - } - - if (!empty($parentBlockFields['repeaters'])) { - foreach ($parentBlockFields['repeaters'] as $childKey => $childBlocks) { - foreach ($childBlocks as $childBlock) { - $childBlock['child_key'] = $childKey; - $parentBlockFields['blocks'][] = $childBlock; - } + foreach ($childBlocks as $index => $childBlock) { + $childBlock = $this->buildBlock($childBlock, $object, $childBlock['is_repeater'] ?? false); + $this->validateBlockArray($childBlock, $childBlock['instance'], true); + $childBlock['child_key'] = $childKey; + $childBlock['position'] = $index + 1; + $childBlock['editor_name'] = $parentBlockFields['editor_name'] ?? 'default'; + $childBlock['blocks'] = $this->getChildBlocks($object, $childBlock); + + $childBlocksList->push($childBlock); } } - foreach ($parentBlockFields['blocks'] ?? [] as $index => $childBlock) { - $childBlock = $this->buildBlock($childBlock, $object, $childBlock['is_repeater'] ?? false); - $this->validateBlockArray($childBlock, $childBlock['instance'], true); - $childBlock['child_key'] = $childBlock['child_key'] ?? Str::afterLast($childBlock['editor_name'] ?? $index, '|'); - $childBlock['position'] = $index + 1; - $childBlock['editor_name'] = $parentBlockFields['editor_name'] ?? 'default'; - $childBlock['blocks'] = $this->getChildBlocks($object, $childBlock); - - $childBlocksList->push($childBlock); - } - return $childBlocksList; } @@ -482,7 +465,7 @@ protected function getBlockBrowsers($block) try { $relationRepository = $this->getModelRepository($relation); $relatedItems = $relationRepository->get([], ['id' => $ids], [], -1); - } catch (\Throwable $th) { + } catch (\Throwable) { $relatedItems = collect(); } $sortedRelatedItems = array_flip($ids); @@ -494,6 +477,7 @@ protected function getBlockBrowsers($block) $items = Collection::make(array_values($sortedRelatedItems))->filter(function ($value) { return is_object($value); })->map(function ($relatedElement) use ($relation) { + // TODO this needs refactoring, it's duplicated from HandleBrowsers return [ 'id' => $relatedElement->id, 'name' => $relatedElement->titleInBrowser ?? $relatedElement->title, @@ -503,6 +487,7 @@ protected function getBlockBrowsers($block) 'edit', $relatedElement->id ), + 'endpointType' => $relatedElement->getMorphClass(), ] + (classHasTrait($relatedElement, HasMedias::class) ? [ 'thumbnail' => $relatedElement->defaultCmsImage(['w' => 100, 'h' => 100]), ] : []); diff --git a/src/Repositories/Behaviors/HandleRepeaters.php b/src/Repositories/Behaviors/HandleRepeaters.php index 5fe225073..dfe785896 100644 --- a/src/Repositories/Behaviors/HandleRepeaters.php +++ b/src/Repositories/Behaviors/HandleRepeaters.php @@ -131,12 +131,6 @@ public function updateRepeaterMorphMany( $relationField[$morphFieldId] = $object->id; $relationField[$morphFieldType] = $object->getMorphClass(); - if (is_array($relationField['content'] ?? null)) { - $content = $relationField['content']; - unset($relationField['content']); - $relationField = array_merge($content, $relationField); - } - if (isset($relationField['id']) && Str::startsWith($relationField['id'], $relation)) { // row already exists, let's update $id = str_replace($relation . '-', '', $relationField['id']); @@ -216,12 +210,6 @@ public function updateRepeaterWithPivot( } } - if (is_array($relationField['content'] ?? null)) { - $content = $relationField['content']; - unset($relationField['content']); - $relationField = array_merge($content, $relationField); - } - if (isset($relationField['id']) && Str::startsWith($relationField['id'], $relation)) { // row already exists, let's update, the $id is the id in the pivot table. $pivotRowId = str_replace($relation . '-', '', $relationField['id']); @@ -328,12 +316,6 @@ public function updateRepeater( $relationField['id'] = $relation . '-' . $id; } - if (is_array($relationField['content'] ?? null)) { - $content = $relationField['content']; - unset($relationField['content']); - $relationField = array_merge($content, $relationField); - } - // Set the active data based on the parent. if (! isset($relationField['languages']) && isset($relationField['active'])) { foreach (array_keys($relationField['active']) as $langCode) { diff --git a/tests/integration/Blocks/BlockChildrenTest.php b/tests/integration/Blocks/BlockChildrenTest.php index cf9d4b440..52eb46846 100644 --- a/tests/integration/Blocks/BlockChildrenTest.php +++ b/tests/integration/Blocks/BlockChildrenTest.php @@ -8,7 +8,7 @@ class BlockChildrenTest extends TestCase { - public function testBCOfBlockSchema(): void + public function testSorting(): void { $module = AnonymousModule::make('childrenservers', $this->app) ->boot(); @@ -24,6 +24,7 @@ public function testBCOfBlockSchema(): void $blocks = [ 'blocks' => [ [ + 'editor_name' => 'description', 'browsers' => [], 'medias' => [], 'blocks' => [ @@ -52,78 +53,6 @@ public function testBCOfBlockSchema(): void ], 'id' => time() + 2, ], - ] - ], - 'type' => 'a17-block-quote', - 'content' => [ - 'quote' => 'This is the quote.', - 'author' => 'This is the author.', - ], - 'id' => time(), - ], - ], - ]; - - $update = $repository->update($server->id, $blocks); - - // Check the nested child order. - $this->assertEquals( - 'This is the nested quote at position 2.', - $update->blocks[0]->children[0]->content['quote'] - ); - $this->assertEquals( - 'This is the nested quote at position 1.', - $update->blocks[0]->children[1]->content['quote'] - ); - } - - public function testSorting(): void - { - $module = AnonymousModule::make('childrenservers', $this->app) - ->boot(); - - /** @var ModuleRepository $repository */ - $repository = app()->make($module->getRepositoryClassName()); - - $server = $repository->create([ - 'title' => 'Hello world', - 'published' => true, - ]); - - $blocks = [ - 'blocks' => [ - [ - 'editor_name' => 'description', - 'browsers' => [], - 'medias' => [], - 'blocks' => [ - [ - 'browsers' => [], - 'medias' => [], - 'blocks' => [], - 'child_key' => 'content', - 'editor_name' => 'blocks-yada-1|content', - 'type' => 'a17-block-quote', - 'is_repeater' => false, - 'content' => [ - 'quote' => 'This is the nested quote at position 2.', - 'author' => 'This is the nested author at position 2.', - ], - 'id' => time() + 1, - ], - [ - 'browsers' => [], - 'medias' => [], - 'blocks' => [], - 'child_key' => 'content', - 'editor_name' => 'blocks-yada-1|content', - 'type' => 'a17-block-quote', - 'is_repeater' => false, - 'content' => [ - 'quote' => 'This is the nested quote at position 1.', - 'author' => 'This is the nested author at position 1.', - ], - 'id' => time() + 2, ], ], 'type' => 'a17-block-quote', @@ -150,14 +79,14 @@ public function testSorting(): void // Now we update it a second time, but we update the order. $blocksUpdate = $blocks; - $blocksUpdate['blocks'][0]['blocks'][0]['id'] = $update->blocks[1]->id; - $blocksUpdate['blocks'][0]['blocks'][1]['id'] = $update->blocks[2]->id; + $blocksUpdate['blocks'][0]['blocks'][0][0]['id'] = $update->blocks[1]->id; + $blocksUpdate['blocks'][0]['blocks'][0][1]['id'] = $update->blocks[2]->id; // We now swap them so their actual position is correct. - $backup = $blocksUpdate['blocks'][0]['blocks'][0]; + $backup = $blocksUpdate['blocks'][0]['blocks'][0][0]; - $blocksUpdate['blocks'][0]['blocks'][0] = $blocksUpdate['blocks'][0]['blocks'][1]; - $blocksUpdate['blocks'][0]['blocks'][1] = $backup; + $blocksUpdate['blocks'][0]['blocks'][0][0] = $blocksUpdate['blocks'][0]['blocks'][0][1]; + $blocksUpdate['blocks'][0]['blocks'][0][1] = $backup; $update = $repository->update($server->id, $blocksUpdate);