Skip to content

fix(notifications): add unenrollment notification trigger#3185

Open
faisalahammad wants to merge 1 commit into
gocodebox:devfrom
faisalahammad:fix/3141-unenrollment-notification
Open

fix(notifications): add unenrollment notification trigger#3185
faisalahammad wants to merge 1 commit into
gocodebox:devfrom
faisalahammad:fix/3141-unenrollment-notification

Conversation

@faisalahammad

@faisalahammad faisalahammad commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a new unenrollment notification trigger that fires when a student is removed from a course or membership. Supports both popup (basic) and email delivery, with all subscribers disabled by default so existing sites are not opted in.

Fixes #3141

Changes

includes/notifications/controllers/class.llms.notification.controller.unenrollment.php (new)

Before: no controller existed for the unenrollment event.

After:

class LLMS_Notification_Controller_Unenrollment extends LLMS_Abstract_Notification_Controller {
    public $id = 'unenrollment';
    protected $action_accepted_args = 4;
    protected $action_hooks = array(
        'llms_user_removed_from_course',
        'llms_user_removed_from_membership',
    );
    // action_callback() captures user_id + post_id and dispatches the notification.
    // get_subscriber() resolves 'author' (course/membership author) and 'student' (the unenrolled user).
    // set_subscriber_options() returns 'no' defaults for all subscribers.
}

Why: mirrors the existing enrollment controller pattern so admins configure one notification for both post types. Uses llms_user_removed_from_membership rather than the _level form (the _level hook was removed in 6.0.0). Accepts 4 args because the unenrollment action passes $user_id, $post_id, $trigger, $new_status.

includes/notifications/views/class.llms.notification.view.unenrollment.php (new)

Before: no view existed for the unenrollment event.

After:

class LLMS_Notification_View_Unenrollment extends LLMS_Abstract_Notification_View {
    public $trigger_id = 'unenrollment';
    protected $basic_options = array( 'auto_dismiss' => 10000, 'dismissible' => true );
    // Merge codes: {{TITLE}}, {{TYPE}}, {{STUDENT_NAME}}
    // Icon: negative variant.
    // Body: "{{STUDENT_NAME}} has been unenrolled from {{TITLE}}."
    // Subject: "{{STUDENT_NAME}} unenrolled from {{TITLE}}"
    // Title: "{{TYPE}} unenrollment"
}

Why: same merge-code and formatting conventions as the enrollment view. Negative icon visually signals removal. The popup auto-dismisses and is manually dismissible like the rest of the basic notifications.

includes/notifications/class.llms.notifications.php

Before: $triggers array ended with subscription_cancelled followed by upcoming_payment_reminder.

After: 'unenrollment' inserted between them to keep alphabetical order.

Why: the loader pulls the controller and view from their conventional paths once the trigger is registered, so no other registration is needed.

.changelogs/issue-3141.yml (new)

significance: minor
type: added
entry: "Added unenrollment notification trigger (popup and email) for courses and memberships, disabled by default."

Why: the project's changelog tooling only picks up files ending in .yml; this matches the contribution workflow.

Testing

Test 1: registration

  1. WP Admin → LifterLMS → Settings → Notifications.
  2. Confirm a new "Unenrollment" row appears.

Result: Works as expected.

Test 2: defaults disabled

  1. Open the Unenrollment notification.
  2. Confirm Student, Author, and Custom Email subscribers are all unchecked.

Result: Works as expected.

Test 3: course unenrollment

  1. Enable Student (basic) and Student (email).
  2. Enroll a test student in a course, then unenroll them from the Students tab.
  3. Log in as the student and load a LifterLMS page.

Result: popup appears with the course title and the negative icon; the student receives the email.

Test 4: membership unenrollment

  1. Repeat Test 3 with a membership.

Result: same popup and email behavior, with {{TYPE}} resolving to "Membership".

Test 5: silent on hard delete

  1. Programmatically call llms_delete_student_enrollment() which fires the llms_user_enrollment_deleted hook (not the unenrollment hook).

Result: no notification is sent.

Adds a new 'unenrollment' notification that fires when a student is removed
from a course or membership. Supports popup (basic) and email delivery, with
all subscribers disabled by default per the feature request.

- New controller listens to llms_user_removed_from_course and
  llms_user_removed_from_membership (the post 6.0.0 hooks).
- New view defines {{TITLE}}, {{TYPE}}, and {{STUDENT_NAME}} merge codes
  with a negative icon variant.
- Register 'unenrollment' trigger in LLMS_Notifications::load().
- All subscribers default to 'no' so existing sites are not opted in.

Fixes gocodebox#3141
@faisalahammad faisalahammad requested a review from brianhogg as a code owner June 15, 2026 20:38
@brianhogg brianhogg moved this to Awaiting Review in Development Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Awaiting Review

Development

Successfully merging this pull request may close these issues.

2 participants