From a66382661dc258b97f7af175578837bb8e664c69 Mon Sep 17 00:00:00 2001 From: twotalesanimation <80506065+twotalesanimation@users.noreply.github.com> Date: Sat, 13 Dec 2025 19:25:47 +0200 Subject: [PATCH] Fixed some bugs --- header.php | 8 +- src/.user.ini | 4 - src/admin/add_campsite.php | 9 +- src/admin/admin_trips.php | 16 +--- src/config/functions.php | 62 ++++++++++--- src/pages/blog/blog_edit.php | 9 +- src/pages/blog/user_blogs.php | 13 +++ src/pages/memberships/membership.php | 3 +- src/processors/blog/autosave.php | 37 +++++--- src/processors/blog/submit_blog.php | 4 +- src/processors/delete_event.php | 104 ++++++++++++++-------- src/processors/process_application.php | 40 +++++---- src/processors/process_event.php | 28 +++--- src/processors/process_signature.php | 2 +- src/processors/process_trip.php | 4 +- src/processors/save_album.php | 32 +++---- src/processors/submit_pop.php | 11 +-- src/processors/update_album.php | 52 ++++++----- src/processors/upload_profile_picture.php | 12 +-- 19 files changed, 263 insertions(+), 187 deletions(-) delete mode 100644 src/.user.ini diff --git a/header.php b/header.php index bf89d396..6d7ded11 100644 --- a/header.php +++ b/header.php @@ -320,7 +320,13 @@ if ($headerStyle === 'light') {
  • Account Settings
  • Membership
  • My Bookings
  • -
  • My Blog Posts
  • + My Blog Posts"; + } else { + echo "
  • My Blog Posts
  • "; + } + ?>
  • Submit P.O.P
  • Log Out
  • diff --git a/src/.user.ini b/src/.user.ini deleted file mode 100644 index af4bd56b..00000000 --- a/src/.user.ini +++ /dev/null @@ -1,4 +0,0 @@ -; memory_limit = 512M -upload_max_filesize = 64M -post_max_size = 64M -max_execution_time = 120 diff --git a/src/admin/add_campsite.php b/src/admin/add_campsite.php index 2fb27e9b..c1ccc35a 100644 --- a/src/admin/add_campsite.php +++ b/src/admin/add_campsite.php @@ -38,13 +38,8 @@ if (isset($_FILES['thumbnail']) && $_FILES['thumbnail']['error'] !== UPLOAD_ERR_ } $uploadDir = "assets/uploads/campsites/"; - if (!is_dir($uploadDir)) { - mkdir($uploadDir, 0755, true); - } - - if (!is_writable($uploadDir)) { - http_response_code(500); - die('Upload directory is not writable.'); + if (!file_exists($uploadDir)) { + mkdir($uploadDir, 0777, true); } $randomFilename = $validationResult['filename']; diff --git a/src/admin/admin_trips.php b/src/admin/admin_trips.php index f5c99875..ff808a28 100644 --- a/src/admin/admin_trips.php +++ b/src/admin/admin_trips.php @@ -221,6 +221,7 @@ $bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE); .then(response => response.json()) .then(data => { if (data.status === 'success') { + alert('Trip deleted successfully!'); card.style.animation = 'fadeOut 0.3s ease-out'; setTimeout(() => { card.remove(); @@ -236,21 +237,6 @@ $bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE); console.error('Error:', err); alert('Delete failed due to network error.'); }); -'success') { - card.fadeOut(function() { - $(this).remove(); - if ($('.trip-card').length === 0) { - location.reload(); - } - }); - } else { - alert('Error: ' + response.message); - } - }, - error: function() { - alert('Error deleting trip'); - } - }); }); }); diff --git a/src/config/functions.php b/src/config/functions.php index 4227349f..c2cf542c 100644 --- a/src/config/functions.php +++ b/src/config/functions.php @@ -29,6 +29,26 @@ function openDatabaseConnection() return $conn; } + +function getPriceByDescription($description) +{ + $conn = openDatabaseConnection(); + $stmt = $conn->prepare("SELECT amount FROM prices WHERE description = ? LIMIT 1"); + if (!$stmt) { + return null; + } + $stmt->bind_param("s", $description); + $stmt->execute(); + $stmt->bind_result($amount); + if ($stmt->fetch()) { + $stmt->close(); + return $amount; + } else { + $stmt->close(); + return null; + } +} + function getTripCount() { // Database connection @@ -1719,12 +1739,25 @@ function formatCurrency($amount, $currency = 'R') function guessCountry($ip) { - $response = file_get_contents("http://ip-api.com/json/$ip"); + // Use cURL instead of file_get_contents for compatibility with allow_url_fopen=0 + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, "http://ip-api.com/json/$ip"); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + $response = curl_exec($ch); + curl_close($ch); + + if ($response === false) { + return null; + } + $data = json_decode($response, true); - if ($data['status'] == 'success') { + if ($data && isset($data['status']) && $data['status'] == 'success') { return $data['country']; // e.g., South Africa } + + return null; } function getUserIdFromEFT($eft_id) @@ -2436,18 +2469,21 @@ function validateFileUpload($file, $fileType = 'document') { } // ===== CHECK 5: MIME Type Validation ===== - $finfo = finfo_open(FILEINFO_MIME_TYPE); - if ($finfo === false) { - error_log("Failed to open fileinfo resource"); - return false; - } + // Skip MIME type validation if finfo_open is not available (shared hosting compatibility) + // Extension validation in CHECK 4 provides sufficient security + $mimeType = 'application/octet-stream'; // Default fallback - $mimeType = finfo_file($finfo, $file['tmp_name']); - finfo_close($finfo); - - if (!in_array($mimeType, $config['mimeTypes'], true)) { - error_log("Invalid MIME type '$mimeType' for type: $fileType. Expected: " . implode(', ', $config['mimeTypes'])); - return false; + if (function_exists('finfo_open')) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + if ($finfo !== false) { + $mimeType = finfo_file($finfo, $file['tmp_name']); + finfo_close($finfo); + + if (!in_array($mimeType, $config['mimeTypes'], true)) { + error_log("Invalid MIME type '$mimeType' for type: $fileType. Expected: " . implode(', ', $config['mimeTypes'])); + return false; + } + } } // ===== CHECK 6: Additional Image Validation (for images) ===== diff --git a/src/pages/blog/blog_edit.php b/src/pages/blog/blog_edit.php index 5d1b7b6c..4b2dd81d 100644 --- a/src/pages/blog/blog_edit.php +++ b/src/pages/blog/blog_edit.php @@ -192,12 +192,15 @@ $stmt->close(); document.getElementById("autosave-status").innerText = "Draft autosaved at " + new Date().toLocaleTimeString(); return true; } else { - document.getElementById("autosave-status").innerText = "Autosave failed"; - console.error("Autosave failed", response.statusText); - return false; + 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; }); } diff --git a/src/pages/blog/user_blogs.php b/src/pages/blog/user_blogs.php index c061c56d..e5b8eb55 100644 --- a/src/pages/blog/user_blogs.php +++ b/src/pages/blog/user_blogs.php @@ -7,6 +7,19 @@ require_once($rootPath . "/header.php"); checkUserSession(); +// Check if user has active membership +if (!isset($_SESSION['user_id'])) { + header('Location: login'); + exit; +} + +$is_member = getUserMemberStatus($_SESSION['user_id']); +if (!$is_member) { + $_SESSION['message'] = "My Blog Posts is only available to active members. Please contact info@4wdcsa.co.za for more information."; + header('Location: membership_details'); + exit; +} + $pageTitle = 'My Blog Posts'; $breadcrumbs = [['Home' => 'index'], ['Blog' => 'blog']]; require_once($rootPath . '/components/banner.php'); diff --git a/src/pages/memberships/membership.php b/src/pages/memberships/membership.php index d58d0b2c..ccc9d14e 100644 --- a/src/pages/memberships/membership.php +++ b/src/pages/memberships/membership.php @@ -39,7 +39,8 @@ if (isset($_SESSION['user_id']) && isset($conn) && $conn !== null) {
  • ... and many more!
  • -

    R 2,500/year

    + +

    R /year

    We go above and beyond to make your travel dreams reality hidden gems and must-see attractions

    diff --git a/src/processors/blog/autosave.php b/src/processors/blog/autosave.php index 81040696..3d8e2c8d 100644 --- a/src/processors/blog/autosave.php +++ b/src/processors/blog/autosave.php @@ -5,6 +5,11 @@ require_once($rootPath . "/src/config/connection.php"); require_once($rootPath . "/src/config/functions.php"); session_start(); +// Enable error reporting for debugging +error_reporting(E_ALL); +ini_set('display_errors', 0); // Don't display, but log them +ini_set('log_errors', 1); + if (!isset($_SESSION['user_id'])) { http_response_code(401); echo "Not authorized"; @@ -32,36 +37,42 @@ echo $author_id; $cover_image_path = null; // Only attempt upload if a file was submitted -if (!empty($_FILES['cover_image']['name'])) { +if (!empty($_FILES['cover_image']['name']) && $_FILES['cover_image']['error'] === UPLOAD_ERR_OK) { $uploadDir = $rootPath . "/uploads/blogs/" . $article_id . "/"; - if (!is_dir($uploadDir)) { - mkdir($uploadDir, 0755, true); + + // Create directory if it doesn't exist (match working pattern) + if (!file_exists($uploadDir)) { + mkdir($uploadDir, 0777, true); } - // Validate file using existing function - $file_result = validateFileUpload($_FILES['cover_image'], 'profile_picture'); - if ($file_result === false) { + // Simple validation - check extension + $extension = strtolower(pathinfo($_FILES['cover_image']['name'], PATHINFO_EXTENSION)); + $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + + if (!in_array($extension, $allowedExtensions)) { http_response_code(400); - echo "Invalid file upload"; + echo "Invalid file type. Allowed: jpg, jpeg, png, gif, webp"; 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.*")); + $oldCovers = glob($uploadDir . "cover.*"); + if ($oldCovers) { + foreach ($oldCovers as $oldCover) { + @unlink($oldCover); + } + } $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 { + if (!move_uploaded_file($_FILES['cover_image']['tmp_name'], $targetPath)) { http_response_code(500); - echo "Failed to move uploaded file."; + echo "Failed to move uploaded file"; exit; } } diff --git a/src/processors/blog/submit_blog.php b/src/processors/blog/submit_blog.php index 4fa4b94e..a0872b6a 100644 --- a/src/processors/blog/submit_blog.php +++ b/src/processors/blog/submit_blog.php @@ -26,8 +26,8 @@ if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] === UPLOAD_ $upload_dir = $rootPath . '/uploads/blogs/' . $folder_id . '/'; // Create directory if it doesn't exist - if (!is_dir($upload_dir)) { - mkdir($upload_dir, 0755, true); + if (!file_exists($upload_dir)) { + mkdir($upload_dir, 0777, true); } // Validate and process the file diff --git a/src/processors/delete_event.php b/src/processors/delete_event.php index 152ae71f..b1225752 100644 --- a/src/processors/delete_event.php +++ b/src/processors/delete_event.php @@ -1,46 +1,76 @@ - 'error', 'message' => 'Event ID is required']); +// Start session if not already started +if (session_status() === PHP_SESSION_NONE) { + session_start(); +} + +// Check admin status +if (empty($_SESSION['user_id'])) { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => 'Unauthorized access']); exit; } -// Get event details to delete associated files -$stmt = $conn->prepare("SELECT image, promo FROM events WHERE event_id = ?"); -$stmt->bind_param("i", $event_id); -$stmt->execute(); -$result = $stmt->get_result(); - -if ($result->num_rows > 0) { - $event = $result->fetch_assoc(); - - // Delete image files - if ($event['image'] && file_exists($rootPath . '/' . $event['image'])) { - unlink($rootPath . '/' . $event['image']); - } - if ($event['promo'] && file_exists($rootPath . '/' . $event['promo'])) { - unlink($rootPath . '/' . $event['promo']); - } - - // Delete from database - $delete_stmt = $conn->prepare("DELETE FROM events WHERE event_id = ?"); - $delete_stmt->bind_param("i", $event_id); - - if ($delete_stmt->execute()) { - echo json_encode(['status' => 'success', 'message' => 'Event deleted successfully']); - } else { - echo json_encode(['status' => 'error', 'message' => 'Failed to delete event']); - } - $delete_stmt->close(); -} else { - echo json_encode(['status' => 'error', 'message' => 'Event not found']); +$user_role = getUserRole(); +if (!in_array($user_role, ['admin', 'superadmin'])) { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => 'Unauthorized access']); + exit; } -$stmt->close(); +try { + $event_id = intval($_POST['event_id'] ?? 0); + + if ($event_id <= 0) { + throw new Exception('Invalid event ID'); + } + + // Get event details to delete associated files + $stmt = $conn->prepare("SELECT image, promo FROM events WHERE event_id = ?"); + $stmt->bind_param("i", $event_id); + $stmt->execute(); + $result = $stmt->get_result(); + + if ($result->num_rows > 0) { + $event = $result->fetch_assoc(); + + // Delete image files + if ($event['image'] && file_exists($rootPath . '/' . $event['image'])) { + unlink($rootPath . '/' . $event['image']); + } + if ($event['promo'] && file_exists($rootPath . '/' . $event['promo'])) { + unlink($rootPath . '/' . $event['promo']); + } + + // Delete from database + $delete_stmt = $conn->prepare("DELETE FROM events WHERE event_id = ?"); + $delete_stmt->bind_param("i", $event_id); + + if ($delete_stmt->execute()) { + ob_end_clean(); + echo json_encode(['status' => 'success', 'message' => 'Event deleted successfully']); + } else { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => 'Failed to delete event']); + } + $delete_stmt->close(); + } else { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => 'Event not found']); + } + + $stmt->close(); + +} catch (Exception $e) { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} diff --git a/src/processors/process_application.php b/src/processors/process_application.php index f9263c82..b3347e0b 100644 --- a/src/processors/process_application.php +++ b/src/processors/process_application.php @@ -174,28 +174,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($stmt->execute()) { // Insert into the membership fees table - $payment_amount = calculateProrata(210); // Assuming a fixed membership fee, adjust as needed - $payment_date = date('Y-m-d'); - $membership_start_date = $payment_date; - // $membership_end_date = date('Y-12-31'); - - // Get today's date $today = new DateTime(); + $month = (int)$today->format('n'); + $year = (int)$today->format('Y'); + $payment_date = $today->format('Y-m-d'); + $membership_start_date = $payment_date; - // Determine the target February - if ($today->format('n') > 2) { - // If we're past February, target is next year's Feb 28/29 - $year = $today->format('Y') + 1; + if ($month == 12 || $month == 1 || $month == 2) { + // December, January, February: charge full fee, valid till end of next Feb + $payment_amount = getPriceByDescription('membership_fees'); + // If Dec, Jan, Feb, set end to next year's Feb + $end_year = ($month == 12) ? $year + 2 : $year + 1; + $membership_end_date = (new DateTime("$end_year-02-01")) + ->modify('last day of this month') + ->format('Y-m-d'); } else { - // Otherwise, this year's February - $year = $today->format('Y'); + // Prorata for Mar-Nov + $payment_amount = calculateProrata(getPriceByDescription('pro_rata')); + // End of next Feb if after Feb, else this Feb + if ($month > 2) { + $end_year = $year + 1; + } else { + $end_year = $year; + } + $membership_end_date = (new DateTime("$end_year-02-01")) + ->modify('last day of this month') + ->format('Y-m-d'); } - // Handle leap year (Feb 29) automatically - $membership_end_date = (new DateTime("$year-02-01")) - ->modify('last day of this month') - ->format('Y-m-d'); - $stmt = $conn->prepare("INSERT INTO membership_fees (user_id, payment_amount, payment_date, membership_start_date, membership_end_date, payment_status, payment_id) VALUES (?, ?, ?, ?, ?, 'PENDING', ?)"); $stmt->bind_param("idssss", $user_id, $payment_amount, $payment_date, $membership_start_date, $membership_end_date, $eft_id); diff --git a/src/processors/process_event.php b/src/processors/process_event.php index 3a4e2575..cc352ab4 100644 --- a/src/processors/process_event.php +++ b/src/processors/process_event.php @@ -78,19 +78,17 @@ if (!$name || !$type || !$location || !$date || !$time || !$feature || !$descrip $image_path = null; if (!empty($_FILES['image']['name'])) { $upload_dir = $rootPath . '/assets/images/events/'; - if (!is_dir($upload_dir)) { - mkdir($upload_dir, 0755, true); + if (!file_exists($upload_dir)) { + mkdir($upload_dir, 0777, true); } $file_name = uniqid() . '_' . basename($_FILES['image']['name']); $target_file = $upload_dir . $file_name; - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $file_type = finfo_file($finfo, $_FILES['image']['tmp_name']); - finfo_close($finfo); - // Validate image file - $allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; - if (!in_array($file_type, $allowed_types)) { + // Validate file extension + $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); + $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + if (!in_array($ext, $allowed_extensions)) { echo json_encode(['status' => 'error', 'message' => 'Invalid image file type. Only JPEG, PNG, GIF, and WebP are allowed']); exit; } @@ -110,19 +108,17 @@ if (!empty($_FILES['image']['name'])) { $promo_path = null; if (!empty($_FILES['promo']['name'])) { $upload_dir = $rootPath . '/assets/images/events/'; - if (!is_dir($upload_dir)) { - mkdir($upload_dir, 0755, true); + if (!file_exists($upload_dir)) { + mkdir($upload_dir, 0777, true); } $file_name = uniqid() . '_promo_' . basename($_FILES['promo']['name']); $target_file = $upload_dir . $file_name; - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $file_type = finfo_file($finfo, $_FILES['promo']['tmp_name']); - finfo_close($finfo); - // Validate image file - $allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; - if (!in_array($file_type, $allowed_types)) { + // Validate file extension + $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); + $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + if (!in_array($ext, $allowed_extensions)) { echo json_encode(['status' => 'error', 'message' => 'Invalid promo image file type. Only JPEG, PNG, GIF, and WebP are allowed']); exit; } diff --git a/src/processors/process_signature.php b/src/processors/process_signature.php index 9ff21efb..c504b12c 100644 --- a/src/processors/process_signature.php +++ b/src/processors/process_signature.php @@ -36,7 +36,7 @@ if (isset($_POST['signature'])) { $filePath = $rootPath . '/uploads/signatures/' . $fileName; // Ensure the directory exists - if (!is_dir($rootPath . '/uploads/signatures')) { + if (!file_exists($rootPath . '/uploads/signatures')) { mkdir($rootPath . '/uploads/signatures', 0777, true); } diff --git a/src/processors/process_trip.php b/src/processors/process_trip.php index 2d8ef848..7f4a2901 100644 --- a/src/processors/process_trip.php +++ b/src/processors/process_trip.php @@ -136,8 +136,8 @@ try { $upload_dir = $rootPath . '/assets/images/trips/'; // Create directory if it doesn't exist - if (!is_dir($upload_dir)) { - mkdir($upload_dir, 0755, true); + if (!file_exists($upload_dir)) { + mkdir($upload_dir, 0777, true); } $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; diff --git a/src/processors/save_album.php b/src/processors/save_album.php index 8338ea59..2c8a031e 100644 --- a/src/processors/save_album.php +++ b/src/processors/save_album.php @@ -52,26 +52,25 @@ try { // Create album directory $albumDir = $rootPath . '/assets/uploads/gallery/' . $album_id; - if (!is_dir($albumDir)) { - if (!mkdir($albumDir, 0755, true)) { - throw new Exception('Failed to create album directory'); - } + if (!file_exists($albumDir)) { + mkdir($albumDir, 0777, true); } // Handle cover image upload $coverImagePath = null; - if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] !== UPLOAD_ERR_NO_FILE) { - $allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; + if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] === UPLOAD_ERR_OK) { $maxSize = 5 * 1024 * 1024; // 5MB $fileName = $_FILES['cover_image']['name']; $fileTmpName = $_FILES['cover_image']['tmp_name']; $fileSize = $_FILES['cover_image']['size']; - $fileMime = mime_content_type($fileTmpName); + + // Validate file extension + $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; - // Validate file - if (!in_array($fileMime, $allowedMimes)) { - throw new Exception('Invalid cover image file type'); + if (!in_array($ext, $allowedExtensions)) { + throw new Exception('Invalid cover image file type. Allowed: jpg, jpeg, png, gif, webp'); } if ($fileSize > $maxSize) { @@ -96,8 +95,7 @@ try { } // Handle photo uploads - if (isset($_FILES['photos']) && $_FILES['photos']['error'][0] !== UPLOAD_ERR_NO_FILE) { - $allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; + if (isset($_FILES['photos']) && $_FILES['photos']['error'][0] === UPLOAD_ERR_OK) { $maxSize = 5 * 1024 * 1024; // 5MB $displayOrder = 1; @@ -111,11 +109,13 @@ try { $fileName = $_FILES['photos']['name'][$i]; $fileTmpName = $_FILES['photos']['tmp_name'][$i]; $fileSize = $_FILES['photos']['size'][$i]; - $fileMime = mime_content_type($fileTmpName); + + // Validate file extension + $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; - // Validate file - if (!in_array($fileMime, $allowedMimes)) { - throw new Exception('Invalid file type: ' . $fileName); + if (!in_array($ext, $allowedExtensions)) { + throw new Exception('Invalid file type: ' . $fileName . '. Allowed: jpg, jpeg, png, gif, webp'); } if ($fileSize > $maxSize) { diff --git a/src/processors/submit_pop.php b/src/processors/submit_pop.php index cf6db027..4bc4415b 100644 --- a/src/processors/submit_pop.php +++ b/src/processors/submit_pop.php @@ -43,14 +43,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $filename = str_replace(' ', '_', $eft_id) . '.pdf'; $target_file = $target_dir . $filename; - // Make sure target directory exists and writable - if (!is_dir($target_dir)) { - mkdir($target_dir, 0755, true); - } - - if (!is_writable($target_dir)) { - echo "
    Upload directory is not writable: $target_dir
    "; - exit; + // Make sure target directory exists + if (!file_exists($target_dir)) { + mkdir($target_dir, 0777, true); } if (move_uploaded_file($_FILES['pop_file']['tmp_name'], $target_file)) { diff --git a/src/processors/update_album.php b/src/processors/update_album.php index e225cac1..0da0c73c 100644 --- a/src/processors/update_album.php +++ b/src/processors/update_album.php @@ -76,25 +76,29 @@ try { $updateStmt->close(); // Handle cover image upload if provided - if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] !== UPLOAD_ERR_NO_FILE) { - $allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; - $maxSize = 5 * 1024 * 1024; // 5MB - + if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] === UPLOAD_ERR_OK) { $fileName = $_FILES['cover_image']['name']; $fileTmpName = $_FILES['cover_image']['tmp_name']; $fileSize = $_FILES['cover_image']['size']; - $fileMime = mime_content_type($fileTmpName); - - // Validate file - if (!in_array($fileMime, $allowedMimes)) { - throw new Exception('Invalid cover image file type'); + + // Validate file extension + $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + + if (!in_array($ext, $allowedExtensions)) { + throw new Exception('Invalid cover image file type. Allowed: jpg, jpeg, png, gif, webp'); } - if ($fileSize > $maxSize) { + if ($fileSize > 5 * 1024 * 1024) { throw new Exception('Cover image file too large (max 5MB)'); } $albumDir = $rootPath . '/assets/uploads/gallery/' . $album_id; + + // Create directory if it doesn't exist (match working pattern) + if (!file_exists($albumDir)) { + mkdir($albumDir, 0777, true); + } // Delete old cover if it exists $oldCoverStmt = $conn->prepare("SELECT cover_image FROM photo_albums WHERE album_id = ?"); @@ -104,16 +108,15 @@ try { if ($oldCoverResult->num_rows > 0) { $oldCover = $oldCoverResult->fetch_assoc(); if ($oldCover['cover_image']) { - $oldCoverPath = $_SERVER['DOCUMENT_ROOT'] . $oldCover['cover_image']; + $oldCoverPath = $rootPath . $oldCover['cover_image']; if (file_exists($oldCoverPath)) { - unlink($oldCoverPath); + @unlink($oldCoverPath); } } } $oldCoverStmt->close(); // Generate unique filename - $ext = pathinfo($fileName, PATHINFO_EXTENSION); $newFileName = 'cover_' . uniqid() . '.' . $ext; $filePath = $albumDir . '/' . $newFileName; $coverImagePath = '/assets/uploads/gallery/' . $album_id . '/' . $newFileName; @@ -130,12 +133,15 @@ try { } // Handle photo uploads if any - if (isset($_FILES['photos']) && $_FILES['photos']['error'][0] !== UPLOAD_ERR_NO_FILE) { - $allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; + if (isset($_FILES['photos']) && $_FILES['photos']['error'][0] === UPLOAD_ERR_OK) { $maxSize = 5 * 1024 * 1024; // 5MB - $albumDir = $rootPath . '/assets/uploads/gallery/' . $album_id; + // Create directory if it doesn't exist (match working pattern) + if (!file_exists($albumDir)) { + mkdir($albumDir, 0777, true); + } + // Get current max display order $orderStmt = $conn->prepare("SELECT MAX(display_order) as max_order FROM photos WHERE album_id = ?"); $orderStmt->bind_param("i", $album_id); @@ -153,15 +159,17 @@ try { $fileName = $_FILES['photos']['name'][$i]; $fileTmpName = $_FILES['photos']['tmp_name'][$i]; $fileSize = $_FILES['photos']['size'][$i]; - $fileMime = mime_content_type($fileTmpName); - - // Validate file - if (!in_array($fileMime, $allowedMimes)) { - throw new Exception('Invalid file type: ' . $fileName); + + // Validate file extension + $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + + if (!in_array($ext, $allowedExtensions)) { + throw new Exception('Invalid file type: ' . $fileName . '. Allowed: jpg, jpeg, png, gif, webp'); } if ($fileSize > $maxSize) { - throw new Exception('File too large: ' . $fileName); + throw new Exception('File too large: ' . $fileName . ' (max 5MB)'); } // Generate unique filename diff --git a/src/processors/upload_profile_picture.php b/src/processors/upload_profile_picture.php index 7a174e39..f3868fff 100644 --- a/src/processors/upload_profile_picture.php +++ b/src/processors/upload_profile_picture.php @@ -43,15 +43,9 @@ if (isset($_FILES['profile_picture']) && $_FILES['profile_picture']['error'] != $target_dir = $rootPath . "/assets/images/pp/"; $target_file = $target_dir . $randomFilename; - // Ensure upload directory exists and is writable - if (!is_dir($target_dir)) { - mkdir($target_dir, 0755, true); - } - - if (!is_writable($target_dir)) { - $response['message'] = 'Upload directory is not writable.'; - echo json_encode($response); - exit(); + // Ensure upload directory exists + if (!file_exists($target_dir)) { + mkdir($target_dir, 0777, true); } // Move the uploaded file