- Resolved fatal errors during plugin activation related to Composer autoloading, procedural function loading ('\die' vs 'die'), and 'dbDelta' SQL formatting.
- Defined and documented required post meta fields in 'memory-bank/project-knowledge/meta-fields.md'.
- Implemented logic for custom columns in 'AdminListTables.php' using defined meta keys.
- Made assessment title dynamic in 'assessment-shell.php'.
- Implemented check for pre-screening status in 'FrontendHandler.php'.
- Replaced placeholder or future implementation TODOs with descriptive notes in core plugin file, settings page, AJAX handler, frontend handler, credits, and payments files.
190 lines
No EOL
8.9 KiB
PHP
190 lines
No EOL
8.9 KiB
PHP
<?php
|
|
/**
|
|
* Template for displaying the assessment interface (pre-screening or main assessment).
|
|
*
|
|
* This template is loaded directly by FrontendHandler::handle_assessment_invite()
|
|
* when a valid invitation token is detected.
|
|
*
|
|
* Available Query Vars:
|
|
* - quiztech_invitation_data: (object) The validated invitation data row from the DB.
|
|
* - quiztech_current_step: (string) 'pre_screening' or 'assessment'.
|
|
* - quiztech_pre_screening_questions: (mixed) The pre-screening questions data (if any).
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
// Retrieve data passed from the handler
|
|
$invitation_data = get_query_var( 'quiztech_invitation_data' );
|
|
$current_step = get_query_var( 'quiztech_current_step' );
|
|
$pre_screening_questions = get_query_var( 'quiztech_pre_screening_questions' );
|
|
|
|
// Basic security check - ensure we have invitation data
|
|
if ( ! $invitation_data || ! $current_step ) {
|
|
// Should not happen if loaded correctly by the handler, but good practice.
|
|
wp_die( esc_html__( 'Could not load assessment data.', 'quiztech' ) );
|
|
}
|
|
|
|
// Minimal HTML structure
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html <?php language_attributes(); ?>>
|
|
<head>
|
|
<meta charset="<?php bloginfo( 'charset' ); ?>">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title><?php echo esc_html( get_the_title( $invitation_data->assessment_id ) ?: __( 'Assessment', 'quiztech' ) ); ?></title>
|
|
<?php // wp_head(); // Consider if theme/WP styles are needed or if it should be isolated ?>
|
|
<style>
|
|
/* Basic styling for isolation */
|
|
body { font-family: sans-serif; padding: 20px; background-color: #f9f9f9; }
|
|
.assessment-container { background-color: #fff; padding: 30px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); max-width: 800px; margin: 20px auto; }
|
|
h1, h2 { color: #333; }
|
|
.error { color: red; font-weight: bold; }
|
|
.step-info { margin-bottom: 20px; padding: 10px; background-color: #eef; border-left: 3px solid #aab; }
|
|
.form-group { margin-bottom: 15px; }
|
|
.form-group label { display: block; margin-bottom: 5px; font-weight: bold; }
|
|
.form-group textarea { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 3px; min-height: 80px; }
|
|
button[type="submit"] { padding: 10px 20px; background-color: #0073aa; color: #fff; border: none; border-radius: 3px; cursor: pointer; }
|
|
button[type="submit"]:hover { background-color: #005a87; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="assessment-container">
|
|
|
|
<h1><?php esc_html_e( 'Assessment Invitation', 'quiztech' ); ?></h1>
|
|
|
|
<?php if ( 'pre_screening' === $current_step ) : ?>
|
|
<div id="quiztech-prescreening-section"> <?php // Added ID for JS targeting ?>
|
|
<div class="step-info">
|
|
<h2><?php esc_html_e( 'Step 1: Pre-Screening Questions', 'quiztech' ); ?></h2>
|
|
<p><?php esc_html_e( 'Please answer the following questions before starting the assessment.', 'quiztech' ); ?></p>
|
|
</div>
|
|
|
|
<form id="quiztech-prescreening-form" method="post" action=""> <?php // Action handled by AJAX ?>
|
|
<?php // Nonce is checked via AJAX, but good to have in form too for non-JS fallback (if implemented) ?>
|
|
<?php // wp_nonce_field( 'quiztech_submit_prescreening_' . $invitation_data->token, 'quiztech_prescreening_nonce' ); ?>
|
|
<?php // Token is passed via localized script vars ?>
|
|
<?php // <input type="hidden" name="quiztech_invitation_token" value="<?php echo esc_attr( $invitation_data->token ); ?>"> ?>
|
|
<input type="hidden" name="action" value="quiztech_submit_prescreening">
|
|
|
|
<?php if ( is_array( $pre_screening_questions ) && ! empty( $pre_screening_questions ) ) : ?>
|
|
<?php foreach ( $pre_screening_questions as $index => $question ) : ?>
|
|
<div class="form-group">
|
|
<label for="pre_screen_answer_<?php echo esc_attr( $index ); ?>">
|
|
<?php echo esc_html( $question ); ?>
|
|
</label>
|
|
<textarea
|
|
id="pre_screen_answer_<?php echo esc_attr( $index ); ?>"
|
|
name="pre_screen_answer[<?php echo esc_attr( $index ); ?>]"
|
|
required
|
|
></textarea>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php else : ?>
|
|
<p><?php esc_html_e( 'No pre-screening questions found, but expected.', 'quiztech' ); ?></p>
|
|
<?php // Optionally show the debug info if needed
|
|
// echo '<pre>Pre-screening Data: ' . esc_html( print_r( $pre_screening_questions, true ) ) . '</pre>';
|
|
?>
|
|
<?php endif; ?>
|
|
|
|
<?php // Render questions here - Removed, handled above ?>
|
|
<button type="submit"><?php esc_html_e( 'Submit Pre-Screening & Start Assessment', 'quiztech' ); ?></button>
|
|
</form>
|
|
</div> <!-- #quiztech-prescreening-section -->
|
|
|
|
<?php elseif ( 'assessment' === $current_step ) : ?>
|
|
<div id="quiztech-assessment-section" style="display: none;"> <?php // Added ID and initially hidden ?>
|
|
<div class="step-info">
|
|
<h2><?php esc_html_e( 'Step 2: Assessment', 'quiztech' ); ?></h2>
|
|
<p><?php printf( esc_html__( 'You are about to begin Assessment ID: %d', 'quiztech' ), absint( $invitation_data->assessment_id ) ); ?></p>
|
|
</div>
|
|
|
|
<?php
|
|
$assessment_id = $invitation_data->assessment_id;
|
|
// Fetch question IDs associated with the assessment (assuming stored in 'question_ids' meta field)
|
|
$question_ids = get_post_meta( $assessment_id, 'question_ids', true );
|
|
|
|
if ( is_array( $question_ids ) && ! empty( $question_ids ) ) :
|
|
?>
|
|
<form id="quiztech-assessment-form" method="post" action=""> <?php // Action handled by AJAX ?>
|
|
<?php wp_nonce_field( 'quiztech_submit_assessment_' . $invitation_data->token, 'quiztech_assessment_nonce' ); ?>
|
|
<input type="hidden" name="quiztech_invitation_token" value="<?php echo esc_attr( $invitation_data->token ); ?>">
|
|
<input type="hidden" name="quiztech_assessment_id" value="<?php echo esc_attr( $assessment_id ); ?>">
|
|
<input type="hidden" name="action" value="quiztech_submit_assessment">
|
|
|
|
<h4><?php esc_html_e( 'Questions:', 'quiztech' ); ?></h4>
|
|
|
|
<?php foreach ( $question_ids as $question_id ) : ?>
|
|
<?php
|
|
$question_post = get_post( $question_id );
|
|
if ( ! $question_post || 'question' !== $question_post->post_type ) {
|
|
continue; // Skip if post not found or not a question
|
|
}
|
|
$question_title = get_the_title( $question_post );
|
|
$question_type = get_post_meta( $question_id, 'question_type', true );
|
|
?>
|
|
<div class="form-group question-group" data-question-id="<?php echo esc_attr( $question_id ); ?>">
|
|
<label><strong><?php echo esc_html( $question_title ); ?></strong></label>
|
|
|
|
<?php // Render input based on question type ?>
|
|
<?php switch ( $question_type ) :
|
|
case 'text': ?>
|
|
<textarea name="assessment_answer[<?php echo esc_attr( $question_id ); ?>]" required></textarea>
|
|
<?php break; ?>
|
|
|
|
<?php case 'multiple-choice': ?>
|
|
<?php
|
|
$choices = get_post_meta( $question_id, 'question_choices', true );
|
|
if ( is_array( $choices ) && ! empty( $choices ) ) :
|
|
foreach ( $choices as $choice_index => $choice_text ) :
|
|
$choice_value = esc_attr( $choice_text ); // Use text as value for simplicity
|
|
$choice_id = 'choice_' . esc_attr( $question_id ) . '_' . esc_attr( $choice_index );
|
|
?>
|
|
<label for="<?php echo $choice_id; ?>">
|
|
<input type="radio"
|
|
id="<?php echo $choice_id; ?>"
|
|
name="assessment_answer[<?php echo esc_attr( $question_id ); ?>]"
|
|
value="<?php echo $choice_value; ?>"
|
|
required>
|
|
<?php echo esc_html( $choice_text ); ?>
|
|
</label><br>
|
|
<?php endforeach; ?>
|
|
<?php else : ?>
|
|
<p class="error"><?php esc_html_e( 'Error: Choices not found for this question.', 'quiztech' ); ?></p>
|
|
<?php endif; ?>
|
|
<?php break; ?>
|
|
|
|
<?php case 'true-false': ?>
|
|
<label><input type="radio" name="assessment_answer[<?php echo esc_attr( $question_id ); ?>]" value="true" required> True</label><br>
|
|
<label><input type="radio" name="assessment_answer[<?php echo esc_attr( $question_id ); ?>]" value="false"> False</label>
|
|
<?php break; ?>
|
|
|
|
<?php default: ?>
|
|
<p class="error"><?php esc_html_e( 'Unsupported question type.', 'quiztech' ); ?></p>
|
|
<?php endswitch; ?>
|
|
</div>
|
|
<hr>
|
|
<?php endforeach; ?>
|
|
|
|
<button type="submit" id="quiztech-submit-assessment"><?php esc_html_e( 'Submit Assessment', 'quiztech' ); ?></button>
|
|
</form>
|
|
<?php
|
|
else :
|
|
echo '<p class="error">' . esc_html__( 'Could not load questions for this assessment.', 'quiztech' ) . '</p>';
|
|
// Debugging info:
|
|
// echo '<pre>Question IDs Data: ' . esc_html( print_r( $question_ids, true ) ) . '</pre>';
|
|
endif;
|
|
?>
|
|
<?php // Removed the simple "Start Assessment" button, replaced by question rendering logic ?>
|
|
</div> <!-- #quiztech-assessment-section -->
|
|
|
|
<?php else : ?>
|
|
<p class="error"><?php esc_html_e( 'An unexpected error occurred. Invalid assessment step.', 'quiztech' ); ?></p>
|
|
<?php endif; ?>
|
|
|
|
</div>
|
|
<?php // wp_footer(); // Consider if needed ?>
|
|
</body>
|
|
</html>
|