From 0e0b06011ed668a6d3cc7123d780b6d4c8aa0088 Mon Sep 17 00:00:00 2001 From: greiser Date: Mon, 27 Jul 2026 12:47:53 +0200 Subject: [PATCH 01/10] Use SSO for the multi-problem selector when server origins match The multi-problem selector now runs shouldUseSSO() before opening its popup, same as the single-problem selector: if the configured problem-selector origin matches the selected MUMIE server's origin, it opens the SSO auto-submit form (with multiSelect=true) via ilMumieTaskSSOService instead of the plain URL; otherwise it falls back to the unauthenticated URL as before. --- changelog.md | 1 + classes/class.ilMumieTaskSSOService.php | 3 ++- classes/class.ilObjMumieTaskGUI.php | 1 + js/ilMumieTaskForm.js | 19 ++++++++++++++++++- templates/problem_selector_sso_form.html | 1 + 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index d83da2c..926613d 100644 --- a/changelog.md +++ b/changelog.md @@ -16,6 +16,7 @@ All important changes to this plugin will be documented in this file. ### Fixed - Fixed a crash when saving LP settings for a worksheet with a deadline, caused by a malformed entry in the MUMIE grade sync response +- The multi-problem selector now uses SSO when the configured problem selector and the selected MUMIE server share the same origin, matching the single-problem selector's behavior ## [v5.0] - 2026-06-02 ### Changed diff --git a/classes/class.ilMumieTaskSSOService.php b/classes/class.ilMumieTaskSSOService.php index a8ee6f3..dddd39c 100644 --- a/classes/class.ilMumieTaskSSOService.php +++ b/classes/class.ilMumieTaskSSOService.php @@ -143,7 +143,7 @@ private function getHTMLCode($taskObj, $ssotoken, $hashed_user, $height = 600): */ private const LECTURER_SUFFIX = '@lecturer@'; - public function getProblemSelectorLaunchForm(string $serverUrl, string $problemLang, string $origin): string + public function getProblemSelectorLaunchForm(string $serverUrl, string $problemLang, string $origin, bool $multiSelect = false): string { global $DIC; $admin_settings = ilMumieTaskAdminSettings::getInstance(); @@ -159,6 +159,7 @@ public function getProblemSelectorLaunchForm(string $serverUrl, string $problemL $tpl->setVariable('SERVER_URL', htmlspecialchars($serverUrl)); $tpl->setVariable('PROBLEM_LANG', htmlspecialchars($problemLang)); $tpl->setVariable('ORIGIN', htmlspecialchars($origin)); + $tpl->setVariable('MULTI_SELECT', $multiSelect ? 'true' : 'false'); return $tpl->get(); } diff --git a/classes/class.ilObjMumieTaskGUI.php b/classes/class.ilObjMumieTaskGUI.php index 1531cdf..9b7f2b7 100644 --- a/classes/class.ilObjMumieTaskGUI.php +++ b/classes/class.ilObjMumieTaskGUI.php @@ -87,6 +87,7 @@ public function launchProblemSelector(): void (string) ($_GET['serverUrl'] ?? ''), (string) ($_GET['problemLang'] ?? ''), (string) ($_GET['origin'] ?? ''), + filter_var($_GET['multiSelect'] ?? false, FILTER_VALIDATE_BOOLEAN), ); exit; } diff --git a/js/ilMumieTaskForm.js b/js/ilMumieTaskForm.js index 68e0bfd..3e724bd 100644 --- a/js/ilMumieTaskForm.js +++ b/js/ilMumieTaskForm.js @@ -206,11 +206,28 @@ multiProblemSelectorButton.onclick = function(e) { e.preventDefault(); + const selectedServerUrl = serverController.getSelectedServer().url_prefix; + const problemLang = langController.getSelectedLanguage(); + const origin = window.location.origin; + + if (shouldUseSSO(selectedServerUrl)) { + problemSelectorWindow = window.open( + problemSelectorSsoUrl + + '&serverUrl=' + encodeURIComponent(selectedServerUrl) + + '&problemLang=' + problemLang + + '&origin=' + encodeURIComponent(origin) + + '&multiSelect=true' + , '_blank', + 'toolbar=0,location=0,menubar=0' + ); + return; + } + problemSelectorWindow = window.open( lmsSelectorUrl + '/lms-problem-selector?' + "serverUrl=" - + encodeURIComponent(serverController.getSelectedServer().url_prefix), + + encodeURIComponent(selectedServerUrl), "_blank", 'toolbar=0,location=0,menubar=0' ); diff --git a/templates/problem_selector_sso_form.html b/templates/problem_selector_sso_form.html index 35ffb8f..b5f1a8b 100644 --- a/templates/problem_selector_sso_form.html +++ b/templates/problem_selector_sso_form.html @@ -5,5 +5,6 @@ + From ae29c5b8d0f8ad5ce9a25653e0a33d79129c05c5 Mon Sep 17 00:00:00 2001 From: greiser Date: Mon, 27 Jul 2026 15:55:00 +0200 Subject: [PATCH 02/10] Receive multi-problem-selector array via postMessage instead of drag-and-drop The problem selector frontend dropped native HTML5 drag-and-drop in favor of a postMessage-only contract (commit d874826d in lemon-fruit), so the "Transfer to LMS" button's array payload never reached ILIAS: ilMumieTaskDropzone.js only listened for a native drop event, and the single postMessage listener in ilMumieTaskForm.js assumed one object. addMessageListener now branches on Array.isArray() and forwards a multi-select payload to the same field/list population logic the dropzone's drop handler already used, re-encoding each task back into the double-JSON-encoded string array ilMumieTaskMultiUploadProcessor expects server-side. The dropzone's own drag/drop handling is left in place as a fallback. --- js/ilMumieTaskDropzone.js | 9 ++++++++- js/ilMumieTaskForm.js | 10 ++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/js/ilMumieTaskDropzone.js b/js/ilMumieTaskDropzone.js index 3e8d245..34bd5f4 100644 --- a/js/ilMumieTaskDropzone.js +++ b/js/ilMumieTaskDropzone.js @@ -16,7 +16,10 @@ }) dropzone.ondrop = (event) => { dropzone.classList.remove(DRAG_OVER_CLASS); - const taskJsonString = event.dataTransfer.getData("mumie/jsonArray"); + applyTasksJson(event.dataTransfer.getData("mumie/jsonArray")); + } + + function applyTasksJson(taskJsonString) { multiProblemInputElem.setAttribute("value", taskJsonString); problemListController.setData(taskJsonString); } @@ -62,6 +65,10 @@ } } })(); + + window.ilMumieTaskDropzone = { + setData: applyTasksJson, + }; }) } )(jQuery) \ No newline at end of file diff --git a/js/ilMumieTaskForm.js b/js/ilMumieTaskForm.js index 3e724bd..f7789d6 100644 --- a/js/ilMumieTaskForm.js +++ b/js/ilMumieTaskForm.js @@ -142,6 +142,16 @@ return; } const importObj = JSON.parse(event.data); + if (Array.isArray(importObj)) { + try { + window.ilMumieTaskDropzone.setData(JSON.stringify(importObj.map(task => JSON.stringify(task)))); + sendSuccess(); + window.focus(); + } catch (error) { + sendFailure(error.message); + } + return; + } const worksheet = importObj.worksheet ?? null; try { langController.setLanguage(importObj.language); From a3e66173e71e8be548f9218c670bdf9a844beb3c Mon Sep 17 00:00:00 2001 From: greiser Date: Mon, 27 Jul 2026 15:57:24 +0200 Subject: [PATCH 03/10] Allow saving new MumieTask via multi-select without a single problem xmum_task stays empty when creating tasks through the multi-select dropzone, but checkInput() required it unconditionally for new (dummy) objects, blocking save even with a valid xmum_multi_problems payload. --- classes/forms/class.ilMumieTaskFormGUI.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/classes/forms/class.ilMumieTaskFormGUI.php b/classes/forms/class.ilMumieTaskFormGUI.php index 802713e..1799e20 100644 --- a/classes/forms/class.ilMumieTaskFormGUI.php +++ b/classes/forms/class.ilMumieTaskFormGUI.php @@ -154,11 +154,15 @@ public function checkInput(): bool return $ok; } + $multi_problems_input = $this->getInput('xmum_multi_problems'); + if (null == $task && $is_dummy) { - $ok = false; - $this->problem_display_item->setAlert($this->i18N->globalTxt('required_field')); + if (empty($multi_problems_input)) { + $ok = false; + $this->problem_display_item->setAlert($this->i18N->globalTxt('required_field')); - return $ok; + return $ok; + } } elseif (null == $task) { $ok = false; $this->problem_display_item->setAlert($this->i18N->txt('frm_tsk_problem_not_found')); @@ -166,7 +170,6 @@ public function checkInput(): bool return $ok; } - $multi_problems_input = $this->getInput('xmum_multi_problems'); if (!empty($multi_problems_input) && !ilMumieTaskMultiUploadProcessor::isValid($multi_problems_input)) { $ok = false; $this->dropzone_item->setAlert($this->i18N->txt('frm_tsk_problems_not_found')); From 0a0ec2a3319505bfc4cae79a7c95443c49135fed Mon Sep 17 00:00:00 2001 From: greiser Date: Mon, 27 Jul 2026 15:59:17 +0200 Subject: [PATCH 04/10] Hide the obsolete drag-and-drop placeholder and drop stale copy Multi-select import now runs entirely through postMessage from the problem selector popup, so native drag-and-drop into the dropzone box is no longer functional. Hide the whole box (the bordered .ui-input-file-input-dropzone wrapper, not just its inner text) and update the instructional/success copy that still described a manual drag step. --- lang/ilias_de.lang | 4 ++-- lang/ilias_en.lang | 4 ++-- templates/MumieTasks/tpl.file-drop-zone.html | 6 ++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 29bfc8d..db5b142 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -123,10 +123,10 @@ student_name#:#Name deadline_extension_desc#:#Hier können Sie Studierenden individuelle Fristverlängerungen gewähren. Falls Sie bereits manuell eine andere Bewertung ausgewählt haben, hat diese Fristverlängerung keine Auswirkung. frm_multi_problem_header#:#Zusätzliche MUMIE-Probleme erzeugen form_drag_mt_here#:#Ziehe Sie die MUMIE-Problems hierhinein -multi_create_success#:#Es wurden %s weitere MUMIE-Tasks über Drag&Drop erstellt! +multi_create_success#:#Es wurden %s weitere MUMIE-Tasks erstellt! mumie_problems#:#MUMIE-Problems open_dnd_prb_selector#:#Mehrfach-Aufgabenauswahl öffnen -dnd_prb_selector_desc#:#Hier klicken, um die Mehrfach-Aufgabenauswahl zu öffnen. Wählen sie einfach die Aufgaben aus, die Sie importieren möchten, und ziehen sie diese in das untere Feld. +dnd_prb_selector_desc#:#Hier klicken, um die Mehrfach-Aufgabenauswahl zu öffnen. Wählen Sie einfach die Aufgaben aus, die Sie importieren möchten. frm_tsk_problems_not_found#:#Ein oder mehrere Problems konnten nicht auf dem Server gefunden werden dropzone_description#:#Sobald Sie auf Speichern klicken, wird Ilias automatisch MUMIE-Tasks für die ausgewählten Aufgaben erstellen. Dabei werden die Einstellungen für Start-Container, online und Abgabefrist von der derzeit ausgewählten MUMIE-Task übernommen. multi_problem_list_description#:#Sie haben die folgenden MUMIE-Problems ausgewählt \ No newline at end of file diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index f788373..ad63df6 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -123,10 +123,10 @@ student_name#:#Name deadline_extension_desc#:#Here you can grant a deadline extension to the student. If you have already manually selected a grade for them, this setting will not have any effect. frm_multi_problem_header#:#Create additional MUMIE Problems form_drag_mt_here#:#Drag MUMIE Problems here -multi_create_success#:#Successfully created %s additional MUMIE Tasks via drag & drop! +multi_create_success#:#Successfully created %s additional MUMIE Tasks! mumie_problems#:#MUMIE Problems open_dnd_prb_selector#:#Open multi problem selector -dnd_prb_selector_desc#:#Clicking here will open the multi problem selection screen. Simply choose the problems you want to import and drag them in the field below.

+dnd_prb_selector_desc#:#Clicking here will open the multi problem selection screen. Simply choose the problems you want to import.

frm_tsk_problems_not_found#:#One or more problems could not be found. dropzone_description#:#Once you click Save, Ilias will automatically create new MUMIE-Tasks for the selected problems. The settings for Launch container, online and Deadline will be copied from this currently opened MUMIE Task. multi_problem_list_description#:#You have selected the following MUMIE Problems \ No newline at end of file diff --git a/templates/MumieTasks/tpl.file-drop-zone.html b/templates/MumieTasks/tpl.file-drop-zone.html index c21fd95..ee73b32 100644 --- a/templates/MumieTasks/tpl.file-drop-zone.html +++ b/templates/MumieTasks/tpl.file-drop-zone.html @@ -1,8 +1,6 @@
-
-
- {TXT_DRAG_PROBLEMS_HERE} -
+