From bf8d6ab6796524166072d42945245a53c93999da Mon Sep 17 00:00:00 2001 From: Ron Lucke <lucke@elan-ev.de> Date: Mon, 4 Nov 2024 07:35:37 +0000 Subject: [PATCH] Fix Courseware Sort issue Closes #4766 Merge request studip/studip!3585 --- .../5.3.26_fix_faulty_container_payload.php | 46 +++++++++++++++++++ .../ContainerTypes/ContainerType.php | 2 +- resources/vue/mixins/courseware/container.js | 6 +-- 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 db/migrations/5.3.26_fix_faulty_container_payload.php diff --git a/db/migrations/5.3.26_fix_faulty_container_payload.php b/db/migrations/5.3.26_fix_faulty_container_payload.php new file mode 100644 index 00000000000..a5c169bc54c --- /dev/null +++ b/db/migrations/5.3.26_fix_faulty_container_payload.php @@ -0,0 +1,46 @@ +<?php +/** + * @see https://gitlab.studip.de/studip/studip/-/issues/4766 + */ +return new class extends Migration { + public function description() + { + return 'Fix container payload, in case an array was inserted into the block list (see BIEST#4766)'; + } + + protected function up() + { + $db = DBManager::get(); + + $query = "SELECT * FROM `cw_containers` + WHERE payload LIKE '%\"blocks\":%' + AND ( + payload LIKE '%\"blocks\":[%[%]%' + OR + payload LIKE '%\"blocks\":[%[^\"]%' + ); + "; + $containers = $db->fetchAll($query); + + $update_container = $db->prepare("UPDATE `cw_containers` SET `payload` = ? WHERE `id` = ?"); + + foreach ($containers as $container) { + $payload = json_decode($container['payload'], true); + $sections = $payload['sections']; + foreach ($sections as &$section) { + $section['blocks'] = array_map(function ($item) { + if (is_array($item)) { + return implode('', array_map('strval', $item)); + } + return strval($item); + }, $section['blocks']); + ; + } + $payload['sections'] = $sections; + $payload = json_encode($payload); + $id = $container['id']; + $update_container->execute([$payload, $id]); + } + } + +}; diff --git a/lib/models/Courseware/ContainerTypes/ContainerType.php b/lib/models/Courseware/ContainerTypes/ContainerType.php index 4e816bef762..3dde592ae64 100644 --- a/lib/models/Courseware/ContainerTypes/ContainerType.php +++ b/lib/models/Courseware/ContainerTypes/ContainerType.php @@ -194,7 +194,7 @@ abstract class ContainerType foreach ($payload['sections'] as &$section) { foreach ($section['blocks'] as &$block) { - $block = $block_map[$block] ?? null; + $block = (is_string($block) || is_int($block)) ? ($block_map[$block] ?? null) : null; } $section['blocks'] = array_values(array_filter($section['blocks'])); } diff --git a/resources/vue/mixins/courseware/container.js b/resources/vue/mixins/courseware/container.js index ef09a8bd801..eb5fcaa106d 100644 --- a/resources/vue/mixins/courseware/container.js +++ b/resources/vue/mixins/courseware/container.js @@ -36,12 +36,12 @@ const containerMixin = { containerUpdate: 'courseware-containers/update' }), dropBlock(e) { - this.isDragging = false; // implemented bei echt container type + this.isDragging = false; // implemented by each container type let data = {}; data.originContainerId = e.from.__vue__.$attrs.containerId; data.targetContainerId = e.to.__vue__.$attrs.containerId; if (data.originContainerId === data.targetContainerId) { - this.storeSort(); // implemented bei echt container type + this.storeSort(); // implemented by each container type } else { data.originSectionId = e.from.__vue__.$attrs.sectionId; data.originSectionBlockList = e.from.__vue__.$children.map(b => { return b.$attrs.blockId; }); @@ -50,7 +50,7 @@ const containerMixin = { data.blockId = e.item._underlying_vm_.id; data.newPos = e.newIndex; const indexInBlockList = data.targetSectionBlockList.findIndex(b => b === data.blockId); - data.targetSectionBlockList.splice(data.newPos, 0, data.targetSectionBlockList.splice(indexInBlockList,1)); + data.targetSectionBlockList.splice(data.newPos, 0, data.targetSectionBlockList.splice(indexInBlockList,1)[0]); // move block id to new position this.storeInAnotherContainer(data); } }, -- GitLab