<?php
// Include header
include_once 'includes/header.php';
// Check if instructor is logged in
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'instructor') {
header('Location: ../login.php');
exit;
}
// Check if attendance table exists and create it if not
function check_attendance_table_exists($conn) {
$check_table_sql = "SHOW TABLES LIKE 'attendance'";
$result = $conn->query($check_table_sql);
if ($result->num_rows == 0) {
// Table doesn't exist, include the setup script
include_once '../admin/database/setup_attendance_table.php';
return false;
}
return true;
}
// Check and create attendance table if needed
$attendance_table_exists = check_attendance_table_exists($conn);
$instructor_id = $_SESSION['user_id'];
$success_message = '';
$error_message = '';
$selected_date = date('Y-m-d');
// Handle form submission for attendance
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit_attendance'])) {
$date = $_POST['attendance_date'];
$attendance_data = $_POST['attendance'] ?? [];
if (empty($date)) {
$error_message = "Please select a date.";
} else {
// Begin transaction
$conn->begin_transaction();
try {
// First, delete any existing attendance records for this date marked by this instructor
$delete_stmt = $conn->prepare("DELETE FROM attendance WHERE date = ? AND marked_by = ?");
$delete_stmt->bind_param("si", $date, $instructor_id);
$delete_stmt->execute();
// Then insert new attendance records
if (!empty($attendance_data)) {
$insert_stmt = $conn->prepare("INSERT INTO attendance (enrollment_id, course_id, student_id, date, status, marked_by, notes) VALUES (?, ?, ?, ?, ?, ?, ?)");
foreach ($attendance_data as $enrollment_id => $data) {
$student_id = $data['id'];
$course_id = $data['course_id'];
$status = $data['status'];
$notes = $data['notes'] ?? '';
$insert_stmt->bind_param("iiissss", $enrollment_id, $course_id, $student_id, $date, $status, $instructor_id, $notes);
$insert_stmt->execute();
}
$insert_stmt->close();
}
// Commit transaction
$conn->commit();
$success_message = "Attendance successfully recorded for " . date('F d, Y', strtotime($date));
$selected_date = $date;
} catch (Exception $e) {
// Rollback transaction on error
$conn->rollback();
$error_message = "Error recording attendance: " . $e->getMessage();
}
}
}
// If date is selected from get parameter
if (isset($_GET['date'])) {
$selected_date = $_GET['date'];
}
// Get all enrolled students (not course-specific)
$students_query = "
SELECT
u.id,
u.username,
u.first_name,
u.last_name,
u.email,
u.profile_image,
e.id AS enrollment_id,
e.course_id,
c.title AS course_title,
e.enrollment_date,
e.status,
a.status AS attendance_status,
a.notes
FROM enrollments e
INNER JOIN users u ON e.user_id = u.id
INNER JOIN courses c ON e.course_id = c.id
LEFT JOIN attendance a ON a.enrollment_id = e.id AND a.date = ? AND a.marked_by = ?
WHERE e.status = 'active' AND u.role = 'student'
ORDER BY c.title, u.first_name, u.last_name
";
$stmt = $conn->prepare($students_query);
$stmt->bind_param("si", $selected_date, $instructor_id);
$stmt->execute();
$students_result = $stmt->get_result();
$students = [];
while ($row = $students_result->fetch_assoc()) {
$students[] = $row;
}
// Get attendance statistics
$stats_query = "
SELECT
COUNT(DISTINCT a.date) as total_days,
COUNT(DISTINCT a.student_id) as total_students,
SUM(CASE WHEN a.status = 'present' THEN 1 ELSE 0 END) as total_present,
SUM(CASE WHEN a.status = 'absent' THEN 1 ELSE 0 END) as total_absent,
SUM(CASE WHEN a.status = 'late' THEN 1 ELSE 0 END) as total_late,
SUM(CASE WHEN a.status = 'excused' THEN 1 ELSE 0 END) as total_excused
FROM attendance a
WHERE a.marked_by = ?
";
$stmt = $conn->prepare($stats_query);
$stmt->bind_param("i", $instructor_id);
$stmt->execute();
$stats_result = $stmt->get_result();
$attendance_stats = $stats_result->fetch_assoc() ?: [
'total_days' => 0,
'total_students' => 0,
'total_present' => 0,
'total_absent' => 0,
'total_late' => 0,
'total_excused' => 0
];
?>
<div class="container-fluid">
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">Attendance Management</h5>
<p class="text-muted">Record and manage attendance for all enrolled students</p>
</div>
</div>
</div>
</div>
<?php if ($success_message): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="fas fa-check-circle me-2"></i> <?php echo $success_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if ($error_message): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if (!$attendance_table_exists): ?>
<div class="alert alert-info alert-dismissible fade show" role="alert">
<i class="fas fa-info-circle me-2"></i> Attendance system has been set up. You can now start marking attendance for your courses.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="row">
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Select Date</h5>
</div>
<div class="card-body">
<form method="get" action="">
<div class="mb-3">
<label for="date" class="form-label">Attendance Date</label>
<input type="date" name="date" id="date" class="form-control" value="<?php echo $selected_date; ?>" max="<?php echo date('Y-m-d'); ?>" required onchange="this.form.submit()">
</div>
</form>
</div>
</div>
<div class="card mt-4">
<div class="card-header">
<h5 class="mb-0">Attendance Statistics</h5>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-6 mb-3">
<h6 class="text-muted">Total Students</h6>
<h3><?php echo $attendance_stats['total_students']; ?></h3>
</div>
<div class="col-6 mb-3">
<h6 class="text-muted">Total Days</h6>
<h3><?php echo $attendance_stats['total_days']; ?></h3>
</div>
</div>
<h6 class="mb-2">Attendance Summary</h6>
<div class="d-flex mb-2">
<div class="flex-grow-1">
<span class="badge bg-success">Present</span>
</div>
<div><?php echo $attendance_stats['total_present']; ?></div>
</div>
<div class="d-flex mb-2">
<div class="flex-grow-1">
<span class="badge bg-danger">Absent</span>
</div>
<div><?php echo $attendance_stats['total_absent']; ?></div>
</div>
<div class="d-flex mb-2">
<div class="flex-grow-1">
<span class="badge bg-warning text-dark">Late</span>
</div>
<div><?php echo $attendance_stats['total_late']; ?></div>
</div>
<div class="d-flex">
<div class="flex-grow-1">
<span class="badge bg-info">Excused</span>
</div>
<div><?php echo $attendance_stats['total_excused']; ?></div>
</div>
</div>
</div>
</div>
<div class="col-md-8">
<?php if (empty($students)): ?>
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle me-2"></i> No students are currently enrolled in any courses.
</div>
<?php else: ?>
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Student Attendance for <?php echo date('F d, Y', strtotime($selected_date)); ?></h5>
<div>
<button type="button" id="selectAllPresent" class="btn btn-sm btn-success me-1">
<i class="fas fa-check me-1"></i> All Present
</button>
<button type="button" id="clearAll" class="btn btn-sm btn-secondary">
<i class="fas fa-undo me-1"></i> Reset
</button>
</div>
</div>
<div class="card-body">
<form method="post" action="" id="attendanceForm">
<input type="hidden" name="attendance_date" value="<?php echo $selected_date; ?>">
<div class="table-responsive">
<table class="table table-hover" id="attendanceTable">
<thead>
<tr>
<th width="40">#</th>
<th>Student</th>
<th>Course</th>
<th width="120">Status</th>
<th width="200">Notes</th>
</tr>
</thead>
<tbody>
<?php $count = 1; foreach ($students as $student): ?>
<tr>
<td><?php echo $count++; ?></td>
<td>
<div class="d-flex align-items-center">
<div class="me-3">
<img src="<?php echo !empty($student['profile_image']) ? '../' . $student['profile_image'] : '../assets/img/default-avatar.png'; ?>"
class="rounded-circle" alt="Profile" style="width: 40px; height: 40px; object-fit: cover;">
</div>
<div>
<h6 class="mb-0"><?php echo htmlspecialchars($student['first_name'] . ' ' . $student['last_name']); ?></h6>
<small class="text-muted"><?php echo htmlspecialchars($student['email']); ?></small>
</div>
</div>
</td>
<td>
<?php echo htmlspecialchars($student['course_title']); ?>
</td>
<td>
<input type="hidden" name="attendance[<?php echo $student['enrollment_id']; ?>][id]" value="<?php echo $student['id']; ?>">
<input type="hidden" name="attendance[<?php echo $student['enrollment_id']; ?>][course_id]" value="<?php echo $student['course_id']; ?>">
<select name="attendance[<?php echo $student['enrollment_id']; ?>][status]" class="form-select form-select-sm attendance-status">
<option value="">-- Select --</option>
<option value="present" <?php echo ($student['attendance_status'] == 'present') ? 'selected' : ''; ?>>Present</option>
<option value="absent" <?php echo ($student['attendance_status'] == 'absent') ? 'selected' : ''; ?>>Absent</option>
<option value="late" <?php echo ($student['attendance_status'] == 'late') ? 'selected' : ''; ?>>Late</option>
<option value="excused" <?php echo ($student['attendance_status'] == 'excused') ? 'selected' : ''; ?>>Excused</option>
</select>
</td>
<td>
<input type="text" name="attendance[<?php echo $student['enrollment_id']; ?>][notes]"
class="form-control form-control-sm" placeholder="Optional notes"
value="<?php echo htmlspecialchars($student['notes'] ?? ''); ?>">
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end mt-4">
<button type="submit" name="submit_attendance" class="btn btn-primary">
<i class="fas fa-save me-2"></i> Save Attendance
</button>
</div>
</form>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Select all present button
const selectAllPresentBtn = document.getElementById('selectAllPresent');
if (selectAllPresentBtn) {
selectAllPresentBtn.addEventListener('click', function() {
document.querySelectorAll('.attendance-status').forEach(select => {
select.value = 'present';
});
});
}
// Clear all button
const clearAllBtn = document.getElementById('clearAll');
if (clearAllBtn) {
clearAllBtn.addEventListener('click', function() {
document.querySelectorAll('.attendance-status').forEach(select => {
select.value = '';
});
document.querySelectorAll('input[type="text"]').forEach(input => {
input.value = '';
});
});
}
// Initialize DataTable for better user experience with many students
if (typeof $.fn.DataTable !== 'undefined') {
$('#attendanceTable').DataTable({
"paging": true,
"lengthChange": true,
"searching": true,
"ordering": true,
"info": true,
"autoWidth": false,
"responsive": true,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
});
}
});
</script>
<?php
// Include footer
include_once 'includes/footer.php';
?>