Path : /home/vishqocm/pcib.in/admin/
File Upload :
Current File : //home/vishqocm/pcib.in/admin/setup_tables.php

<?php
// Start session
session_start();

// Include database configuration
require_once '../config/database.php';

// Check if user is logged in and has admin role
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
    header('Location: login.php');
    exit;
}

// Array to store results
$results = [];
$success = true;

// Tables we need to check/create
$tables = [
    'exam_settings' => "
        CREATE TABLE IF NOT EXISTS `exam_settings` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `setting_key` varchar(100) NOT NULL,
            `setting_value` text NOT NULL,
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            UNIQUE KEY `setting_key` (`setting_key`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ",
    
    'question_banks' => "
        CREATE TABLE IF NOT EXISTS `question_banks` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `title` varchar(255) NOT NULL,
            `description` text,
            `course_id` int(11) DEFAULT NULL,
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            KEY `course_id` (`course_id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ",
    
    'questions' => "
        CREATE TABLE IF NOT EXISTS `questions` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `question_bank_id` int(11) NOT NULL,
            `question_text` text NOT NULL,
            `question_type` enum('multiple_choice','true_false','short_answer','essay') NOT NULL,
            `difficulty` enum('easy','medium','hard') NOT NULL DEFAULT 'medium',
            `marks` decimal(5,2) NOT NULL DEFAULT '1.00',
            `is_practice` tinyint(1) NOT NULL DEFAULT '0',
            `explanation` text,
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            KEY `question_bank_id` (`question_bank_id`),
            CONSTRAINT `questions_ibfk_1` FOREIGN KEY (`question_bank_id`) REFERENCES `question_banks` (`id`) ON DELETE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ",
    
    'question_options' => "
        CREATE TABLE IF NOT EXISTS `question_options` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `question_id` int(11) NOT NULL,
            `option_text` text NOT NULL,
            `is_correct` tinyint(1) NOT NULL DEFAULT '0',
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            KEY `question_id` (`question_id`),
            CONSTRAINT `question_options_ibfk_1` FOREIGN KEY (`question_id`) REFERENCES `questions` (`id`) ON DELETE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ",
    
    'exam_schedules' => "
        CREATE TABLE IF NOT EXISTS `exam_schedules` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `title` varchar(255) NOT NULL,
            `description` text,
            `course_id` int(11) NOT NULL,
            `exam_date` date NOT NULL,
            `start_time` time NOT NULL,
            `end_time` time NOT NULL,
            `duration_minutes` int(11) NOT NULL,
            `location` varchar(255) DEFAULT NULL,
            `passing_percentage` decimal(5,2) NOT NULL DEFAULT '40.00',
            `is_active` tinyint(1) NOT NULL DEFAULT '1',
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            KEY `course_id` (`course_id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ",
    
    'exam_question_maps' => "
        CREATE TABLE IF NOT EXISTS `exam_question_maps` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `exam_id` int(11) NOT NULL,
            `question_id` int(11) NOT NULL,
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            UNIQUE KEY `exam_question_unique` (`exam_id`,`question_id`),
            KEY `question_id` (`question_id`),
            CONSTRAINT `exam_question_maps_ibfk_1` FOREIGN KEY (`exam_id`) REFERENCES `exam_schedules` (`id`) ON DELETE CASCADE,
            CONSTRAINT `exam_question_maps_ibfk_2` FOREIGN KEY (`question_id`) REFERENCES `questions` (`id`) ON DELETE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ",
    
    'student_exams' => "
        CREATE TABLE IF NOT EXISTS `student_exams` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `user_id` int(11) NOT NULL,
            `exam_id` int(11) NOT NULL,
            `status` enum('pending','in_progress','completed','graded','passed','failed') NOT NULL DEFAULT 'pending',
            `start_time` datetime DEFAULT NULL,
            `end_time` datetime DEFAULT NULL,
            `total_score` decimal(10,2) DEFAULT NULL,
            `percentage` decimal(5,2) DEFAULT NULL,
            `attempt_number` int(11) DEFAULT '1',
            `admin_remarks` text,
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            KEY `user_id` (`user_id`),
            KEY `exam_id` (`exam_id`),
            CONSTRAINT `student_exams_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
            CONSTRAINT `student_exams_ibfk_2` FOREIGN KEY (`exam_id`) REFERENCES `exam_schedules` (`id`) ON DELETE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ",
    
    'student_answers' => "
        CREATE TABLE IF NOT EXISTS `student_answers` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `student_exam_id` int(11) NOT NULL,
            `question_id` int(11) NOT NULL,
            `answer_text` text,
            `selected_option_id` int(11) DEFAULT NULL,
            `is_correct` tinyint(1) DEFAULT NULL,
            `marks_obtained` decimal(5,2) DEFAULT NULL,
            `admin_remarks` text,
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            KEY `student_exam_id` (`student_exam_id`),
            KEY `question_id` (`question_id`),
            KEY `selected_option_id` (`selected_option_id`),
            CONSTRAINT `student_answers_ibfk_1` FOREIGN KEY (`student_exam_id`) REFERENCES `student_exams` (`id`) ON DELETE CASCADE,
            CONSTRAINT `student_answers_ibfk_2` FOREIGN KEY (`question_id`) REFERENCES `questions` (`id`) ON DELETE CASCADE,
            CONSTRAINT `student_answers_ibfk_3` FOREIGN KEY (`selected_option_id`) REFERENCES `question_options` (`id`) ON DELETE SET NULL
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ",
    
    'exam_certificates' => "
        CREATE TABLE IF NOT EXISTS `exam_certificates` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `student_exam_id` int(11) NOT NULL,
            `certificate_number` varchar(50) NOT NULL,
            `issue_date` date NOT NULL,
            `expiry_date` date DEFAULT NULL,
            `certificate_data` text,
            `verification_code` varchar(50) NOT NULL,
            `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            UNIQUE KEY `certificate_number` (`certificate_number`),
            UNIQUE KEY `verification_code` (`verification_code`),
            KEY `student_exam_id` (`student_exam_id`),
            CONSTRAINT `exam_certificates_ibfk_1` FOREIGN KEY (`student_exam_id`) REFERENCES `student_exams` (`id`) ON DELETE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    "
];

// Add default settings
$default_settings = [
    ["default_passing_percentage", "40"],
    ["default_duration_minutes", "60"],
    ["randomize_questions", "1"],
    ["randomize_options", "1"],
    ["show_results_immediately", "1"],
    ["allow_exam_retake", "1"],
    ["max_retake_attempts", "3"],
    ["retake_waiting_period_days", "7"],
    ["block_exam_navigation", "0"],
    ["exam_result_certificate", "1"]
];

// Add a course FK relationship to question_banks if needed
$add_course_fk = "
    ALTER TABLE `question_banks` 
    ADD CONSTRAINT `question_banks_ibfk_1` 
    FOREIGN KEY (`course_id`) REFERENCES `courses` (`id`) ON DELETE SET NULL;
";

// Add a course FK relationship to exam_schedules if needed
$add_course_fk_exams = "
    ALTER TABLE `exam_schedules` 
    ADD CONSTRAINT `exam_schedules_ibfk_1` 
    FOREIGN KEY (`course_id`) REFERENCES `courses` (`id`) ON DELETE CASCADE;
";

// Add is_practice column to questions table if it doesn't exist
$add_is_practice_column = "
    ALTER TABLE `questions` 
    ADD COLUMN `is_practice` tinyint(1) NOT NULL DEFAULT '0' AFTER `marks`
    ";

// Process each table creation
foreach ($tables as $table_name => $create_query) {
    // Check if table exists
    $table_exists_query = "SHOW TABLES LIKE '$table_name'";
    $table_exists_result = $conn->query($table_exists_query);
    
    if ($table_exists_result->num_rows > 0) {
        $results[] = "Table <strong>$table_name</strong> already exists.";
    } else {
        // Create the table
        try {
            if ($conn->query($create_query)) {
                $results[] = "Table <strong>$table_name</strong> created successfully.";
                
                // If we just created the exam_settings table, populate default settings
                if ($table_name === 'exam_settings') {
                    $insert_settings_query = "INSERT INTO `exam_settings` (`setting_key`, `setting_value`) VALUES (?, ?)";
                    $stmt = $conn->prepare($insert_settings_query);
                    
                    foreach ($default_settings as $setting) {
                        $stmt->bind_param("ss", $setting[0], $setting[1]);
                        $stmt->execute();
                    }
                    
                    $results[] = "Default exam settings added.";
                }
            } else {
                $results[] = "Error creating table <strong>$table_name</strong>: " . $conn->error;
                $success = false;
            }
        } catch (Exception $e) {
            $results[] = "Exception creating table <strong>$table_name</strong>: " . $e->getMessage();
            $success = false;
        }
    }
}

// Add foreign key constraints if needed
try {
    // Check if the course_id column in question_banks has a foreign key
    $fk_check_query = "SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
                       WHERE TABLE_NAME = 'question_banks' 
                       AND COLUMN_NAME = 'course_id' 
                       AND REFERENCED_TABLE_NAME = 'courses'";
    $fk_check_result = $conn->query($fk_check_query);
    
    if ($fk_check_result->num_rows === 0) {
        if ($conn->query($add_course_fk)) {
            $results[] = "Foreign key constraint added for question_banks.course_id -> courses.id";
        } else {
            $results[] = "Error adding foreign key constraint to question_banks: " . $conn->error;
        }
    }
    
    // Check if the course_id column in exam_schedules has a foreign key
    $fk_check_exams_query = "SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
                            WHERE TABLE_NAME = 'exam_schedules' 
                            AND COLUMN_NAME = 'course_id' 
                            AND REFERENCED_TABLE_NAME = 'courses'";
    $fk_check_exams_result = $conn->query($fk_check_exams_query);
    
    if ($fk_check_exams_result->num_rows === 0) {
        if ($conn->query($add_course_fk_exams)) {
            $results[] = "Foreign key constraint added for exam_schedules.course_id -> courses.id";
        } else {
            $results[] = "Error adding foreign key constraint to exam_schedules: " . $conn->error;
        }
    }
} catch (Exception $e) {
    $results[] = "Exception adding foreign key constraints: " . $e->getMessage();
    $success = false;
}

// Check and add is_practice column to questions table if it doesn't exist
try {
    // Check if is_practice column exists in questions table
    $column_check_query = "SHOW COLUMNS FROM `questions` LIKE 'is_practice'";
    $column_check_result = $conn->query($column_check_query);
    
    if ($column_check_result->num_rows === 0) {
        // Column doesn't exist, add it
        if ($conn->query($add_is_practice_column)) {
            $results[] = "Added 'is_practice' column to questions table";
        } else {
            $results[] = "Error adding 'is_practice' column to questions table: " . $conn->error;
            $success = false;
        }
    } else {
        $results[] = "Column 'is_practice' already exists in questions table";
    }
} catch (Exception $e) {
    $results[] = "Exception checking/adding 'is_practice' column: " . $e->getMessage();
    $success = false;
}

// Include header
include_once 'includes/header.php';
?>

<div class="container-fluid">
    <div class="d-sm-flex align-items-center justify-content-between mb-4">
        <h1 class="h3 mb-0 text-gray-800">Exam Database Setup</h1>
        <a href="settings.php" class="btn btn-primary btn-sm shadow-sm">
            <i class="fas fa-arrow-left fa-sm text-white-50"></i> Back to Exam Settings
        </a>
    </div>
    
    <div class="card shadow mb-4">
        <div class="card-header py-3">
            <h6 class="m-0 font-weight-bold text-primary">Database Tables Status</h6>
        </div>
        <div class="card-body">
            <?php if ($success): ?>
                <div class="alert alert-success">
                    <i class="fas fa-check-circle"></i> Database setup completed successfully!
                </div>
            <?php else: ?>
                <div class="alert alert-danger">
                    <i class="fas fa-exclamation-triangle"></i> There were issues with the database setup. Please check the details below.
                </div>
            <?php endif; ?>
            
            <div class="table-responsive">
                <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
                    <thead>
                        <tr>
                            <th>Operation</th>
                            <th>Result</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($results as $result): ?>
                            <tr>
                                <td><?php echo $result; ?></td>
                                <td>
                                    <?php if (strpos($result, 'Error') !== false || strpos($result, 'Exception') !== false): ?>
                                        <span class="badge bg-danger">Failed</span>
                                    <?php else: ?>
                                        <span class="badge bg-success">Success</span>
                                    <?php endif; ?>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
            
            <div class="text-center mt-4">
                <a href="dashboard.php" class="btn btn-primary">
                    <i class="fas fa-tachometer-alt"></i> Go to Exam Dashboard
                </a>
            </div>
        </div>
    </div>
    
    <!-- Schema Information -->
    <div class="card shadow mb-4">
        <div class="card-header py-3">
            <h6 class="m-0 font-weight-bold text-primary">Database Schema Information</h6>
        </div>
        <div class="card-body">
            <p>The exam system uses the following tables:</p>
            
            <div class="row">
                <div class="col-md-6 mb-4">
                    <div class="card h-100">
                        <div class="card-header">
                            <h6 class="font-weight-bold">Question Management</h6>
                        </div>
                        <div class="card-body">
                            <ul>
                                <li><strong>question_banks</strong> - Organizes questions by topic or course</li>
                                <li><strong>questions</strong> - Stores the question text, type, and difficulty</li>
                                <li><strong>question_options</strong> - Stores options for multiple choice questions</li>
                            </ul>
                        </div>
                    </div>
                </div>
                
                <div class="col-md-6 mb-4">
                    <div class="card h-100">
                        <div class="card-header">
                            <h6 class="font-weight-bold">Exam Management</h6>
                        </div>
                        <div class="card-body">
                            <ul>
                                <li><strong>exam_schedules</strong> - Defines exams, their timing, and settings</li>
                                <li><strong>exam_question_maps</strong> - Maps questions to specific exams</li>
                                <li><strong>exam_settings</strong> - Global settings for the exam system</li>
                            </ul>
                        </div>
                    </div>
                </div>
                
                <div class="col-md-6 mb-4">
                    <div class="card h-100">
                        <div class="card-header">
                            <h6 class="font-weight-bold">Student Attempts</h6>
                        </div>
                        <div class="card-body">
                            <ul>
                                <li><strong>student_exams</strong> - Tracks exam attempts by students</li>
                                <li><strong>student_answers</strong> - Records student answers for each question</li>
                            </ul>
                        </div>
                    </div>
                </div>
                
                <div class="col-md-6 mb-4">
                    <div class="card h-100">
                        <div class="card-header">
                            <h6 class="font-weight-bold">Certificates</h6>
                        </div>
                        <div class="card-body">
                            <ul>
                                <li><strong>exam_certificates</strong> - Stores certificates issued for passed exams</li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<?php
// Include footer
include_once 'includes/footer.php';
?>