Server : Apache System : Linux profile 3.10.0-1160.88.1.el7.x86_64 #1 SMP Tue Mar 7 15:41:52 UTC 2023 x86_64 User : apache ( 48) PHP Version : 8.0.28 Disable Function : NONE Directory : /var/www/html/pragyabhardwaj/admin/ |
<?php
// 🔥 Mandatory for keeping track of CSRF security tokens
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
include 'db.php';
$upload_path = "static/upload/";
$msg = "";
// 🛡️ Initialize a session-bound CSRF token if one doesn't exist yet
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
/* ================= UTILITY FUNCTION FOR SECURE FILE UPLOAD ================= */
function validateAndUploadFile($file_field, $allowed_exts, $allowed_mimes, $prefix, $id, $upload_path) {
if (empty($_FILES[$file_field]['name'])) return null;
$filename = $_FILES[$file_field]['name'];
$tmp_name = $_FILES[$file_field]['tmp_name'];
// 1. Strict Extension Check
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!in_array($ext, $allowed_exts)) {
return ['error' => "❌ Invalid file extension! Allowed: " . implode(', ', $allowed_exts)];
}
// 2. Deep Binary Content Verification (MIME-Type)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $tmp_name);
finfo_close($finfo);
if (!in_array($mime, $allowed_mimes)) {
return ['error' => "❌ Malicious file structure detected! Upload aborted."];
}
// 3. Cryptographically Random Renaming (Prevents guessing or overriding files)
$new_name = $prefix . "_" . $id . "_" . bin2hex(random_bytes(4)) . "." . $ext;
if (move_uploaded_file($tmp_name, $upload_path . $new_name)) {
return ['success' => $new_name];
}
return ['error' => "❌ Failed to write the uploaded file to the directory."];
}
/* ================= POST: DELETE ================= */
if (isset($_POST['action_delete'])) {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("❌ CSRF Token Validation Failed!");
}
$id = intval($_POST['id']);
// Prepared Statement for Select
$stmt = $conn->prepare("SELECT image, pdf FROM book_chapters WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$data = $stmt->get_result()->fetch_assoc();
$stmt->close();
if ($data) {
if (!empty($data['image']) && file_exists($upload_path . $data['image'])) unlink($upload_path . $data['image']);
if (!empty($data['pdf']) && file_exists($upload_path . $data['pdf'])) unlink($upload_path . $data['pdf']);
}
// Prepared Statement for Delete
$stmt = $conn->prepare("DELETE FROM book_chapters WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
header("Location: index.php?page=book_chapter_form");
exit;
}
/* ================= POST: REMOVE IMAGE ================= */
if (isset($_POST['action_remove_image'])) {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("❌ CSRF Token Validation Failed!");
}
$id = intval($_POST['id']);
$stmt = $conn->prepare("SELECT image FROM book_chapters WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$data = $stmt->get_result()->fetch_assoc();
$stmt->close();
if ($data && $data['image']) {
$file = $upload_path . $data['image'];
if (file_exists($file)) unlink($file);
$stmt = $conn->prepare("UPDATE book_chapters SET image='' WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
}
header("Location: index.php?page=book_chapter_form");
exit;
}
/* ================= POST: REMOVE PDF ================= */
if (isset($_POST['action_remove_pdf'])) {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("❌ CSRF Token Validation Failed!");
}
$id = intval($_POST['id']);
$stmt = $conn->prepare("SELECT pdf FROM book_chapters WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$data = $stmt->get_result()->fetch_assoc();
$stmt->close();
if ($data && $data['pdf']) {
$file = $upload_path . $data['pdf'];
if (file_exists($file)) unlink($file);
$stmt = $conn->prepare("UPDATE book_chapters SET pdf='' WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
}
header("Location: index.php?page=book_chapter_form");
exit;
}
/* ================= POST: UPDATE ================= */
if (isset($_POST['update'])) {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("❌ CSRF Token Validation Failed!");
}
$id = intval($_POST['id']);
$title = trim($_POST['title']);
$inst = trim($_POST['institute']);
$year = trim($_POST['year']);
$details = trim($_POST['details']);
$link = filter_var(trim($_POST['link']), FILTER_SANITIZE_URL);
$image = $_POST['old_image'];
$pdf = $_POST['old_pdf'];
$img_exts = ['jpg', 'jpeg', 'png', 'gif'];
$img_mimes = ['image/jpeg', 'image/png', 'image/gif'];
$pdf_exts = ['pdf'];
$pdf_mimes = ['application/pdf'];
/* IMAGE UPDATE processing */
if (!empty($_FILES['new_image']['name'])) {
$upload_res = validateAndUploadFile('new_image', $img_exts, $img_mimes, 'book_chapter', $id, $upload_path);
if (isset($upload_res['error'])) {
die($upload_res['error']);
} else {
if ($image && file_exists($upload_path . $image)) unlink($upload_path . $image);
$image = $upload_res['success'];
}
}
/* PDF UPDATE processing */
if (!empty($_FILES['new_pdf']['name'])) {
$upload_res = validateAndUploadFile('new_pdf', $pdf_exts, $pdf_mimes, 'book_chapter_pdf', $id, $upload_path);
if (isset($upload_res['error'])) {
die($upload_res['error']);
} else {
if ($pdf && file_exists($upload_path . $pdf)) unlink($upload_path . $pdf);
$pdf = $upload_res['success'];
}
}
// Secured Mutation
$stmt = $conn->prepare("UPDATE book_chapters SET title=?, institute=?, year=?, details=?, link=?, image=?, pdf=? WHERE id=?");
$stmt->bind_param("sssssssi", $title, $inst, $year, $details, $link, $image, $pdf, $id);
$stmt->execute();
$stmt->close();
header("Location: index.php?page=book_chapter_form");
exit;
}
/* ================= POST: INSERT ================= */
if (isset($_POST['save'])) {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("❌ CSRF Token Validation Failed!");
}
$title = trim($_POST['title']);
$inst = trim($_POST['institute']);
$year = trim($_POST['year']);
$details = trim($_POST['details']);
$link = filter_var(trim($_POST['link']), FILTER_SANITIZE_URL);
// Initial safe execution
$stmt = $conn->prepare("INSERT INTO book_chapters (title, institute, year, details, link, image, pdf, sort_order) VALUES (?, ?, ?, ?, ?, '', '', 0)");
$stmt->bind_param("sssss", $title, $inst, $year, $details, $link);
$stmt->execute();
$last_id = $stmt->insert_id;
$stmt->close();
$img_exts = ['jpg', 'jpeg', 'png', 'gif'];
$img_mimes = ['image/jpeg', 'image/png', 'image/gif'];
$pdf_exts = ['pdf'];
$pdf_mimes = ['application/pdf'];
/* IMAGE INSERT processing */
if (!empty($_FILES['image']['name'])) {
$upload_res = validateAndUploadFile('image', $img_exts, $img_mimes, 'book_chapter', $last_id, $upload_path);
if (isset($upload_res['error'])) {
$msg = $upload_res['error'];
} else {
$image = $upload_res['success'];
$stmt = $conn->prepare("UPDATE book_chapters SET image=? WHERE id=?");
$stmt->bind_param("si", $image, $last_id);
$stmt->execute();
$stmt->close();
}
}
/* PDF INSERT processing */
if (!empty($_FILES['pdf']['name'])) {
$upload_res = validateAndUploadFile('pdf', $pdf_exts, $pdf_mimes, 'book_chapter_pdf', $last_id, $upload_path);
if (isset($upload_res['error'])) {
$msg = $upload_res['error'];
} else {
$pdf = $upload_res['success'];
$stmt = $conn->prepare("UPDATE book_chapters SET pdf=? WHERE id=?");
$stmt->bind_param("si", $pdf, $last_id);
$stmt->execute();
$stmt->close();
}
}
if (empty($msg)) {
header("Location: index.php?page=book_chapter_form");
exit;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Book Chapters</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="static/css/admin.css">
</head>
<body>
<?php include 'admin/topbar.php'; ?>
<div class="container mt-4">
<div class="box p-4 bg-light border rounded">
<h2>📚 Add Book Chapter</h2>
<?php if(!empty($msg)) echo "<div class='alert alert-danger'>".htmlspecialchars($msg)."</div>"; ?>
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token']; ?>">
<div class="row">
<div class="col-md-3 mb-3"><label>Cover Image</label><input type="file" name="image" class="form-control"></div>
<div class="col-md-2 mb-3"><label>Year</label><input type="text" name="year" class="form-control" placeholder="Year"></div>
<div class="col-md-3 mb-3"><label>Title</label><input type="text" name="title" class="form-control" placeholder="Title"></div>
<div class="col-md-4 mb-3"><label>Publisher</label><input type="text" name="institute" class="form-control" placeholder="Publisher"></div>
<div class="col-md-6 mb-3"><label>External Link</label><input type="url" name="link" class="form-control" placeholder="https://example.com"></div>
<div class="col-md-6 mb-3"><label>PDF File</label><input type="file" name="pdf" class="form-control"></div>
<div class="col-12 mb-3"><label>Details</label><textarea name="details" class="form-control" placeholder="Details"></textarea></div>
<div class="col-12"><button name="save" class="btn btn-primary px-5">Save Chapter</button></div>
</div>
</form>
<hr>
<h4>All Records (Inline Edit)</h4>
<div class="table-responsive">
<table class="table table-bordered table-hover align-middle">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Image</th>
<th>Year</th>
<th>Title</th>
<th>Publisher</th>
<th>Link</th>
<th>PDF</th>
<th>Details</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
$res = mysqli_query($conn, "SELECT * FROM book_chapters ORDER BY sort_order ASC, id DESC");
while($row = mysqli_fetch_assoc($res)){
?>
<tr>
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token']; ?>">
<input type="hidden" name="id" value="<?= $row['id'] ?>">
<td><?= $row['id'] ?></td>
<td>
<?php if($row['image']) { ?>
<img src="<?= htmlspecialchars($upload_path . $row['image']) ?>" width="60" class="d-block mb-1">
<?php } ?>
<input type="file" name="new_image" class="form-control form-control-sm mb-1">
<input type="hidden" name="old_image" value="<?= htmlspecialchars($row['image']) ?>">
<?php if($row['image']) { ?>
<button type="submit" name="action_remove_image" class="btn btn-warning btn-sm w-100">Remove</button>
<?php } ?>
</td>
<td><input type="text" name="year" class="form-control" value="<?= htmlspecialchars($row['year']) ?>"></td>
<td><input type="text" name="title" class="form-control" value="<?= htmlspecialchars($row['title']) ?>"></td>
<td><input type="text" name="institute" class="form-control" value="<?= htmlspecialchars($row['institute']) ?>"></td>
<td><input type="url" name="link" class="form-control" value="<?= htmlspecialchars($row['link']) ?>"></td>
<td>
<?php if($row['pdf']) { ?>
<a href="<?= htmlspecialchars($upload_path . $row['pdf']) ?>" target="_blank" class="btn btn-outline-secondary btn-sm d-block mb-1">View PDF</a>
<?php } ?>
<input type="file" name="new_pdf" class="form-control form-control-sm mb-1">
<input type="hidden" name="old_pdf" value="<?= htmlspecialchars($row['pdf']) ?>">
<?php if($row['pdf']) { ?>
<button type="submit" name="action_remove_pdf" class="btn btn-warning btn-sm w-100">Remove</button>
<?php } ?>
</td>
<td><textarea name="details" class="form-control" rows="2"><?= htmlspecialchars($row['details']) ?></textarea></td>
<td>
<button type="submit" name="update" class="btn btn-success btn-sm w-100 mb-1">Update</button>
<button type="submit" name="action_delete" class="btn btn-danger btn-sm w-100" onclick="return confirm('Delete this chapter?');">Delete</button>
</td>
</form>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>