37138-vm/functions.php
Flatlogic Bot bb0884a9fc SIAKAD 1.0
2025-12-24 04:07:02 +00:00

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;
}
?>