quiztech-assessment-platform/public/templates/assessment-shell.php
Ruben Ramirez 6beb1c2251 Fix activation errors and address initial TODOs
- 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.
2025-04-03 19:12:26 -05:00

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>