282 lines
12 KiB
PHP
282 lines
12 KiB
PHP
<?php
|
|
$rootPath = dirname(dirname(dirname(__DIR__)));
|
|
require_once($rootPath . "/src/config/env.php");
|
|
require_once($rootPath . "/src/config/connection.php");
|
|
require_once($rootPath . "/src/config/functions.php");
|
|
require_once($rootPath . "/header.php");
|
|
|
|
// Ensure the user is logged in
|
|
if (!isset($_SESSION['user_id'])) {
|
|
die("User not logged in.");
|
|
}
|
|
|
|
$pageTitle = 'Edit Blog Post';
|
|
$breadcrumbs = [['Home' => 'index'], ['My Blog Posts' => 'user_blogs']];
|
|
require_once($rootPath . '/components/banner.php');
|
|
|
|
$token = $_GET['token'];
|
|
// Sanitize the trip_id to prevent SQL injection
|
|
$blog_id = intval(decryptData($token, $salt)); // Ensures $trip_id is treated as an integer
|
|
|
|
$user_id = $_SESSION['user_id'];
|
|
$role = getUserRole();
|
|
|
|
// Fetch article info
|
|
$stmt = $conn->prepare("SELECT * FROM blogs WHERE blog_id = ?");
|
|
$stmt->bind_param("i", $blog_id);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result();
|
|
if ($result->num_rows === 0) {
|
|
die("Blog post not found.");
|
|
}
|
|
$article = $result->fetch_assoc();
|
|
$stmt->close();
|
|
?>
|
|
|
|
<script src="https://cdn.tiny.cloud/1/o6xuedbd9z22xk0p5zszinevn4bdbljxnfwn0tjjvv6r37pb/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>
|
|
<script>
|
|
tinymce.init({
|
|
selector: '#content',
|
|
plugins: 'image code link',
|
|
toolbar: 'undo redo | blocks | bold italic | alignleft aligncenter alignright | code | image | link',
|
|
images_upload_url: 'upload_blog_image?blog_id=<?= $blog_id ?>',
|
|
image_class_list: [
|
|
{ title: 'None', value: '' },
|
|
{ title: 'Left Align', value: 'img-left' },
|
|
{ title: 'Right Align', value: 'img-right' },
|
|
{ title: 'Rounded', value: 'img-rounded' }
|
|
],
|
|
automatic_uploads: true,
|
|
images_upload_credentials: true, // include cookies if needed
|
|
content_style: "body { font-family:Helvetica,Arial,sans-serif; font-size:14px }",
|
|
|
|
setup: function (editor) {
|
|
editor.on('init', function () {
|
|
setTimeout(() => {
|
|
editor.setContent(`<?= str_replace("`", "\`", addslashes($article['content'])) ?>`);
|
|
}, 100);
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<section class="account-settings-area py-70 rel z-1">
|
|
<div class="container">
|
|
<div class="row align-items-center">
|
|
<div class="col-lg-12">
|
|
<div class="comment-form bgc-lighter z-1 rel mb-55">
|
|
<form action="submit_blog.php" method="POST" enctype="multipart/form-data">
|
|
<input type="hidden" name="article_id" value="<?= htmlspecialchars($blog_id) ?>">
|
|
<div class="section-title py-20">
|
|
<h2>Edit Blog</h2>
|
|
<div id="autosave-status" style="font-style: italic; font-size: 0.9em;"></div>
|
|
</div>
|
|
<div class="row mt-35">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="title">Blog Title</label>
|
|
<input type="text" id="title" class="form-control" name="title" placeholder="Title" required value="<?= htmlspecialchars($article['title']) ?>">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<label for="subtitle">Description</label>
|
|
<input type="text" id="subtitle" class="form-control" name="subtitle" placeholder="Description" required value="<?= htmlspecialchars($article['description']) ?>">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<label for="cover_image">Cover Image</label>
|
|
<input type="file" class="form-control" name="cover_image" id="cover_image" accept="image/*">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12 mb-10">
|
|
<div class="form-group">
|
|
<label for="category">Blog Category</label>
|
|
<select name="category" class="form-control" id="category" required>
|
|
<option value="Trip Report" <?= $article['category'] == 'Trip Report' ? 'selected' : '' ?>>Trip Report</option>
|
|
<option value="Gear Review" <?= $article['category'] == 'Gear Review' ? 'selected' : '' ?>>Gear Review</option>
|
|
<option value="Talking Dirty" <?= $article['category'] == 'Talking Dirty' ? 'selected' : '' ?>>Talking Dirty</option>
|
|
<option value="Report" <?= $article['category'] == 'Report' ? 'selected' : '' ?>>Report</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12 mb-10">
|
|
<div class="form-group">
|
|
<?php if ($role === 'admin' || $role === 'superadmin'): ?>
|
|
<label for="author">Author:</label>
|
|
<select class="form-control" name="author" id="author">
|
|
<?php
|
|
$user_query = $conn->query("SELECT user_id, CONCAT(first_name, ' ', last_name) AS name FROM users ORDER BY first_name ASC");
|
|
while ($user = $user_query->fetch_assoc()):
|
|
?>
|
|
<option value="<?= $user['user_id'] ?>" <?= $user['user_id'] == $article['author'] ? 'selected' : '' ?>>
|
|
<?= htmlspecialchars($user['name']) ?>
|
|
</option>
|
|
<?php endwhile; ?>
|
|
</select>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<textarea id="content" name="content"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<button type="button" class="theme-btn style-three" style="width:100%;" id="manualSaveBtn">Save Draft</button>
|
|
</div>
|
|
<div class="form-group">
|
|
<a href="blog_read.php?token=<?php echo encryptData($blog_id, $salt); ?>" class="theme-btn style-three" style="width:100%;">Preview</a>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<?php
|
|
if ($article['status'] == 'draft'){
|
|
echo '<div class="form-group">
|
|
<button type="button" class="theme-btn style-two" style="width:100%;" id="manualPostBtn">Publish</button>
|
|
|
|
</div> ';
|
|
} else {
|
|
echo '<div class="form-group">
|
|
<button type="button" class="theme-btn style-two" style="width:100%;" id="manualDraftBtn">Un-Publish</button>
|
|
|
|
</div> ';
|
|
}?>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
<script>
|
|
function autosavePost() {
|
|
const title = document.querySelector('[name="title"]').value;
|
|
const content = tinymce.get("content").getContent();
|
|
const subtitle = document.querySelector('[name="subtitle"]').value;
|
|
const category = document.querySelector('[name="category"]').value;
|
|
const author = document.querySelector('[name="author"]').value;
|
|
const articleId = document.querySelector('[name="article_id"]').value;
|
|
const coverImageInput = document.querySelector('[name="cover_image"]');
|
|
|
|
console.log("Saving: ", { title, subtitle, content, category, articleId, author });
|
|
|
|
const formData = new FormData();
|
|
formData.append("id", articleId);
|
|
formData.append("title", title);
|
|
formData.append("content", content);
|
|
formData.append("subtitle", subtitle);
|
|
formData.append("category", category);
|
|
formData.append("author", author);
|
|
|
|
// Only append image if a new file is selected
|
|
if (coverImageInput.files.length > 0) {
|
|
formData.append("cover_image", coverImageInput.files[0]);
|
|
}
|
|
|
|
return fetch("autosave", {
|
|
method: "POST",
|
|
body: formData
|
|
}).then(response => {
|
|
if (response.ok) {
|
|
document.getElementById("autosave-status").innerText = "Draft autosaved at " + new Date().toLocaleTimeString();
|
|
return true;
|
|
} else {
|
|
return response.text().then(errorText => {
|
|
document.getElementById("autosave-status").innerText = "Autosave failed: " + errorText;
|
|
console.error("Autosave failed", response.status, errorText);
|
|
return false;
|
|
});
|
|
}
|
|
}).catch(err => {
|
|
console.error("Autosave error:", err);
|
|
document.getElementById("autosave-status").innerText = "Autosave error: " + err.message;
|
|
return false;
|
|
});
|
|
}
|
|
|
|
// Trigger autosave every 15s
|
|
setInterval(autosavePost, 15000);
|
|
|
|
// Manual autosave button
|
|
const manualSaveBtn = document.getElementById("manualSaveBtn");
|
|
if (manualSaveBtn) {
|
|
manualSaveBtn.addEventListener("click", autosavePost);
|
|
}
|
|
|
|
// Manual publish button
|
|
const manualPostBtn = document.getElementById("manualPostBtn");
|
|
if (manualPostBtn) {
|
|
manualPostBtn.addEventListener("click", function () {
|
|
autosavePost().then(success => {
|
|
if (!success) return;
|
|
|
|
const articleId = document.querySelector('[name="article_id"]').value;
|
|
const publishData = new FormData();
|
|
publishData.append("id", articleId);
|
|
|
|
fetch("publish_blog", {
|
|
method: "POST",
|
|
body: publishData
|
|
}).then(response => {
|
|
if (response.ok) {
|
|
alert("Post published successfully!");
|
|
// Optional: redirect to the live post
|
|
window.location.href = "blog_read.php?token=<?php echo encryptData($blog_id, $salt);?>";
|
|
} else {
|
|
alert("Publish failed.");
|
|
console.error("Publish error:", response.statusText);
|
|
}
|
|
}).catch(err => {
|
|
console.error("Publish error:", err);
|
|
alert("Publish failed due to network error.");
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
// Manual unpublish button
|
|
const manualDraftBtn = document.getElementById("manualDraftBtn");
|
|
if (manualDraftBtn) {
|
|
manualDraftBtn.addEventListener("click", function () {
|
|
autosavePost().then(success => {
|
|
if (!success) return;
|
|
|
|
const articleId = document.querySelector('[name="article_id"]').value;
|
|
const publishData = new FormData();
|
|
publishData.append("id", articleId);
|
|
|
|
fetch("blog_unpublish", {
|
|
method: "POST",
|
|
body: publishData
|
|
}).then(response => {
|
|
if (response.ok) {
|
|
alert("Post unpublished successfully!");
|
|
// Optional: redirect to the live post
|
|
window.location.href = "blog_read.php?token=<?php echo encryptData($blog_id, $salt);?>";
|
|
} else {
|
|
alert("unPublish failed.");
|
|
console.error("Publish error:", response.statusText);
|
|
}
|
|
}).catch(err => {
|
|
console.error("Publish error:", err);
|
|
alert("Publish failed due to network error.");
|
|
});
|
|
});
|
|
});
|
|
}
|
|
</script>
|
|
|
|
</script>
|
|
|
|
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|