<?php
$pageTitle = "Manage Announcements";
include_once('includes/header.php');
// Check if user is logged in and is admin
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header("Location: ../login.php");
exit();
}
// Initialize messages
$success_message = $error_message = $info_message = '';
// Handle flash messages
if (isset($_SESSION['success_message'])) {
$success_message = $_SESSION['success_message'];
unset($_SESSION['success_message']);
}
if (isset($_SESSION['error_message'])) {
$error_message = $_SESSION['error_message'];
unset($_SESSION['error_message']);
}
if (isset($_SESSION['info_message'])) {
$info_message = $_SESSION['info_message'];
unset($_SESSION['info_message']);
}
// Check if tables exist, if not create them
$tableExists = $conn->query("SHOW TABLES LIKE 'announcements'")->num_rows > 0;
if (!$tableExists) {
// Create announcements table
$conn->query("
CREATE TABLE IF NOT EXISTS `announcements` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
`created_by` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
`target_type` enum('all','course','user') NOT NULL DEFAULT 'all',
`course_id` int(11) DEFAULT NULL,
`importance` enum('normal','important','urgent') NOT NULL DEFAULT 'normal',
`status` enum('active','inactive') NOT NULL DEFAULT 'active',
`attachment` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `created_by` (`created_by`),
KEY `course_id` (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
");
// Create announcement_reads table
$conn->query("
CREATE TABLE IF NOT EXISTS `announcement_reads` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`announcement_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`read_date` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_read` (`announcement_id`,`user_id`),
KEY `announcement_id` (`announcement_id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
");
$info_message = "Announcement tables created successfully.";
}
// Handle form submission to create/update announcement
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_announcement'])) {
// Get form data
$title = trim($_POST['title']);
$content = trim($_POST['content']);
$target_type = $_POST['target_type'];
$course_id = ($target_type === 'course' && !empty($_POST['course_id'])) ? intval($_POST['course_id']) : null;
$importance = $_POST['importance'];
$status = $_POST['status'];
$start_date = !empty($_POST['start_date']) ? $_POST['start_date'] : date('Y-m-d');
$end_date = !empty($_POST['end_date']) ? $_POST['end_date'] : null;
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
// Validate required fields
if (empty($title) || empty($content)) {
$error_message = "Title and content are required.";
} else {
// Handle file upload if attachment is provided
$attachment_path = null;
if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] == 0) {
$allowed_extensions = ['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png', 'xlsx', 'pptx', 'txt'];
$filename = $_FILES['attachment']['name'];
$file_extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (in_array($file_extension, $allowed_extensions)) {
// Create uploads folder if it doesn't exist
$upload_dir = '../uploads/announcements/';
if (!file_exists($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
// Generate unique filename
$new_filename = 'announcement_' . time() . '_' . uniqid() . '.' . $file_extension;
$upload_path = $upload_dir . $new_filename;
if (move_uploaded_file($_FILES['attachment']['tmp_name'], $upload_path)) {
$attachment_path = 'uploads/announcements/' . $new_filename;
} else {
$error_message = "Failed to upload attachment. Please try again.";
}
} else {
$error_message = "Invalid file type. Allowed file types: " . implode(', ', $allowed_extensions);
}
}
if (empty($error_message)) {
// Current user and time
$user_id = $_SESSION['user_id'];
$created_at = date('Y-m-d H:i:s');
if ($id > 0) {
// Update existing announcement
$query = "
UPDATE announcements SET
title = ?, content = ?, updated_at = ?, start_date = ?, end_date = ?,
target_type = ?, course_id = ?, importance = ?, status = ?
";
// Only update attachment if new one was uploaded
if ($attachment_path) {
$query .= ", attachment = ?";
}
$query .= " WHERE id = ?";
$stmt = $conn->prepare($query);
if ($attachment_path) {
$stmt->bind_param("ssssssissi", $title, $content, $created_at, $start_date, $end_date,
$target_type, $course_id, $importance, $status, $attachment_path, $id);
} else {
$stmt->bind_param("ssssssssi", $title, $content, $created_at, $start_date, $end_date,
$target_type, $course_id, $importance, $status, $id);
}
if ($stmt->execute()) {
$success_message = "Announcement updated successfully.";
} else {
$error_message = "Error updating announcement: " . $stmt->error;
}
} else {
// Create new announcement
$stmt = $conn->prepare("
INSERT INTO announcements (title, content, created_by, created_at, start_date, end_date,
target_type, course_id, importance, status, attachment)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
$stmt->bind_param("ssissssisss", $title, $content, $user_id, $created_at, $start_date, $end_date,
$target_type, $course_id, $importance, $status, $attachment_path);
if ($stmt->execute()) {
$success_message = "Announcement created successfully.";
} else {
$error_message = "Error creating announcement: " . $stmt->error;
}
}
}
}
}
// Handle announcement deletion
if (isset($_GET['delete']) && is_numeric($_GET['delete'])) {
$id = intval($_GET['delete']);
// Get attachment info before deleting
$attachment_query = $conn->prepare("SELECT attachment FROM announcements WHERE id = ?");
$attachment_query->bind_param("i", $id);
$attachment_query->execute();
$attachment_result = $attachment_query->get_result();
if ($attachment_result->num_rows > 0) {
$attachment_data = $attachment_result->fetch_assoc();
$attachment_path = $attachment_data['attachment'];
// Delete the announcement
$delete_query = $conn->prepare("DELETE FROM announcements WHERE id = ?");
$delete_query->bind_param("i", $id);
if ($delete_query->execute()) {
// Also delete associated read records
$conn->query("DELETE FROM announcement_reads WHERE announcement_id = $id");
// Delete the attachment file if it exists
if (!empty($attachment_path) && file_exists('../' . $attachment_path)) {
unlink('../' . $attachment_path);
}
$success_message = "Announcement deleted successfully.";
} else {
$error_message = "Error deleting announcement.";
}
} else {
$error_message = "Announcement not found.";
}
}
// Get all courses for dropdown
$courses_query = "SELECT id, title FROM courses ORDER BY title";
$courses_result = $conn->query($courses_query);
$courses = [];
if ($courses_result->num_rows > 0) {
while ($row = $courses_result->fetch_assoc()) {
$courses[] = $row;
}
}
// Load announcement for editing if ID is provided
$editing = false;
$announcement = [
'id' => '',
'title' => '',
'content' => '',
'target_type' => 'all',
'course_id' => '',
'importance' => 'normal',
'status' => 'active',
'start_date' => date('Y-m-d'),
'end_date' => ''
];
if (isset($_GET['edit']) && is_numeric($_GET['edit'])) {
$id = intval($_GET['edit']);
$query = "SELECT * FROM announcements WHERE id = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$announcement = $result->fetch_assoc();
$editing = true;
}
}
// Get all announcements
$query = "
SELECT a.*, CONCAT(u.first_name, ' ', u.last_name) as creator_name, c.title as course_title,
(SELECT COUNT(*) FROM announcement_reads WHERE announcement_id = a.id) as read_count
FROM announcements a
LEFT JOIN users u ON a.created_by = u.id
LEFT JOIN courses c ON a.course_id = c.id
ORDER BY a.created_at DESC
";
$result = $conn->query($query);
$announcements = [];
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$announcements[] = $row;
}
}
?>
<div class="container-fluid">
<h1 class="h3 mb-4 text-gray-800"><?php echo $pageTitle; ?></h1>
<?php if (!empty($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 (!empty($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 (!empty($info_message)): ?>
<div class="alert alert-info alert-dismissible fade show" role="alert">
<i class="fas fa-info-circle me-2"></i> <?php echo $info_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="row">
<div class="col-lg-4">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<?php echo $editing ? 'Edit Announcement' : 'Create New Announcement'; ?>
</h6>
</div>
<div class="card-body">
<form action="" method="POST" enctype="multipart/form-data">
<?php if ($editing): ?>
<input type="hidden" name="id" value="<?php echo $announcement['id']; ?>">
<?php endif; ?>
<div class="mb-3">
<label for="title" class="form-label">Title <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="title" name="title" required
value="<?php echo htmlspecialchars($announcement['title']); ?>">
</div>
<div class="mb-3">
<label for="content" class="form-label">Content <span class="text-danger">*</span></label>
<textarea class="form-control" id="content" name="content" rows="5" required><?php echo htmlspecialchars($announcement['content']); ?></textarea>
</div>
<div class="mb-3">
<label for="target_type" class="form-label">Target Audience</label>
<select class="form-control" id="target_type" name="target_type">
<option value="all" <?php echo $announcement['target_type'] === 'all' ? 'selected' : ''; ?>>
All Students
</option>
<option value="course" <?php echo $announcement['target_type'] === 'course' ? 'selected' : ''; ?>>
Course Students Only
</option>
</select>
</div>
<div class="mb-3" id="course_selector" style="<?php echo $announcement['target_type'] !== 'course' ? 'display: none;' : ''; ?>">
<label for="course_id" class="form-label">Select Course</label>
<select class="form-control" id="course_id" name="course_id">
<option value="">-- Select Course --</option>
<?php foreach ($courses as $course): ?>
<option value="<?php echo $course['id']; ?>" <?php echo $announcement['course_id'] == $course['id'] ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($course['title']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="importance" class="form-label">Importance Level</label>
<select class="form-control" id="importance" name="importance">
<option value="normal" <?php echo $announcement['importance'] === 'normal' ? 'selected' : ''; ?>>
Normal
</option>
<option value="important" <?php echo $announcement['importance'] === 'important' ? 'selected' : ''; ?>>
Important
</option>
<option value="urgent" <?php echo $announcement['importance'] === 'urgent' ? 'selected' : ''; ?>>
Urgent
</option>
</select>
</div>
<div class="mb-3">
<label for="status" class="form-label">Status</label>
<select class="form-control" id="status" name="status">
<option value="active" <?php echo $announcement['status'] === 'active' ? 'selected' : ''; ?>>
Active
</option>
<option value="inactive" <?php echo $announcement['status'] === 'inactive' ? 'selected' : ''; ?>>
Inactive
</option>
</select>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="start_date" class="form-label">Start Date</label>
<input type="date" class="form-control" id="start_date" name="start_date"
value="<?php echo $announcement['start_date']; ?>">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="end_date" class="form-label">End Date</label>
<input type="date" class="form-control" id="end_date" name="end_date"
value="<?php echo $announcement['end_date']; ?>">
<small class="form-text text-muted">Leave blank for no expiration</small>
</div>
</div>
</div>
<div class="mb-3">
<label for="attachment" class="form-label">Attachment</label>
<input type="file" class="form-control" id="attachment" name="attachment">
<small class="form-text text-muted">Allowed: PDF, DOC, DOCX, JPG, PNG, XLSX, PPTX, TXT</small>
<?php if (!empty($announcement['attachment'])): ?>
<div class="mt-2">
<p>Current attachment: <a href="../<?php echo htmlspecialchars($announcement['attachment']); ?>" target="_blank">
<?php echo basename($announcement['attachment']); ?>
</a></p>
</div>
<?php endif; ?>
</div>
<div class="d-grid gap-2">
<button type="submit" name="save_announcement" class="btn btn-primary">
<i class="fas fa-save me-2"></i> <?php echo $editing ? 'Update Announcement' : 'Create Announcement'; ?>
</button>
<?php if ($editing): ?>
<a href="announcements.php" class="btn btn-secondary">
<i class="fas fa-plus me-2"></i> Create New
</a>
<?php endif; ?>
</div>
</form>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">All Announcements</h6>
</div>
<div class="card-body">
<?php if (empty($announcements)): ?>
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i> No announcements found. Create your first announcement now.
</div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-bordered" id="announcementsTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Title</th>
<th>Target</th>
<th>Created</th>
<th>Status</th>
<th>Read Count</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($announcements as $a): ?>
<tr>
<td>
<div class="d-flex align-items-center">
<?php if ($a['importance'] === 'urgent'): ?>
<span class="badge bg-danger me-2">URGENT</span>
<?php elseif ($a['importance'] === 'important'): ?>
<span class="badge bg-warning me-2">IMPORTANT</span>
<?php endif; ?>
<?php echo htmlspecialchars($a['title']); ?>
</div>
</td>
<td>
<?php if ($a['target_type'] === 'course'): ?>
<span class="badge bg-info">Course</span>
<div class="small mt-1"><?php echo htmlspecialchars($a['course_title']); ?></div>
<?php else: ?>
<span class="badge bg-primary">All Students</span>
<?php endif; ?>
</td>
<td>
<div><?php echo date('M d, Y', strtotime($a['created_at'])); ?></div>
<div class="small text-muted">by <?php echo htmlspecialchars($a['creator_name']); ?></div>
<?php if (!empty($a['end_date'])): ?>
<div class="small text-muted">
Expires: <?php echo date('M d, Y', strtotime($a['end_date'])); ?>
<?php if (strtotime($a['end_date']) < time()): ?>
<span class="badge bg-danger">Expired</span>
<?php endif; ?>
</div>
<?php endif; ?>
</td>
<td>
<?php if ($a['status'] === 'active'): ?>
<span class="badge bg-success">Active</span>
<?php else: ?>
<span class="badge bg-secondary">Inactive</span>
<?php endif; ?>
</td>
<td>
<?php echo $a['read_count']; ?> students
</td>
<td>
<div class="btn-group" role="group">
<a href="announcements.php?edit=<?php echo $a['id']; ?>" class="btn btn-sm btn-primary">
<i class="fas fa-edit"></i>
</a>
<a href="#" class="btn btn-sm btn-info" data-bs-toggle="modal" data-bs-target="#viewModal<?php echo $a['id']; ?>">
<i class="fas fa-eye"></i>
</a>
<a href="#" class="btn btn-sm btn-danger" onclick="confirmDelete(<?php echo $a['id']; ?>)">
<i class="fas fa-trash"></i>
</a>
</div>
<!-- View Modal -->
<div class="modal fade" id="viewModal<?php echo $a['id']; ?>" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo htmlspecialchars($a['title']); ?></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row mb-3">
<div class="col-md-6">
<p><strong>Created by:</strong> <?php echo htmlspecialchars($a['creator_name']); ?></p>
<p><strong>Date:</strong> <?php echo date('M d, Y', strtotime($a['created_at'])); ?></p>
<?php if (!empty($a['end_date'])): ?>
<p><strong>Expires:</strong> <?php echo date('M d, Y', strtotime($a['end_date'])); ?></p>
<?php endif; ?>
</div>
<div class="col-md-6">
<p><strong>Target:</strong>
<?php echo $a['target_type'] === 'course' ? 'Course: ' . htmlspecialchars($a['course_title']) : 'All Students'; ?>
</p>
<p><strong>Importance:</strong> <?php echo ucfirst($a['importance']); ?></p>
<p><strong>Status:</strong> <?php echo ucfirst($a['status']); ?></p>
</div>
</div>
<h6>Announcement Content:</h6>
<div class="border p-3 rounded mb-3 bg-light">
<?php echo nl2br(htmlspecialchars($a['content'])); ?>
</div>
<?php if (!empty($a['attachment'])): ?>
<p><strong>Attachment:</strong>
<a href="../<?php echo htmlspecialchars($a['attachment']); ?>" target="_blank">
<?php echo basename($a['attachment']); ?>
</a>
</p>
<?php endif; ?>
<div class="alert alert-info mt-3">
<i class="fas fa-eye me-2"></i> This announcement has been read by <strong><?php echo $a['read_count']; ?></strong> students.
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Initialize datatable
$('#announcementsTable').DataTable({
order: [[2, 'desc']] // Sort by created date
});
// Handle course selector visibility
document.getElementById('target_type').addEventListener('change', function() {
const courseSelector = document.getElementById('course_selector');
courseSelector.style.display = this.value === 'course' ? 'block' : 'none';
});
// Form validation
const form = document.querySelector('form');
if (form) {
form.addEventListener('submit', function(event) {
const targetType = document.getElementById('target_type').value;
const courseId = document.getElementById('course_id').value;
if (targetType === 'course' && !courseId) {
event.preventDefault();
alert('Please select a course for course-specific announcements.');
}
});
}
});
// Confirm deletion
function confirmDelete(id) {
if (confirm('Are you sure you want to delete this announcement? This action cannot be undone.')) {
window.location.href = 'announcements.php?delete=' + id;
}
}
</script>
<?php include_once('includes/footer.php'); ?>