Blog system enhancements: fix publish/unpublish permissions, add action buttons to blog listings, update gallery to show only published blog images, improve blog card layout and description truncation

This commit is contained in:
twotalesanimation
2025-12-08 10:20:12 +02:00
parent 54bd98c5de
commit 0af0bd33f9
66 changed files with 2178 additions and 210 deletions

View File

@@ -0,0 +1,91 @@
<?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");
session_start();
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo "Not authorized";
exit;
}
$article_id = (int)($_POST['id'] ?? 0);
$title = $_POST['title'] ?? '';
$content = $_POST['content'] ?? '';
$description = $_POST['subtitle'] ?? '';
$category = $_POST['category'] ?? '';
$user_id = $_SESSION['user_id'];
// Default to current user
$author_id = $_SESSION['user_id'];
// Allow override if admin
$role = getUserRole();
if (($role === 'admin' || $role === 'superadmin') && isset($_POST['author'])) {
$author_id = (int)$_POST['author'];
}
echo $author_id;
$cover_image_path = null;
// Only attempt upload if a file was submitted
if (!empty($_FILES['cover_image']['name'])) {
$uploadDir = $rootPath . "/uploads/blogs/" . $article_id . "/";
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// Validate file using existing function
$file_result = validateFileUpload($_FILES['cover_image'], 'profile_picture');
if ($file_result === false) {
http_response_code(400);
echo "Invalid file upload";
exit;
}
// Use fixed filename "cover" to avoid creating multiple copies on autosave
$extension = $file_result['extension'];
$filename = "cover." . $extension;
// Delete old cover if it exists with different extension
array_map('unlink', glob($uploadDir . "cover.*"));
$targetPath = $uploadDir . $filename;
$cover_image_path = "/uploads/blogs/" . $article_id . "/" . $filename;
// Move the uploaded file
if (move_uploaded_file($_FILES['cover_image']['tmp_name'], $targetPath)) {
// File moved successfully, $cover_image_path is set
} else {
http_response_code(500);
echo "Failed to move uploaded file.";
exit;
}
}
// Prepare SQL with/without image update
if ($cover_image_path) {
$stmt = $conn->prepare("
UPDATE blogs
SET title = ?, content = ?, description = ?, category = ?, image = ?, author = ?
WHERE blog_id = ?
");
$stmt->bind_param("ssssssi", $title, $content, $description, $category, $cover_image_path, $author_id, $article_id);
} else {
$stmt = $conn->prepare("
UPDATE blogs
SET title = ?, content = ?, description = ?, category = ?, author = ?
WHERE blog_id = ?
");
$stmt->bind_param("ssssii", $title, $content, $description, $category, $author_id, $article_id);
}
if ($stmt->execute()) {
echo "Saved";
} else {
http_response_code(500);
echo "Database update failed: " . $stmt->error;
}

View File

@@ -0,0 +1,33 @@
<?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");
session_start();
if (!isset($_SESSION['user_id'])) {
die("Not logged in");
}
$user_id = $_SESSION['user_id'];
$role = getUserRole();
if(!getUserMemberStatus($user_id)){
if ($role === 'user'){
$_SESSION['message'] = "Blogs only available to active members. Please contact info@4wdcsa.co.za for more information.";
header("Location: user_blogs.php");
exit;
}
}
$date = date('Y-m-d');
$status = 'draft';
$stmt = $conn->prepare("INSERT INTO blogs (author, title, category, description, content, date, status)
VALUES (?, '', '', '', '', ?, ?)");
$stmt->bind_param("iss", $user_id, $date, $status);
$stmt->execute();
$blog_id = $stmt->insert_id;
header("Location: blog_edit.php?token=" . encryptData($blog_id, $salt));
exit;

View File

@@ -0,0 +1,37 @@
<?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");
session_start();
if (!isset($_SESSION['user_id'])) {
$_SESSION['message'] = "Not authorized.";
header("Location: user_blogs.php");
exit;
}
$token = $_GET['token'];
// Sanitize the trip_id to prevent SQL injection
$article_id = intval(decryptData($token, $salt)); // Ensures $trip_id is treated as an integer
$user_id = $_SESSION['user_id'];
if ($article_id <= 0) {
$_SESSION['message'] = "Invalid blog ID.";
header("Location: user_blogs.php");
exit;
}
$stmt = $conn->prepare("UPDATE blogs SET status = 'deleted' WHERE blog_id = ? AND author = ?");
$stmt->bind_param("ii", $article_id, $user_id);
if ($stmt->execute()) {
$_SESSION['message'] = "Blog deleted!";
} else {
$_SESSION['message'] = "Failed to delete blog: " . $stmt->error;
}
header("Location: user_blogs.php");
exit;
?>

View File

@@ -0,0 +1,54 @@
<?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");
session_start();
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo "Not authorized";
exit;
}
$article_id = (int)($_POST['id'] ?? 0);
$user_id = $_SESSION['user_id'];
$role = getUserRole();
if ($article_id <= 0) {
http_response_code(400);
echo "Invalid blog ID";
exit;
}
// Check permissions: user must be author or admin
$stmt = $conn->prepare("SELECT author FROM blogs WHERE blog_id = ?");
$stmt->bind_param("i", $article_id);
$stmt->execute();
$result = $stmt->get_result();
$blog = $result->fetch_assoc();
$stmt->close();
if (!$blog) {
http_response_code(404);
echo "Blog not found";
exit;
}
// Allow if user is author or admin
if ($blog['author'] != $user_id && !in_array($role, ['admin', 'superadmin'])) {
http_response_code(403);
echo "Not authorized to unpublish this blog";
exit;
}
$stmt = $conn->prepare("UPDATE blogs SET status = 'draft' WHERE blog_id = ?");
$stmt->bind_param("i", $article_id);
if ($stmt->execute()) {
echo "Unpublished";
} else {
http_response_code(500);
echo "Failed to unpublish: " . $stmt->error;
}
?>

View File

@@ -0,0 +1,54 @@
<?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");
session_start();
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo "Not authorized";
exit;
}
$article_id = (int)($_POST['id'] ?? 0);
$user_id = $_SESSION['user_id'];
$role = getUserRole();
if ($article_id <= 0) {
http_response_code(400);
echo "Invalid blog ID";
exit;
}
// Check permissions: user must be author or admin
$stmt = $conn->prepare("SELECT author FROM blogs WHERE blog_id = ?");
$stmt->bind_param("i", $article_id);
$stmt->execute();
$result = $stmt->get_result();
$blog = $result->fetch_assoc();
$stmt->close();
if (!$blog) {
http_response_code(404);
echo "Blog not found";
exit;
}
// Allow if user is author or admin
if ($blog['author'] != $user_id && !in_array($role, ['admin', 'superadmin'])) {
http_response_code(403);
echo "Not authorized to publish this blog";
exit;
}
$stmt = $conn->prepare("UPDATE blogs SET status = 'published' WHERE blog_id = ?");
$stmt->bind_param("i", $article_id);
if ($stmt->execute()) {
echo "Published";
} else {
http_response_code(500);
echo "Failed to publish: " . $stmt->error;
}
?>

View File

@@ -0,0 +1,83 @@
<?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");
session_start();
if (!isset($_SESSION['user_id'])) {
die("Login required");
}
$title = $_POST['title'];
$category = $_POST['category'];
$description = $_POST['description'];
$content = $_POST['content'];
$user_id = $_SESSION['user_id'];
$date = date('Y-m-d');
$article_id = $_POST['article_id'] ?? null;
$image = null;
// Handle cover image upload if provided
if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] === UPLOAD_ERR_OK) {
// For new blogs, we'll use the blog_id after insert, for now use temp folder
// Update: For editing, use article_id; for new blogs, we'll need to handle this after insert
$folder_id = $article_id ?? 'temp_' . uniqid();
$upload_dir = $rootPath . '/uploads/blogs/' . $folder_id . '/';
// Create directory if it doesn't exist
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
// Validate and process the file
$file_result = validateFileUpload($_FILES['cover_image'], 'profile_picture');
if ($file_result !== false) {
// Use fixed filename "cover" to avoid duplicates
$extension = $file_result['extension'];
$filename = "cover." . $extension;
// Delete old cover if it exists with different extension
array_map('unlink', glob($upload_dir . "cover.*"));
$upload_path = $upload_dir . $filename;
if (move_uploaded_file($_FILES['cover_image']['tmp_name'], $upload_path)) {
// Store relative path for database
$image = '/uploads/blogs/' . $folder_id . '/' . $filename;
}
}
}
// If updating an existing blog, get the existing image if no new one was uploaded
if ($article_id && !$image) {
$check_stmt = $conn->prepare("SELECT image FROM blogs WHERE blog_id = ?");
$check_stmt->bind_param("i", $article_id);
$check_stmt->execute();
$result = $check_stmt->get_result();
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$image = $row['image'];
}
$check_stmt->close();
}
// Check if this is an update or insert
if ($article_id) {
// Update existing blog
$stmt = $conn->prepare("UPDATE blogs SET title = ?, content = ?, description = ?, category = ?" . ($image ? ", image = ?" : "") . " WHERE blog_id = ?");
if ($image) {
$stmt->bind_param("sssssi", $title, $content, $description, $category, $image, $article_id);
} else {
$stmt->bind_param("ssssi", $title, $content, $description, $category, $article_id);
}
} else {
// Insert new blog
$stmt = $conn->prepare("INSERT INTO blogs (author, title, content, description, category, date, image) VALUES (?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("issssss", $user_id, $title, $content, $description, $category, $date, $image);
}
$stmt->execute();
$stmt->close();
header("Location: blog.php");

View File

@@ -0,0 +1,40 @@
<?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");
session_start();
header('Content-Type: application/json');
if (!isset($_FILES['file'])) {
echo json_encode(['error' => 'No file uploaded']);
http_response_code(400);
exit;
}
// Get blog_id from query parameter
$blog_id = isset($_GET['blog_id']) ? intval($_GET['blog_id']) : null;
if (!$blog_id) {
echo json_encode(['error' => 'Blog ID required']);
http_response_code(400);
exit;
}
$targetDir = $rootPath . "/uploads/blogs/" . $blog_id . "/";
if (!file_exists($targetDir)) {
mkdir($targetDir, 0777, true);
}
$tmp = $_FILES['file']['tmp_name'];
$name = basename($_FILES['file']['name']);
$targetFile = $targetDir . uniqid() . "-" . $name;
if (move_uploaded_file($tmp, $targetFile)) {
// Return a relative path for the image
$relativePath = "/uploads/blogs/" . $blog_id . "/" . basename($targetFile);
echo json_encode(['location' => $relativePath]);
} else {
echo json_encode(['error' => 'Failed to move uploaded file']);
http_response_code(500);
}