// 1. Override Passing Threshold dynamically
add_filter('learndash_quiz_passing_percentage', 'ppunch_dynamic_quiz_passing_percentage', 10, 2);
function ppunch_dynamic_quiz_passing_percentage($passing_percentage, $quiz_post) {
if (is_admin() || !is_user_logged_in()) {
return $passing_percentage;
}
$user_id = get_current_user_id();
// Apply a stricter passing percentage (85%) if the student is in a premium group
if (learndash_is_user_in_group($user_id, 123)) {
return 85;
}
return $passing_percentage;
}
Explanation:
Overrides simple/variable product catalog prices and adjusts cart item totals dynamically before final checkout calculations.
learndash quiz passing score
dynamic passing grade
custom lms grading
// 1. Hide the Start Quiz Button based on historical attempt limits
add_filter('learndash_show_quiz_take_button', 'ppunch_restrict_quiz_access_attempts', 10, 3);
function ppunch_restrict_quiz_access_attempts($show_button, $user_id, $quiz_id) {
if (is_admin()) {
return $show_button;
}
// Fetch historical attempts from user meta
$attempts = get_user_meta($user_id, '_sfwd-quizzes', true);
$count = 0;
if (is_array($attempts)) {
foreach ($attempts as $attempt) {
if ($attempt['quiz'] == $quiz_id) {
$count++;
}
}
}
// Block if the user has reached 3 attempts
if ($count >= 3) {
return false;
}
return $show_button;
}
Explanation:
Blocks the quiz button from rendering if attempts logged under user meta exceed limits.
restrict learndash quiz
limit quiz attempts
conditional lms access
// 1. Fire Webhook Sync on Quiz Completion
add_action('learndash_quiz_completed', 'ppunch_sync_quiz_telemetry_webhook', 10, 2);
function ppunch_sync_quiz_telemetry_webhook($quiz_data, $user) {
$user_id = $user->ID;
$quiz_id = $quiz_data['quiz'];
$attempt_time = $quiz_data['time'];
// Guard: Prevent duplicate syncs for this specific attempt timestamp
$sent_key = "_ppunch_webhook_sent_{$quiz_id}_{$attempt_time}";
if (get_user_meta($user_id, $sent_key, true)) {
return;
}
update_user_meta($user_id, $sent_key, 'yes');
$webhook_url = 'https://api.yourcrm.com/v1/scores';
$payload = [
'user_id' => $user_id,
'quiz_id' => $quiz_id,
'percentage' => $quiz_data['percentage'],
'score' => $quiz_data['score'],
'points' => $quiz_data['points'],
];
wp_remote_post($webhook_url, [
'method' => 'POST',
'blocking' => false, // Non-blocking: Keeps LMS page load instant
'body' => json_encode($payload),
'headers' => [
'Content-Type' => 'application/json',
],
'timeout' => 3,
]);
}
Explanation:
Sends a background, non-blocking HTTP request upon quiz completion, flagged to prevent duplicate execution.
sync learndash quiz score
non blocking crm integration
quiz completed webhook
// 1. Inject custom columns and data to the user profile table
add_filter('learndash_profile_quiz_columns', 'ppunch_add_profile_quiz_time_spent_column', 10, 2);
function ppunch_add_profile_quiz_time_spent_column($columns, $quiz_attempt) {
$time = isset($quiz_attempt['time_spent']) ? intval($quiz_attempt['time_spent']) : 0;
$time_label = 'N/A';
if ($time > 0) {
$minutes = floor($time / 60);
$seconds = $time % 60;
$time_label = "{$minutes}m {$seconds}s";
}
$columns['time_spent'] = [
'id' => 'time_spent',
'label' => 'Time Spent',
'content' => $time_label,
'class' => 'ld-column-time-spent',
];
return $columns;
}
Explanation:
Appends custom columns and inserts computed telemetry values (such as duration spent) directly into the profile quiz array.
custom learndash profile columns
quiz history details
lms table fields
// 1. Override Post-Quiz Redirect Target
add_filter('learndash_quiz_redirect', 'ppunch_conditional_quiz_redirect', 10, 2);
function ppunch_conditional_quiz_redirect($redirect_url, $quiz_data) {
if (is_admin()) {
return $redirect_url;
}
$has_passed = isset($quiz_data['has_passed']) && $quiz_data['has_passed'] == 1;
// If they failed, send them to a dedicated review page
if (!$has_passed) {
return site_url('/remedial-review-module/');
}
// If they passed, advance them directly to the next course
return site_url('/course/advanced-curriculum/');
}
Explanation:
Inspects the passing status on submission and updates the target redirection URL.
learndash redirect after quiz
conditional lms routing
post quiz navigation