<?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;
}
// Check if exam_id is provided
if (!isset($_GET['exam_id']) || !is_numeric($_GET['exam_id'])) {
header('Location: exam_schedules.php');
exit;
}
$exam_id = $_GET['exam_id'];
// Get exam details
$exam_query = "SELECT es.*, c.title as course_title
FROM exam_schedules es
JOIN courses c ON es.course_id = c.id
WHERE es.id = ?";
$stmt = $conn->prepare($exam_query);
$stmt->bind_param("i", $exam_id);
$stmt->execute();
$exam_result = $stmt->get_result();
if ($exam_result->num_rows === 0) {
header('Location: exam_schedules.php');
exit;
}
$exam = $exam_result->fetch_assoc();
// Process update student exam status
if (isset($_POST['update_status'])) {
$student_exam_id = $_POST['student_exam_id'];
$new_status = $_POST['new_status'];
$admin_remarks = $_POST['admin_remarks'];
$update_query = "UPDATE student_exams SET status = ?, admin_remarks = ? WHERE id = ?";
$stmt = $conn->prepare($update_query);
$stmt->bind_param("ssi", $new_status, $admin_remarks, $student_exam_id);
if ($stmt->execute()) {
$success_message = "Student exam status updated successfully.";
} else {
$error_message = "Failed to update student exam status.";
}
}
// Get total questions in the exam
$questions_count_query = "SELECT COUNT(*) as total FROM exam_question_maps WHERE exam_id = ?";
$stmt = $conn->prepare($questions_count_query);
$stmt->bind_param("i", $exam_id);
$stmt->execute();
$questions_count_result = $stmt->get_result()->fetch_assoc();
$total_questions = $questions_count_result['total'];
// Get total marks in the exam
$total_marks_query = "SELECT SUM(q.marks) as total_marks
FROM questions q
JOIN exam_question_maps eqm ON q.id = eqm.question_id
WHERE eqm.exam_id = ?";
$stmt = $conn->prepare($total_marks_query);
$stmt->bind_param("i", $exam_id);
$stmt->execute();
$total_marks_result = $stmt->get_result()->fetch_assoc();
$total_marks = $total_marks_result['total_marks'] ?? 0;
// Get student exam attempts
$student_exams_query = "SELECT se.*,
u.first_name, u.last_name, u.email, u.student_id,
(SELECT COUNT(*) FROM student_answers sa WHERE sa.student_exam_id = se.id AND sa.is_correct = 1) as correct_answers
FROM student_exams se
JOIN users u ON se.user_id = u.id
WHERE se.exam_id = ?
ORDER BY se.created_at DESC";
$stmt = $conn->prepare($student_exams_query);
$stmt->bind_param("i", $exam_id);
$stmt->execute();
$student_exams_result = $stmt->get_result();
$student_exams = [];
while ($student_exam = $student_exams_result->fetch_assoc()) {
$student_exams[] = $student_exam;
}
// 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 Results</h1>
<a href="exam_schedules.php" class="btn btn-secondary btn-sm shadow-sm">
<i class="fas fa-arrow-left fa-sm text-white-50"></i> Back to Exams
</a>
</div>
<?php if (isset($error_message)): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<?php echo $error_message; ?>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<?php endif; ?>
<?php if (isset($success_message)): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<?php echo $success_message; ?>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<?php endif; ?>
<!-- Exam Information Card -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Exam Information</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-bordered">
<tr>
<th>Exam Title</th>
<td><?php echo htmlspecialchars($exam['title']); ?></td>
</tr>
<tr>
<th>Course</th>
<td><?php echo htmlspecialchars($exam['course_title']); ?></td>
</tr>
<tr>
<th>Date</th>
<td><?php echo date('d M, Y', strtotime($exam['exam_date'])); ?></td>
</tr>
<tr>
<th>Duration</th>
<td><?php echo $exam['duration_minutes']; ?> minutes</td>
</tr>
</table>
</div>
<div class="col-md-6">
<div class="card bg-primary text-white shadow mb-4">
<div class="card-body">
<div class="text-center">
<h4>Exam Statistics</h4>
<hr class="sidebar-divider">
<div class="h5 mb-0 font-weight-bold">Total Questions: <?php echo $total_questions; ?></div>
<div class="h5 mb-0 font-weight-bold">Total Marks: <?php echo $total_marks; ?></div>
<div class="h5 mb-0 font-weight-bold">Passing Percentage: <?php echo $exam['passing_percentage']; ?>%</div>
<div class="h5 mb-0 font-weight-bold mt-3">Total Attempts: <?php echo count($student_exams); ?></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Students Results Table -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Student Results</h6>
<span class="badge badge-primary badge-pill"><?php echo count($student_exams); ?> Attempts</span>
</div>
<div class="card-body">
<?php if (empty($student_exams)): ?>
<div class="alert alert-info">
<i class="fas fa-info-circle"></i> No student has attempted this exam yet.
</div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-bordered" id="resultsTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Student</th>
<th>Start Time</th>
<th>End Time</th>
<th>Score</th>
<th>Percentage</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($student_exams as $student_exam): ?>
<tr>
<td>
<?php echo htmlspecialchars($student_exam['first_name'] . ' ' . $student_exam['last_name']); ?>
<div class="small text-muted"><?php echo htmlspecialchars($student_exam['student_id']); ?></div>
</td>
<td>
<?php echo $student_exam['start_time'] ? date('d M, Y H:i', strtotime($student_exam['start_time'])) : 'Not started'; ?>
</td>
<td>
<?php echo $student_exam['end_time'] ? date('d M, Y H:i', strtotime($student_exam['end_time'])) : 'In progress'; ?>
</td>
<td>
<?php
if ($student_exam['status'] === 'completed' || $student_exam['status'] === 'graded' ||
$student_exam['status'] === 'passed' || $student_exam['status'] === 'failed') {
echo $student_exam['total_score'] . ' / ' . $total_marks;
echo '<div class="small text-muted">Correct: ' . $student_exam['correct_answers'] . ' / ' . $total_questions . '</div>';
} else {
echo 'Not graded';
}
?>
</td>
<td>
<?php
if ($student_exam['percentage'] !== null) {
$percentage_class = ($student_exam['percentage'] >= $exam['passing_percentage']) ? 'success' : 'danger';
echo '<span class="badge badge-' . $percentage_class . '">' . number_format($student_exam['percentage'], 2) . '%</span>';
} else {
echo 'N/A';
}
?>
</td>
<td>
<?php
$status_badge_class = '';
switch ($student_exam['status']) {
case 'pending':
$status_badge_class = 'secondary';
break;
case 'in_progress':
$status_badge_class = 'info';
break;
case 'completed':
$status_badge_class = 'primary';
break;
case 'graded':
$status_badge_class = 'warning';
break;
case 'passed':
$status_badge_class = 'success';
break;
case 'failed':
$status_badge_class = 'danger';
break;
default:
$status_badge_class = 'secondary';
}
?>
<span class="badge badge-<?php echo $status_badge_class; ?>">
<?php echo ucfirst(str_replace('_', ' ', $student_exam['status'])); ?>
</span>
</td>
<td>
<a href="view_student_answers.php?exam_id=<?php echo $exam_id; ?>&student_exam_id=<?php echo $student_exam['id']; ?>"
class="btn btn-info btn-sm mb-1">
<i class="fas fa-eye"></i> View Answers
</a>
<button type="button" class="btn btn-primary btn-sm mb-1"
onclick="showUpdateStatusModal(<?php echo $student_exam['id']; ?>, '<?php echo $student_exam['status']; ?>', '<?php echo addslashes($student_exam['admin_remarks']); ?>')">
<i class="fas fa-edit"></i> Update Status
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
<!-- Update Status Modal -->
<div class="modal fade" id="updateStatusModal" tabindex="-1" role="dialog" aria-labelledby="updateStatusModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="updateStatusModalLabel">Update Student Exam Status</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form method="post" action="">
<div class="modal-body">
<input type="hidden" id="student_exam_id" name="student_exam_id">
<div class="form-group">
<label for="new_status">Status</label>
<select class="form-control" id="new_status" name="new_status" required>
<option value="pending">Pending</option>
<option value="in_progress">In Progress</option>
<option value="completed">Completed</option>
<option value="graded">Graded</option>
<option value="passed">Passed</option>
<option value="failed">Failed</option>
</select>
</div>
<div class="form-group">
<label for="admin_remarks">Admin Remarks</label>
<textarea class="form-control" id="admin_remarks" name="admin_remarks" rows="3"></textarea>
<small class="form-text text-muted">
Add any remarks or notes about this student's exam performance.
</small>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" name="update_status" class="btn btn-primary">Update Status</button>
</div>
</form>
</div>
</div>
</div>
<script>
$(document).ready(function() {
// Initialize DataTable
$('#resultsTable').DataTable({
"order": [[ 1, "desc" ]], // Sort by start time by default (descending)
"columnDefs": [
{ "width": "20%", "targets": 0 }, // Student column
{ "width": "15%", "targets": 1 }, // Start Time column
{ "width": "15%", "targets": 2 }, // End Time column
{ "width": "10%", "targets": 3 }, // Score column
{ "width": "10%", "targets": 4 }, // Percentage column
{ "width": "10%", "targets": 5 }, // Status column
{ "width": "20%", "targets": 6 } // Actions column
]
});
});
// Function to show the update status modal
function showUpdateStatusModal(studentExamId, currentStatus, adminRemarks) {
$('#student_exam_id').val(studentExamId);
$('#new_status').val(currentStatus);
$('#admin_remarks').val(adminRemarks);
$('#updateStatusModal').modal('show');
}
</script>
<?php
// Include footer
include_once 'includes/footer.php';
?>