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 0000000000000000000000000000000000000000..a5c169bc54cb40254060cdf0d056b924260c4c19 --- /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 4e816bef762fa5b4780a8f735feb4a45505dea47..3dde592ae64f20a33d1303234a62d67461a84346 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 ef09a8bd801cb4ac74ec99debdc9d0e2a88ec229..eb5fcaa106dc9ef140bce737bb4d6ca8ed24f0c7 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); } },