Home / Disable / WPForms Quiz — Save results as Entry Note
Duplicate Snippet

Embed Snippet on Your Site

WPForms Quiz — Save results as Entry Note

This PHP snippet lets you save quiz results in Entry Notes

Ralden Souza PRO
<10
Code Preview
php
<?php
/**
 * WPForms Quiz — Save results as Entry Note
 *
 * Automatically adds a note to each quiz entry with the quiz results.
 * Supports all three quiz types: Graded, Personality, and Weighted.
 *
 * @link https://wpforms.com/developers/wpforms_process_entry_save/
 */
/**
 * Build note content for Graded quizzes.
 *
 * Calculates score from field quiz_result (correct/incorrect) and resolves
 * the grade letter from the form's grading scale.
 *
 * @param array $fields    Entry fields.
 * @param array $form_data Form data.
 *
 * @return string
 */
function wpforms_quiz_note_graded( array $fields, array $form_data ): string {
    $correct   = 0;
    $incorrect = 0;
    $total     = 0;
    foreach ( $fields as $field ) {
        if ( empty( $field['quiz_result'] ) || ! is_string( $field['quiz_result'] ) ) {
            continue;
        }
        $total++;
        if ( $field['quiz_result'] === 'correct' ) {
            $correct++;
        } else {
            $incorrect++;
        }
    }
    $percentage  = $total > 0 ? (int) round( ( $correct / $total ) * 100 ) : 0;
    $grade       = 'N/A';
    $grade_scale = $form_data['settings']['quiz']['grades'] ?? [];
    foreach ( $grade_scale as $row ) {
        if ( $percentage >= (int) $row['min'] && $percentage <= (int) $row['max'] ) {
            $grade = $row['grade'];
            break;
        }
    }
    return wpautop( sprintf(
        "Quiz Results (Graded)\n" .
        "Score: %d%% — Grade: %s\n" .
        "Correct: %d / %d — Incorrect: %d",
        $percentage,
        $grade,
        $correct,
        $total,
        $incorrect
    ) );
}
/**
 * Build note content for Personality quizzes.
 *
 * Reads the winning personality type from entry_meta (already saved at this
 * hook's priority). Also tallies votes per personality from field quiz_result
 * to show a breakdown.
 *
 * @param array $fields    Entry fields.
 * @param array $form_data Form data.
 * @param int   $entry_id  Entry ID.
 *
 * @return string
 */
function wpforms_quiz_note_personality( array $fields, array $form_data, int $entry_id ): string {
    $meta             = wpforms()->obj( 'entry_meta' )->get_meta( [
        'entry_id' => $entry_id,
        'type'     => 'quiz_outcome',
    ] );
    $personality_type = isset( $meta[0]->data ) ? sanitize_text_field( $meta[0]->data ) : 'N/A';
    // Count votes per personality from field quiz_result.
    // Structure: quiz_result = [ 0 => [ 0 => personality_index ] ] (0-based).
    $personalities = $form_data['settings']['quiz']['personalities'] ?? [];
    $vote_counts   = [];
    foreach ( $fields as $field ) {
        if ( empty( $field['quiz_result'] ) || ! is_array( $field['quiz_result'] ) ) {
            continue;
        }
        $personality_index = $field['quiz_result'][0][0] ?? null;
        if ( $personality_index === null ) {
            continue;
        }
        $label = $personalities[ $personality_index ] ?? 'Personality ' . ( $personality_index + 1 );
        $vote_counts[ $label ] = ( $vote_counts[ $label ] ?? 0 ) + 1;
    }
    $breakdown = '';
    if ( ! empty( $vote_counts ) ) {
        arsort( $vote_counts );
        $parts = [];
        foreach ( $vote_counts as $label => $count ) {
            $parts[] = $label . ': ' . $count;
        }
        $breakdown = "\nBreakdown: " . implode( ' — ', $parts );
    }
    return wpautop( sprintf(
        "Quiz Results (Personality)\n" .
        "Result: %s%s",
        $personality_type,
        $breakdown
    ) );
}
/**
 * Build note content for Weighted quizzes.
 *
 * Reads the total weight percentage from entry_meta. Also calculates the raw
 * total weight and maximum possible weight from field quiz_result values.
 *
 * @param array $fields    Entry fields.
 * @param array $form_data Form data.
 * @param int   $entry_id  Entry ID.
 *
 * @return string
 */
