659 lines
24 KiB
PHP
659 lines
24 KiB
PHP
|
|
<?php
|
|
|
|
function is_active($page_name) {
|
|
$page = $_GET['page'] ?? 'dashboard';
|
|
return $page === $page_name ? 'active' : '';
|
|
}
|
|
|
|
function get_page_title() {
|
|
$page = $_GET['page'] ?? 'dashboard';
|
|
return ucfirst($page);
|
|
}
|
|
|
|
function get_all_murid() {
|
|
$pdo = db();
|
|
$stmt = $pdo->query("SELECT m.id, m.nis, m.nisn, m.nama_lengkap, m.jenis_kelamin, m.email, m.foto, k.nama_kelas
|
|
FROM murid m
|
|
LEFT JOIN kelas k ON m.kelas_id = k.id
|
|
ORDER BY m.nama_lengkap ASC");
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function get_murid_by_id($id) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT * FROM murid WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function handle_murid_action() {
|
|
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
|
|
|
// Handle Delete Action via GET first as it redirects
|
|
if ($action === 'delete' && isset($_GET['id'])) {
|
|
$id = $_GET['id'];
|
|
$murid = get_murid_by_id($id); // Get murid data to delete foto
|
|
$pdo = db();
|
|
try {
|
|
// Delete old photo if exists
|
|
if (!empty($murid['foto'])) {
|
|
$photo_path = 'assets/uploads/murid/' . $murid['foto'];
|
|
if (file_exists($photo_path)) {
|
|
unlink($photo_path);
|
|
}
|
|
}
|
|
$stmt = $pdo->prepare("DELETE FROM murid WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
header("Location: index.php?page=murid&status=deleted");
|
|
exit();
|
|
} catch (PDOException $e) {
|
|
header("Location: index.php?page=murid&status=error");
|
|
exit();
|
|
}
|
|
}
|
|
|
|
// Only proceed with POST actions from here
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
return null;
|
|
}
|
|
|
|
$pdo = db();
|
|
$id = $_POST['id'] ?? null;
|
|
|
|
// Handle Import
|
|
if ($action === 'import') {
|
|
if (isset($_FILES['file_murid']) && $_FILES['file_murid']['error'] === UPLOAD_ERR_OK) {
|
|
$file_tmp_path = $_FILES['file_murid']['tmp_name'];
|
|
return import_murid_from_xlsx($file_tmp_path);
|
|
} else {
|
|
return ['success' => false, 'message' => 'Gagal mengunggah file. Silakan coba lagi.'];
|
|
}
|
|
}
|
|
|
|
// Handle Add/Edit
|
|
$nis = $_POST['nis'] ?? '';
|
|
$nisn = $_POST['nisn'] ?? '';
|
|
$nama_lengkap = $_POST['nama_lengkap'] ?? '';
|
|
$tempat_lahir = $_POST['tempat_lahir'] ?? '';
|
|
$tanggal_lahir = $_POST['tanggal_lahir'] ?? '';
|
|
$jenis_kelamin = $_POST['jenis_kelamin'] ?? '';
|
|
$alamat = $_POST['alamat'] ?? '';
|
|
$latitude = $_POST['latitude'] ?? '';
|
|
$longitude = $_POST['longitude'] ?? '';
|
|
$no_telepon = $_POST['no_telepon'] ?? '';
|
|
$email = $_POST['email'] ?? '';
|
|
$kelas_id = !empty($_POST['kelas_id']) ? $_POST['kelas_id'] : null;
|
|
|
|
|
|
$foto_filename = $_POST['foto_existing'] ?? null;
|
|
|
|
// Handle file upload
|
|
if (isset($_FILES['foto']) && $_FILES['foto']['error'] === UPLOAD_ERR_OK) {
|
|
$upload_dir = 'assets/uploads/murid/';
|
|
if (!is_dir($upload_dir)) {
|
|
mkdir($upload_dir, 0777, true);
|
|
}
|
|
|
|
$tmp_name = $_FILES['foto']['tmp_name'];
|
|
$original_name = basename($_FILES['foto']['name']);
|
|
$file_ext = strtolower(pathinfo($original_name, PATHINFO_EXTENSION));
|
|
$safe_filename = preg_replace('/[^A-Za-z0-9_.-]/', '_', pathinfo($original_name, PATHINFO_FILENAME));
|
|
$foto_filename = uniqid() . '_' . $safe_filename . '.' . $file_ext;
|
|
|
|
// Delete old photo if a new one is uploaded during edit
|
|
if ($action === 'edit' && !empty($_POST['foto_existing'])) {
|
|
$old_photo_path = $upload_dir . $_POST['foto_existing'];
|
|
if (file_exists($old_photo_path)) {
|
|
unlink($old_photo_path);
|
|
}
|
|
}
|
|
|
|
if (!move_uploaded_file($tmp_name, $upload_dir . $foto_filename)) {
|
|
return ['success' => false, 'message' => 'Gagal memindahkan file foto.'];
|
|
}
|
|
}
|
|
|
|
try {
|
|
if ($action === 'add') {
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO murid (nis, nisn, nama_lengkap, tempat_lahir, tanggal_lahir, jenis_kelamin, alamat, foto, latitude, longitude, no_telepon, email, kelas_id)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
|
);
|
|
$stmt->execute([$nis, $nisn, $nama_lengkap, $tempat_lahir, $tanggal_lahir, $jenis_kelamin, $alamat, $foto_filename, $latitude, $longitude, $no_telepon, $email, $kelas_id]);
|
|
return ['success' => true, 'message' => 'Data murid berhasil ditambahkan.'];
|
|
} elseif ($action === 'edit' && $id) {
|
|
$stmt = $pdo->prepare(
|
|
"UPDATE murid SET nis = ?, nisn = ?, nama_lengkap = ?, tempat_lahir = ?, tanggal_lahir = ?,
|
|
jenis_kelamin = ?, alamat = ?, foto = ?, latitude = ?, longitude = ?, no_telepon = ?, email = ?, kelas_id = ? WHERE id = ?"
|
|
);
|
|
$stmt->execute([$nis, $nisn, $nama_lengkap, $tempat_lahir, $tanggal_lahir, $jenis_kelamin, $alamat, $foto_filename, $latitude, $longitude, $no_telepon, $email, $kelas_id, $id]);
|
|
return ['success' => true, 'message' => 'Data murid berhasil diperbarui.'];
|
|
}
|
|
} catch (PDOException $e) {
|
|
if ($e->getCode() == 23000) { // Integrity constraint violation
|
|
return ['success' => false, 'message' => 'Gagal menyimpan data. NIS atau NISN sudah terdaftar.'];
|
|
}
|
|
return ['success' => false, 'message' => 'Terjadi kesalahan database: ' . $e->getMessage()];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function import_murid_from_xlsx($filepath) {
|
|
// Include the parser library
|
|
require_once 'libs/SimpleXLSX.php';
|
|
|
|
// Check if the file exists and is readable
|
|
if (!file_exists($filepath) || !is_readable($filepath)) {
|
|
return ['success' => false, 'message' => 'File tidak ditemukan atau tidak bisa dibaca.'];
|
|
}
|
|
|
|
// Try to parse the XLSX file
|
|
if ($xlsx = Shuchkin\SimpleXLSX::parse($filepath)) {
|
|
$pdo = db();
|
|
$success_count = 0;
|
|
$fail_count = 0;
|
|
$errors = [];
|
|
|
|
// Get rows as array
|
|
$rows = $xlsx->rows();
|
|
|
|
// Skip header row (the first row)
|
|
$is_header = true;
|
|
|
|
foreach ($rows as $row) {
|
|
if ($is_header) {
|
|
$is_header = false;
|
|
continue;
|
|
}
|
|
|
|
// Assign columns to variables - assuming order: NIS, NISN, Nama, Tgl Lahir, Alamat
|
|
$nis = $row[0] ?? '';
|
|
$nisn = $row[1] ?? '';
|
|
$nama_lengkap = $row[2] ?? '';
|
|
$tanggal_lahir = $row[3] ?? '';
|
|
$alamat = $row[4] ?? '';
|
|
|
|
// Basic validation: skip if NIS or name is empty
|
|
if (empty($nis) || empty($nama_lengkap)) {
|
|
$fail_count++;
|
|
$errors[] = "Baris data dengan NIS '.htmlspecialchars($nis).' dan Nama '.htmlspecialchars($nama_lengkap).' dilewati karena data tidak lengkap.";
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
// Using the existing add function logic
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO murid (nis, nisn, nama_lengkap, tanggal_lahir, alamat)
|
|
VALUES (?, ?, ?, ?, ?)"
|
|
);
|
|
$stmt->execute([$nis, $nisn, $nama_lengkap, $tanggal_lahir, $alamat]);
|
|
$success_count++;
|
|
} catch (PDOException $e) {
|
|
$fail_count++;
|
|
if ($e->getCode() == 23000) {
|
|
$errors[] = "NIS atau NISN '.htmlspecialchars($nis).' sudah ada di database.";
|
|
} else {
|
|
$errors[] = "Gagal memasukkan data untuk NIS '.htmlspecialchars($nis).': " . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
$message = "Impor selesai. Berhasil: {$success_count}, Gagal: {$fail_count}.";
|
|
if (!empty($errors)) {
|
|
$message .= "<br>Detail kegagalan:<br>" . implode("<br>", $errors);
|
|
}
|
|
|
|
return ['success' => ($fail_count === 0), 'message' => $message];
|
|
|
|
} else {
|
|
return ['success' => false, 'message' => 'Gagal memproses file XLSX: ' . Shuchkin\SimpleXLSX::parseError()];
|
|
}
|
|
}
|
|
|
|
function get_all_guru() {
|
|
$pdo = db();
|
|
$stmt = $pdo->query("SELECT id, nip, nama, foto FROM guru ORDER BY nama ASC");
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function get_guru_by_id($id) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT * FROM guru WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function handle_guru_action() {
|
|
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
|
|
|
if ($action === 'delete' && isset($_GET['id'])) {
|
|
$id = $_GET['id'];
|
|
$guru = get_guru_by_id($id);
|
|
$pdo = db();
|
|
try {
|
|
if (!empty($guru['foto'])) {
|
|
$photo_path = 'assets/uploads/guru/' . $guru['foto'];
|
|
if (file_exists($photo_path)) {
|
|
unlink($photo_path);
|
|
}
|
|
}
|
|
$stmt = $pdo->prepare("DELETE FROM guru WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
header("Location: index.php?page=teachers&status=deleted");
|
|
exit();
|
|
} catch (PDOException $e) {
|
|
header("Location: index.php?page=teachers&status=error");
|
|
exit();
|
|
}
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
return null;
|
|
}
|
|
|
|
$pdo = db();
|
|
$id = $_POST['id'] ?? null;
|
|
$nip = $_POST['nip'] ?? '';
|
|
$nama = $_POST['nama'] ?? '';
|
|
$alamat = $_POST['alamat'] ?? '';
|
|
$telepon = $_POST['telepon'] ?? '';
|
|
$latitude = $_POST['latitude'] ?? '';
|
|
$longitude = $_POST['longitude'] ?? '';
|
|
|
|
$foto_filename = $_POST['foto_existing'] ?? null;
|
|
|
|
if (isset($_FILES['foto']) && $_FILES['foto']['error'] === UPLOAD_ERR_OK) {
|
|
$upload_dir = 'assets/uploads/guru/';
|
|
if (!is_dir($upload_dir)) {
|
|
mkdir($upload_dir, 0777, true);
|
|
}
|
|
|
|
$tmp_name = $_FILES['foto']['tmp_name'];
|
|
$original_name = basename($_FILES['foto']['name']);
|
|
$file_ext = strtolower(pathinfo($original_name, PATHINFO_EXTENSION));
|
|
$safe_filename = preg_replace('/[^A-Za-z0-9_.-]/', '_', pathinfo($original_name, PATHINFO_FILENAME));
|
|
$foto_filename = uniqid() . '_' . $safe_filename . '.' . $file_ext;
|
|
|
|
if ($action === 'edit' && !empty($_POST['foto_existing'])) {
|
|
$old_photo_path = $upload_dir . $_POST['foto_existing'];
|
|
if (file_exists($old_photo_path)) {
|
|
unlink($old_photo_path);
|
|
}
|
|
}
|
|
|
|
if (!move_uploaded_file($tmp_name, $upload_dir . $foto_filename)) {
|
|
return ['success' => false, 'message' => 'Gagal memindahkan file foto.'];
|
|
}
|
|
}
|
|
|
|
try {
|
|
if ($action === 'add') {
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO guru (nip, nama, alamat, telepon, foto, latitude, longitude)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)"
|
|
);
|
|
$stmt->execute([$nip, $nama, $alamat, $telepon, $foto_filename, $latitude, $longitude]);
|
|
return ['success' => true, 'message' => 'Data guru berhasil ditambahkan.'];
|
|
} elseif ($action === 'edit' && $id) {
|
|
$stmt = $pdo->prepare(
|
|
"UPDATE guru SET nip = ?, nama = ?, alamat = ?, telepon = ?, foto = ?, latitude = ?, longitude = ? WHERE id = ?"
|
|
);
|
|
$stmt->execute([$nip, $nama, $alamat, $telepon, $foto_filename, $latitude, $longitude, $id]);
|
|
return ['success' => true, 'message' => 'Data guru berhasil diperbarui.'];
|
|
}
|
|
} catch (PDOException $e) {
|
|
if ($e->getCode() == 23000) { // Integrity constraint violation
|
|
return ['success' => false, 'message' => 'Gagal menyimpan data. NIP sudah terdaftar.'];
|
|
}
|
|
return ['success' => false, 'message' => 'Terjadi kesalahan database: ' . $e->getMessage()];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function get_all_kelas() {
|
|
$pdo = db();
|
|
$stmt = $pdo->query("
|
|
SELECT k.id, k.nama_kelas, g.nama as nama_wali_kelas
|
|
FROM kelas k
|
|
LEFT JOIN guru g ON k.id_wali_kelas = g.id
|
|
ORDER BY k.nama_kelas ASC
|
|
");
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function get_kelas_by_id($id) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT * FROM kelas WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function handle_kelas_action() {
|
|
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
|
|
|
if ($action === 'delete' && isset($_GET['id'])) {
|
|
$id = $_GET['id'];
|
|
$pdo = db();
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM kelas WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
header("Location: index.php?page=classes&status=deleted");
|
|
exit();
|
|
} catch (PDOException $e) {
|
|
// Foreign key constraint might fail, though ON DELETE SET NULL should prevent it.
|
|
// Good to have a generic error handler.
|
|
header("Location: index.php?page=classes&status=error");
|
|
exit();
|
|
}
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
return null;
|
|
}
|
|
|
|
$pdo = db();
|
|
$id = $_POST['id'] ?? null;
|
|
$nama_kelas = $_POST['nama_kelas'] ?? '';
|
|
// Use 'none' or null for the wali kelas if not selected
|
|
$id_wali_kelas = !empty($_POST['id_wali_kelas']) ? $_POST['id_wali_kelas'] : null;
|
|
|
|
try {
|
|
if ($action === 'add') {
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO kelas (nama_kelas, id_wali_kelas) VALUES (?, ?)"
|
|
);
|
|
$stmt->execute([$nama_kelas, $id_wali_kelas]);
|
|
return ['success' => true, 'message' => 'Data kelas berhasil ditambahkan.'];
|
|
} elseif ($action === 'edit' && $id) {
|
|
$stmt = $pdo->prepare(
|
|
"UPDATE kelas SET nama_kelas = ?, id_wali_kelas = ? WHERE id = ?"
|
|
);
|
|
$stmt->execute([$nama_kelas, $id_wali_kelas, $id]);
|
|
return ['success' => true, 'message' => 'Data kelas berhasil diperbarui.'];
|
|
}
|
|
} catch (PDOException $e) {
|
|
if ($e->getCode() == 23000) {
|
|
return ['success' => false, 'message' => 'Gagal menyimpan data. Nama kelas mungkin sudah ada.'];
|
|
}
|
|
return ['success' => false, 'message' => 'Terjadi kesalahan database: ' . $e->getMessage()];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
function get_all_jadwal() {
|
|
$pdo = db();
|
|
$stmt = $pdo->query("
|
|
SELECT
|
|
j.id,
|
|
j.hari,
|
|
j.jam_mulai,
|
|
j.jam_selesai,
|
|
mp.nama_matapelajaran,
|
|
k.nama_kelas,
|
|
g.nama as nama_guru
|
|
FROM jadwal j
|
|
JOIN kelas k ON j.id_kelas = k.id
|
|
JOIN guru g ON j.id_guru = g.id
|
|
LEFT JOIN mata_pelajaran mp ON j.id_matapelajaran = mp.id
|
|
ORDER BY k.nama_kelas, FIELD(j.hari, 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu'), j.jam_mulai
|
|
");
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function get_jadwal_by_id($id) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT * FROM jadwal WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function handle_jadwal_action() {
|
|
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
|
|
|
if ($action === 'delete' && isset($_GET['id'])) {
|
|
$id = $_GET['id'];
|
|
$pdo = db();
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM jadwal WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
header("Location: index.php?page=schedule&status=deleted");
|
|
exit();
|
|
} catch (PDOException $e) {
|
|
header("Location: index.php?page=schedule&status=error");
|
|
exit();
|
|
}
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
return null;
|
|
}
|
|
|
|
$pdo = db();
|
|
$id = $_POST['id'] ?? null;
|
|
$id_kelas = $_POST['id_kelas'] ?? '';
|
|
$id_guru = $_POST['id_guru'] ?? '';
|
|
$id_matapelajaran = $_POST['id_matapelajaran'] ?? ''; // New field
|
|
$hari = $_POST['hari'] ?? '';
|
|
$jam_mulai = $_POST['jam_mulai'] ?? '';
|
|
$jam_selesai = $_POST['jam_selesai'] ?? '';
|
|
|
|
// Basic validation
|
|
if (empty($id_kelas) || empty($id_guru) || empty($id_matapelajaran) || empty($hari) || empty($jam_mulai) || empty($jam_selesai)) {
|
|
return ['success' => false, 'message' => 'Semua kolom wajib diisi.'];
|
|
}
|
|
|
|
try {
|
|
if ($action === 'add') {
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO jadwal (id_kelas, id_guru, id_matapelajaran, hari, jam_mulai, jam_selesai)
|
|
VALUES (?, ?, ?, ?, ?, ?)"
|
|
);
|
|
$stmt->execute([$id_kelas, $id_guru, $id_matapelajaran, $hari, $jam_mulai, $jam_selesai]);
|
|
return ['success' => true, 'message' => 'Data jadwal berhasil ditambahkan.'];
|
|
} elseif ($action === 'edit' && $id) {
|
|
$stmt = $pdo->prepare(
|
|
"UPDATE jadwal SET id_kelas = ?, id_guru = ?, id_matapelajaran = ?, hari = ?, jam_mulai = ?, jam_selesai = ?
|
|
WHERE id = ?"
|
|
);
|
|
$stmt->execute([$id_kelas, $id_guru, $id_matapelajaran, $hari, $jam_mulai, $jam_selesai, $id]);
|
|
return ['success' => true, 'message' => 'Data jadwal berhasil diperbarui.'];
|
|
}
|
|
} catch (PDOException $e) {
|
|
return ['success' => false, 'message' => 'Terjadi kesalahan database: ' . $e->getMessage()];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// Attendance Functions
|
|
|
|
function get_murid_by_kelas($kelas_id) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT id, nama_lengkap FROM murid WHERE kelas_id = ? ORDER BY nama_lengkap ASC");
|
|
$stmt->execute([$kelas_id]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function get_jadwal_by_kelas_and_hari($kelas_id, $hari) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("
|
|
SELECT j.id, mp.nama_matapelajaran, j.jam_mulai, j.jam_selesai
|
|
FROM jadwal j
|
|
LEFT JOIN mata_pelajaran mp ON j.id_matapelajaran = mp.id
|
|
WHERE j.id_kelas = ? AND j.hari = ? ORDER BY j.jam_mulai ASC");
|
|
$stmt->execute([$kelas_id, $hari]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function get_absensi($id_kelas, $tanggal) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("
|
|
SELECT murid_id, jadwal_id, status
|
|
FROM absensi
|
|
WHERE tanggal = ? AND jadwal_id IN (SELECT id FROM jadwal WHERE id_kelas = ?)
|
|
");
|
|
$stmt->execute([$tanggal, $id_kelas]);
|
|
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Format the result for easier lookup in the template
|
|
$absensi_data = [];
|
|
foreach ($result as $row) {
|
|
$absensi_data[$row['murid_id']][$row['jadwal_id']] = $row['status'];
|
|
}
|
|
return $absensi_data;
|
|
}
|
|
|
|
function handle_absensi_action() {
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['action']) || $_POST['action'] !== 'save_absensi') {
|
|
return null;
|
|
}
|
|
|
|
$id_kelas = $_POST['id_kelas'] ?? '';
|
|
$tanggal = $_POST['tanggal'] ?? '';
|
|
$absensi = $_POST['absensi'] ?? [];
|
|
|
|
if (empty($id_kelas) || empty($tanggal) || empty($absensi)) {
|
|
return ['success' => false, 'message' => 'Data tidak lengkap. Harap pilih kelas, tanggal, dan isi absensi.'];
|
|
}
|
|
|
|
$pdo = db();
|
|
try {
|
|
$pdo->beginTransaction();
|
|
|
|
// Prepare statement for inserting/updating attendance
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO absensi (jadwal_id, murid_id, tanggal, status)
|
|
VALUES (:jadwal_id, :murid_id, :tanggal, :status)
|
|
ON DUPLICATE KEY UPDATE status = :status
|
|
");
|
|
|
|
foreach ($absensi as $murid_id => $jadwal_absensi) {
|
|
foreach ($jadwal_absensi as $jadwal_id => $status) {
|
|
if (!empty($status)) {
|
|
$stmt->execute([
|
|
':jadwal_id' => $jadwal_id,
|
|
':murid_id' => $murid_id,
|
|
':tanggal' => $tanggal,
|
|
':status' => $status
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
$pdo->commit();
|
|
return ['success' => true, 'message' => 'Absensi berhasil disimpan.'];
|
|
|
|
} catch (PDOException $e) {
|
|
$pdo->rollBack();
|
|
return ['success' => false, 'message' => 'Gagal menyimpan absensi: ' . $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
function get_rekap_absensi($id_kelas, $start_date, $end_date) {
|
|
$pdo = db();
|
|
|
|
// Validate input dates
|
|
if (empty($id_kelas) || empty($start_date) || empty($end_date)) {
|
|
return [];
|
|
}
|
|
|
|
$sql = "
|
|
SELECT
|
|
m.id as murid_id,
|
|
m.nis,
|
|
m.nama_lengkap,
|
|
COUNT(a.id) as total_absensi,
|
|
SUM(CASE WHEN a.status = 'Hadir' THEN 1 ELSE 0 END) as total_hadir,
|
|
SUM(CASE WHEN a.status = 'Sakit' THEN 1 ELSE 0 END) as total_sakit,
|
|
SUM(CASE WHEN a.status = 'Izin' THEN 1 ELSE 0 END) as total_izin,
|
|
SUM(CASE WHEN a.status = 'Alpa' THEN 1 ELSE 0 END) as total_alpa
|
|
FROM murid m
|
|
LEFT JOIN absensi a ON m.id = a.murid_id
|
|
WHERE m.kelas_id = :id_kelas
|
|
AND a.tanggal BETWEEN :start_date AND :end_date
|
|
GROUP BY m.id, m.nis, m.nama_lengkap
|
|
ORDER BY m.nama_lengkap ASC;
|
|
";
|
|
|
|
try {
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute([
|
|
':id_kelas' => $id_kelas,
|
|
':start_date' => $start_date,
|
|
':end_date' => $end_date
|
|
]);
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
// Log error or handle it as needed
|
|
error_log("Rekap Absensi Error: " . $e->getMessage());
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Subject (Mata Pelajaran) Functions
|
|
|
|
function get_all_matapelajaran() {
|
|
$pdo = db();
|
|
$stmt = $pdo->query("SELECT * FROM mata_pelajaran ORDER BY nama_matapelajaran ASC");
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function get_matapelajaran_by_id($id) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT * FROM mata_pelajaran WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
function handle_matapelajaran_action() {
|
|
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
|
|
|
if ($action === 'delete' && isset($_GET['id'])) {
|
|
$id = $_GET['id'];
|
|
$pdo = db();
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM mata_pelajaran WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
header("Location: index.php?page=subjects&status=deleted");
|
|
exit();
|
|
} catch (PDOException $e) {
|
|
header("Location: index.php?page=subjects&status=error&err_msg=" . urlencode($e->getMessage()));
|
|
exit();
|
|
}
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
return null;
|
|
}
|
|
|
|
$pdo = db();
|
|
$id = $_POST['id'] ?? null;
|
|
$nama_matapelajaran = $_POST['nama_matapelajaran'] ?? '';
|
|
|
|
try {
|
|
if ($action === 'add') {
|
|
$stmt = $pdo->prepare("INSERT INTO mata_pelajaran (nama_matapelajaran) VALUES (?)");
|
|
$stmt->execute([$nama_matapelajaran]);
|
|
return ['success' => true, 'message' => 'Data mata pelajaran berhasil ditambahkan.'];
|
|
} elseif ($action === 'edit' && $id) {
|
|
$stmt = $pdo->prepare("UPDATE mata_pelajaran SET nama_matapelajaran = ? WHERE id = ?");
|
|
$stmt->execute([$nama_matapelajaran, $id]);
|
|
return ['success' => true, 'message' => 'Data mata pelajaran berhasil diperbarui.'];
|
|
}
|
|
} catch (PDOException $e) {
|
|
if ($e->getCode() == 23000) {
|
|
return ['success' => false, 'message' => 'Gagal menyimpan data. Nama mata pelajaran mungkin sudah ada.'];
|
|
}
|
|
return ['success' => false, 'message' => 'Terjadi kesalahan database: ' . $e->getMessage()];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
?>
|