Skip to content

fix(set_ode): make online SCORM package replacement idempotent#57

Merged
eXeLearningProject merged 2 commits intomainfrom
fix/issue-55-online-image-paths
Apr 30, 2026
Merged

fix(set_ode): make online SCORM package replacement idempotent#57
eXeLearningProject merged 2 commits intomainfrom
fix/issue-55-online-image-paths

Conversation

@erseco
Copy link
Copy Markdown
Collaborator

@erseco erseco commented Apr 29, 2026

Summary

Complements exelearning/exelearning#1740 (which fixes the visible 404 on content/resources/<uuid>.<ext> by generating the SCORM package in the browser). This PR fixes a separate Moodle-side robustness bug surfaced while investigating mod_exescorm#55: replacing a SCORM package via set_ode.php was not idempotent and could leave the activity broken if the operation failed mid-way.

Root cause

set_ode.php previously wiped the entire package filearea before writing the new file (delete_area_files(...'package')) and never updated timemodified. While that worked for the happy path, it left the activity in a half-broken state if anything between the deletion and exescorm_parse() failed: no package on disk, but the DB row still pointed at the (now missing) reference.

In addition, the lack of a timemodified update meant downstream code couldn't tell when the package was last refreshed via online save.

Changes

  • set_ode.php

    • Replace the wholesale delete_area_files() with a targeted delete of the files at itemid 0 so we only drop the entry that the new file would collide with, keeping the operation reversible if it bails out below.
    • Set $exescorm->timemodified = time() together with the new reference so the activity advances in lockstep with the file replacement.
    • Add inline comments documenting the constraint that a SCORM package always lives at itemid 0 and that exescorm_parse() reads from the package filearea using $exescorm->reference.
  • tests/online_save_test.php (new)

    • Integration test simulating two consecutive online saves on the same activity, verifying:
      • the package filearea ends with a single file,
      • that file is the freshly stored one,
      • the activity's reference column matches it.
    • Catches regressions where a second online save with a different filename leaves stale files behind in the area.

Relationship to mod_exescorm#55

The 404 on content/resources/<uuid>.<ext> reported in #55 is fixed on the eXeLearning side by exelearning/exelearning#1740 — the SCORM package is now generated in the browser (where the live Y.Doc and IndexedDB asset blobs are), and BaseExporter.addAssetsToZipWithResourcePath also writes each asset under its <assetId><ext> literal path so any stale URL still resolves.

This PR does not make that symptom go away on its own. It addresses a separate Moodle-side robustness issue: making the package-replacement step idempotent so a partial failure no longer leaves the activity pointing at a missing file, and so the package filearea always ends with exactly one entry matching the activity's reference.

Refs: mod_exescorm#55, exelearning/exelearning#1740

Test plan

  • PHPUnit (composer test / docker test target).
  • Manual: create a SCORM activity, edit via eXeLearning Online, save back twice with different package filenames, confirm only the latest one remains in the package filearea and the activity loads correctly.

Moodle Playground Preview

The changes in this pull request can be previewed and tested using a Moodle Playground instance.

Preview in Moodle Playground

⚠️ The embedded eXeLearning editor is not included in this preview. You can install it from Modules > eXeLearning SCORM > Configure using the "Download & Install Editor" button. All other module features (ELPX upload, viewer, preview) work normally.

set_ode.php now performs a targeted delete of the existing package at
itemid 0 before storing the new file (instead of wiping the whole
filearea), records timemodified together with the new reference, and
relies on exescorm_parse() to refresh content/version. This mirrors the
embedded editor save flow and prevents stale package files from being
left behind when an online save replaces an existing package.

Adds an integration test exercising the package replacement to guard
against regressions of the symptom described in #55.
@erseco erseco self-assigned this Apr 29, 2026
Copy link
Copy Markdown
Collaborator

@ignaciogros ignaciogros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue might be in eXeLearning:

  • Open eXeLearning online and add an image x.png.
  • Export as SCORM: the image is placed in content/resources/x.png and is correctly referenced in the HTML. Example: <img src="content/resources/x.png">.

But if instead of downloading you click on "Finish" to publish to Moodle, and download the generated content (the SCORM .zip file), you'll see that the content/resources folder does not exist, and the image is not correctly referenced in the HTML. Example: <img src="content/resources/f4c4e81d-c0a6-be4a-c26e-4082c34b08aa.png"> (instead of x.png).

@erseco
Copy link
Copy Markdown
Collaborator Author

erseco commented Apr 29, 2026

Follow-up: the actual root cause (broken images served by Moodle when content comes from the Finish to Moodle path) lives on the eXeLearning side and is fixed in:

The client now flushes pending assets to the server before triggering platformPetitionSet, and the server-side exporter writes each asset under both its resolved path and its <uuid><ext> fallback path so 404s like the one in this issue stop happening even if a stale reference slips through.

This Moodle-side PR (#57) keeps the package replacement idempotent during online saves, complementing that fix.

@erseco erseco changed the title Fix #55: Make online package replacement idempotent fix(set_ode): make online SCORM package replacement idempotent Apr 29, 2026
@eXeLearningProject eXeLearningProject merged commit da44000 into main Apr 30, 2026
1 check passed
@eXeLearningProject eXeLearningProject deleted the fix/issue-55-online-image-paths branch April 30, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants