1 Commits

Author SHA1 Message Date
twotalesanimation
062dc46ffd small updates 2025-12-02 18:17:20 +02:00
35 changed files with 309 additions and 1305 deletions

View File

@@ -1,4 +1,4 @@
php_flag display_errors On
php_flag display_errors Off
# php_value error_reporting -1
RedirectMatch 403 ^/\.well-known
Options -Indexes

View File

@@ -1,144 +0,0 @@
<?php include_once('header02.php');
checkAdmin();
checkUserSession();
$result = $conn->prepare("
SELECT
b.blog_id,
b.title,
b.description,
b.status,
b.date,
b.image,
CONCAT(u.first_name, ' ', u.last_name) AS author_name,
u.email AS author_email,
u.profile_pic
FROM blogs b
JOIN users u ON b.author = u.user_id
WHERE b.status != 'deleted'
ORDER BY b.date DESC
");
$result->execute();
$posts = $result->get_result();
?>
<style>
.image {
width: 400px;
/* Set your desired width */
height: 350px;
/* Set your desired height */
overflow: hidden;
/* Hide any overflow */
display: block;
/* Ensure proper block behavior */
}
.image img {
width: 100%;
/* Image scales to fill the container */
height: 100%;
/* Image scales to fill the container */
object-fit: cover;
/* Fills the container while maintaining aspect ratio */
object-position: top;
/* Aligns the top of the image with the top of the container */
display: block;
/* Prevents inline whitespace issues */
}
</style>
<?php
$bannerFolder = 'assets/images/banners/';
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
if (!empty($bannerImages)) {
$randomBanner = $bannerImages[array_rand($bannerImages)];
}
?>
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
<!-- Overlay PNG -->
<div class="banner-overlay"></div>
<div class="container">
<div class="banner-inner text-white">
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">Admin Blogs</h2>
<nav aria-label="breadcrumb">
<ol class="breadcrumb justify-content-center mb-20" data-aos="fade-right" data-aos-delay="200" data-aos-duration="1500" data-aos-offset="50">
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
<li class="breadcrumb-item active">Admin Blogs</li>
</ol>
</nav>
</div>
</div>
</section>
<!-- Page Banner End -->
<!-- Blog List Area start -->
<section class="blog-list-page py-100 rel z-1">
<div class="container">
<div class="row">
<div class="col-lg-12">
<h2>My Posts</h2>
<?php if (isset($_SESSION['message'])): ?>
<div class="alert alert-warning message-box">
<?php echo $_SESSION['message']; ?>
<span class="close-btn" onclick="this.parentElement.style.display='none'">&times;</span>
</div>
<?php unset($_SESSION['message']); ?>
<?php endif; ?>
<a href="blog_create.php">+ New Post</a>
<?php while ($post = $posts->fetch_assoc()):
// Output the HTML structure with dynamic data
echo '
<div class="destination-item style-three bgc-lighter booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
<div class="image" style="width:200px;height:200px;">
<img src="' . $post["image"] . '" alt="' . $post["title"] . '">
</div>
<div class="content" style="width:100%;">
<div class="destination-header d-flex align-items-start gap-3">
<img src="' . $post["profile_pic"] . '" alt="Author" class="rounded-circle border" width="80" height="80">
<div>
<span class="badge bg-dark mb-1">' . strtoupper($post["status"]) . '</span>
<h5 class="mb-0">' . $post["title"] . '</h5>
<small class="text-muted">' . $post["author_name"] . '</small>
</div>
</div>
<p>' . $post["description"] . '</p>
<div class="destination-footer">
<div class="btn-group" style="display:flex; justify-content:flex-end; gap:10px; margin-top:10px;">
<a href="blog_edit.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Edit"><i class="bi bi-pencil"></i></a>
<a href="blog_read.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Preview"><i class="bi bi-eye"></i></a>
<a href="blog_delete.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Delete"><i class="bi bi-trash"></i></a>
</div>
</div>
</div>
</div>
';
endwhile; ?>
</div>
</div>
</div>
</section>
<!-- Blog List Area end -->
<script>
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
tooltipTriggerList.forEach(el => new bootstrap.Tooltip(el));
</script>
<?php include_once("insta_footer.php"); ?>

View File

@@ -2,7 +2,7 @@
checkAdmin();
// Fetch all trips
$courseSql = "SELECT date, course_id, course_type FROM courses WHERE DATE(date) >= CURDATE()";
$courseSql = "SELECT date, course_id, course_type FROM courses";
$courseResult = $conn->query($courseSql);
if (!$courseResult) {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

View File

@@ -1,101 +0,0 @@
<?php
require_once("env.php");
require_once("session.php");
require_once("connection.php");
require_once("functions.php");
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 = __DIR__ . "/uploads/blogs/".$article_id."/images/";
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
// Sanitize and rename file
$originalName = basename($_FILES['cover_image']['name']);
$originalName = preg_replace("/[^a-zA-Z0-9\._-]/", "_", $originalName); // remove unsafe characters
$targetPath = $uploadDir . $originalName;
$publicPath = "/uploads/blogs/".$article_id."/images/" . $originalName;
// Error detection before upload
$fileError = $_FILES['cover_image']['error'];
if ($fileError !== UPLOAD_ERR_OK) {
$errorMessages = [
UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive in the HTML form.',
UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.',
UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.',
UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.',
UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the upload.',
];
$errorMessage = $errorMessages[$fileError] ?? 'Unknown upload error.';
http_response_code(500);
echo "Upload error: $errorMessage";
exit;
}
// Skip upload if identical file already exists
if (file_exists($targetPath)) {
$cover_image_path = $publicPath;
} else {
if (move_uploaded_file($_FILES['cover_image']['tmp_name'], $targetPath)) {
$cover_image_path = $publicPath;
} 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

@@ -86,7 +86,7 @@ if (!empty($bannerImages)) {
$icon = "fa-lock";
} else {
if (getUserMemberStatus($_SESSION['user_id'])) {
$blog_link = "blog_read.php?token=".encryptData($blog_id, $salt);
$blog_link = $row['link'];
$button_hover = "Read More";
$icon = "fa-arrow-right";
} else {
@@ -96,7 +96,7 @@ if (!empty($bannerImages)) {
}
}
} else {
$blog_link = "blog_read.php?token=".encryptData($blog_id, $salt);
$blog_link = $row['link'];
$button_hover = "Read More";
$icon = "fa-arrow-right";
}
@@ -105,7 +105,7 @@ if (!empty($bannerImages)) {
echo '
<div class="blog-item style-three" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
<div class="image">
<img style="border-radius:20px;" src="' . $image . '" alt="Blog List">
<img style="border-radius:20px;" src="assets/images/blog/' . $blog_id . '/' . $image . '" alt="Blog List">
</div>
<div class="content">
<a href="blog.php" class="category">' . $category . '</a>

View File

@@ -1,33 +0,0 @@
<?php
// session_start();
require_once("env.php");
require_once("session.php");
require_once("connection.php");
require_once("functions.php");
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

@@ -1,36 +0,0 @@
<?php
require_once("env.php");
require_once("session.php");
require_once("connection.php");
require_once("functions.php");
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

@@ -1,265 +0,0 @@
<?php
include_once('header02.php');
// Ensure the user is logged in
if (!isset($_SESSION['user_id'])) {
die("User not logged in.");
}
$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.php?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.php", {
method: "POST",
body: formData
}).then(response => {
if (response.ok) {
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;
}
}).catch(err => {
console.error("Autosave error:", err);
return false;
});
}
// Trigger autosave every 15s
setInterval(autosavePost, 15000);
// Manual autosave button
document.getElementById("manualSaveBtn").addEventListener("click", autosavePost);
// Manual publish button
document.getElementById("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.php", {
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
document.getElementById("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.php", {
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("insta_footer.php"); ?>

View File

@@ -1,176 +0,0 @@
<?php include_once('header02.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
$page_id = 'blog_'.$blog_id;
echo getCommentCount($page_id);
$stmt = $conn->prepare("
SELECT a.title, a.category, a.description, a.content, a.date,
u.first_name, u.last_name
FROM blogs a
JOIN users u ON a.author = u.user_id
WHERE a.blog_id = ?
");
$stmt->bind_param("i", $blog_id);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
die("Article not found.");
}
$row = $result->fetch_assoc();
$author = htmlspecialchars($row['first_name'] . ' ' . $row['last_name']);
?>
<style>
.image {
width: 400px;
/* Set your desired width */
height: 350px;
/* Set your desired height */
overflow: hidden;
/* Hide any overflow */
display: block;
/* Ensure proper block behavior */
}
.image img {
width: 100%;
/* Image scales to fill the container */
height: 100%;
/* Image scales to fill the container */
object-fit: cover;
/* Fills the container while maintaining aspect ratio */
object-position: top;
/* Aligns the top of the image with the top of the container */
display: block;
/* Prevents inline whitespace issues */
}
</style>
<style>
body {
/* font-family: Arial, sans-serif; */
line-height: 1.6;
/* max-width: 800px; */
margin: auto;
/* padding: 20px; */
}
h1,
h2 {
color: #2c3e50;
}
h2 {
margin-top: 2em;
}
.content {
margin-bottom: 2em;
}
.img-left,
.img-right {
max-width: 30%;
margin: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
.img-left {
float: left;
}
.img-right {
float: right;
}
.clearfix {
clear: both;
}
</style>
<?php
$bannerFolder = 'assets/images/banners/';
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
if (!empty($bannerImages)) {
$randomBanner = $bannerImages[array_rand($bannerImages)];
}
?>
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
<div class="banner-overlay"></div>
<div class="container">
<div class="banner-inner text-white">
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50"><?= htmlspecialchars($row['title']) ?></h2>
<nav aria-label="breadcrumb">
<ol class="breadcrumb justify-content-center mb-20" data-aos="fade-right" data-aos-delay="200" data-aos-duration="1500" data-aos-offset="50">
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
<li class="breadcrumb-item active"><?= htmlspecialchars($row['title']) ?></li>
</ol>
</nav>
</div>
</div>
</section>
<!-- Page Banner End -->
<!-- Blog Detaisl Area start -->
<section class="blog-detaisl-page py-100 rel z-1">
<div class="container">
<div class="row">
<div class="col-lg-8">
<div class="blog-details-content" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
<a href="blog.html" class="category"><?= htmlspecialchars($row['category']) ?></a>
<ul class="blog-meta mb-30">
<li><img src="assets/images/pp/default.png" alt="Admin"> <a href="#"><?= $author?></a></li>
<li><i class="far fa-calendar-alt"></i> <a href="#"><?= htmlspecialchars($row['date']) ?></a></li>
<li><i class="far fa-comments"></i> <a href="#">Comments (<?= getCommentCount($page_id);?>)</a></li>
</ul>
<?= $row['content'] ?>
</div>
<hr class="mb-45">
<div class="tag-share mb-50">
<div class="item" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
<h6>Tags </h6>
<div class="tag-coulds">
<a href="blog.php"><?= htmlspecialchars($row['category']) ?></a>
</div>
</div>
</div>
<?php include_once('comment_box.php'); ?>
</div>
<div class="col-lg-4 col-md-8 col-sm-10 rmt-75">
<div class="blog-sidebar">
<div class="widget widget-gallery" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
<h5 class="widget-title">Gallery</h5>
<div class="gallery">
<?php
$folder = 'uploads/blogs/'.$blog_id.'/images/';
$files = glob($folder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
shuffle($files); // Randomize the order
foreach ($files as $file) {
echo '<a href="' . $file . '" style="width: 110px; height: 110px; overflow: hidden; display: inline-block; margin: 2px;">';
echo '<img src="' . $file . '" alt="Gallery" style="width: 100%; height: 100%; object-fit: cover; display: block;">';
echo '</a>';
}
?>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<?php include_once("insta_footer.php"); ?>

View File

@@ -1,31 +0,0 @@
<?php
require_once("env.php");
require_once("session.php");
require_once("connection.php");
require_once("functions.php");
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo "Not authorized";
exit;
}
$article_id = (int)($_POST['id'] ?? 0);
$user_id = $_SESSION['user_id'];
if ($article_id <= 0) {
http_response_code(400);
echo "Invalid blog ID";
exit;
}
$stmt = $conn->prepare("UPDATE blogs SET status = 'draft' WHERE blog_id = ? AND author = ?");
$stmt->bind_param("ii", $article_id, $user_id);
if ($stmt->execute()) {
echo "Published";
} else {
http_response_code(500);
echo "Failed to publish: " . $stmt->error;
}
?>

View File

@@ -2,7 +2,7 @@
checkUserSession();
// SQL query to fetch dates for driver training
$sql = "SELECT course_id, date FROM courses WHERE course_type = 'bush_mechanics'";
$sql = "SELECT course_id, date FROM courses WHERE course_type = 'bush_mechanics' AND date >= CURDATE()";
$result = $conn->query($sql);
$page_id = 'bush_mechanics';
?>
@@ -114,7 +114,7 @@ if (!empty($bannerImages)) {
</select>
</li>
<?php
if ($is_member) {
if ($is_member || $pending_member) {
echo '
<li>
Additional Members <span class="price"></span>
@@ -169,8 +169,16 @@ if (!empty($bannerImages)) {
<label for="agreeCheckbox" id="agreeLabel" style="color: #888;">I have read and agree to the indemnity terms</label>
</div>
</div>
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5">
<span data-hover="Book Now">Book Now</span>
<?php
$button_text = "Book Now";
$button_disabled = "";
if (!$result || $result->num_rows == 0) {
$button_text = "No booking dates available";
$button_disabled = "disabled";
}
?>
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5" <?php echo $button_disabled; ?>>
<span data-hover="<?php echo $button_text; ?>"><?php echo $button_text; ?></span>
<i class="fal fa-arrow-right"></i>
</button>
<div class="text-center">
@@ -357,6 +365,7 @@ if (!empty($bannerImages)) {
// Fetch PHP variables
var isMember = <?php echo $is_member ? 'true' : 'false'; ?>;
var pendingMember = <?php echo $pending_member ? 'true' : 'false'; ?>;
var cost_members = <?= getPrice('bush_mechanics', 'member');?>;
var cost_nonmembers = <?= getPrice('bush_mechanics', 'nonmember');?>;
@@ -364,7 +373,7 @@ if (!empty($bannerImages)) {
var total = 0;
// Calculate cost for members
if (isMember) {
if (isMember || pendingMember) {
total = (cost_members) + (members * cost_members) + (nonmembers * cost_nonmembers);
} else {
// Calculate cost for non-members

View File

@@ -2,9 +2,14 @@
checkUserSession();
// SQL query to fetch dates for driver training
$sql = "SELECT course_id, date FROM courses WHERE course_type = 'driver_training'";
$sql = "SELECT course_id, date
FROM courses
WHERE course_type = 'driver_training'
AND date >= CURDATE()";
$result = $conn->query($sql);
$page_id = 'driver_training';
?>
<style>
@@ -99,11 +104,11 @@ if (!empty($bannerImages)) {
Select Date
<select name="course_id" id="course_id" required>
<?php
if ($result->num_rows > 0) {
if ($result && $result->num_rows > 0) {
// Output each course as an option
while ($row = $result->fetch_assoc()) {
$course_id = htmlspecialchars($row['course_id']); // Escape output for security
$date = htmlspecialchars($row['date']); // Escape output for security
$date = htmlspecialchars($row['date']); // Escape output for security
echo "<option value='$course_id'>$date</option>";
}
} else {
@@ -111,9 +116,10 @@ if (!empty($bannerImages)) {
}
?>
</select>
</li>
<?php
if ($is_member) {
if ($is_member || $pending_member) {
echo '
<li>
Additional Members <span class="price"></span>
@@ -136,6 +142,7 @@ if (!empty($bannerImages)) {
<option value="3">03</option>
</select>
</li>
</ul>
<hr class="mb-25">
@@ -168,8 +175,16 @@ if (!empty($bannerImages)) {
<label for="agreeCheckbox" id="agreeLabel" style="color: #888;">I have read and agree to the indemnity terms</label>
</div>
</div>
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5">
<span data-hover="Book Now">Book Now</span>
<?php
$button_text = "Book Now";
$button_disabled = "";
if (!$result || $result->num_rows == 0) {
$button_text = "No booking dates available";
$button_disabled = "disabled";
}
?>
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5" <?php echo $button_disabled; ?>>
<span data-hover="<?php echo $button_text; ?>"><?php echo $button_text; ?></span>
<i class="fal fa-arrow-right"></i>
</button>
<div class="text-center">
@@ -355,6 +370,7 @@ if (!empty($bannerImages)) {
// Fetch PHP variables
var isMember = <?php echo $is_member ? 'true' : 'false'; ?>;
var pendingMember = <?php echo $pending_member ? 'true' : 'false'; ?>;
var cost_members = <?= getPrice('driver_training', 'member'); ?>;
var cost_nonmembers = <?= getPrice('driver_training', 'nonmember'); ?>;
@@ -362,7 +378,7 @@ if (!empty($bannerImages)) {
var total = 0;
// Calculate cost for members
if (isMember) {
if (isMember || pendingMember) {
total = (cost_members) + (members * cost_members) + (nonmembers * cost_nonmembers);
} else {
// Calculate cost for non-members

View File

@@ -189,6 +189,83 @@ function sendInvoice($email, $name, $eft_id, $amount, $description)
}
}
function getEFTDetails($eft_id) {
$conn = openDatabaseConnection();
$stmt = $conn->prepare("SELECT amount, description FROM efts WHERE eft_id = ? LIMIT 1");
$stmt->bind_param("s", $eft_id);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
return [
'amount' => $row['amount'],
'description' => $row['description']
];
} else {
return false; // EFT not found
}
}
function sendPOP($fullname, $eft_id, $amount, $description)
{
global $mailjet;
$message = [
'Messages' => [
[
'From' => [
'Email' => "info@4wdcsa.co.za",
'Name' => "4WDCSA Web Admin"
],
'To' => [
[
'Email' => 'chrispintoza@gmail.com',
'Name' => 'Chris Pinto'
],
[
'Email' => 'info@4wdcsa.co.za',
'Name' => 'Jacqui Boshoff'
],
[
'Email' => 'louiseb@global.co.za',
'Name' => 'Louise Blignault'
]
],
'TemplateID' => 7054062,
'TemplateLanguage' => true,
'Subject' => "4WDCSA - Proof of Payment Received",
'Variables' => [
'fullname' => $fullname,
'eft_id' => $eft_id,
'amount' => $amount,
'description' => $description,
]
]
]
];
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.mailjet.com/v3.1/',
]);
$response = $client->request('POST', 'send', [
'json' => $message,
'auth' => ['1a44f8d5e847537dbb8d3c76fe73a93c', 'ec98b45c53a7694c4f30d09eee9ad280']
]);
if ($response->getStatusCode() == 200) {
$body = $response->getBody();
$response = json_decode($body);
if ($response->Messages[0]->Status == 'success') {
return True;
} else {
return False;
}
}
}
function sendEmail($email, $subject, $message)
{
global $mailjet;
@@ -414,6 +491,91 @@ function getUserMemberStatus($user_id)
return false; // Membership is not active
}
function getUserMemberStatusPending($user_id)
{
$conn = openDatabaseConnection();
// Step 1: Check if the user is a member
$queryUser = "SELECT member FROM users WHERE user_id = ?";
$stmtUser = $conn->prepare($queryUser);
if (!$stmtUser) {
error_log("Failed to prepare user query: " . $conn->error);
return false;
}
$stmtUser->bind_param('i', $user_id);
$stmtUser->execute();
$resultUser = $stmtUser->get_result();
$stmtUser->close();
if ($resultUser->num_rows === 0) {
error_log("User not found for user_id: $user_id");
return false;
}
// Step 3: Check the membership_application table for accept_indemnity status
$queryApplication = "SELECT accept_indemnity FROM membership_application WHERE user_id = ?";
$stmtApplication = $conn->prepare($queryApplication);
if (!$stmtApplication) {
error_log("Failed to prepare application query: " . $conn->error);
return false;
}
$stmtApplication->bind_param('i', $user_id);
$stmtApplication->execute();
$resultApplication = $stmtApplication->get_result();
$stmtApplication->close();
if ($resultApplication->num_rows === 0) {
error_log("No membership application found for user_id: $user_id");
return false;
}
$application = $resultApplication->fetch_assoc();
$accept_indemnity = $application['accept_indemnity'];
// Validate accept_indemnity
if ($accept_indemnity !== 1) {
error_log("User has not accepted indemnity for user_id: $user_id");
return false;
}
// Step 2: Check membership fees table for valid payment status and membership_end_date
$queryFees = "SELECT payment_status, membership_end_date FROM membership_fees WHERE user_id = ?";
$stmtFees = $conn->prepare($queryFees);
if (!$stmtFees) {
error_log("Failed to prepare fees query: " . $conn->error);
return false;
}
$stmtFees->bind_param('i', $user_id);
$stmtFees->execute();
$resultFees = $stmtFees->get_result();
$stmtFees->close();
if ($resultFees->num_rows === 0) {
error_log("Membership fees not found for user_id: $user_id");
return false;
}
$fees = $resultFees->fetch_assoc();
$payment_status = $fees['payment_status'];
$membership_end_date = $fees['membership_end_date'];
// Validate payment status and membership_end_date
$current_date = new DateTime();
$membership_end_date_obj = DateTime::createFromFormat('Y-m-d', $membership_end_date);
if ($payment_status === "AWAITING PAYMENT" && $current_date <= $membership_end_date_obj) {
return true; // Membership is pending
} else {
return false;
}
return false; // Membership is not pending
}
function checkUserSession()
{
@@ -961,19 +1123,21 @@ function checkSuperAdmin()
function calculateProrata($prorata)
{
// Get the current month as a number (1 = January, 12 = December)
// Get current month number (1 = January, 12 = December)
$currentMonth = date('n');
// Total months in a year
// Shift months so March becomes month 1 in the cycle
// (March=1, April=2, ..., February=12)
$shiftedMonth = ($currentMonth - 3 + 12) % 12 + 1;
// Total months in a "March to February" year
$totalMonths = 12;
// Calculate the remaining months including the current month
$remainingMonths = $totalMonths - $currentMonth + 1;
// Calculate remaining months including the current month
$remainingMonths = $totalMonths - $shiftedMonth + 1;
// Multiply by prorata value
$prorataAmount = $remainingMonths * $prorata;
return $prorataAmount;
return $remainingMonths * $prorata;
}
function getFullName($user_id)
@@ -1784,8 +1948,8 @@ function getCommentCount($page_id) {
$conn = openDatabaseConnection();
// Prepare statement to avoid SQL injection
$stmt = $conn->prepare("SELECT COUNT(*) FROM comments WHERE `page_id` = ?");
$stmt->bind_param("s", $page_id);
$stmt = $conn->prepare("SELECT COUNT(*) FROM comments WHERE page_id = ?");
$stmt->bind_param("i", $page_id);
$stmt->execute();
// Get result
@@ -1798,3 +1962,18 @@ function getCommentCount($page_id) {
return $count;
}
function hasPhoneNumber($user_id) {
$conn = openDatabaseConnection();
// Prepare SQL
$stmt = $conn->prepare("SELECT phone_number FROM users WHERE id = ? LIMIT 1");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$stmt->bind_result($phone_number);
$stmt->fetch();
$stmt->close();
// Return true only if a phone number exists and is not empty
return !empty($phone_number);
}

View File

@@ -7,12 +7,14 @@ require_once("functions.php");
$is_logged_in = isset($_SESSION['user_id']);
if (isset($_SESSION['user_id'])) {
$is_member = getUserMemberStatus($_SESSION['user_id']);
$pending_member = getUserMemberStatusPending($_SESSION['user_id']);
$user_id = $_SESSION['user_id'];
} else {
$is_member = false;
}
$role = getUserRole();
logVisitor();
?>
<!DOCTYPE html>
@@ -211,7 +213,6 @@ logVisitor();
<!-- <li><a href="admin_payments.php">Payfast Payments</a></li> -->
<li><a href="admin_efts.php">EFT Payments</a></li>
<li><a href="process_payments.php">Process Payments</a></li>
<li><a href="admin_blogs.php">Manage Blogs</a></li>
<!-- <li><a href="bar_tabs.php">Bar</a></li> -->
<?php if ($role === 'superadmin') { ?>
<li><a href="admin_visitors.php">Visitor Log</a></li>
@@ -233,7 +234,6 @@ logVisitor();
<li><a href="account_settings.php">Account Settings</a></li>
<li><a href="membership_details.php">Membership</a></li>
<li><a href="bookings.php">My Bookings</a></li>
<li><a href="user_blogs.php">My Blogs</a></li>
<li><a href="submit_pop.php">Submit P.O.P</a></li>
<li><a href="logout.php">Log Out</a></li>
</ul>

View File

@@ -8,6 +8,7 @@ $is_logged_in = isset($_SESSION['user_id']);
$role = getUserRole();
if (isset($_SESSION['user_id'])) {
$is_member = getUserMemberStatus($_SESSION['user_id']);
$pending_member = getUserMemberStatusPending($_SESSION['user_id']);
$user_id = $_SESSION['user_id'];
}
logVisitor();
@@ -33,8 +34,6 @@ logVisitor();
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
<!-- Flaticon -->
<link rel="stylesheet" href="assets/css/flaticon.min.css">
<!-- Font Awesome -->
@@ -226,7 +225,6 @@ logVisitor();
<!-- <li><a href="admin_payments.php">Payfast Payments</a></li> -->
<li><a href="admin_efts.php">EFT Payments</a></li>
<li><a href="process_payments.php">Process Payments</a></li>
<li><a href="admin_blogs.php">Manage Blogs</a></li>
<?php if ($role === 'superadmin') { ?>
<li><a href="admin_visitors.php">Visitor Log</a></li>
<?php } ?>
@@ -241,7 +239,6 @@ logVisitor();
<li><a href="account_settings.php">Account Settings</a></li>
<li><a href="membership_details.php">Membership</a></li>
<li><a href="bookings.php">My Bookings</a></li>
<li><a href="user_blogs.php">My Blogs</a></li>
<li><a href="submit_pop.php">Submit P.O.P</a></li>
<li><a href="logout.php">Log Out</a></li>
</ul>

190
index.php
View File

@@ -51,7 +51,7 @@ if (!empty($bannerImages)) {
<div style="padding-top: 50px; padding-bottom: 50px;">
<img style="width: 250px; margin-bottom: 20px;" src="assets/images/logos/weblogo2.png" alt="Logo">
<h1 class="hero-title" data-aos="flip-up" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
Welcome to<br>the 4 Wheel Drive Club<br>of Southern Africa
Welcome to<br>the Four Wheel Drive Club<br>of Southern Africa
</h1>
<a href="membership.php" class="theme-btn style-two bgc-secondary" style="margin-top: 20px; background-color: #e90000; padding: 10px 20px; color: white; text-decoration: none; border-radius: 25px;">
<span data-hover="Become a Member">Become a Member</span>
@@ -190,105 +190,6 @@ if (countUpcomingTrips() > 0) { ?>
</a>
</div>
</section>
<!-- Popular Destinations Area start -->
<!-- <section class="popular-destinations-area rel z-1">
<div class="container-fluid">
<div class="popular-destinations-wrap br-20 bgc-lighter pt-100 pb-70">
<div class="row justify-content-center">
<div class="col-lg-12">
<div class="section-title text-center counter-text-wrap mb-70" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
<h2>Explore Popular Destinations</h2>
<p>One site <span class="count-text plus" data-speed="3000" data-stop="34500">0</span> most popular experience</p>
</div>
</div>
</div>
<div class="container">
<div class="row justify-content-center">
<div class="col-xl-3 col-md-6">
<div class="destination-item style-two" data-aos="flip-up" data-aos-duration="1500" data-aos-offset="50">
<div class="image">
<a href="#" class="heart"><i class="fas fa-heart"></i></a>
<img src="assets/images/destinations/destination1.jpg" alt="Destination">
</div>
<div class="content">
<h6><a href="destination-details.html">Thailand beach</a></h6>
<span class="time">5352+ tours & 856+ Activity</span>
<a href="#" class="more"><i class="fas fa-chevron-right"></i></a>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="destination-item style-two" data-aos="flip-up" data-aos-delay="100" data-aos-duration="1500" data-aos-offset="50">
<div class="image">
<a href="#" class="heart"><i class="fas fa-heart"></i></a>
<img src="assets/images/destinations/destination2.jpg" alt="Destination">
</div>
<div class="content">
<h6><a href="destination-details.html">Parga, Greece</a></h6>
<span class="time">5352+ tours & 856+ Activity</span>
<a href="#" class="more"><i class="fas fa-chevron-right"></i></a>
</div>
</div>
</div>
<div class="col-md-6">
<div class="destination-item style-two" data-aos="flip-up" data-aos-delay="200" data-aos-duration="1500" data-aos-offset="50">
<div class="image">
<a href="#" class="heart"><i class="fas fa-heart"></i></a>
<img src="assets/images/destinations/destination3.jpg" alt="Destination">
</div>
<div class="content">
<h6><a href="destination-details.html">Castellammare del Golfo, Italy</a></h6>
<span class="time">5352+ tours & 856+ Activity</span>
<a href="#" class="more"><i class="fas fa-chevron-right"></i></a>
</div>
</div>
</div>
<div class="col-md-6">
<div class="destination-item style-two" data-aos="flip-up" data-aos-duration="1500" data-aos-offset="50">
<div class="image">
<a href="#" class="heart"><i class="fas fa-heart"></i></a>
<img src="assets/images/destinations/destination4.jpg" alt="Destination">
</div>
<div class="content">
<h6><a href="destination-details.html">Reserve of Canada, Canada</a></h6>
<span class="time">5352+ tours & 856+ Activity</span>
<a href="#" class="more"><i class="fas fa-chevron-right"></i></a>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="destination-item style-two" data-aos="flip-up" data-aos-delay="100" data-aos-duration="1500" data-aos-offset="50">
<div class="image">
<a href="#" class="heart"><i class="fas fa-heart"></i></a>
<img src="assets/images/destinations/destination5.jpg" alt="Destination">
</div>
<div class="content">
<h6><a href="destination-details.html">Dubai united states</a></h6>
<span class="time">5352+ tours & 856+ Activity</span>
<a href="#" class="more"><i class="fas fa-chevron-right"></i></a>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="destination-item style-two" data-aos="flip-up" data-aos-delay="200" data-aos-duration="1500" data-aos-offset="50">
<div class="image">
<a href="#" class="heart"><i class="fas fa-heart"></i></a>
<img src="assets/images/destinations/destination6.jpg" alt="Destination">
</div>
<div class="content">
<h6><a href="destination-details.html">Milos, Greece</a></h6>
<span class="time">5352+ tours & 856+ Activity</span>
<a href="#" class="more"><i class="fas fa-chevron-right"></i></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section> -->
<!-- Popular Destinations Area end -->
<!-- Features Area start -->
<section class="features-area pt-100 pb-45 rel z-1">
@@ -311,31 +212,6 @@ if (countUpcomingTrips() > 0) { ?>
<i class="fal fa-arrow-right"></i>
</a>
</div>
<!-- <div class="menu-btns py-10">
<a href="campsite_booking.php" class="theme-btn style-two bgc-secondary">
<span data-hover="Book a Campsite">Book a Campsite</span>
<i class="fal fa-arrow-right"></i>
</a>
</div> -->
<!-- <div class="features-customer-box">
<div class="image">
<img src="assets/images/features/features-box.jpg" alt="Features">
</div>
<div class="content">
<div class="feature-authors mb-15">
<img src="assets/images/features/feature-author1.jpg" alt="Author">
<img src="assets/images/features/feature-author2.jpg" alt="Author">
<img src="assets/images/features/feature-author3.jpg" alt="Author">
<span>4k+</span>
</div>
<h6>850K+ Happy Customer</h6>
<div class="divider style-two counter-text-wrap my-25"><span><span class="count-text plus" data-speed="3000" data-stop="25">0</span> Years</span></div>
<p>We pride ourselves offering personalized itineraries</p>
</div>
</div> -->
</div>
</div>
<div class="col-xl-6" data-aos="fade-right" data-aos-duration="1500" data-aos-offset="50">
@@ -478,56 +354,10 @@ if (countUpcomingTrips() > 0) { ?>
</div>
</div>
<!-- <div class="hotel-more-btn text-center mt-40">
<a href="destination2.html" class="theme-btn style-four">
<span data-hover="Explore More Hotel">Explore More Hotel</span>
<i class="fal fa-arrow-right"></i>
</a>
</div> -->
</div>
</section>
<!-- Hotel Area end -->
<!-- CTA Area start -->
<!-- <section class="cta-area pt-100 rel z-1">
<div class="container-fluid">
<div class="row">
<div class="col-xl-4 col-md-6" data-aos="zoom-in-down" data-aos-duration="1500" data-aos-offset="50">
<div class="cta-item" style="background-image: url(assets/images/cta/cta1.jpg);">
<span class="category">Tent Camping</span>
<h2>Explore the world best tourism</h2>
<a href="trip-details.php" class="theme-btn style-two bgc-secondary">
<span data-hover="Explore Tours">Explore Tours</span>
<i class="fal fa-arrow-right"></i>
</a>
</div>
</div>
<div class="col-xl-4 col-md-6" data-aos="zoom-in-down" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
<div class="cta-item" style="background-image: url(assets/images/cta/cta2.jpg);">
<span class="category">Sea Beach</span>
<h2>World largest Sea Beach in Thailand</h2>
<a href="trip-details.php" class="theme-btn style-two">
<span data-hover="Explore Tours">Explore Tours</span>
<i class="fal fa-arrow-right"></i>
</a>
</div>
</div>
<div class="col-xl-4 col-md-6" data-aos="zoom-in-down" data-aos-delay="100" data-aos-duration="1500" data-aos-offset="50">
<div class="cta-item" style="background-image: url(assets/images/cta/cta3.jpg);">
<span class="category">Water Falls</span>
<h2>Largest Water falls Bali, Indonesia</h2>
<a href="trip-details.php" class="theme-btn style-two bgc-secondary">
<span data-hover="Explore Tours">Explore Tours</span>
<i class="fal fa-arrow-right"></i>
</a>
</div>
</div>
</div>
</div>
</section> -->
<!-- CTA Area end -->
<!-- Blog Area start -->
<section class="blog-area py-70 rel z-1">
<div class="container">
@@ -541,7 +371,7 @@ if (countUpcomingTrips() > 0) { ?>
</div>
<div class="row justify-content-center">
<?php
$sql = "SELECT blog_id, title, date, category, image, description, author, link, members_only FROM blogs WHERE status = 'published' ORDER BY date DESC LIMIT 3 ";
$sql = "SELECT blog_id, title, date, category, image, description, author, link, members_only FROM blogs WHERE status = 'published' ORDER BY date DESC LIMIT 3";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
@@ -562,7 +392,7 @@ if (countUpcomingTrips() > 0) { ?>
$icon = "fa-lock";
}else{
if (getUserMemberStatus($_SESSION['user_id'])) {
$blog_link = "blog_read.php?token=".encryptData($blog_id, $salt);
$blog_link = $row['link'];
$button_hover = "Read More";
$icon = "fa-arrow-right";
}else{
@@ -572,7 +402,7 @@ if (countUpcomingTrips() > 0) { ?>
}
}
}else{
$blog_link = "blog_read.php?token=".encryptData($blog_id, $salt);
$blog_link = $row['link'];
$button_hover = "Read More";
$icon = "fa-arrow-right";
}
@@ -591,7 +421,7 @@ if (countUpcomingTrips() > 0) { ?>
</ul>
</div>
<div class="image">
<img style="border-radius:20px;" src="' . $blog_image . '" alt="Blog List">
<img style="border-radius:20px;" src="assets/images/blog/' . $blog_id . '/' . $blog_image . '" alt="Blog List">
</div>
<a style="width:100%;" href="' . $blog_link . '" class="theme-btn">
<span style="width:100%;" data-hover="'.$button_hover.'">Read More</span>
@@ -664,16 +494,6 @@ if (countUpcomingTrips() > 0) { ?>
</form>
</div>
</div>
<!--
<form class="newsletter-form mb-50" action="#">
<input id="news-email" type="email" placeholder="Email Address" required>
<button type="submit" class="theme-btn bgc-secondary style-two">
<span data-hover="Subscribe">Subscribe</span>
<i class="fal fa-arrow-right"></i>
</button>
</form> -->
</div>
</div>
</div>

View File

@@ -113,7 +113,24 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$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');
// $membership_end_date = date('Y-12-31');
// Get today's date
$today = new DateTime();
// 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;
} else {
// Otherwise, this year's February
$year = $today->format('Y');
}
// 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', ?)");

View File

@@ -14,11 +14,12 @@ if (!$user_id) {
exit();
}
$is_member = getUserMemberStatus($user_id);
$pending_member = getUserMemberStatusPending($user_id);
// Check if the form has been submitted
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Input variables from the form (use default values if not provided)
$members = isset($_POST['members']) ? intval($_POST['members']) : 0; // Default to 1 vehicle
$additional_members = isset($_POST['members']) ? intval($_POST['members']) : 0; // Default to 1 vehicle
$num_adults = isset($_POST['non-members']) ? intval($_POST['non-members']) : 0; // Default to 1 adult
$course_id = isset($_POST['course_id']) ? intval($_POST['course_id']) : 0; // Default to 0 children
checkAndRedirectCourseBooking($course_id);
@@ -54,16 +55,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$description = "General Course " . $date; // Default fallback description
}
// Assume the membership status is determined elsewhere
$is_member = getUserMemberStatus($user_id);
// Initialize total and discount amount
$total = 0;
// Calculate total based on membership
if ($is_member) {
$num_members = 1 + $members;
$total = (($cost_members) + ($members * $cost_members) + ($num_adults * $cost_nonmembers));
if ($is_member || $pending_member) {
$num_members = 1 + $additional_members;
$total = ($num_members * $cost_members) + ($num_adults * $cost_nonmembers);
$payment_amount = $total;
} else {
$num_members = 0;
@@ -78,18 +76,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$num_vehicles = 1;
$discountAmount = 0;
$eft_id = strtoupper("COURSE ".date("m-d", strtotime($date))." ".getInitialSurname($user_id));
$notes = "";
if ($pending_member){
$notes = "Membership Payment pending at time of booking. Please confirm payment has been received.";
}
// Insert booking into the database
$sql = "INSERT INTO bookings (booking_type, user_id, from_date, to_date, num_vehicles, num_adults, total_amount, discount_amount, status, payment_id, course_id, course_non_members, eft_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$sql = "INSERT INTO bookings (booking_type, user_id, from_date, to_date, num_vehicles, num_adults, total_amount, discount_amount, status, payment_id, course_id, course_non_members, eft_id, notes)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
if (!$stmt) {
die("Preparation failed: " . $conn->error);
}
$stmt->bind_param('sissiiddssiis', $type, $user_id, $date, $date, $num_vehicles, $num_members, $total, $discountAmount, $status, $payment_id, $course_id, $num_adults, $eft_id);
$stmt->bind_param('sissiiddssiiss', $type, $user_id, $date, $date, $num_vehicles, $num_members, $total, $discountAmount, $status, $payment_id, $course_id, $num_adults, $eft_id, $notes);
if ($stmt->execute()) {
$booking_id = $conn->insert_id;
@@ -114,28 +116,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo "Error processing booking: $error_message";
}
// if ($stmt->execute()) {
// if ($payment_amount < 1) {
// if (processZeroPayment($payment_id, $payment_amount, $description)) {
// echo "<script>alert('Booking successfully created!'); window.location.href = 'bookings.php';</script>";
// } else {
// $error_message = $stmt->error;
// echo "Error processing booking: $error_message";
// }
// } else {
// if (processPayment($payment_id, $payment_amount, $description)) {
// echo "<script>alert('Booking successfully created!'); window.location.href = 'bookings.php';</script>";
// } else {
// $error_message = $stmt->error;
// echo "Error processing booking: $error_message";
// }
// }
// } else {
// // Handle error if insert fails and echo the MySQL error
// $error_message = $stmt->error;
// echo "Error processing booking: $error_message";
// }
$stmt->close();
$conn->close();
} else {

View File

@@ -1,31 +0,0 @@
<?php
require_once("env.php");
require_once("session.php");
require_once("connection.php");
require_once("functions.php");
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo "Not authorized";
exit;
}
$article_id = (int)($_POST['id'] ?? 0);
$user_id = $_SESSION['user_id'];
if ($article_id <= 0) {
http_response_code(400);
echo "Invalid blog ID";
exit;
}
$stmt = $conn->prepare("UPDATE blogs SET status = 'published' WHERE blog_id = ? AND author = ?");
$stmt->bind_param("ii", $article_id, $user_id);
if ($stmt->execute()) {
echo "Published";
} else {
http_response_code(500);
echo "Failed to publish: " . $stmt->error;
}
?>

View File

@@ -2,7 +2,7 @@
checkUserSession();
// SQL query to fetch dates for driver training
$sql = "SELECT course_id, date FROM courses WHERE course_type = 'rescue_recovery'";
$sql = "SELECT course_id, date FROM courses WHERE course_type = 'rescue_recovery' AND date >= CURDATE()";
$result = $conn->query($sql);
$page_id = 'rescue_recovery';
?>
@@ -113,7 +113,7 @@ if (!empty($bannerImages)) {
</select>
</li>
<?php
if ($is_member) {
if ($is_member || $pending_member) {
echo '
<li>
Additional Members <span class="price"></span>
@@ -168,8 +168,16 @@ if (!empty($bannerImages)) {
<label for="agreeCheckbox" id="agreeLabel" style="color: #888;">I have read and agree to the indemnity terms</label>
</div>
</div>
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5">
<span data-hover="Book Now">Book Now</span>
<?php
$button_text = "Book Now";
$button_disabled = "";
if (!$result || $result->num_rows == 0) {
$button_text = "No booking dates available";
$button_disabled = "disabled";
}
?>
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5" <?php echo $button_disabled; ?>>
<span data-hover="<?php echo $button_text; ?>"><?php echo $button_text; ?></span>
<i class="fal fa-arrow-right"></i>
</button>
<div class="text-center">
@@ -290,6 +298,7 @@ if (!empty($bannerImages)) {
// Fetch PHP variables
var isMember = <?php echo $is_member ? 'true' : 'false'; ?>;
var pendingMember = <?php echo $pending_member ? 'true' : 'false'; ?>;
var cost_members = <?= getPrice('rescue_recovery', 'member'); ?>;
var cost_nonmembers = <?= getPrice('rescue_recovery', 'nonmember'); ?>;
@@ -297,7 +306,7 @@ if (!empty($bannerImages)) {
var total = 0;
// Calculate cost for members
if (isMember) {
if (isMember || pendingMember) {
total = (cost_members) + (members * cost_members) + (nonmembers * cost_nonmembers);
} else {
// Calculate cost for non-members

View File

@@ -1,24 +0,0 @@
<?php
session_start();
require_once("env.php");
require_once("session.php");
require_once("connection.php");
require_once("functions.php");
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');
$stmt = $conn->prepare("INSERT INTO blogs (author, title, content, description, category, date) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param("isssss", $user_id, $title, $content, $description, $category, $date);
$stmt->execute();
header("Location: blog.php");

View File

@@ -1,5 +1,7 @@
<?php include_once('header02.php');
checkUserSession();
umask(002); // At the top of the PHP script, before move_uploaded_file()
$user_id = $_SESSION['user_id'] ?? null;
@@ -50,6 +52,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
if (move_uploaded_file($file['tmp_name'], $target_file)) {
chmod($target_file, 0664);
// Update EFT and booking status
$payment_type = $_POST['payment_type'] ?? 'booking';
@@ -73,43 +76,33 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$stmt2->execute();
}
// Notify n8n and send the path to the uploaded file
$webhook_url = 'https://n8n.4wdcsa.co.za/webhook/process-pop';
// Send notification email using sendPOP()
$fullname = getFullName($user_id); // Assuming this returns "First Last"
$postData = [
'eft_id' => $eft_id,
'payment_type' => $payment_type,
];
$eftDetails = getEFTDetails($eft_id);
$modified = str_replace(' ', '_', $eft_id);
$ch = curl_init($webhook_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
$response = curl_exec($ch);
$error = curl_error($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($error) {
error_log("Webhook Error: $error");
$_SESSION['message'] = $error;
header("Location: bookings.php");
} else {
$_SESSION['message'] = "Thank you! We are busy processing your payment!";
header("Location: bookings.php");
}
exit;
if ($eftDetails) {
$amount = "R" . number_format($eftDetails['amount'], 2);
$description = $eftDetails['description'];
} else {
echo "<div class='alert alert-danger'>Unable to move uploaded file.</div>";
echo "<pre>Tmp file exists? " . (file_exists($file['tmp_name']) ? "Yes" : "No") . "</pre>";
echo "<pre>Tmp file path: " . htmlspecialchars($file['tmp_name']) . "</pre>";
exit;
$amount = "R0.00";
$description = "Payment"; // fallback
}
if (sendPOP($fullname, $modified, $amount, $description)) {
$_SESSION['message'] = "Thank you! Your payment proof has been uploaded and notification sent.";
} else {
$_SESSION['message'] = "Payment uploaded, but notification email could not be sent.";
}
header("Location: bookings.php");
exit;
} else {
echo "<div class='alert alert-danger'>Unable to move uploaded file.</div>";
exit;
}
}

View File

@@ -1,27 +0,0 @@
<?php
header('Content-Type: application/json');
$blog_id = $_GET['blog_id'] ?? null;
if (!isset($_FILES['file'])) {
echo json_encode(['error' => 'No file uploaded']);
http_response_code(400);
exit;
}
$targetDir = "uploads/blogs/".$blog_id."/images/";
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)) {
echo json_encode(['location' => $targetFile]);
} else {
echo json_encode(['error' => 'Failed to move uploaded file']);
http_response_code(500);
}

View File

@@ -1,24 +0,0 @@
<?php
header('Content-Type: application/json');
if (!isset($_FILES['file'])) {
echo json_encode(['error' => 'No file uploaded']);
http_response_code(400);
exit;
}
$targetDir = "uploads/blogs/images/";
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)) {
echo json_encode(['location' => $targetFile]);
} else {
echo json_encode(['error' => 'Failed to move uploaded file']);
http_response_code(500);
}

View File

View File

@@ -1,124 +0,0 @@
<?php include_once('header02.php');
checkUserSession();
$result = $conn->prepare("SELECT blog_id, title, description, status, date, image FROM blogs WHERE author = ? AND status != 'deleted' ORDER BY date DESC");
$result->bind_param("i", $user_id);
$result->execute();
$posts = $result->get_result();
?>
<style>
.image {
width: 400px;
/* Set your desired width */
height: 350px;
/* Set your desired height */
overflow: hidden;
/* Hide any overflow */
display: block;
/* Ensure proper block behavior */
}
.image img {
width: 100%;
/* Image scales to fill the container */
height: 100%;
/* Image scales to fill the container */
object-fit: cover;
/* Fills the container while maintaining aspect ratio */
object-position: top;
/* Aligns the top of the image with the top of the container */
display: block;
/* Prevents inline whitespace issues */
}
</style>
<?php
$bannerFolder = 'assets/images/banners/';
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
if (!empty($bannerImages)) {
$randomBanner = $bannerImages[array_rand($bannerImages)];
}
?>
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
<!-- Overlay PNG -->
<div class="banner-overlay"></div>
<div class="container">
<div class="banner-inner text-white">
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">My Blogs</h2>
<nav aria-label="breadcrumb">
<ol class="breadcrumb justify-content-center mb-20" data-aos="fade-right" data-aos-delay="200" data-aos-duration="1500" data-aos-offset="50">
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
<li class="breadcrumb-item active">My Blogs</li>
</ol>
</nav>
</div>
</div>
</section>
<!-- Page Banner End -->
<!-- Blog List Area start -->
<section class="blog-list-page py-100 rel z-1">
<div class="container">
<div class="row">
<div class="col-lg-12">
<h2>My Posts</h2>
<?php if (isset($_SESSION['message'])): ?>
<div class="alert alert-warning message-box">
<?php echo $_SESSION['message']; ?>
<span class="close-btn" onclick="this.parentElement.style.display='none'">&times;</span>
</div>
<?php unset($_SESSION['message']); ?>
<?php endif; ?>
<a href="blog_create.php">+ New Post</a>
<?php while ($post = $posts->fetch_assoc()):
// Output the HTML structure with dynamic data
echo '
<div class="destination-item style-three bgc-lighter booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
<div class="image" style="width:200px;height:200px;"><img src="' . $post["image"] . '" alt="' . $post["title"] . '"></div>
<div class="content" style="width:100%;">
<div class="destination-header">
<span class="badge bg-dark"> ' . strtoupper($post["status"]) . '</span>
</div>
<h5>' . $post["title"] . '</a></h5>
<p>' . $post["description"] . '</p>
<div class="destination-footer">
<div class="btn-group" style="display:flex; justify-content:flex-end; gap:10px; margin-top:10px;">
<a href="blog_edit.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Edit"><i class="bi bi-pencil"></i></a>
<a href="blog_read.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Preview"><i class="bi bi-eye"></i></a>
<a href="blog_delete.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Delete"><i class="bi bi-trash"></i></a>
</div>
</div>
</div>
</div>';
endwhile; ?>
</div>
</div>
</div>
</section>
<!-- Blog List Area end -->
<script>
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
tooltipTriggerList.forEach(el => new bootstrap.Tooltip(el));
</script>
<?php include_once("insta_footer.php"); ?>