post editor
This commit is contained in:
parent
44a47c5d24
commit
415571db64
105
admin.php
Normal file
105
admin.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
|
||||
// Handle deletion
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_id'])) {
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("DELETE FROM posts WHERE id = ?");
|
||||
$stmt->execute([$_POST['delete_id']]);
|
||||
header("Location: admin.php?deleted=true");
|
||||
exit;
|
||||
} catch (PDOException $e) {
|
||||
error_log("DB Error: " . $e->getMessage());
|
||||
// In a real app, you'd have a more robust error handling system
|
||||
die("Error deleting post. Check logs for details.");
|
||||
}
|
||||
}
|
||||
|
||||
$posts = [];
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->query("SELECT id, title, created_at FROM posts ORDER BY created_at DESC");
|
||||
$posts = $stmt->fetchAll();
|
||||
} catch (PDOException $e) {
|
||||
error_log("DB Error: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Admin - Manage Posts</title>
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/">My Awesome Blog</a>
|
||||
<a href="admin.php" class="nav-link">Admin</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container my-5">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h2">Manage Posts</h1>
|
||||
<a href="editor.php" class="btn btn-primary">Create New Post</a>
|
||||
</div>
|
||||
|
||||
<?php if (isset($_GET['deleted'])): ?>
|
||||
<div class="alert alert-success">Post deleted successfully.</div>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_GET['saved'])): ?>
|
||||
<div class="alert alert-success">Post saved successfully.</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($posts)): ?>
|
||||
<div class="text-center py-5">
|
||||
<p class="lead">No posts found.</p>
|
||||
<a href="editor.php" class="btn btn-primary">Create your first post</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="card">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th scope="col">Title</th>
|
||||
<th scope="col">Created At</th>
|
||||
<th scope="col" class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($posts as $post): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($post['title']); ?></td>
|
||||
<td><?php echo date("F j, Y, g:i a", strtotime($post['created_at'])); ?></td>
|
||||
<td class="text-end">
|
||||
<a href="editor.php?id=<?php echo $post['id']; ?>" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
<form action="admin.php" method="POST" onsubmit="return confirm('Are you sure you want to delete this post?');" class="d-inline">
|
||||
<input type="hidden" name="delete_id" value="<?php echo $post['id']; ?>">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-white border-top">
|
||||
<div class="container text-center">
|
||||
<span class="text-muted">© <?php echo date("Y"); ?> My Awesome Blog. All Rights Reserved.</span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
140
editor.php
Normal file
140
editor.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
|
||||
$post = [
|
||||
'id' => null,
|
||||
'title' => '',
|
||||
'content' => '',
|
||||
'excerpt' => '',
|
||||
'image_url' => ''
|
||||
];
|
||||
$pageTitle = 'Create New Post';
|
||||
$action = 'editor.php';
|
||||
|
||||
// Edit mode
|
||||
if (isset($_GET['id'])) {
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("SELECT * FROM posts WHERE id = ?");
|
||||
$stmt->execute([$_GET['id']]);
|
||||
$post = $stmt->fetch();
|
||||
if (!$post) {
|
||||
// Post not found, redirect or show error
|
||||
header("Location: admin.php?error=notfound");
|
||||
exit;
|
||||
}
|
||||
$pageTitle = 'Edit Post';
|
||||
$action = 'editor.php?id=' . $_GET['id'];
|
||||
} catch (PDOException $e) {
|
||||
error_log("DB Error: " . $e->getMessage());
|
||||
die("Error fetching post. Check logs.");
|
||||
}
|
||||
}
|
||||
|
||||
// Handle form submission
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$title = $_POST['title'] ?? '';
|
||||
$content = $_POST['content'] ?? '';
|
||||
$excerpt = $_POST['excerpt'] ?? '';
|
||||
$imageUrl = $_POST['image_url'] ?? '';
|
||||
$id = $_POST['id'] ?? null;
|
||||
|
||||
// Basic validation
|
||||
if (empty($title) || empty($content)) {
|
||||
$error = "Title and Content are required.";
|
||||
} else {
|
||||
try {
|
||||
$pdo = db();
|
||||
if ($id) {
|
||||
// Update
|
||||
$stmt = $pdo->prepare("UPDATE posts SET title = ?, content = ?, excerpt = ?, image_url = ? WHERE id = ?");
|
||||
$stmt->execute([$title, $content, $excerpt, $imageUrl, $id]);
|
||||
} else {
|
||||
// Insert
|
||||
$stmt = $pdo->prepare("INSERT INTO posts (title, content, excerpt, image_url) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$title, $content, $excerpt, $imageUrl]);
|
||||
}
|
||||
header("Location: admin.php?saved=true");
|
||||
exit;
|
||||
} catch (PDOException $e) {
|
||||
error_log("DB Error: " . $e->getMessage());
|
||||
$error = "Error saving post. Check logs for details.";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?php echo $pageTitle; ?></title>
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/">My Awesome Blog</a>
|
||||
<a href="admin.php" class="nav-link">Admin</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container my-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<h1 class="h2 mb-4"><?php echo $pageTitle; ?></h1>
|
||||
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form action="<?php echo $action; ?>" method="POST">
|
||||
<input type="hidden" name="id" value="<?php echo htmlspecialchars($post['id'] ?? ''); ?>">
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label">Title</label>
|
||||
<input type="text" class="form-control" id="title" name="title" value="<?php echo htmlspecialchars($post['title'] ?? ''); ?>" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="content" class="form-label">Content</label>
|
||||
<textarea class="form-control" id="content" name="content" rows="10" required><?php echo htmlspecialchars($post['content'] ?? ''); ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="excerpt" class="form-label">Excerpt</label>
|
||||
<textarea class="form-control" id="excerpt" name="excerpt" rows="3"><?php echo htmlspecialchars($post['excerpt'] ?? ''); ?></textarea>
|
||||
<div class="form-text">A short summary of the post, shown on the main blog page.</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="image_url" class="form-label">Image URL</label>
|
||||
<input type="url" class="form-control" id="image_url" name="image_url" value="<?php echo htmlspecialchars($post['image_url'] ?? 'https://picsum.photos/seed/'.uniqid().'/800/600'); ?>">
|
||||
<div class="form-text">URL for the post's main image. A new random placeholder is generated for you.</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<a href="admin.php" class="btn btn-secondary me-2">Cancel</a>
|
||||
<button type="submit" class="btn btn-primary">Save Post</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-white border-top">
|
||||
<div class="container text-center">
|
||||
<span class="text-muted">© <?php echo date("Y"); ?> My Awesome Blog. All Rights Reserved.</span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -71,7 +71,7 @@ try {
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-white border-top">
|
||||
<div class="container text-center">
|
||||
<span class="text-muted">© <?php echo date("Y"); ?> My Awesome Blog. All Rights Reserved.</span>
|
||||
<span class="text-muted">© <?php echo date("Y"); ?> My Awesome Blog. All Rights Reserved. | <a href="admin.php">Admin</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user