ProfilePress Courses Developer Hooks: Actions and Filters
The ProfilePress course builder has WordPress actions and filters that let developers react to what students do and change how courses work, without editing the plugin. This article lists the hooks you’re most likely to need, with their arguments and a few examples.
It’s for developers. To change what course pages look like, also see overriding the course templates from a theme.
Before you start
- Put your code in a child theme’s
functions.phpfile or in a code snippets plugin, not in the ProfilePress plugin files. - Every hook name starts with
ppress_lms_. - Where a hook passes
$course, it’s aProfilePress\Core\LMS\Courseobject, and$lessonis aProfilePress\Core\LMS\Lessonobject. Both haveget_id(),get_title()andget_permalink(). A lesson’s course is$lesson->get_course(). - Where a hook passes
$course_id, it’s the course’s post ID. - Hooks fire on the site where the course is, so on multisite they work per site.
Student events (actions)
Use these to send data to another system, log activity or reward students.
| Action | Fires when | Arguments |
|---|---|---|
ppress_lms_user_enrolled |
A student is enrolled in a course for the first time. | $user_id, $course_id, $source (plan, manual or free) |
ppress_lms_user_reenrolled |
A student who is already enrolled is enrolled again, for example by buying a second plan that includes the course or by being enrolled by hand. A student who was removed and comes back fires ppress_lms_user_enrolled instead. |
$user_id, $course_id, $source |
ppress_lms_user_unenrolled |
A student is removed from a course. | $user_id, $course_id |
ppress_lms_lesson_completed |
A student completes a lesson or passes a quiz, the first time only. | $user_id, $lesson, $course |
ppress_lms_lesson_uncompleted |
A student marks a completed lesson as not complete. | $user_id, $lesson, $course |
ppress_lms_course_completed |
A student completes every lesson in a course. Fires once per student and course. | $user_id, $course |
ppress_lms_quiz_submitted |
A student submits a quiz. | $user_id, $lesson, $grade (array with score, correct, total, points, max_points and passed), $attempts (attempts used), $questions |
ppress_lms_certificate_issued |
A student’s certificate is created. | $user_id, $course, $code (the certificate’s verification code) |
ppress_lms_course_reviewed |
A student saves a course review. | $comment_id, $user_id, $course, $rating (1 to 5) |
ppress_lms_file_downloaded |
A student downloads a lesson file. | $user_id, $lesson, $attachment (the file’s details) |
ppress_lms_access_renewed |
A student’s access period restarts on a course with an access duration, for example after buying the course again. | $user_id, $course |
Access
| Filter | What it changes | Arguments |
|---|---|---|
ppress_lms_has_course_access |
Whether a user can take a course. Return true or false. |
$access, $user_id, $course |
ppress_lms_lesson_access |
Whether a user can open a lesson, and why not. The value is an array: access (true or false), reason (for example login, purchase, drip, sequential, prerequisite, expired or not_started) and available_at (a timestamp for drip locks). |
$result, $user_id, $lesson, $course |
ppress_lms_can_manage |
Whether a user can manage a course: edit it, see every lesson unlocked and grade it. | $can_manage, $user_id, $course_id |
ppress_lms_manage_capability |
The capability that makes a user a site-wide course manager. Default: manage_options. |
$capability |
ppress_lms_can_download_file |
Whether a user can download a lesson file. | $can_download, $user_id, $lesson, $attachment |
ppress_lms_access_expiry |
When a student’s access ends, on courses with an access duration. A timestamp. | $expires, $user_id, $course |
ppress_lms_missing_prerequisites |
The prerequisite courses a student still has to complete. An array of Course objects. |
$missing, $user_id, $course |
Access filters decide what students can see, so test them carefully. Returning true from ppress_lms_has_course_access for the wrong users gives away a paid course.
Course pages and lessons
| Hook | Type | What it does | Arguments |
|---|---|---|---|
ppress_lms_template |
Filter | The file used for a course template. | $template (path), $name (for example course or enroll-card) |
ppress_lms_certificate_template |
Filter | The file used for the certificate page. | $template (path) |
ppress_lms_course_cta |
Filter | The main button on the enroll card and course cards. An array with state, label, url, price, billing, plans and secondary (extra links). |
$cta, $user_id, $course |
ppress_lms_lock_message |
Filter | The message shown on a locked lesson. | $message, $access (the lesson access array), $course, $user_id |
ppress_lms_course_before_layout |
Action | Prints content at the top of the course page. | $course, $user_id |
ppress_lms_course_hero_meta |
Action | Prints items in the course page’s header, after the lesson count and duration. | $course, $user_id |
ppress_lms_course_after_content |
Action | Prints content below the course content, where reviews show. | $course, $user_id |
ppress_lms_enroll_card_notes |
Action | Prints notes on the enroll card, under its button and links. | $course, $user_id, $cta |
ppress_lms_course_card_meta |
Action | Prints details on course cards in the catalog, My Courses and bundle pages. | $course, $user_id |
ppress_lms_lesson_body_after_content |
Action | Prints content after a lesson’s content. | $lesson, $user_id |
ppress_lms_show_complete_button |
Filter | Whether a lesson shows the Mark as complete button. | $show, $lesson, $user_id |
ppress_lms_video_embed |
Filter | The HTML that embeds a lesson’s video. | $html, $url |
ppress_lms_accent_color |
Filter | The accent color, as a hex value. | $color |
ppress_lms_focus_mode_enabled |
Filter | Whether lessons open in focus mode. | $enabled |
ppress_lms_comment_author_name |
Filter | The name shown on a review or Q&A post. | $name, $comment, $user |
Course catalog
| Filter | What it changes | Arguments |
|---|---|---|
ppress_lms_catalog_query_args |
The WP_Query arguments for the catalog, the course archive and the Course Catalog block. |
$args, $atts (shortcode or block settings), $filters (the visitor’s search, category, level, sort and page) |
ppress_lms_catalog_sort_options |
The choices in the catalog’s sort menu, as key => label. |
$options |
ppress_lms_archive_shows_catalog |
Return false to let your theme render the /courses/ archive and course category pages instead of the catalog. |
$show |
ppress_lms_archive_catalog_atts |
The settings of the catalog on the course archive, such as limit and columns. |
$atts |
ppress_lms_course_levels |
The course levels you can choose in the builder, as key => label. |
$levels |
Emails and certificates
| Filter | What it changes | Arguments |
|---|---|---|
ppress_lms_send_course_email |
Whether a course email is sent. Return false to skip it. $key is lms_course_enrolled, lms_lesson_unlocked, lms_course_completed or lms_inactivity_reminder. |
$send, $key, $user_id, $course |
ppress_lms_email_placeholder_values |
The values of course email placeholders. Each entry is '{{name}}' => [value, is_url]; set is_url to true for links. Add an entry to create your own placeholder. |
$values, $user_id, $course |
ppress_lms_certificate_placeholders |
The certificate text placeholders, as '{name}' => value. Add an entry to create your own. |
$placeholders, $user_id, $course |
Reviews and Q&A
| Filter | What it changes | Arguments |
|---|---|---|
ppress_lms_review_auto_approve |
Whether a review is published straight away. Return false to hold every review for moderation. |
$approve, $user_id, $course |
ppress_lms_can_review_course |
Whether a user can review a course. By default, enrolled students can. | $can_review, $user_id, $course |
ppress_lms_qa_notification_recipients |
The email addresses notified about a new lesson question or answer. | $recipients, $comment, $course |
Course builder and admin screens
| Hook | Type | What it does | Arguments |
|---|---|---|---|
ppress_lms_course_saved |
Action | Fires after a course is saved in the builder. $data is the submitted course data, so you can save your own fields. |
$course_id, $data |
ppress_lms_lesson_saved |
Action | Fires after a lesson is saved in the builder. | $lesson_id, $data |
ppress_lms_builder_learning_experience |
Action | Prints fields in the builder’s Learning experience card. | $course |
ppress_lms_builder_access_rules |
Action | Prints fields in the builder’s Access rules card. | $course |
ppress_lms_builder_topbar_actions |
Action | Prints buttons or menu items in the builder’s top bar. | $course |
ppress_lms_course_row_actions |
Filter | The links under each course in the course list. | $actions, $course |
ppress_lms_admin_tabs |
Filter | The tabs at the top of ProfilePress » Courses. | $tabs |
ppress_lms_export_course_meta_keys |
Filter | The course meta keys included when a course is exported. Add your own fields’ keys so they’re exported too. | $keys |
Examples
Send course completions to another system
add_action('ppress_lms_course_completed', function ($user_id, $course) {
$user = get_userdata($user_id);
wp_remote_post('https://example.com/webhook', [
'body' => [
'email' => $user->user_email,
'course' => $course->get_title(),
],
]);
}, 10, 2);
For simple cases, the Advanced Courses addon’s completion actions can send a webhook without code. See Course completion actions.
Hold every review for moderation
add_filter('ppress_lms_review_auto_approve', '__return_false');
Add a “Title (Z–A)” sort to the catalog
add_filter('ppress_lms_catalog_sort_options', function ($options) {
$options['title_desc'] = 'Title (Z–A)';
return $options;
});
add_filter('ppress_lms_catalog_query_args', function ($args, $atts, $filters) {
if ($filters['sort'] === 'title_desc') {
$args['orderby'] = 'title';
$args['order'] = 'DESC';
}
return $args;
}, 10, 3);
Add a {student_email} placeholder to certificates
add_filter('ppress_lms_certificate_placeholders', function ($placeholders, $user_id) {
$user = get_userdata($user_id);
$placeholders['{student_email}'] = $user ? $user->user_email : '';
return $placeholders;
}, 10, 2);
Don’t send the inactivity reminder for one course
add_filter('ppress_lms_send_course_email', function ($send, $key, $user_id, $course) {
if ($key === 'lms_inactivity_reminder' && $course->get_id() === 123) {
return false;
}
return $send;
}, 10, 4);
Frequently asked questions
Is this every course hook?
No. The course builder has more hooks, mostly used by its own modules and the Advanced Courses addon, such as hooks to add lesson types or quiz question types. The ones above are the stable, commonly needed ones. To find others, search the plugin’s src/LMS folder for ppress_lms_.
My hook doesn’t run. Why?
Check that courses aren’t turned off under ProfilePress » Settings » Courses, since most course hooks don’t fire then. Also check that you passed the right number of arguments to add_action or add_filter: the fourth parameter must be at least the number of arguments your function uses.