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.php file 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 a ProfilePress\Core\LMS\Course object, and $lesson is a ProfilePress\Core\LMS\Lesson object. Both have get_id(), get_title() and get_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.

Related articles

Create Paid Membership Websites in Minutes

Install ProfilePress today and get a modern and powerful WordPress membership & ecommerce website – the easy way!