function wpforms_quiz_note_weighted( array $fields, array $form_data, int $entry_id ): string {
    $meta       = wpforms()->obj( 'entry_meta' )->get_meta( [
        'entry_id' => $entry_id,
        'type'     => 'quiz_outcome',
    ] );
    $percentage = isset( $meta[0]->data ) ? (float) $meta[0]->data : 0.0;
    // Calculate total weight and max possible weight from field quiz_result.
    // Structure: quiz_result = [ 0 => chosen_weight ] (numeric weight of chosen option).
    $total_weight   = 0;
    $max_weight     = 0;
    $question_count = 0;
    foreach ( $fields as $field ) {
        if ( empty( $field['quiz_result'] ) || ! is_array( $field['quiz_result'] ) ) {
            continue;
        }
        $chosen_weight  = (int) ( $field['quiz_result'][0] ?? 0 );
        $total_weight  += $chosen_weight;
        $question_count++;
        $field_id      = $field['id'] ?? null;
        $field_choices = $field_id !== null ? ( $form_data['fields'][ $field_id ]['choices'] ?? [] ) : [];
        $field_max     = 0;
        foreach ( $field_choices as $choice ) {
            $weight    = isset( $choice['value'] ) ? (int) $choice['value'] : 0;
            $field_max = max( $field_max, $weight );
        }
        $max_weight += $field_max;
    }
    $max_display = $max_weight > 0 ? ' / ' . $max_weight : '';
    return wpautop( sprintf(
        "Quiz Results (Weighted)\n" .
        "Score: %.2f%%\n" .
        "Total Weight: %d%s — Questions: %d",
        $percentage,
        $total_weight,
        $max_display,
        $question_count
    ) );
}
/**
 * Save quiz results as an entry note when a quiz form is submitted.
 *
 * Runs on all WPForms quiz forms (Graded, Personality, Weighted).
 * To restrict to a specific form, replace 0 with the form ID.
 *
 * @param array $fields    Sanitized entry field values/properties.
 * @param array $entry     Original $_POST global.
 * @param array $form_data Processed form settings/data.
 * @param int   $entry_id  Saved entry ID.
 * @param int   $payment_id Payment ID (0 if none).
 */
function wpforms_quiz_save_results_as_note( $fields, $entry, $form_data, $entry_id, $payment_id ) {
    $target_form_id = 0; // Set to a specific form ID to restrict, or 0 for all quiz forms.
    if ( $target_form_id !== 0 && ( empty( $form_data['id'] ) || (int) $form_data['id'] !== $target_form_id ) ) {
        return;
    }
    if ( empty( $form_data['settings']['quiz']['enabled'] ) || $form_data['settings']['quiz']['enabled'] !== '1' ) {
        return;
    }
    $entry_id  = (int) $entry_id;
    $quiz_type = $form_data['settings']['quiz']['type'] ?? '';
    if ( ! $entry_id || ! $quiz_type ) {
        return;
    }
    // Resolve a valid user_id — WPForms' note display requires a real WordPress user.
    $user_id = get_current_user_id();
    if ( ! $user_id ) {
        $admins  = get_users( [ 'role' => 'administrator', 'number' => 1, 'fields' => 'ID' ] );
        $user_id = ! empty( $admins ) ? (int) $admins[0] : 1;
    }
    if ( $quiz_type === 'graded' ) {
        $note_content = wpforms_quiz_note_graded( $fields, $form_data );
    } elseif ( $quiz_type === 'personality' ) {
        $note_content = wpforms_quiz_note_personality( $fields, $form_data, $entry_id );
    } elseif ( $quiz_type === 'weighted' ) {
        $note_content = wpforms_quiz_note_weighted( $fields, $form_data, $entry_id );
    } else {
        return;
    }
    $entry_meta = wpforms()->obj( 'entry_meta' );
    if ( ! $entry_meta || ! $note_content ) {
        return;
    }
    $entry_meta->add(
        [
            'entry_id' => $entry_id,
            'form_id'  => (int) $form_data['id'],
            'user_id'  => $user_id,
            'type'     => 'note',
            'data'     => $note_content,
        ],
        'entry_meta'
    );
}
add_action( 'wpforms_process_entry_saved', 'wpforms_quiz_save_results_as_note', 20, 5 );

Comments

Add a Comment