This maintenance version introduces some minor improvements and a few relevant fixes, stabilizing code while preparing for the upcoming 4.2 release.
The following points are particularly relevant:
- Usage stats: fixed an issue blocking tracking of browsing actions with MySql databases (worked on mariadb)
- Average course time now allows decimals
- Course type editing: is not possible anymore to change the course type if users are already enrolled to the course. This and other conditions (subscriptions via API or import) led to some inconsistencies in previous versions, with "ghost" subscribed users on master courses converted from elearning to classroom or vice versa. Also, An automatic realignment algorithm ensures consistency between master course enrollments and classroom session enrollments by removing users enrolled only in the master course and adding those enrolled only in sessions. It operates on one or all classroom courses, respects overbooking rules, and safely handles repeated executions without side effects. It is also applied during upgrades to fix legacy inconsistencies.Check techincal details below.
Automatic realignment of classroom course enrollments
Context:
In classroom-type courses, enrollment in the "master" course and enrollment in individual sessions/dates are managed in two separate tables. Over time, due to misalignments caused by imports, APIs, migrations, or manual operations, inconsistent states could occur: users enrolled in the course but not in any session, or users enrolled in a session without being enrolled in the parent course.
A realignment algorithm has been introduced to automatically resolve both cases.
Where:
Method SubscriptionAlms::cleanupUsersNotEnrolledInClassroomDates($id_course = null) — formalms/html/appLms/admin/models/SubscriptionAlms.php
Reference commit: 34803f5747fc5dec00c19b6669b36f2ac7e2763e
Scope:
- If a course ID is provided, it operates only on that course.
- If invoked without parameters, it scans all classroom-type courses in the platform.
- E-learning courses and editions are not affected.
The method performs two realignment steps, one in each direction:
Cleanup of “ghost” enrollments from the master course
It identifies users present in the master course (learning_courseuser) who are not enrolled in any course session (learning_course_date_user). These users are unenrolled from the master course, restoring a consistent state.
Automatic enrollment in the master course
It identifies users enrolled in one or more sessions/dates (learning_course_date_user) who are not enrolled in the parent course (learning_courseuser). For each user:
- Retrieves the course levels; if missing, they are created.
- Assigns the user to the student level group.
- Creates the enrollment record in the master course, respecting the overbooking rules configured for the course.
Handled scenarios
| Case | Action |
|---|---|
| User enrolled in the master course but not in any session | Unenrollment from the master course |
| User enrolled in a session but not in the master course | Enrollment in the master course as student, creation of levels if missing |
Properties
- Idempotent operation: it can be executed multiple times without producing duplicates or side effects.
- Overbooking rules are respected, so automatic enrollment in the master course does not bypass configured limits.
- It is also invoked during upgrade procedures to fix legacy inconsistencies in migrating environments.




