diff --git a/db/migrations/005_create_exams_table.sql b/db/migrations/005_create_exams_table.sql
new file mode 100644
index 0000000..e11f43e
--- /dev/null
+++ b/db/migrations/005_create_exams_table.sql
@@ -0,0 +1,7 @@
+CREATE TABLE IF NOT EXISTS exams (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ created_by INT NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE CASCADE
+);
\ No newline at end of file
diff --git a/db/migrations/006_create_exam_questions_table.sql b/db/migrations/006_create_exam_questions_table.sql
new file mode 100644
index 0000000..800b2bb
--- /dev/null
+++ b/db/migrations/006_create_exam_questions_table.sql
@@ -0,0 +1,9 @@
+CREATE TABLE IF NOT EXISTS exam_questions (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ exam_id INT NOT NULL,
+ question_text TEXT NOT NULL,
+ question_type ENUM('multiple_choice', 'free_text') NOT NULL,
+ options JSON,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (exam_id) REFERENCES exams(id) ON DELETE CASCADE
+);
\ No newline at end of file
diff --git a/db/migrations/007_create_student_exams_table.sql b/db/migrations/007_create_student_exams_table.sql
new file mode 100644
index 0000000..44c2005
--- /dev/null
+++ b/db/migrations/007_create_student_exams_table.sql
@@ -0,0 +1,12 @@
+CREATE TABLE IF NOT EXISTS student_exams (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ exam_id INT NOT NULL,
+ student_id INT NOT NULL,
+ status ENUM('assigned', 'in-progress', 'completed') DEFAULT 'assigned',
+ score INT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ FOREIGN KEY (exam_id) REFERENCES exams(id) ON DELETE CASCADE,
+ FOREIGN KEY (student_id) REFERENCES users(id) ON DELETE CASCADE,
+ UNIQUE KEY (exam_id, student_id)
+);
\ No newline at end of file
diff --git a/db/migrations/008_create_student_answers_table.sql b/db/migrations/008_create_student_answers_table.sql
new file mode 100644
index 0000000..ae220b8
--- /dev/null
+++ b/db/migrations/008_create_student_answers_table.sql
@@ -0,0 +1,10 @@
+CREATE TABLE IF NOT EXISTS student_answers (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ student_exam_id INT NOT NULL,
+ question_id INT NOT NULL,
+ answer_text TEXT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (student_exam_id) REFERENCES student_exams(id) ON DELETE CASCADE,
+ FOREIGN KEY (question_id) REFERENCES exam_questions(id) ON DELETE CASCADE,
+ UNIQUE KEY (student_exam_id, question_id)
+);
\ No newline at end of file
diff --git a/exam_questions.php b/exam_questions.php
new file mode 100644
index 0000000..1802de8
--- /dev/null
+++ b/exam_questions.php
@@ -0,0 +1,180 @@
+prepare('SELECT * FROM exams WHERE id = ? AND created_by = ?');
+$stmt->execute([$exam_id, $user_id]);
+$exam = $stmt->fetch();
+
+if (!$exam) {
+ echo "Exam not found or you don't have permission to edit it.";
+ exit();
+}
+
+// Handle question form submission
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['question_text'])) {
+ $question_text = trim($_POST['question_text']);
+ $question_type = $_POST['question_type'];
+ $options = null;
+
+ if ($question_type === 'multiple_choice') {
+ $options_raw = trim($_POST['options']);
+ if (!empty($options_raw)) {
+ $options = json_encode(array_map('trim', explode("\n", $options_raw)));
+ }
+ }
+
+ if (!empty($question_text)) {
+ if (isset($_POST['question_id']) && !empty($_POST['question_id'])) {
+ // Update question
+ $stmt = $pdo->prepare('UPDATE exam_questions SET question_text = ?, question_type = ?, options = ? WHERE id = ? AND exam_id = ?');
+ $stmt->execute([$question_text, $question_type, $options, $_POST['question_id'], $exam_id]);
+ } else {
+ // Add new question
+ $stmt = $pdo->prepare('INSERT INTO exam_questions (exam_id, question_text, question_type, options) VALUES (?, ?, ?, ?)');
+ $stmt->execute([$exam_id, $question_text, $question_type, $options]);
+ }
+ }
+ header('Location: exam_questions.php?exam_id=' . $exam_id);
+ exit();
+}
+
+// Handle question deletion
+if (isset($_GET['delete_question'])) {
+ $question_id = $_GET['delete_question'];
+ $stmt = $pdo->prepare('DELETE FROM exam_questions WHERE id = ? AND exam_id = ?');
+ $stmt->execute([$question_id, $exam_id]);
+ header('Location: exam_questions.php?exam_id=' . $exam_id);
+ exit();
+}
+
+// Fetch questions for the exam
+$stmt = $pdo->prepare('SELECT * FROM exam_questions WHERE exam_id = ? ORDER BY created_at ASC');
+$stmt->execute([$exam_id]);
+$questions = $stmt->fetchAll();
+
+// Check if we are editing a question
+$edit_question = null;
+if (isset($_GET['edit_question'])) {
+ $stmt = $pdo->prepare('SELECT * FROM exam_questions WHERE id = ? AND exam_id = ?');
+ $stmt->execute([$_GET['edit_question'], $exam_id]);
+ $edit_question = $stmt->fetch();
+}
+
+?>
+
+
+
+
+
+ Manage Questions for
+
+
+
+
+ Manage Questions for ""
+
+
+
+
+
+
+ Questions
+
+
+
+ | Question |
+ Type |
+ Actions |
+
+
+
+
+
+ |
+ |
+
+ Edit |
+ Delete
+ |
+
+
+
+
+ | No questions have been added to this exam yet. |
+
+
+
+
+
+
+
+
+
diff --git a/exams.php b/exams.php
index 4bed414..5fe7531 100644
--- a/exams.php
+++ b/exams.php
@@ -1,32 +1,177 @@
Dashboard';
+
+// Role-based logic
+if ($role === 'teacher') {
+ $page_title = 'Manage Exams';
+
+ // Handle form submissions for creating/editing exams
+ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['exam_name'])) {
+ $exam_name = trim($_POST['exam_name']);
+ if (!empty($exam_name)) {
+ if (isset($_POST['exam_id']) && !empty($_POST['exam_id'])) {
+ $stmt = $pdo->prepare('UPDATE exams SET name = ? WHERE id = ? AND created_by = ?');
+ $stmt->execute([$exam_name, $_POST['exam_id'], $user_id]);
+ } else {
+ $stmt = $pdo->prepare('INSERT INTO exams (name, created_by) VALUES (?, ?)');
+ $stmt->execute([$exam_name, $user_id]);
+ }
+ }
+ header('Location: exams.php');
+ exit();
+ }
+
+ // Handle exam deletion
+ if (isset($_GET['delete_exam'])) {
+ $stmt = $pdo->prepare('DELETE FROM exams WHERE id = ? AND created_by = ?');
+ $stmt->execute([$_GET['delete_exam'], $user_id]);
+ header('Location: exams.php');
+ exit();
+ }
+
+ // Fetch exams for the teacher view
+ $stmt = $pdo->prepare('SELECT * FROM exams WHERE created_by = ? ORDER BY created_at DESC');
+ $stmt->execute([$user_id]);
+ $exams = $stmt->fetchAll();
+
+ // Check if we are editing an exam
+ $edit_exam = null;
+ if (isset($_GET['edit_exam'])) {
+ $stmt = $pdo->prepare('SELECT * FROM exams WHERE id = ? AND created_by = ?');
+ $stmt->execute([$_GET['edit_exam'], $user_id]);
+ $edit_exam = $stmt->fetch();
+ }
+
+} elseif ($role === 'student') {
+ $page_title = 'Your Exams';
+
+ // Fetch assigned exams for the student view
+ $stmt = $pdo->prepare('
+ SELECT e.name, se.status, se.score, se.id as student_exam_id
+ FROM student_exams se
+ JOIN exams e ON se.exam_id = e.id
+ WHERE se.student_id = ?
+ ORDER BY e.created_at DESC
+ ');
+ $stmt->execute([$user_id]);
+ $assigned_exams = $stmt->fetchAll();
+
+} else {
+ // Redirect other roles to their dashboard
+ header('Location: ' . $role . '_dashboard.php');
+ exit();
+}
?>
- Exams
-
+
+
- Exam Management
- This page will contain student exam information.
+
+
+
+
+
+ Assigned Exams
+
+
+
+ | Exam Name |
+ Status |
+ Score |
+ Action |
+
+
+
+
+
+ |
+ |
+ |
+
+
+ Take Exam
+
+ View Results
+
+ |
+
+
+
+ | You have no assigned exams. |
+
+
+
+
+
\ No newline at end of file
diff --git a/take_exam.php b/take_exam.php
new file mode 100644
index 0000000..d5e900a
--- /dev/null
+++ b/take_exam.php
@@ -0,0 +1,133 @@
+prepare('SELECT * FROM student_exams WHERE id = ? AND student_id = ?');
+$stmt->execute([$student_exam_id, $user_id]);
+$student_exam = $stmt->fetch();
+
+if (!$student_exam) {
+ echo "You are not assigned to this exam.";
+ exit();
+}
+
+// Prevent re-taking a completed exam
+if ($student_exam['status'] === 'completed') {
+ echo "You have already completed this exam.";
+ // Maybe redirect to a results page in the future
+ echo '
Back to Exams';
+ exit();
+}
+
+// Fetch exam details
+$stmt = $pdo->prepare('SELECT * FROM exams WHERE id = ?');
+$stmt->execute([$student_exam['exam_id']]);
+$exam = $stmt->fetch();
+
+// Fetch exam questions
+$stmt = $pdo->prepare('SELECT * FROM exam_questions WHERE exam_id = ? ORDER BY id ASC');
+$stmt->execute([$exam['id']]);
+$questions = $stmt->fetchAll();
+
+// Handle exam submission
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['answers'])) {
+ $answers = $_POST['answers'];
+
+ $pdo->beginTransaction();
+ try {
+ foreach ($answers as $question_id => $answer_text) {
+ // Use INSERT ... ON DUPLICATE KEY UPDATE to prevent duplicate answer submissions
+ $sql = 'INSERT INTO student_answers (student_exam_id, question_id, answer_text) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE answer_text = VALUES(answer_text)';
+ $stmt = $pdo->prepare($sql);
+ $stmt->execute([$student_exam_id, $question_id, trim($answer_text)]);
+ }
+
+ // Mark exam as completed
+ $stmt = $pdo->prepare('UPDATE student_exams SET status = \'completed\' WHERE id = ?');
+ $stmt->execute([$student_exam_id]);
+
+ $pdo->commit();
+
+ header('Location: exams.php');
+ exit();
+
+ } catch (Exception $e) {
+ $pdo->rollBack();
+ // Log error properly in a real application
+ die("An error occurred while submitting your exam. Please try again. Error: " . $e->getMessage());
+ }
+}
+
+// If student is starting the exam, mark it as 'in-progress'
+if ($student_exam['status'] === 'assigned') {
+ $stmt = $pdo->prepare('UPDATE student_exams SET status = \'in-progress\' WHERE id = ?');
+ $stmt->execute([$student_exam_id]);
+}
+
+?>
+
+
+
+
+
+ Take Exam:
+
+
+
+
+
+
+
+
+