Problem/Motivation

In many courses, having lesson access set as “free” or “linear” works perfectly and it’s exactly what you want for pre-built or fully automatic training paths.

But in hybrid courses, teachers often prefer to unlock lessons gradually, depending on the student’s progress, the date, or other criteria. To make this possible, the idea was to add an EventDispatcher that lets us check lesson access before it’s granted.

I’m also working on a contrib module in the ecosystem to provide a UI for teachers (so they can check or uncheck which lessons are accessible), but that’s another story.

Steps to reproduce

Proposed resolution

This patch introduces an event-driven mechanism to extend lesson access without touching the core LMS logic. A new LessonAccessEvent is dispatched in TrainingManager::getRequestedLessonStatus() and getNextLessonStatus() right before access to a lesson is granted.

Custom or contrib modules can subscribe to this event and decide whether a lesson should remain locked. When blocking access, subscribers can call $event->denyAccess($message, $redirectUrl), which allows returning a custom message and optionally redirecting the learner elsewhere.

To keep things organized, all event names are centralized in a new LmsEvents class. The TrainingException class has also been extended with a CUSTOM_ACCESS_DENIED constant, and now supports custom messages and redirect URLs for denied access.

The change is fully backwards-compatible, if no module subscribes to the event, everything behaves as before. The LMS default access logic continues to work unchanged.

This opens the door to common scenarios such as:
• Progressive lesson unlocking for specific groups or classes
• Time-based access restrictions
• Prerequisite validation before moving forward

Remaining tasks

Code review and test

User interface changes

RAS

API changes

New event system:
- Added LmsEvents class with LESSON_ACCESS and QA_CONTENT constants
- Added LessonAccessEvent dispatched in TrainingManager::getRequestedLessonStatus() and getNextLessonStatus()
- Event allows subscribers to deny access via $event->denyAccess($message, $redirectUrl)

TrainingException changes:
- Added CUSTOM_ACCESS_DENIED constant (value: 13)
- Constructor now accepts optional $customMessage and $redirectUrl parameters
- Added getCustomMessage() and getRedirectUrl() methods

Data model changes

RAS

CommentFileSizeAuthor
lms-lesson-access-event.patch7.39 KBalumni

Issue fork lms-3550125

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

alumni created an issue. See original summary.

graber’s picture

Status: Needs review » Needs work

Left some comments on the MR.

graber’s picture

Title: Access event Lesson » Add API for other modules to control lesson access
graber’s picture

Status: Needs work » Needs review

graber’s picture

Assigned: alumni » Unassigned
Status: Needs review » Fixed

We've got it, thanks :)

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.