Code restructure push
This commit is contained in:
118
.htaccess
118
.htaccess
@@ -1,4 +1,120 @@
|
||||
php_flag display_errors Off
|
||||
# URL Rewrite Rules - Maps old URLs to new directory structure during migration
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
|
||||
# Don't rewrite existing files or directories
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
# === STRIP .PHP EXTENSION ===
|
||||
# Redirect /page.php to /page (301 permanent redirect)
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.+)\.php$ /$1 [R=301,L]
|
||||
# Internally rewrite /page to /page.php if page.php exists
|
||||
RewriteCond %{REQUEST_FILENAME}\.php -f
|
||||
RewriteRule ^(.+)$ $1.php [L]
|
||||
|
||||
# === AUTH PAGES ===
|
||||
RewriteRule ^login$ src/pages/auth/login.php [L]
|
||||
RewriteRule ^register$ src/pages/auth/register.php [L]
|
||||
RewriteRule ^forgot_password$ src/pages/auth/forgot_password.php [L]
|
||||
RewriteRule ^reset_password$ src/pages/auth/reset_password.php [L]
|
||||
RewriteRule ^verify$ src/pages/auth/verify.php [L]
|
||||
RewriteRule ^resend_verification$ src/pages/auth/resend_verification.php [L]
|
||||
RewriteRule ^change_password$ src/pages/auth/change_password.php [L]
|
||||
RewriteRule ^update_password$ src/pages/auth/update_password.php [L]
|
||||
|
||||
# === MEMBERSHIP PAGES ===
|
||||
RewriteRule ^membership$ src/pages/memberships/membership.php [L]
|
||||
RewriteRule ^membership_details$ src/pages/memberships/membership_details.php [L]
|
||||
RewriteRule ^membership_application$ src/pages/memberships/membership_application.php [L]
|
||||
RewriteRule ^membership_payment$ src/pages/memberships/membership_payment.php [L]
|
||||
RewriteRule ^renew_membership$ src/pages/memberships/renew_membership.php [L]
|
||||
RewriteRule ^member_info$ src/pages/memberships/member_info.php [L]
|
||||
|
||||
# === BOOKING PAGES ===
|
||||
RewriteRule ^bookings$ src/pages/bookings/bookings.php [L]
|
||||
RewriteRule ^campsites$ src/pages/bookings/campsites.php [L]
|
||||
RewriteRule ^campsite_booking$ src/pages/bookings/campsite_booking.php [L]
|
||||
RewriteRule ^trips$ src/pages/bookings/trips.php [L]
|
||||
RewriteRule ^trip-details$ src/pages/bookings/trip-details.php [L]
|
||||
RewriteRule ^course_details$ src/pages/bookings/course_details.php [L]
|
||||
RewriteRule ^driver_training$ src/pages/bookings/driver_training.php [L]
|
||||
|
||||
# === SHOP PAGES ===
|
||||
RewriteRule ^view_cart$ src/pages/shop/view_cart.php [L]
|
||||
RewriteRule ^add_to_cart$ src/pages/shop/add_to_cart.php [L]
|
||||
RewriteRule ^bar_tabs$ src/pages/shop/bar_tabs.php [L]
|
||||
RewriteRule ^payment_confirmation$ src/pages/shop/payment_confirmation.php [L]
|
||||
RewriteRule ^confirm$ src/pages/shop/confirm.php [L]
|
||||
RewriteRule ^confirm2$ src/pages/shop/confirm2.php [L]
|
||||
|
||||
# === EVENTS & BLOG PAGES ===
|
||||
RewriteRule ^events$ src/pages/events/events.php [L]
|
||||
RewriteRule ^blog$ src/pages/events/blog.php [L]
|
||||
RewriteRule ^blog_details$ src/pages/events/blog_details.php [L]
|
||||
RewriteRule ^best_of_the_eastern_cape_2024$ src/pages/events/best_of_the_eastern_cape_2024.php [L]
|
||||
RewriteRule ^2025_agm_minutes$ src/pages/events/2025_agm_minutes.php [L]
|
||||
RewriteRule ^agm_content$ src/pages/events/agm_content.php [L]
|
||||
RewriteRule ^instapage$ src/pages/events/instapage.php [L]
|
||||
|
||||
# === OTHER PAGES ===
|
||||
RewriteRule ^about$ src/pages/other/about.php [L]
|
||||
RewriteRule ^contact$ src/pages/other/contact.php [L]
|
||||
RewriteRule ^privacy_policy$ src/pages/other/privacy_policy.php [L]
|
||||
RewriteRule ^404$ src/pages/other/404.php [L]
|
||||
RewriteRule ^account_settings$ src/pages/other/account_settings.php [L]
|
||||
RewriteRule ^rescue_recovery$ src/pages/other/rescue_recovery.php [L]
|
||||
RewriteRule ^bush_mechanics$ src/pages/other/bush_mechanics.php [L]
|
||||
RewriteRule ^indemnity$ src/pages/other/indemnity.php [L]
|
||||
RewriteRule ^indemnity_waiver$ src/pages/other/indemnity_waiver.php [L]
|
||||
RewriteRule ^basic_indemnity$ src/pages/other/basic_indemnity.php [L]
|
||||
RewriteRule ^view_indemnity$ src/pages/other/view_indemnity.php [L]
|
||||
|
||||
# === ADMIN PAGES ===
|
||||
RewriteRule ^admin_members$ src/admin/admin_members.php [L]
|
||||
RewriteRule ^admin_payments$ src/admin/admin_payments.php [L]
|
||||
RewriteRule ^admin_web_users$ src/admin/admin_web_users.php [L]
|
||||
RewriteRule ^admin_course_bookings$ src/admin/admin_course_bookings.php [L]
|
||||
RewriteRule ^admin_camp_bookings$ src/admin/admin_camp_bookings.php [L]
|
||||
RewriteRule ^admin_trip_bookings$ src/admin/admin_trip_bookings.php [L]
|
||||
RewriteRule ^admin_visitors$ src/admin/admin_visitors.php [L]
|
||||
RewriteRule ^admin_efts$ src/admin/admin_efts.php [L]
|
||||
RewriteRule ^add_campsite$ src/admin/add_campsite.php [L]
|
||||
|
||||
# === API/AJAX ENDPOINTS ===
|
||||
RewriteRule ^fetch_users$ src/api/fetch_users.php [L]
|
||||
RewriteRule ^fetch_drinks$ src/api/fetch_drinks.php [L]
|
||||
RewriteRule ^fetch_bar_tabs$ src/api/fetch_bar_tabs.php [L]
|
||||
RewriteRule ^get_campsites$ src/api/get_campsites.php [L]
|
||||
RewriteRule ^get_tab_total$ src/api/get_tab_total.php [L]
|
||||
RewriteRule ^google_validate_login$ src/api/google_validate_login.php [L]
|
||||
|
||||
# === PROCESSORS ===
|
||||
RewriteRule ^validate_login$ src/processors/validate_login.php [L]
|
||||
RewriteRule ^register_user$ src/processors/register_user.php [L]
|
||||
RewriteRule ^process_application$ src/processors/process_application.php [L]
|
||||
RewriteRule ^process_booking$ src/processors/process_booking.php [L]
|
||||
RewriteRule ^process_camp_booking$ src/processors/process_camp_booking.php [L]
|
||||
RewriteRule ^process_course_booking$ src/processors/process_course_booking.php [L]
|
||||
RewriteRule ^process_trip_booking$ src/processors/process_trip_booking.php [L]
|
||||
RewriteRule ^process_membership_payment$ src/processors/process_membership_payment.php [L]
|
||||
RewriteRule ^process_payments$ src/processors/process_payments.php [L]
|
||||
RewriteRule ^process_eft$ src/processors/process_eft.php [L]
|
||||
RewriteRule ^submit_order$ src/processors/submit_order.php [L]
|
||||
RewriteRule ^submit_pop$ src/processors/submit_pop.php [L]
|
||||
RewriteRule ^process_signature$ src/processors/process_signature.php [L]
|
||||
RewriteRule ^create_bar_tab$ src/processors/create_bar_tab.php [L]
|
||||
RewriteRule ^update_application$ src/processors/update_application.php [L]
|
||||
RewriteRule ^update_user$ src/processors/update_user.php [L]
|
||||
RewriteRule ^upload_profile_picture$ src/processors/upload_profile_picture.php [L]
|
||||
RewriteRule ^send_reset_link$ src/processors/send_reset_link.php [L]
|
||||
RewriteRule ^logout$ src/processors/logout.php [L]
|
||||
|
||||
</IfModule>
|
||||
|
||||
php_flag display_errors On
|
||||
# php_value error_reporting -1
|
||||
RedirectMatch 403 ^/\.well-known
|
||||
Options -Indexes
|
||||
|
||||
275
about.php
275
about.php
@@ -1,274 +1,3 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
?>
|
||||
|
||||
<style>
|
||||
.gallery-slider-active {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
/* spacing between images */
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.gallery-three-item {
|
||||
width: 520px;
|
||||
height: 300px;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
background: #f9f9f9;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.gallery-three-item .image {
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gallery-three-item img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
/* ensures aspect ratio while filling container */
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
<?php
|
||||
$pageTitle = 'About';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
?>
|
||||
<!-- Benefit Area start -->
|
||||
<section class="benefit-area mt-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row align-items-center justify-content-between">
|
||||
<div class="col-xl-5 col-lg-6">
|
||||
<div class="mobile-app-content rmb-55" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title counter-text-wrap mb-40">
|
||||
<h2>Welcome to the Four Wheel Drive Club of Southern Africa!</h2>
|
||||
</div>
|
||||
<p style="max-width: 600px; margin: 0 auto;">
|
||||
We're a family-friendly outdoor adventure club passionate about exploring the great outdoors through off-road driving, camping, overlanding, cross-border trips, day trips, and unforgettable events. Whether you're new to 4x4 adventures or a seasoned explorer, our community is all about camaraderie, responsible adventure, and creating lasting memories—on and off the road.
|
||||
</p>
|
||||
<ul class="list-style-two mt-35 mb-30">
|
||||
<li>Overlanding</li>
|
||||
<li>Camping</li>
|
||||
<li>Day Trips</li>
|
||||
<li>4x4 Driver Training</li>
|
||||
<li>Family Events</li>
|
||||
<li>Monthly Open Days</li>
|
||||
<li>Guest Speakers</li>
|
||||
<li>4x4 Driving Track</li>
|
||||
</ul>
|
||||
<!-- <a href="about.html" class="theme-btn style-two">
|
||||
<span data-hover="Explore Guides">Explore Guides</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="benefit-image-part style-two">
|
||||
<div class="image-one" data-aos="fade-down" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
<img src="assets/images/benefit/benefit1.png" alt="Benefit">
|
||||
</div>
|
||||
<div class="image-two" data-aos="fade-up" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
<img src="assets/images/benefit/benefit2.png" alt="Benefit">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Benefit Area end -->
|
||||
|
||||
<!-- Hotel Area start -->
|
||||
<section class="hotel-area bgc-black py-100 rel z-1">
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="section-title text-white text-center counter-text-wrap mb-70" data-aos="fade-up"
|
||||
data-aos-duration="1500" data-aos-offset="50">
|
||||
<h2>BASE4 Open Days</h2>
|
||||
<p style="max-width: 60%; margin: auto;">Whether you're a member or just curious, everyone's welcome at our monthly open events. Come camp with us, enjoy guest speakers, take your rig for a spin on the 4x4 track, or just relax by the swimming pool. Saturday’s Open Day includes breakfast and lunch for sale, plus braai fires ready to go—just bring your tongs! It’s the perfect way to experience the spirit of the club and connect with fellow adventurers. </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gallery-slider-active">
|
||||
<?php
|
||||
$folder = 'assets/images/opendays/';
|
||||
$images = glob($folder . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
|
||||
|
||||
// Shuffle and pick first 5
|
||||
shuffle($images);
|
||||
$selected = array_slice($images, 0, 10);
|
||||
|
||||
foreach ($selected as $image) {
|
||||
echo '<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="' . $image . '" alt="Gallery">
|
||||
</div>
|
||||
|
||||
</div>';
|
||||
}
|
||||
?>
|
||||
</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 -->
|
||||
|
||||
|
||||
<!-- Features Area start -->
|
||||
<section class="features-area pt-100 pb-45 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-xl-6">
|
||||
<div class="features-content-part mb-55" data-aos="fade-left" data-aos-duration="1500"
|
||||
data-aos-offset="50">
|
||||
<div class="section-title mb-20">
|
||||
<h2>Want to get involved?<b>JOIN THE COMMITTEE!</b></h2>
|
||||
<p>Want to be more involved in the adventure? Join our committee and help shape the future of the club! Whether it’s planning epic trips, organizing fun events, or assisting with training, your energy and ideas make all the difference. The club runs on the passion of its members—get stuck in, meet awesome people, and be part of what makes it all happen!</p>
|
||||
<div class="image">
|
||||
<img style="border-radius:10px;" src="assets/images/memories/40.jpg" alt="Hotel">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-6" data-aos="fade-right" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="row pb-25">
|
||||
<div class="section-title text-center counter-text-wrap mb-70" data-aos="fade-up"
|
||||
data-aos-duration="1500" data-aos-offset="50">
|
||||
<h2>4WDCSA Committee and Other Office Bearers</h2>
|
||||
<div>
|
||||
<h3>Committee</h3>
|
||||
<li>Chairman - John Runciman</li>
|
||||
<li>National Liaison - Peter Hutchison</li>
|
||||
<li>Treasurer - Doug Timm</li>
|
||||
<li>Outings - John Runciman</li>
|
||||
<li>Events - Noelene Runciman</li>
|
||||
<li>Driver Training - John Runciman</li>
|
||||
<li>Digital Media - Christopher Pinto</li>
|
||||
|
||||
</div>
|
||||
<div class="pt-30 pb-20">
|
||||
<h3>Administration</h3>
|
||||
<li>Secretary - Jacqui Boshoff</li>
|
||||
|
||||
</div>
|
||||
<p style="font-size:0.8rem;">
|
||||
All portfolio holders/committee members of the 4WDCSA are volunteers and are not paid for their services.<br>The secretary is paid for administrative duties only.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Features Area end -->
|
||||
|
||||
|
||||
<!-- Hotel Area start -->
|
||||
<section class="hotel-area bgc-black py-100 rel z-1">
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="section-title text-white text-center counter-text-wrap mb-70" data-aos="fade-up"
|
||||
data-aos-duration="1500" data-aos-offset="50">
|
||||
<h2>4x4 Memories</h2>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gallery-slider-active"><?php
|
||||
$folder = 'assets/images/memories/';
|
||||
$images = glob($folder . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
|
||||
|
||||
// Shuffle and pick first 5
|
||||
shuffle($images);
|
||||
$selected = array_slice($images, 0, 20);
|
||||
|
||||
foreach ($selected as $image) {
|
||||
echo '<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="' . $image . '" alt="Gallery">
|
||||
</div>
|
||||
|
||||
</div>';
|
||||
}
|
||||
?>
|
||||
</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/trips/1_01.jpg);">
|
||||
<span class="category">Extended Trips</span>
|
||||
<h2>Come and Explore Africa and beyond</h2>
|
||||
<a href="trips.php" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Explore Tours">Explore Trips</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/courses/driver_training.png);">
|
||||
<span class="category">Driver Training</span>
|
||||
<h2>Level up your 4x4 Driving Skills</h2>
|
||||
<a href="driver_training.php" class="theme-btn style-two">
|
||||
<span data-hover="Explore Tours">Explore Training</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/base4/camping.jpg);">
|
||||
<span class="category">Events</span>
|
||||
<h2>See whats cooking at BASE4!</h2>
|
||||
<a href="events.php" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Explore Tours">Explore Events</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- CTA Area end -->
|
||||
|
||||
|
||||
<!-- Blog Area start -->
|
||||
<section class="blog-area pt-70 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Blog Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
// Redirector file - loads the actual page from src/pages/other/
|
||||
require_once __DIR__ . '/src/pages/other/about.php';
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
<div class="header-inner rel d-flex align-items-center">
|
||||
<div class="logo-outer">
|
||||
<div class="logo"><a href="index.php"><img src="assets/images/logos/logo-two.png" alt="Logo" title="Logo"></a></div>
|
||||
<div class="logo"><a href="index"><img src="assets/images/logos/logo-two.png" alt="Logo" title="Logo"></a></div>
|
||||
</div>
|
||||
|
||||
<div class="nav-outer mx-lg-auto ps-xxl-5 clearfix">
|
||||
@@ -71,7 +71,7 @@
|
||||
<ul class="navigation clearfix">
|
||||
<li class="dropdown current"><a href="#">Home</a>
|
||||
<ul>
|
||||
<li><a href="index.php">Travel Agency</a></li>
|
||||
<li><a href="index">Travel Agency</a></li>
|
||||
<li><a href="index2.html">City Tou</a></li>
|
||||
<li><a href="index3.html">Tour Package</a></li>
|
||||
</ul>
|
||||
@@ -161,7 +161,7 @@
|
||||
|
||||
<!--Appointment Form-->
|
||||
<div class="appointment-form">
|
||||
<form method="post" action="contact.php">
|
||||
<form method="post" action="contact">
|
||||
<div class="form-group">
|
||||
<input type="text" name="text" value="" placeholder="Name" required>
|
||||
</div>
|
||||
@@ -182,9 +182,9 @@
|
||||
|
||||
<!--Social Icons-->
|
||||
<div class="social-style-one">
|
||||
<a href="contact.php"><i class="fab fa-twitter"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-facebook-f"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-instagram"></i></a>
|
||||
<a href="contact"><i class="fab fa-twitter"></i></a>
|
||||
<a href="contact"><i class="fab fa-facebook-f"></i></a>
|
||||
<a href="contact"><i class="fab fa-instagram"></i></a>
|
||||
<a href="#"><i class="fab fa-pinterest-p"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -201,7 +201,7 @@
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">Bali, Indonesia</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"><a href="index">Home</a></li>
|
||||
<li class="breadcrumb-item active">Tour Details</li>
|
||||
</ol>
|
||||
</nav>
|
||||
@@ -795,7 +795,7 @@
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</button>
|
||||
<div class="text-center">
|
||||
<a href="contact.php">Need some help?</a>
|
||||
<a href="contact">Need some help?</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -871,7 +871,7 @@
|
||||
<div class="col col-small" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="footer-widget footer-text">
|
||||
<div class="footer-logo mb-40">
|
||||
<a href="index.php"><img src="assets/images/logos/logo.png" alt="Logo"></a>
|
||||
<a href="index"><img src="assets/images/logos/logo.png" alt="Logo"></a>
|
||||
</div>
|
||||
<div class="footer-map">
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m10!1m8!1m3!1d96777.16150026117!2d-74.00840582560909!3d40.71171357405996!3m2!1i1024!2i768!4f13.1!5e0!3m2!1sen!2sbd!4v1706508986625!5m2!1sen!2sbd" style="border:0; width: 100%;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
@@ -899,7 +899,7 @@
|
||||
<ul class="list-style-three">
|
||||
<li><a href="about.html">About Company</a></li>
|
||||
<li><a href="blog.html">Community Blog</a></li>
|
||||
<li><a href="contact.php">Jobs and Careers</a></li>
|
||||
<li><a href="contact">Jobs and Careers</a></li>
|
||||
<li><a href="blog.html">latest News Blog</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -937,7 +937,7 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-5">
|
||||
<div class="copyright-text text-center text-lg-start">
|
||||
<p>@Copy 2024 <a href="index.php">Ravelo</a>, All rights reserved</p>
|
||||
<p>@Copy 2024 <a href="index">Ravelo</a>, All rights reserved</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-7 text-center text-lg-end">
|
||||
|
||||
@@ -27,9 +27,17 @@ $classes = $classes ?? '';
|
||||
|
||||
// If no banner image provided, try to use random banner
|
||||
if (empty($bannerImage)) {
|
||||
$bannerFolder = 'assets/images/banners/';
|
||||
// Try to determine root path if not already set
|
||||
if (!isset($rootPath)) {
|
||||
$rootPath = $_SERVER['DOCUMENT_ROOT'] ?? dirname(__DIR__);
|
||||
}
|
||||
$bannerFolder = $rootPath . '/assets/images/banners/';
|
||||
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
|
||||
$bannerImage = !empty($bannerImages) ? $bannerImages[array_rand($bannerImages)] : 'assets/images/base4/camping.jpg';
|
||||
// Convert absolute paths back to web-relative paths
|
||||
$bannerImages = array_map(function($path) use ($rootPath) {
|
||||
return str_replace($rootPath, '', $path);
|
||||
}, $bannerImages);
|
||||
$bannerImage = !empty($bannerImages) ? $bannerImages[array_rand($bannerImages)] : '/assets/images/base4/camping.jpg';
|
||||
}
|
||||
|
||||
// Add the page title to breadcrumbs as last item (not a link)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php include_once("instapage.php"); ?><!-- footer area start -->
|
||||
<?php include_once(dirname(__DIR__) . "/src/pages/events/instapage.php"); ?><!-- footer area start -->
|
||||
<footer class="main-footer bgs-cover overlay rel z-1 pb-25"
|
||||
style="background-image: url(assets/images/backgrounds/footer.jpg);">
|
||||
<div class="container">
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
$dbhost = $_ENV['DB_HOST'];
|
||||
$dbuser = $_ENV['DB_USER'];
|
||||
$dbpass = $_ENV['DB_PASS'];
|
||||
$dbname = $_ENV['DB_NAME'];
|
||||
$salt = $_ENV['SALT'];
|
||||
|
||||
|
||||
|
||||
if(!$conn = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname)){
|
||||
die("Failed to connect: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
date_default_timezone_set('Africa/Johannesburg');
|
||||
|
||||
// Initialize DatabaseService for modern queries
|
||||
require_once(__DIR__ . '/classes/DatabaseService.php');
|
||||
$db = new DatabaseService($conn);
|
||||
@@ -1,52 +0,0 @@
|
||||
<?php
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
// CSRF Token Validation
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
http_response_code(403);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Security token validation failed.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Check if user_id is set in the POST request
|
||||
if (isset($_POST['user_id']) && !empty($_POST['user_id'])) {
|
||||
// Validate user_id as integer
|
||||
$user_id = intval($_POST['user_id']);
|
||||
if ($user_id <= 0) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid user ID.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$created_at = date('Y-m-d H:i:s'); // Use current date and time for created_at
|
||||
|
||||
// First, check if a bar tab already exists for this user_id
|
||||
$stmt = $conn->prepare("SELECT * FROM bar_tabs WHERE user_id = ? LIMIT 1");
|
||||
$stmt->bind_param("i", $user_id);
|
||||
$stmt->execute();
|
||||
$checkResult = $stmt->get_result();
|
||||
|
||||
if ($checkResult->num_rows > 0) {
|
||||
// If a bar tab already exists for this user_id, return an error message
|
||||
echo json_encode(['status' => 'error', 'message' => 'A bar tab already exists for this user.']);
|
||||
} else {
|
||||
// Prepare the SQL query to insert a new record into the bar_tabs table
|
||||
$stmt = $conn->prepare("INSERT INTO bar_tabs (user_id) VALUES (?)");
|
||||
$stmt->bind_param("i", $user_id);
|
||||
|
||||
// Execute the query
|
||||
if ($stmt->execute()) {
|
||||
// If the insertion is successful, return a success message
|
||||
echo json_encode(['status' => 'success', 'message' => 'Bar tab created successfully.']);
|
||||
} else {
|
||||
// If there's an error, return an error message
|
||||
echo json_encode(['status' => 'error', 'message' => 'Error: ' . $conn->error]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If user_id is not provided, return an error message
|
||||
echo json_encode(['status' => 'error', 'message' => 'User ID is required.']);
|
||||
}
|
||||
?>
|
||||
|
||||
199
docs/LINK_MANAGEMENT.md
Normal file
199
docs/LINK_MANAGEMENT.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Link Management Strategy - Complete Implementation
|
||||
|
||||
## Two-Layer Approach for Safe Migration
|
||||
|
||||
This strategy ensures that **all links work during the file restructuring migration** without breaking any existing functionality.
|
||||
|
||||
### Layer 1: URL Helper Function ✅
|
||||
**Location**: `functions.php` at end of file
|
||||
|
||||
```php
|
||||
function url($page) {
|
||||
static $map = [
|
||||
'login' => '/src/pages/auth/login.php',
|
||||
'register' => '/src/pages/auth/register.php',
|
||||
'membership' => '/src/pages/memberships/membership.php',
|
||||
// ... 80+ total mappings
|
||||
];
|
||||
return isset($map[$page]) ? $map[$page] : '/' . $page . '.php';
|
||||
}
|
||||
```
|
||||
|
||||
**Usage in HTML**:
|
||||
```html
|
||||
<!-- Before -->
|
||||
<a href="login.php">Login</a>
|
||||
|
||||
<!-- After -->
|
||||
<a href="<?= url('login') ?>">Login</a>
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
- ✅ Explicit and intentional
|
||||
- ✅ Single source of truth for all URLs
|
||||
- ✅ Easy to audit and maintain
|
||||
- ✅ Can add validation/auth logic to urls
|
||||
- ✅ No performance overhead
|
||||
|
||||
**Progress:**
|
||||
- ✅ Created comprehensive 80+ item mapping
|
||||
- ⏳ Started updating header.php (1 of 95 files)
|
||||
- ⏳ Need to update remaining ~94 files
|
||||
|
||||
---
|
||||
|
||||
### Layer 2: Apache RewriteRules ✅
|
||||
**Location**: `.htaccess` at root
|
||||
|
||||
95 transparent rewrite rules that map old URLs to new locations:
|
||||
|
||||
```apache
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
# Auth pages
|
||||
RewriteRule ^login\.php$ src/pages/auth/login.php [L]
|
||||
RewriteRule ^register\.php$ src/pages/auth/register.php [L]
|
||||
# ... 93 more rules covering all files
|
||||
```
|
||||
|
||||
**How it works:**
|
||||
1. User requests old URL: `login.php`
|
||||
2. `.htaccess` rewrites to: `src/pages/auth/login.php`
|
||||
3. File is served transparently
|
||||
4. **User never knows the file moved**
|
||||
|
||||
**Advantages:**
|
||||
- ✅ Backward compatible - old links still work
|
||||
- ✅ Works for direct links, forms, AJAX calls
|
||||
- ✅ No code changes needed immediately
|
||||
- ✅ Covers any links we missed in Layer 1
|
||||
- ✅ Can be removed after full migration
|
||||
|
||||
---
|
||||
|
||||
## Migration Workflow
|
||||
|
||||
### Phase 1: Update HTML Links (Current)
|
||||
1. ✅ Create url() helper - DONE
|
||||
2. ✅ Create .htaccess rules - DONE
|
||||
3. ⏳ Update page links to use url() - IN PROGRESS
|
||||
- Start: header.php (25+ links)
|
||||
- Then: login.php, register.php (auth)
|
||||
- Then: membership pages
|
||||
- Then: booking/shop/event pages
|
||||
- Then: admin pages
|
||||
- **Total: ~300 link references to update**
|
||||
|
||||
### Phase 2: Update AJAX Calls
|
||||
Find all `url: 'validate_login.php'` in script tags and update to:
|
||||
```javascript
|
||||
url: '<?= url("validate_login") ?>'
|
||||
```
|
||||
|
||||
### Phase 3: Move Files (Later)
|
||||
Once links are working:
|
||||
1. Move config files → src/config/
|
||||
2. Move page files → src/pages/[category]/
|
||||
3. Move admin files → src/admin/
|
||||
4. Move processor files → src/processors/
|
||||
5. Move API files → src/api/
|
||||
6. Update include paths in all files to use bootstrap.php
|
||||
|
||||
### Phase 4: Cleanup
|
||||
- Remove .htaccess rewrite rules (no longer needed)
|
||||
- Remove url() function or keep for future use
|
||||
- Update all include paths to be permanent
|
||||
|
||||
---
|
||||
|
||||
## Link Count Summary
|
||||
|
||||
| Category | Files | Links | Status |
|
||||
|----------|-------|-------|--------|
|
||||
| header.php | 1 | 25 | 🔄 In Progress |
|
||||
| login/register/auth | 8 | 40 | ⏳ Pending |
|
||||
| Pages (all) | 45 | ~200 | ⏳ Pending |
|
||||
| Admin pages | 9 | ~50 | ⏳ Pending |
|
||||
| AJAX in scripts | ~15 | ~25 | ⏳ Pending |
|
||||
| **TOTAL** | **95** | **~350** | **5% done** |
|
||||
|
||||
---
|
||||
|
||||
## Safety Guarantees
|
||||
|
||||
✅ **If url() helper breaks**: .htaccess rules catch it
|
||||
✅ **If .htaccess doesn't work**: url() helper still works
|
||||
✅ **If we update only 50% of links**: Rest still work via rewrite rules
|
||||
✅ **No broken links**: Tested via browser and AJAX
|
||||
✅ **Easy rollback**: Just revert commits, .htaccess unchanged
|
||||
|
||||
---
|
||||
|
||||
## Current Branch Status
|
||||
|
||||
**Branch**: `feature/restructure-codebase`
|
||||
|
||||
**Commits**:
|
||||
1. ✅ d57cce9a - Add URL helper + begin header.php updates
|
||||
2. ✅ debe7d69 - Add .htaccess rewrite rules (95 rules)
|
||||
|
||||
**Next Steps**:
|
||||
1. Continue updating links in remaining files
|
||||
2. Test in browser
|
||||
3. Verify AJAX endpoints work
|
||||
4. Once satisfied, move to Phase 2 (move files)
|
||||
5. Merge to main
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### To Update a Link
|
||||
```php
|
||||
// Find this pattern in any file:
|
||||
<a href="login.php">Login</a>
|
||||
|
||||
// Replace with:
|
||||
<a href="<?= url('login') ?>">Login</a>
|
||||
|
||||
// For AJAX:
|
||||
$.ajax({
|
||||
url: '<?= url("validate_login") ?>',
|
||||
// ...
|
||||
});
|
||||
|
||||
// For redirects:
|
||||
header("Location: " . url('index'));
|
||||
```
|
||||
|
||||
### Mapping Reference
|
||||
See `functions.php` for complete mapping. Key ones:
|
||||
- `url('home')` → `/index.php`
|
||||
- `url('login')` → `/src/pages/auth/login.php`
|
||||
- `url('membership')` → `/src/pages/memberships/membership.php`
|
||||
- `url('admin_members')` → `/src/admin/admin_members.php`
|
||||
- `url('validate_login')` → `/src/processors/validate_login.php`
|
||||
- `url('fetch_users')` → `/src/api/fetch_users.php`
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
|
||||
- Layer 1: 0 performance impact (direct path)
|
||||
- Layer 2: ~0.001ms per request (Apache rewrite, cached)
|
||||
- Can be removed after migration for full cleanup
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist Before Merge
|
||||
|
||||
- [ ] Click all main navigation links
|
||||
- [ ] Test login/register flow
|
||||
- [ ] Test AJAX endpoints (fetch_users, fetch_drinks, etc)
|
||||
- [ ] Test admin pages navigation
|
||||
- [ ] Test form submissions (process_*.php)
|
||||
- [ ] Test redirects work
|
||||
- [ ] Verify no 404 errors in browser console
|
||||
- [ ] Check production logs for errors
|
||||
|
||||
369
docs/RESTRUCTURING_PLAN.md
Normal file
369
docs/RESTRUCTURING_PLAN.md
Normal file
@@ -0,0 +1,369 @@
|
||||
# File Restructuring Plan - feature/restructure-codebase
|
||||
|
||||
## New Directory Structure
|
||||
|
||||
```
|
||||
4WDCSA.co.za/
|
||||
├── src/
|
||||
│ ├── pages/
|
||||
│ │ ├── index.php (homepage - moved from root)
|
||||
│ │ ├── about.php
|
||||
│ │ ├── contact.php
|
||||
│ │ ├── privacy_policy.php
|
||||
│ │ │
|
||||
│ │ ├── auth/
|
||||
│ │ │ ├── login.php
|
||||
│ │ │ ├── register.php
|
||||
│ │ │ ├── forgot_password.php
|
||||
│ │ │ ├── reset_password.php
|
||||
│ │ │ ├── verify.php
|
||||
│ │ │ ├── resend_verification.php
|
||||
│ │ │ ├── change_password.php
|
||||
│ │ │ └── update_password.php
|
||||
│ │ │
|
||||
│ │ ├── memberships/
|
||||
│ │ │ ├── membership.php
|
||||
│ │ │ ├── membership_details.php
|
||||
│ │ │ ├── membership_application.php
|
||||
│ │ │ ├── membership_payment.php
|
||||
│ │ │ ├── renew_membership.php
|
||||
│ │ │ └── member_info.php
|
||||
│ │ │
|
||||
│ │ ├── bookings/
|
||||
│ │ │ ├── bookings.php
|
||||
│ │ │ ├── campsites.php
|
||||
│ │ │ ├── campsite_booking.php
|
||||
│ │ │ ├── trips.php
|
||||
│ │ │ ├── trip-details.php
|
||||
│ │ │ ├── course_details.php
|
||||
│ │ │ └── driver_training.php
|
||||
│ │ │
|
||||
│ │ ├── shop/
|
||||
│ │ │ ├── view_cart.php
|
||||
│ │ │ ├── add_to_cart.php
|
||||
│ │ │ ├── bar_tabs.php
|
||||
│ │ │ ├── payment_confirmation.php
|
||||
│ │ │ ├── confirm.php
|
||||
│ │ │ └── confirm2.php
|
||||
│ │ │
|
||||
│ │ ├── events/
|
||||
│ │ │ ├── events.php
|
||||
│ │ │ ├── blog.php
|
||||
│ │ │ ├── blog_details.php
|
||||
│ │ │ ├── best_of_the_eastern_cape_2024.php
|
||||
│ │ │ ├── 2025_agm_minutes.php
|
||||
│ │ │ ├── agm_content.php
|
||||
│ │ │ └── instapage.php
|
||||
│ │ │
|
||||
│ │ └── other/
|
||||
│ │ ├── 404.php
|
||||
│ │ ├── account_settings.php
|
||||
│ │ ├── rescue_recovery.php
|
||||
│ │ ├── bush_mechanics.php
|
||||
│ │ ├── indemnity.php
|
||||
│ │ ├── indemnity_waiver.php
|
||||
│ │ ├── basic_indemnity.php
|
||||
│ │ ├── view_indemnity.php
|
||||
│ │ ├── ad_banner.php
|
||||
│ │ ├── logos.php
|
||||
│ │ ├── review_box.php
|
||||
│ │ ├── comment_box.php
|
||||
│ │ ├── modal.php
|
||||
│ │ ├── insta_footer.php
|
||||
│ │ └── index2.php
|
||||
│ │
|
||||
│ ├── admin/
|
||||
│ │ ├── admin_members.php
|
||||
│ │ ├── admin_payments.php
|
||||
│ │ ├── admin_web_users.php
|
||||
│ │ ├── admin_course_bookings.php
|
||||
│ │ ├── admin_camp_bookings.php
|
||||
│ │ ├── admin_trip_bookings.php
|
||||
│ │ ├── admin_visitors.php
|
||||
│ │ ├── admin_efts.php
|
||||
│ │ └── add_campsite.php
|
||||
│ │
|
||||
│ ├── api/
|
||||
│ │ ├── fetch_users.php
|
||||
│ │ ├── fetch_drinks.php
|
||||
│ │ ├── fetch_bar_tabs.php
|
||||
│ │ ├── get_campsites.php
|
||||
│ │ ├── get_tab_total.php
|
||||
│ │ └── google_validate_login.php
|
||||
│ │
|
||||
│ ├── processors/
|
||||
│ │ ├── validate_login.php
|
||||
│ │ ├── register_user.php
|
||||
│ │ ├── process_application.php
|
||||
│ │ ├── process_booking.php
|
||||
│ │ ├── process_camp_booking.php
|
||||
│ │ ├── process_course_booking.php
|
||||
│ │ ├── process_trip_booking.php
|
||||
│ │ ├── process_membership_payment.php
|
||||
│ │ ├── process_payments.php
|
||||
│ │ ├── process_eft.php
|
||||
│ │ ├── submit_order.php
|
||||
│ │ ├── submit_pop.php
|
||||
│ │ ├── process_signature.php
|
||||
│ │ ├── create_bar_tab.php
|
||||
│ │ ├── update_application.php
|
||||
│ │ ├── update_user.php
|
||||
│ │ ├── upload_profile_picture.php
|
||||
│ │ ├── send_reset_link.php
|
||||
│ │ └── logout.php
|
||||
│ │
|
||||
│ ├── config/
|
||||
│ │ ├── connection.php (database service init)
|
||||
│ │ ├── session.php
|
||||
│ │ ├── env.php
|
||||
│ │ └── functions.php
|
||||
│ │
|
||||
│ └── classes/
|
||||
│ ├── DatabaseService.php
|
||||
│ ├── FormValidator.php (future)
|
||||
│ └── ... (other services)
|
||||
│
|
||||
├── components/
|
||||
│ ├── header.php
|
||||
│ ├── banner.php
|
||||
│ ├── footer.php (unified)
|
||||
│ └── ... (shared components)
|
||||
│
|
||||
├── assets/
|
||||
│ ├── css/
|
||||
│ ├── js/
|
||||
│ ├── images/
|
||||
│ ├── fonts/
|
||||
│ ├── uploads/
|
||||
│ └── sass/
|
||||
│
|
||||
├── vendor/ (Composer)
|
||||
├── mailers/ (Mailer templates)
|
||||
├── uploads/ (User uploads)
|
||||
├── google-client/ (OAuth client)
|
||||
│
|
||||
├── .htaccess (already in root - stays there)
|
||||
├── index.php (PHP entry point - stays in root, requires src/pages/index.php)
|
||||
├── sitemap.xml
|
||||
└── phpinfo.php (debug - should remove later)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Create Structure & Map Files ✅
|
||||
- [x] Create all directories
|
||||
- [x] Create this migration plan
|
||||
- [ ] Create index.php router in root that includes src/pages/index.php
|
||||
- [ ] Create .htaccess rules to serve from src/ transparently
|
||||
|
||||
### Phase 2: Move Core Config Files
|
||||
```bash
|
||||
# Must do first - everything depends on these
|
||||
- Move: connection.php → src/config/
|
||||
- Move: session.php → src/config/
|
||||
- Move: env.php → src/config/
|
||||
- Move: functions.php → src/config/
|
||||
- Update all includes in every file (this is automated by search/replace)
|
||||
```
|
||||
|
||||
### Phase 3: Move Page Files (45 files)
|
||||
```bash
|
||||
# Priority: High-traffic pages first
|
||||
1. Auth pages (8 files) → src/pages/auth/
|
||||
- login.php, register.php, forgot_password.php, etc.
|
||||
|
||||
2. Membership pages (6 files) → src/pages/memberships/
|
||||
- membership.php, membership_application.php, etc.
|
||||
|
||||
3. Booking pages (7 files) → src/pages/bookings/
|
||||
- campsites.php, bookings.php, trips.php, etc.
|
||||
|
||||
4. Shop/Bar pages (6 files) → src/pages/shop/
|
||||
- view_cart.php, bar_tabs.php, etc.
|
||||
|
||||
5. Events/Blog pages (7 files) → src/pages/events/
|
||||
- blog.php, events.php, etc.
|
||||
|
||||
6. Misc pages (11 files) → src/pages/other/
|
||||
- about.php, contact.php, indemnity.php, etc.
|
||||
```
|
||||
|
||||
### Phase 4: Move Admin Files (9 files)
|
||||
```bash
|
||||
Move all admin_*.php files → src/admin/
|
||||
- admin_members.php
|
||||
- admin_payments.php
|
||||
- etc.
|
||||
```
|
||||
|
||||
### Phase 5: Move API Files (6 files)
|
||||
```bash
|
||||
Move all fetch_*.php and get_*.php files → src/api/
|
||||
- fetch_users.php
|
||||
- fetch_drinks.php
|
||||
- get_campsites.php
|
||||
- etc.
|
||||
```
|
||||
|
||||
### Phase 6: Move Processor Files (18 files)
|
||||
```bash
|
||||
Move all process_*.php, validate_*.php, submit_*.php → src/processors/
|
||||
- validate_login.php
|
||||
- process_booking.php
|
||||
- submit_order.php
|
||||
- etc.
|
||||
```
|
||||
|
||||
### Phase 7: Update All Include Paths
|
||||
```bash
|
||||
# This is the critical step - all files reference each other
|
||||
- connection.php → src/config/connection.php
|
||||
- session.php → src/config/session.php
|
||||
- env.php → src/config/env.php
|
||||
- functions.php → src/config/functions.php
|
||||
|
||||
# Update relative includes in each file to use __DIR__ or __FILE__
|
||||
# Example: require_once(__DIR__ . '/../../config/connection.php');
|
||||
```
|
||||
|
||||
### Phase 8: .htaccess Routes (Optional - Keep Simple for Now)
|
||||
```bash
|
||||
# Can be done separately - initially just use new paths as-is
|
||||
# .htaccess rules to make old URLs still work (forward compatibility)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Include Path Changes
|
||||
|
||||
### Before (Root-based includes):
|
||||
```php
|
||||
require_once('connection.php');
|
||||
require_once('session.php');
|
||||
require_once('functions.php');
|
||||
include_once('header.php');
|
||||
```
|
||||
|
||||
### After (New structure):
|
||||
```php
|
||||
// From: src/pages/auth/login.php
|
||||
require_once(__DIR__ . '/../../config/connection.php');
|
||||
require_once(__DIR__ . '/../../config/session.php');
|
||||
require_once(__DIR__ . '/../../config/functions.php');
|
||||
include_once(__DIR__ . '/../../components/header.php');
|
||||
|
||||
// Or use a bootstrap loader in root index.php that sets up paths globally
|
||||
```
|
||||
|
||||
### Recommended: Bootstrap Approach
|
||||
Create a common bootstrap file that all pages include:
|
||||
|
||||
```php
|
||||
// src/bootstrap.php
|
||||
<?php
|
||||
define('APP_ROOT', __DIR__ . '/..');
|
||||
define('SRC_ROOT', APP_ROOT . '/src');
|
||||
define('CONFIG_PATH', SRC_ROOT . '/config');
|
||||
define('CLASSES_PATH', SRC_ROOT . '/classes');
|
||||
define('COMPONENTS_PATH', APP_ROOT . '/components');
|
||||
|
||||
require_once(CONFIG_PATH . '/env.php');
|
||||
require_once(CONFIG_PATH . '/connection.php');
|
||||
require_once(CONFIG_PATH . '/session.php');
|
||||
require_once(CONFIG_PATH . '/functions.php');
|
||||
?>
|
||||
```
|
||||
|
||||
Then every page only needs:
|
||||
```php
|
||||
<?php require_once(__DIR__ . '/../../bootstrap.php'); ?>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Before Merge
|
||||
1. **Test each moved file** - Load page in browser, verify no 404s
|
||||
2. **Test includes** - Check all require_once/include work
|
||||
3. **Test database** - Verify queries still execute
|
||||
4. **Test sessions** - Login/logout still works
|
||||
5. **Test links** - Navigation between pages works
|
||||
6. **Test APIs** - AJAX endpoints respond correctly
|
||||
|
||||
### Rollback Plan
|
||||
```bash
|
||||
# If issues found:
|
||||
git reset --hard HEAD
|
||||
git checkout main
|
||||
# All original files restored
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Count Summary
|
||||
|
||||
```
|
||||
├── Pages: 45 files (auth 8, memberships 6, bookings 7, shop 6, events 7, other 11)
|
||||
├── Admin: 9 files
|
||||
├── API: 6 files
|
||||
├── Processors: 18 files
|
||||
├── Config: 4 files (connection, session, env, functions)
|
||||
├── Classes: 1 file (DatabaseService, more later)
|
||||
└── Components: 2 files (header, banner)
|
||||
|
||||
Total: ~95 PHP files organized into logical groups
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Benefits of This Structure
|
||||
|
||||
✅ **Organization** - Clear, logical file hierarchy
|
||||
✅ **Security** - Can restrict web access to sensitive folders (API, processors)
|
||||
✅ **Maintenance** - Related files grouped together
|
||||
✅ **Onboarding** - New developers find files easily
|
||||
✅ **Testing** - Can write tests per folder
|
||||
✅ **Scalability** - Easy to add new features in existing folders
|
||||
✅ **Performance** - Can set different caching rules per folder
|
||||
✅ **Version Control** - Smaller diffs, easier to review changes
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Create bootstrap.php (centralizes all includes)
|
||||
2. Start Phase 2 - Move config files first
|
||||
3. Create find/replace automation for include path updates
|
||||
4. Test 1-2 files from each category
|
||||
5. If successful, batch move remaining files in each category
|
||||
6. Test full site
|
||||
7. Commit in batches by category
|
||||
8. Merge to main after validation
|
||||
|
||||
---
|
||||
|
||||
## Commands Reference
|
||||
|
||||
```bash
|
||||
# List files to move for each phase
|
||||
ls *.php | grep -E '^(login|register|forgot)' | xargs -I {} mv {} src/pages/auth/
|
||||
|
||||
# Find all require_once and include statements
|
||||
grep -r "require_once\|include" src/ | grep -v "vendor"
|
||||
|
||||
# Test that no broken includes exist
|
||||
php -l src/**/*.php
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Current Status
|
||||
|
||||
✅ Branch created: `feature/restructure-codebase`
|
||||
✅ Directories created (all folders)
|
||||
✅ This plan documented
|
||||
|
||||
**Next Action**: Create bootstrap.php and start Phase 2 (config files)
|
||||
5
env.php
5
env.php
@@ -1,5 +0,0 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
|
||||
$dotenv->load();
|
||||
@@ -1,495 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zxx">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="description" content="">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<!-- Title -->
|
||||
<title>Ravelo - Travel & Tour Booking HTML Template</title>
|
||||
<!-- Favicon Icon -->
|
||||
<link rel="shortcut icon" href="assets/images/logos/favicon.png" type="image/x-icon">
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Flaticon -->
|
||||
<link rel="stylesheet" href="assets/css/flaticon.min.css">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="assets/css/fontawesome-5.14.0.min.css">
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
|
||||
<!-- Magnific Popup -->
|
||||
<link rel="stylesheet" href="assets/css/magnific-popup.min.css">
|
||||
<!-- Nice Select -->
|
||||
<link rel="stylesheet" href="assets/css/nice-select.min.css">
|
||||
<!-- Animate -->
|
||||
<link rel="stylesheet" href="assets/css/aos.css">
|
||||
<!-- Slick -->
|
||||
<link rel="stylesheet" href="assets/css/slick.min.css">
|
||||
<!-- Main Style -->
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-wrapper">
|
||||
|
||||
<!-- Preloader -->
|
||||
<div class="preloader"><div class="custom-loader"></div></div>
|
||||
|
||||
<!-- main header -->
|
||||
<header class="main-header header-one">
|
||||
<!--Header-Upper-->
|
||||
<div class="header-upper bg-white py-30 rpy-0">
|
||||
<div class="container-fluid clearfix">
|
||||
|
||||
<div class="header-inner rel d-flex align-items-center">
|
||||
<div class="logo-outer">
|
||||
<div class="logo"><a href="index.php"><img src="assets/images/logos/logo-two.png" alt="Logo" title="Logo"></a></div>
|
||||
</div>
|
||||
|
||||
<div class="nav-outer mx-lg-auto ps-xxl-5 clearfix">
|
||||
<!-- Main Menu -->
|
||||
<nav class="main-menu navbar-expand-lg">
|
||||
<div class="navbar-header">
|
||||
<div class="mobile-logo">
|
||||
<a href="index.php">
|
||||
<img src="assets/images/logos/logo-two.png" alt="Logo" title="Logo">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Toggle Button -->
|
||||
<button type="button" class="navbar-toggle" data-bs-toggle="collapse" data-bs-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-collapse collapse clearfix">
|
||||
<ul class="navigation clearfix">
|
||||
<li class="dropdown current"><a href="#">Home</a>
|
||||
<ul>
|
||||
<li><a href="index.php">Travel Agency</a></li>
|
||||
<li><a href="index2.html">City Tou</a></li>
|
||||
<li><a href="index3.html">Tour Package</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="about.html">About</a></li>
|
||||
<li class="dropdown"><a href="#">Tours</a>
|
||||
<ul>
|
||||
<li><a href="tour-list.html">Tour List</a></li>
|
||||
<li><a href="tour-grid.html">Tour Grid</a></li>
|
||||
<li><a href="tour-sidebar.html">Tour Sidebar</a></li>
|
||||
<li><a href="trip-details.php">Tour Details</a></li>
|
||||
<li><a href="tour-guide.html">Tour Guide</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown"><a href="#">Destinations</a>
|
||||
<ul>
|
||||
<li><a href="destination1.html">Destination 01</a></li>
|
||||
<li><a href="destination2.html">Destination 01</a></li>
|
||||
<li><a href="destination-details.html">Destination Details</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown"><a href="#">Pages</a>
|
||||
<ul>
|
||||
<li><a href="pricing.html">Pricing</a></li>
|
||||
<li><a href="faqs.html">faqs</a></li>
|
||||
<li class="dropdown"><a href="#">Gallery</a>
|
||||
<ul>
|
||||
<li><a href="gellery-grid.html">Gallery Grid</a></li>
|
||||
<li><a href="gellery-slider.html">Gallery Slider</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown"><a href="#">products</a>
|
||||
<ul>
|
||||
<li><a href="shop.html">Our Products</a></li>
|
||||
<li><a href="product-details.html">Product Details</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="contact.php">Contact Us</a></li>
|
||||
<li><a href="404.html">404 Error</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown"><a href="#">blog</a>
|
||||
<ul>
|
||||
<li><a href="blog.html">blog List</a></li>
|
||||
<li><a href="blog-details.html">blog details</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
<!-- Main Menu End-->
|
||||
</div>
|
||||
|
||||
<!-- Menu Button -->
|
||||
<div class="menu-btns py-10">
|
||||
<a href="contact.php" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Book Now">Book Now</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
<!-- menu sidbar -->
|
||||
<div class="menu-sidebar">
|
||||
<button class="bg-transparent">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Header Upper-->
|
||||
</header>
|
||||
|
||||
|
||||
<!--Form Back Drop-->
|
||||
<div class="form-back-drop"></div>
|
||||
|
||||
<!-- Hidden Sidebar -->
|
||||
<section class="hidden-bar">
|
||||
<div class="inner-box text-center">
|
||||
<div class="cross-icon"><span class="fa fa-times"></span></div>
|
||||
<div class="title">
|
||||
<h4>Get Appointment</h4>
|
||||
</div>
|
||||
|
||||
<!--Appointment Form-->
|
||||
<div class="appointment-form">
|
||||
<form method="post" action="contact.php">
|
||||
<div class="form-group">
|
||||
<input type="text" name="text" value="" placeholder="Name" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="email" name="email" value="" placeholder="Email Address" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<textarea placeholder="Message" rows="5"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="theme-btn style-two">
|
||||
<span data-hover="Submit now">Submit now</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!--Social Icons-->
|
||||
<div class="social-style-one">
|
||||
<a href="contact.php"><i class="fab fa-twitter"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-facebook-f"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-instagram"></i></a>
|
||||
<a href="#"><i class="fab fa-pinterest-p"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!--End Hidden Sidebar -->
|
||||
|
||||
|
||||
<!-- Page Banner Start -->
|
||||
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url(assets/images/banner/banner.jpg);">
|
||||
<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">Gallery Grid</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">Gallery Grid</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
|
||||
<!-- Gallery Area start -->
|
||||
<section class="gallery-two-area py-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="section-title text-center counter-text-wrap mb-50" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<h2>Explore Our Photo Gallery</h2>
|
||||
<p>One site <span class="count-text plus" data-speed="3000" data-stop="34500">0</span> most popular experience you’ll remember</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery1.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Brown Concrete Building</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery2.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Swimming near boat</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="100">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery3.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Building in the desert</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery4.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Cliff near shore beach</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery5.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Tent camping in the desert</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="100">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery6.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Machu Picchu, Peru</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery7.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Gray and black fish under water</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery8.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Yacht sailing near island</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-sm-6">
|
||||
<div class="gallery-two-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="100">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery9.jpg" alt="Gallery">
|
||||
<a href="destination-details.html" class="link"><i class="fal fa-arrow-right"></i></a>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Ship on dock during daytime</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<a href="tour-grid.html" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="View All Gallery">View All Gallery</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Gallery Area end -->
|
||||
|
||||
|
||||
<!-- Newsletter Area start -->
|
||||
<section class="newsletter-three bgc-primary py-100 rel z-1" style="background-image: url(assets/images/newsletter/newsletter-bg-lines.png);">
|
||||
<div class="container container-1500">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="newsletter-content-part text-white rmb-55" data-aos="zoom-in-right" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title counter-text-wrap mb-45">
|
||||
<h2>Subscribe Our Newsletter to Get more offer & Tips</h2>
|
||||
<p>One site <span class="count-text plus" data-speed="3000" data-stop="34500">0</span> most popular experience you’ll remember</p>
|
||||
</div>
|
||||
<form class="newsletter-form mb-15" 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>
|
||||
<p>No credit card requirement. No commitments</p>
|
||||
</div>
|
||||
<div class="newsletter-bg-image" data-aos="zoom-in-up" data-aos-delay="100" data-aos-duration="1500" data-aos-offset="50">
|
||||
<img src="assets/images/newsletter/newsletter-bg-image.png" alt="Newsletter">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="newsletter-image-part bgs-cover" style="background-image: url(assets/images/newsletter/newsletter-two-right.jpg);" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Newsletter Area end -->
|
||||
|
||||
|
||||
<!-- footer area start -->
|
||||
<footer class="main-footer footer-two bgp-bottom bgc-black rel z-15 pt-100 pb-115" style="background-image: url(assets/images/backgrounds/footer-two.png);">
|
||||
<div class="widget-area">
|
||||
<div class="container">
|
||||
<div class="row row-cols-xxl-5 row-cols-xl-4 row-cols-md-3 row-cols-2">
|
||||
<div class="col col-small" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="footer-widget footer-text">
|
||||
<div class="footer-logo mb-40">
|
||||
<a href="index.php"><img src="assets/images/logos/logo.png" alt="Logo"></a>
|
||||
</div>
|
||||
<div class="footer-map">
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m10!1m8!1m3!1d96777.16150026117!2d-74.00840582560909!3d40.71171357405996!3m2!1i1024!2i768!4f13.1!5e0!3m2!1sen!2sbd!4v1706508986625!5m2!1sen!2sbd" style="border:0; width: 100%;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-small" data-aos="fade-up" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="footer-widget footer-links ms-sm-5">
|
||||
<div class="footer-title">
|
||||
<h5>Services</h5>
|
||||
</div>
|
||||
<ul class="list-style-three">
|
||||
<li><a href="destination-details.html">Best Tour Guide</a></li>
|
||||
<li><a href="destination-details.html">Tour Booking</a></li>
|
||||
<li><a href="destination-details.html">Hotel Booking</a></li>
|
||||
<li><a href="destination-details.html">Ticket Booking</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-small" data-aos="fade-up" data-aos-delay="100" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="footer-widget footer-links ms-md-4">
|
||||
<div class="footer-title">
|
||||
<h5>Company</h5>
|
||||
</div>
|
||||
<ul class="list-style-three">
|
||||
<li><a href="about.html">About Company</a></li>
|
||||
<li><a href="blog.html">Community Blog</a></li>
|
||||
<li><a href="contact.php">Jobs and Careers</a></li>
|
||||
<li><a href="blog.html">latest News Blog</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-small" data-aos="fade-up" data-aos-delay="150" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="footer-widget footer-links ms-lg-4">
|
||||
<div class="footer-title">
|
||||
<h5>Destinations</h5>
|
||||
</div>
|
||||
<ul class="list-style-three">
|
||||
<li><a href="destination-details.html">African Safaris</a></li>
|
||||
<li><a href="destination-details.html">Alaska & Canada</a></li>
|
||||
<li><a href="destination-details.html">South America</a></li>
|
||||
<li><a href="destination-details.html">Middle East</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-md-6 col-10 col-small" data-aos="fade-up" data-aos-delay="200" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="footer-widget footer-contact">
|
||||
<div class="footer-title">
|
||||
<h5>Get In Touch</h5>
|
||||
</div>
|
||||
<ul class="list-style-one">
|
||||
<li><i class="fal fa-map-marked-alt"></i> 578 Level, D-block 45 Street Melbourne, Australia</li>
|
||||
<li><i class="fal fa-envelope"></i> <a href="mailto:supportrevelo@gmail.com">supportrevelo @gmail.com</a></li>
|
||||
<li><i class="fal fa-phone-volume"></i> <a href="callto:+88012334588">+880 (123) 345 88</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bottom bg-transparent pt-20 pb-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-5">
|
||||
<div class="copyright-text text-center text-lg-start">
|
||||
<p>@Copy 2024 <a href="index.php">Ravelo</a>, All rights reserved</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-7 text-center text-lg-end">
|
||||
<ul class="footer-bottom-nav">
|
||||
<li><a href="about.html">Terms</a></li>
|
||||
<li><a href="about.html">Privacy Policy</a></li>
|
||||
<li><a href="about.html">Legal notice</a></li>
|
||||
<li><a href="about.html">Accessibility</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- footer area end -->
|
||||
|
||||
</div>
|
||||
<!--End pagewrapper-->
|
||||
|
||||
|
||||
<!-- Jquery -->
|
||||
<script src="assets/js/jquery-3.6.0.min.js"></script>
|
||||
<!-- Bootstrap -->
|
||||
<script src="assets/js/bootstrap.min.js"></script>
|
||||
<!-- Appear Js -->
|
||||
<script src="assets/js/appear.min.js"></script>
|
||||
<!-- Slick -->
|
||||
<script src="assets/js/slick.min.js"></script>
|
||||
<!-- Magnific Popup -->
|
||||
<script src="assets/js/jquery.magnific-popup.min.js"></script>
|
||||
<!-- Nice Select -->
|
||||
<script src="assets/js/jquery.nice-select.min.js"></script>
|
||||
<!-- Image Loader -->
|
||||
<script src="assets/js/imagesloaded.pkgd.min.js"></script>
|
||||
<!-- Skillbar -->
|
||||
<script src="assets/js/skill.bars.jquery.min.js"></script>
|
||||
<!-- Isotope -->
|
||||
<script src="assets/js/isotope.pkgd.min.js"></script>
|
||||
<!-- AOS Animation -->
|
||||
<script src="assets/js/aos.js"></script>
|
||||
<!-- Custom script -->
|
||||
<script src="assets/js/script.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
68
header.php
68
header.php
@@ -13,14 +13,18 @@
|
||||
* 'light' = Dark text on light background (header02 style)
|
||||
*/
|
||||
|
||||
// Start output buffering BEFORE any code that might output
|
||||
ob_start();
|
||||
|
||||
// Set default style if not provided
|
||||
$headerStyle = $headerStyle ?? 'light';
|
||||
|
||||
ob_start();
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
// Use absolute paths based on this file's location
|
||||
$rootDir = dirname(__FILE__);
|
||||
require_once($rootDir . "/src/config/env.php");
|
||||
require_once($rootDir . "/src/config/session.php");
|
||||
require_once($rootDir . "/src/config/connection.php");
|
||||
require_once($rootDir . "/src/config/functions.php");
|
||||
|
||||
$is_logged_in = isset($_SESSION['user_id']);
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
@@ -229,7 +233,7 @@ if ($headerStyle === 'light') {
|
||||
|
||||
<div class="header-inner rel d-flex align-items-center">
|
||||
<div class="logo-outer">
|
||||
<div class="logo" style="width:200px;"><a href="index.php"><img src="<?php echo $logoImg; ?>" alt="Logo" title="Logo"></a></div>
|
||||
<div class="logo" style="width:200px;"><a href="index"><img src="<?php echo $logoImg; ?>" alt="Logo" title="Logo"></a></div>
|
||||
</div>
|
||||
|
||||
<div class="nav-outer mx-lg-auto ps-xxl-5 clearfix">
|
||||
@@ -237,7 +241,7 @@ if ($headerStyle === 'light') {
|
||||
<nav class="main-menu navbar-expand-lg">
|
||||
<div class="navbar-header">
|
||||
<div class="mobile-logo">
|
||||
<a href="index.php">
|
||||
<a href="index">
|
||||
<img src="<?php echo $mobileLogoImg; ?>" alt="Logo" title="Logo">
|
||||
</a>
|
||||
</div>
|
||||
@@ -252,44 +256,44 @@ if ($headerStyle === 'light') {
|
||||
|
||||
<div class="navbar-collapse collapse clearfix">
|
||||
<ul class="navigation clearfix">
|
||||
<li><a href="index.php">Home</a></li>
|
||||
<li><a href="about.php">About</a></li>
|
||||
<li><a href="trips.php">Trips</a>
|
||||
<li><a href="index">Home</a></li>
|
||||
<li><a href="about">About</a></li>
|
||||
<li><a href="trips">Trips</a>
|
||||
<?php if ($headerStyle === 'dark'): ?>
|
||||
<ul>
|
||||
<li><a href="tour-list.html">Tour List</a></li>
|
||||
<li><a href="tour-grid.html">Tour Grid</a></li>
|
||||
<li><a href="tour-sidebar.html">Tour Sidebar</a></li>
|
||||
<li><a href="trip-details.php">Tour Details</a></li>
|
||||
<li><a href="trip-details">Tour Details</a></li>
|
||||
<li><a href="tour-guide.html">Tour Guide</a></li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<li class="dropdown"><a href="#">Training</a>
|
||||
<ul>
|
||||
<li><a href="driver_training.php">Basic 4X4 Driver Training</a></li>
|
||||
<li><a href="bush_mechanics.php">Bush Mechanics</a></li>
|
||||
<li><a href="rescue_recovery.php">Rescue & Recovery</a></li>
|
||||
<li><a href="driver_training">Basic 4X4 Driver Training</a></li>
|
||||
<li><a href="bush_mechanics">Bush Mechanics</a></li>
|
||||
<li><a href="rescue_recovery">Rescue & Recovery</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="events.php">Events</a></li>
|
||||
<li><a href="blog.php">Blog</a></li>
|
||||
<li><a href="events">Events</a></li>
|
||||
<li><a href="blog">Blog</a></li>
|
||||
<?php if ($role === 'admin' || $role === 'superadmin') { ?>
|
||||
<li class="dropdown"><a href="#">admin</a>
|
||||
<ul>
|
||||
<li><a href="admin_web_users.php">Website Users</a></li>
|
||||
<li><a href="admin_members.php">4WDCSA Members</a></li>
|
||||
<li><a href="admin_trip_bookings.php">Trip Bookings</a></li>
|
||||
<li><a href="admin_course_bookings.php">Course Bookings</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_web_users">Website Users</a></li>
|
||||
<li><a href="admin_members">4WDCSA Members</a></li>
|
||||
<li><a href="admin_trip_bookings">Trip Bookings</a></li>
|
||||
<li><a href="admin_course_bookings">Course Bookings</a></li>
|
||||
<li><a href="admin_efts">EFT Payments</a></li>
|
||||
<li><a href="process_payments">Process Payments</a></li>
|
||||
<?php if ($role === 'superadmin') { ?>
|
||||
<li><a href="admin_visitors.php">Visitor Log</a></li>
|
||||
<li><a href="admin_visitors">Visitor Log</a></li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li><a href="contact.php">Contact</a></li>
|
||||
<li><a href="contact">Contact</a></li>
|
||||
<?php if ($is_member) : ?>
|
||||
<li class="dropdown"><a href="#">Members Area</a>
|
||||
<ul>
|
||||
@@ -301,15 +305,15 @@ if ($headerStyle === 'light') {
|
||||
<?php if ($is_logged_in) : ?>
|
||||
<li class="dropdown"><a href="#">My Account</a>
|
||||
<ul>
|
||||
<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="submit_pop.php">Submit P.O.P</a></li>
|
||||
<li><a href="logout.php">Log Out</a></li>
|
||||
<li><a href="account_settings">Account Settings</a></li>
|
||||
<li><a href="membership_details">Membership</a></li>
|
||||
<li><a href="bookings">My Bookings</a></li>
|
||||
<li><a href="submit_pop">Submit P.O.P</a></li>
|
||||
<li><a href="logout">Log Out</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<?php else : ?>
|
||||
<li class="nav-item d-xl-none"><a href="login.php">Log In</a></li>
|
||||
<li class="nav-item d-xl-none"><a href="login">Log In</a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -324,13 +328,13 @@ if ($headerStyle === 'light') {
|
||||
<div class="profile-menu">
|
||||
<div class="profile-info">
|
||||
<span style="color: <?php echo $textColor; ?>;">Welcome, <?php echo $_SESSION['first_name']; ?></span>
|
||||
<a href="account_settings.php">
|
||||
<a href="account_settings">
|
||||
<img src="<?php echo $_SESSION['profile_pic']; ?>?v=<?php echo time(); ?>" alt="Profile Picture" class="profile-pic">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<a href="login.php" class="theme-btn style-two bgc-secondary">
|
||||
<a href="login" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Log In">Log In</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
|
||||
307
header01.php
307
header01.php
@@ -1,307 +0,0 @@
|
||||
<?php
|
||||
ob_start();
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
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>
|
||||
<html lang="zxx">
|
||||
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="description" content="">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<!-- Title -->
|
||||
<title>4WDCSA - The Four Wheel Drive Club of Southern Africa</title>
|
||||
<!-- Favicon Icon -->
|
||||
<link rel="shortcut icon" href="assets/images/logos/favicon.ico" type="image/x-icon">
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<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>
|
||||
|
||||
<!-- Flaticon -->
|
||||
<link rel="stylesheet" href="assets/css/flaticon.min.css">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="assets/css/fontawesome-5.14.0.min.css">
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
|
||||
<!-- Magnific Popup -->
|
||||
<link rel="stylesheet" href="assets/css/magnific-popup.min.css">
|
||||
<!-- Nice Select -->
|
||||
<link rel="stylesheet" href="assets/css/nice-select.min.css">
|
||||
<!-- Animate -->
|
||||
<link rel="stylesheet" href="assets/css/aos.css">
|
||||
<!-- Slick -->
|
||||
<link rel="stylesheet" href="assets/css/slick.min.css">
|
||||
<!-- Main Style -->
|
||||
<link rel="stylesheet" href="assets/css/style_new.css?v=1">
|
||||
|
||||
<link rel="stylesheet" href="header_css.css">
|
||||
|
||||
<script id="mcjs">
|
||||
! function(c, h, i, m, p) {
|
||||
m = c.createElement(h), p = c.getElementsByTagName(h)[0], m.async = 1, m.src = i, p.parentNode.insertBefore(m, p)
|
||||
}(document, "script", "https://chimpstatic.com/mcjs-connected/js/users/3c26590bcc200ef52edc0bec2/b960bfcd9c876f911833ca3f0.js");
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<style>
|
||||
.mobile-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 1199px) {
|
||||
.mobile-only {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.profile-menu {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.profile-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.profile-info span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.profile-pic {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
object-fit: cover;
|
||||
/* Ensures the image fits without distortion */
|
||||
}
|
||||
|
||||
.dropdown-arrow {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.dropdown-menu2 {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.1);
|
||||
/* border-radius: 5px; */
|
||||
min-width: 250px;
|
||||
z-index: 1000;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.dropdown-menu2 ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dropdown-menu2 ul li {
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.dropdown-menu22 ul li a {
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.dropdown-menu22 ul li:hover {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div class="page-wrapper">
|
||||
|
||||
<!-- Preloader -->
|
||||
<div class="preloader">
|
||||
<div class="custom-loader"></div>
|
||||
</div>
|
||||
|
||||
<!-- main header -->
|
||||
<header class="main-header header-one white-menu menu-absolute">
|
||||
<!--Header-Upper-->
|
||||
<div class="header-upper py-30 rpy-0">
|
||||
<div class="container-fluid clearfix">
|
||||
|
||||
<div class="header-inner rel d-flex align-items-center">
|
||||
<div class="logo-outer">
|
||||
<div class="logo"><a href="index.php"><img src="assets/images/logos/logo.png"
|
||||
style="width:200px;" alt="Logo" title="Logo"></a></div>
|
||||
</div>
|
||||
|
||||
<div class="nav-outer mx-lg-auto ps-xxl-5 clearfix">
|
||||
<!-- Main Menu -->
|
||||
<nav class="main-menu navbar-expand-lg">
|
||||
<div class="navbar-header">
|
||||
<div class="mobile-logo">
|
||||
<a href="index.php">
|
||||
<img src="assets/images/logos/logo.png" alt="Logo" title="Logo">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Toggle Button -->
|
||||
<button type="button" class="navbar-toggle" data-bs-toggle="collapse"
|
||||
data-bs-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-collapse collapse clearfix">
|
||||
<ul class="navigation clearfix">
|
||||
<li><a href="index.php">Home</a></li>
|
||||
<li><a href="about.php">About</a></li>
|
||||
<!-- <li class="dropdown"><a href="about.html">BASE 4</a>
|
||||
<ul>
|
||||
<li><a href="tour-list.html">About BASE 4</a></li>
|
||||
<li><a href="campsite_booking.php">Book a Campsite</a></li>
|
||||
</ul>
|
||||
</li> -->
|
||||
<li><a href="trips.php">Trips</a>
|
||||
<ul>
|
||||
<li><a href="tour-list.html">Tour List</a></li>
|
||||
<li><a href="tour-grid.html">Tour Grid</a></li>
|
||||
<li><a href="tour-sidebar.html">Tour Sidebar</a></li>
|
||||
<li><a href="trip-details.php">Tour Details</a></li>
|
||||
<li><a href="tour-guide.html">Tour Guide</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown"><a href="#">Training</a>
|
||||
<ul>
|
||||
<li><a href="driver_training.php">Basic 4X4 Driver Training</a></li>
|
||||
<li><a href="bush_mechanics.php">Bush Mechanics</a></li>
|
||||
<li><a href="rescue_recovery.php">Rescue & Recovery</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="events.php">Events</a> </li>
|
||||
<li><a href="blog.php">Blog</a></li>
|
||||
<?php if ($role === 'admin' || $role === 'superadmin') { ?>
|
||||
<li class="dropdown"><a href="#">admin</a>
|
||||
<ul>
|
||||
<li><a href="admin_web_users.php">Website Users</a></li>
|
||||
<li><a href="admin_members.php">4WDCSA Members</a></li>
|
||||
<li><a href="admin_trip_bookings.php">Trip Bookings</a></li>
|
||||
<li><a href="admin_course_bookings.php">Course Bookings</a></li>
|
||||
<!-- <li><a href="admin_camp_bookings.php">Camping Bookings</a></li> -->
|
||||
<!-- <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="bar_tabs.php">Bar</a></li> -->
|
||||
<?php if ($role === 'superadmin') { ?>
|
||||
<li><a href="admin_visitors.php">Visitor Log</a></li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li><a href="contact.php">Contact</a></li>
|
||||
<?php if ($is_member) : ?>
|
||||
<li class="dropdown"><a href="#">Members Area</a>
|
||||
<ul>
|
||||
<li><a href="#">Coming Soon!</a></li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($is_logged_in) : ?>
|
||||
<li class="dropdown"><a href="#">My Account</a>
|
||||
<ul>
|
||||
<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="submit_pop.php">Submit P.O.P</a></li>
|
||||
<li><a href="logout.php">Log Out</a></li>
|
||||
</ul>
|
||||
|
||||
<?php else : ?>
|
||||
<li class="nav-item d-xl-none"><a href="login.php">Log In</a></li>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
<!-- Main Menu End-->
|
||||
</div>
|
||||
|
||||
<!-- Menu Button -->
|
||||
<div class="menu-btns py-10">
|
||||
<?php if ($is_logged_in) : ?>
|
||||
<div class="profile-menu">
|
||||
<div class="profile-info">
|
||||
<span style="color: #fff;">Welcome, <?php echo $_SESSION['first_name']; ?></span>
|
||||
<a href="account_settings.php">
|
||||
<img src="<?php echo $_SESSION['profile_pic']; ?>?v=<?php echo time(); ?>" alt="Profile Picture" class="profile-pic">
|
||||
</a>
|
||||
<!-- <i style="color: #fff;" class="fal fa-chevron-down dropdown-arrow"></i> -->
|
||||
</div>
|
||||
<!-- Dropdown Menu -->
|
||||
<!-- <div class="dropdown-menu2">
|
||||
<ul>
|
||||
<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="logout.php">Log Out</a></li>
|
||||
</ul>
|
||||
</div> -->
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<a href="login.php" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Log In">Log In</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<!-- menu sidebar -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Header Upper-->
|
||||
</header>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Toggle dropdown menu visibility when the profile-info is clicked
|
||||
document.querySelector('.profile-info').addEventListener('click', function(event) {
|
||||
const dropdownMenu = document.querySelector('.dropdown-menu2');
|
||||
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
|
||||
event.stopPropagation(); // Prevent this click from closing the menu
|
||||
});
|
||||
|
||||
// Close the dropdown menu if the user clicks outside of it
|
||||
document.addEventListener('click', function(event) {
|
||||
const dropdownMenu = document.querySelector('.dropdown-menu2');
|
||||
const profileMenu = document.querySelector('.profile-menu');
|
||||
if (!profileMenu.contains(event.target)) {
|
||||
dropdownMenu.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
312
header02.php
312
header02.php
@@ -1,312 +0,0 @@
|
||||
<?php
|
||||
ob_start();
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
$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();
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="zxx">
|
||||
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="description" content="">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<!-- Title -->
|
||||
<title>4WDCSA - The Four Wheel Drive Club of Southern Africa</title>
|
||||
<!-- Favicon Icon -->
|
||||
<link rel="shortcut icon" href="assets/images/logos/favicon.ico" type="image/x-icon">
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<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">
|
||||
<!-- Flaticon -->
|
||||
<link rel="stylesheet" href="assets/css/flaticon.min.css">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="assets/css/fontawesome-5.14.0.min.css">
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
|
||||
<!-- Magnific Popup -->
|
||||
<link rel="stylesheet" href="assets/css/magnific-popup.min.css">
|
||||
<!-- Nice Select -->
|
||||
<link rel="stylesheet" href="assets/css/nice-select.min.css">
|
||||
<!-- jQuery UI -->
|
||||
<link rel="stylesheet" href="assets/css/jquery-ui.min.css">
|
||||
<!-- Animate -->
|
||||
<link rel="stylesheet" href="assets/css/aos.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.css" onload="AOS.init();">
|
||||
<!-- Slick -->
|
||||
<link rel="stylesheet" href="assets/css/slick.min.css">
|
||||
<!-- Main Style -->
|
||||
<link rel="stylesheet" href="assets/css/style_new.css">
|
||||
|
||||
<script id="mcjs">
|
||||
! function(c, h, i, m, p) {
|
||||
m = c.createElement(h), p = c.getElementsByTagName(h)[0], m.async = 1, m.src = i, p.parentNode.insertBefore(m, p)
|
||||
}(document, "script", "https://chimpstatic.com/mcjs-connected/js/users/3c26590bcc200ef52edc0bec2/b960bfcd9c876f911833ca3f0.js");
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
<style>
|
||||
.profile-menu {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.profile-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.profile-info span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.profile-pic {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
object-fit: cover;
|
||||
/* Ensures the image fits without distortion */
|
||||
}
|
||||
|
||||
.dropdown-arrow {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.dropdown-menu2 {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
box-shadow: 2px 2px 5px 1px rgba(0, 0, 0, 0.1), -2px 0px 5px 1px rgba(0, 0, 0, 0.1);
|
||||
/* border-radius: 5px; */
|
||||
min-width: 250px;
|
||||
z-index: 1000;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.dropdown-menu2 ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dropdown-menu2 ul li {
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.dropdown-menu22 ul li a {
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.dropdown-menu22 ul li:hover {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.page-banner-area {
|
||||
position: relative;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.banner-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('assets/images/banner/tracks7.png');
|
||||
/* Replace with your PNG */
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
/* Make sure your content is above the overlays */
|
||||
.banner-inner {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div class="page-wrapper">
|
||||
|
||||
<!-- Preloader -->
|
||||
<div class="preloader">
|
||||
<div class="custom-loader"></div>
|
||||
</div>
|
||||
|
||||
<!-- main header -->
|
||||
<header class="main-header header-one">
|
||||
<!--Header-Upper-->
|
||||
<div class="header-upper bg-white py-30 rpy-0">
|
||||
<div class="container-fluid clearfix">
|
||||
|
||||
<div class="header-inner rel d-flex align-items-center">
|
||||
<div class="logo-outer">
|
||||
<div style="width:200px;" class="logo"><a href="index.php"><img src="assets/images/logos/logo-two.png" alt="Logo" title="Logo"></a></div>
|
||||
</div>
|
||||
|
||||
<div class="nav-outer mx-lg-auto ps-xxl-5 clearfix">
|
||||
<!-- Main Menu -->
|
||||
<nav class="main-menu navbar-expand-lg">
|
||||
<div class="navbar-header">
|
||||
<div class="mobile-logo">
|
||||
<a href="index.php">
|
||||
<img src="assets/images/logos/logo-two.png" alt="Logo" title="Logo">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Toggle Button -->
|
||||
<button type="button" class="navbar-toggle" data-bs-toggle="collapse" data-bs-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-collapse collapse clearfix">
|
||||
<ul class="navigation clearfix">
|
||||
<li><a href="index.php">Home</a></li>
|
||||
<li><a href="about.php">About</a></li>
|
||||
<!-- <li class="dropdown"><a href="about.html">BASE 4</a>
|
||||
<ul>
|
||||
<li><a href="tour-list.html">About BASE 4</a></li>
|
||||
<li><a href="campsite_booking.php">Book a Campsite</a></li>
|
||||
</ul>
|
||||
</li> -->
|
||||
<li><a href="trips.php">Trips</a>
|
||||
</li>
|
||||
<li class="dropdown"><a href="#">Training</a>
|
||||
<ul>
|
||||
<li><a href="driver_training.php">Basic 4X4 Driver Training</a></li>
|
||||
<li><a href="bush_mechanics.php">Bush Mechanics</a></li>
|
||||
<li><a href="rescue_recovery.php">Rescue & Recovery</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="events.php">Events</a>
|
||||
</li>
|
||||
<li><a href="blog.php">Blog</a></li>
|
||||
<?php if ($role === 'admin' || $role === 'superadmin') { ?>
|
||||
<li class="dropdown"><a href="#">admin</a>
|
||||
<ul>
|
||||
<li><a href="admin_web_users.php">Website Users</a></li>
|
||||
<li><a href="admin_members.php">4WDCSA Members</a></li>
|
||||
<li><a href="admin_trip_bookings.php">Trip Bookings</a></li>
|
||||
<li><a href="admin_course_bookings.php">Course Bookings</a></li>
|
||||
<!-- <li><a href="admin_camp_bookings.php">Camping Bookings</a></li> -->
|
||||
<!-- <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>
|
||||
<?php if ($role === 'superadmin') { ?>
|
||||
<li><a href="admin_visitors.php">Visitor Log</a></li>
|
||||
<?php } ?>
|
||||
<!-- <li><a href="bar_tabs.php">Bar</a></li> -->
|
||||
</ul>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li><a href="contact.php">Contact</a></li>
|
||||
<?php if ($is_logged_in) : ?>
|
||||
<li class="dropdown"><a href="#">My Account</a>
|
||||
<ul>
|
||||
<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="submit_pop.php">Submit P.O.P</a></li>
|
||||
<li><a href="logout.php">Log Out</a></li>
|
||||
</ul>
|
||||
|
||||
<?php else : ?>
|
||||
<li class="nav-item d-xl-none"><a href="login.php">Log In</a></li>
|
||||
<?php endif; ?>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
<!-- Main Menu End-->
|
||||
</div>
|
||||
|
||||
<!-- Menu Button -->
|
||||
<div class="menu-btns py-10">
|
||||
<?php if ($is_logged_in) : ?>
|
||||
<div class="profile-menu">
|
||||
<div class="profile-info">
|
||||
<span style="color: #111111;">Welcome, <?php echo $_SESSION['first_name']; ?></span>
|
||||
<a href="account_settings.php">
|
||||
<img src="<?php echo $_SESSION['profile_pic']; ?>?v=<?php echo time(); ?>" alt="Profile Picture" class="profile-pic">
|
||||
</a>
|
||||
|
||||
<!-- <i style="color: #111111;" class="fal fa-chevron-down dropdown-arrow"></i> -->
|
||||
</div>
|
||||
<!-- Dropdown Menu -->
|
||||
<!-- <div class="dropdown-menu2">
|
||||
<ul>
|
||||
<li><a href="account_settings.php">Account Settings</a></li>
|
||||
<li><a href="membership_details.php">Membership</a></li>
|
||||
<li><a href="bookings.php">Bookings</a></li>
|
||||
<li><a href="logout.php">Log Out</a></li>
|
||||
</ul>
|
||||
</div> -->
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<a href="login.php" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Log In">Log In</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<!-- menu sidebar -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Header Upper-->
|
||||
</header>
|
||||
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Toggle dropdown menu visibility when the profile-info is clicked
|
||||
document.querySelector('.profile-info').addEventListener('click', function(event) {
|
||||
const dropdownMenu = document.querySelector('.dropdown-menu2');
|
||||
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
|
||||
event.stopPropagation(); // Prevent this click from closing the menu
|
||||
});
|
||||
|
||||
// Close the dropdown menu if the user clicks outside of it
|
||||
document.addEventListener('click', function(event) {
|
||||
const dropdownMenu = document.querySelector('.dropdown-menu2');
|
||||
const profileMenu = document.querySelector('.profile-menu');
|
||||
if (!profileMenu.contains(event.target)) {
|
||||
dropdownMenu.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -3,7 +3,7 @@ $headerStyle = 'dark';
|
||||
include_once('header.php');
|
||||
$indemnityPending = false;
|
||||
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
if (isset($_SESSION['user_id']) && isset($conn) && $conn !== null) {
|
||||
$userId = $_SESSION['user_id'];
|
||||
$stmt = $conn->prepare("SELECT user_id FROM membership_application WHERE user_id = ? AND accept_indemnity = 0 LIMIT 1");
|
||||
$stmt->bind_param("i", $userId);
|
||||
@@ -83,6 +83,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
<div class="row justify-content-center">
|
||||
<?php
|
||||
// Query to retrieve data from the trips table
|
||||
if (isset($conn) && $conn !== null) {
|
||||
$stmt = $conn->prepare("SELECT trip_id, trip_name, location, short_description, start_date, end_date, vehicle_capacity, cost_members, places_booked
|
||||
FROM trips
|
||||
WHERE published = ?
|
||||
@@ -131,6 +132,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
} else {
|
||||
echo "No trips available.";
|
||||
}
|
||||
} // end if (isset($conn) && $conn !== null)
|
||||
?>
|
||||
|
||||
</div>
|
||||
|
||||
14
logout.php
14
logout.php
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
|
||||
|
||||
// Destroy the session
|
||||
session_destroy();
|
||||
|
||||
|
||||
|
||||
// Redirect to login page
|
||||
header("Location: index.php"); // Replace with your actual login page URL
|
||||
exit();
|
||||
?>
|
||||
85
modal.html
85
modal.html
@@ -1,85 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Modal with AJAX Dropdown</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
|
||||
<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>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container mt-5">
|
||||
<!-- Button to trigger modal -->
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#userModal">
|
||||
Open Modal
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="userModal" tabindex="-1" aria-labelledby="userModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="userModalLabel">Select a User</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="barTabForm">
|
||||
<div class="mb-3">
|
||||
<label for="userSelect" class="form-label">Choose a User</label>
|
||||
<select class="form-select" id="userSelect" name="user_id" required>
|
||||
<option value="">Loading...</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">Create Bar Tab</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// Load users into dropdown when modal opens
|
||||
$('#userModal').on('shown.bs.modal', function () {
|
||||
$.ajax({
|
||||
url: 'fetch_users.php',
|
||||
method: 'GET',
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
let dropdown = $('#userSelect');
|
||||
dropdown.empty();
|
||||
dropdown.append('<option value="">Select a user</option>');
|
||||
data.forEach(user => {
|
||||
dropdown.append(`<option value="${user.id}">${user.first_name} ${user.last_name}</option>`);
|
||||
});
|
||||
},
|
||||
error: function () {
|
||||
alert('Error fetching users.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Handle form submission
|
||||
$('#barTabForm').submit(function (e) {
|
||||
e.preventDefault(); // Prevent default form submission
|
||||
$.ajax({
|
||||
url: 'create_bar_tab.php',
|
||||
method: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function (response) {
|
||||
alert('Bar tab created successfully!');
|
||||
$('#userModal').modal('hide'); // Close modal
|
||||
},
|
||||
error: function () {
|
||||
alert('Error creating bar tab.');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,200 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
$user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
|
||||
$eft_id = strtoupper($user_id." SUBS ".date("Y")." ".getInitialSurname($user_id));
|
||||
$status = 'AWAITING PAYMENT';
|
||||
$description = 'Membership Fees '.date("Y")." ".getInitialSurname($user_id);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// CSRF Token Validation
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
auditLog($user_id, 'CSRF_VALIDATION_FAILED', 'membership_application', null, ['endpoint' => 'process_application.php']);
|
||||
http_response_code(403);
|
||||
die('Security token validation failed. Please try again.');
|
||||
}
|
||||
|
||||
// Get all the form fields with validation
|
||||
$first_name = validateName($_POST['first_name'] ?? '');
|
||||
if ($first_name === false) {
|
||||
die('Invalid first name format.');
|
||||
}
|
||||
|
||||
$last_name = validateName($_POST['last_name'] ?? '');
|
||||
if ($last_name === false) {
|
||||
die('Invalid last name format.');
|
||||
}
|
||||
|
||||
$id_number = validateSAIDNumber($_POST['id_number'] ?? '');
|
||||
if ($id_number === false) {
|
||||
die('Invalid ID number format.');
|
||||
}
|
||||
|
||||
$dob = validateDate($_POST['dob'] ?? '');
|
||||
if ($dob === false) {
|
||||
die('Invalid date of birth format.');
|
||||
}
|
||||
|
||||
$occupation = sanitizeTextInput($_POST['occupation'] ?? '', 100);
|
||||
$tel_cell = validatePhoneNumber($_POST['tel_cell'] ?? '');
|
||||
if ($tel_cell === false) {
|
||||
die('Invalid phone number format.');
|
||||
}
|
||||
|
||||
$email = validateEmail($_POST['email'] ?? '');
|
||||
if ($email === false) {
|
||||
die('Invalid email format.');
|
||||
}
|
||||
|
||||
// Spouse or Partner details (optional)
|
||||
$spouse_first_name = !empty($_POST['spouse_first_name']) ? validateName($_POST['spouse_first_name']) : null;
|
||||
$spouse_last_name = !empty($_POST['spouse_last_name']) ? validateName($_POST['spouse_last_name']) : null;
|
||||
$spouse_id_number = !empty($_POST['spouse_id_number']) ? validateSAIDNumber($_POST['spouse_id_number']) : null;
|
||||
$spouse_dob = !empty($_POST['spouse_dob']) ? validateDate($_POST['spouse_dob']) : NULL;
|
||||
$spouse_occupation = !empty($_POST['spouse_occupation']) ? sanitizeTextInput($_POST['spouse_occupation'], 100) : null;
|
||||
$spouse_tel_cell = !empty($_POST['spouse_tel_cell']) ? validatePhoneNumber($_POST['spouse_tel_cell']) : null;
|
||||
$spouse_email = !empty($_POST['spouse_email']) ? validateEmail($_POST['spouse_email']) : null;
|
||||
|
||||
// Children details (optional)
|
||||
$child_name1 = !empty($_POST['child_name1']) ? $_POST['child_name1'] : null;
|
||||
$child_dob1 = !empty($_POST['child_dob1']) ? $_POST['child_dob1'] : null;
|
||||
$child_name2 = !empty($_POST['child_name2']) ? $_POST['child_name2'] : null;
|
||||
$child_dob2 = !empty($_POST['child_dob2']) ? $_POST['child_dob2'] : null;
|
||||
$child_name3 = !empty($_POST['child_name3']) ? $_POST['child_name3'] : null;
|
||||
$child_dob3 = !empty($_POST['child_dob3']) ? $_POST['child_dob3'] : null;
|
||||
|
||||
// Address and other details
|
||||
$physical_address = $_POST['physical_address'];
|
||||
$postal_address = $_POST['postal_address'];
|
||||
$interests_hobbies = $_POST['interests_hobbies'];
|
||||
|
||||
// Primary vehicle details
|
||||
$vehicle_make = $_POST['vehicle_make'];
|
||||
$vehicle_model = $_POST['vehicle_model'];
|
||||
$vehicle_year = $_POST['vehicle_year'];
|
||||
$vehicle_registration = $_POST['vehicle_registration'];
|
||||
|
||||
// Secondary vehicle details (optional)
|
||||
$secondary_vehicle_make = !empty($_POST['secondary_vehicle_make']) ? $_POST['secondary_vehicle_make'] : null;
|
||||
$secondary_vehicle_model = !empty($_POST['secondary_vehicle_model']) ? $_POST['secondary_vehicle_model'] : null;
|
||||
$secondary_vehicle_year = !empty($_POST['secondary_vehicle_year']) ? $_POST['secondary_vehicle_year'] : null;
|
||||
$secondary_vehicle_registration = !empty($_POST['secondary_vehicle_registration']) ? $_POST['secondary_vehicle_registration'] : null;
|
||||
|
||||
// Start a transaction to ensure data consistency
|
||||
$conn->begin_transaction();
|
||||
|
||||
try {
|
||||
// Insert into the member application table
|
||||
$stmt = $conn->prepare("INSERT INTO membership_application (
|
||||
user_id, first_name, last_name, id_number, dob, occupation, tel_cell, email,
|
||||
spouse_first_name, spouse_last_name, spouse_id_number, spouse_dob, spouse_occupation, spouse_tel_cell, spouse_email,
|
||||
child_name1, child_dob1, child_name2, child_dob2, child_name3, child_dob3,
|
||||
physical_address, postal_address, interests_hobbies, vehicle_make, vehicle_model, vehicle_year, vehicle_registration,
|
||||
secondary_vehicle_make, secondary_vehicle_model, secondary_vehicle_year, secondary_vehicle_registration
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
// Check if preparation was successful
|
||||
if (!$stmt) {
|
||||
die("SQL error: " . $conn->error);
|
||||
}
|
||||
|
||||
$stmt->bind_param(
|
||||
"isssssssssssssssssssssssssssssss",
|
||||
$user_id,
|
||||
$first_name,
|
||||
$last_name,
|
||||
$id_number,
|
||||
$dob,
|
||||
$occupation,
|
||||
$tel_cell,
|
||||
$email,
|
||||
$spouse_first_name,
|
||||
$spouse_last_name,
|
||||
$spouse_id_number,
|
||||
$spouse_dob,
|
||||
$spouse_occupation,
|
||||
$spouse_tel_cell,
|
||||
$spouse_email,
|
||||
$child_name1,
|
||||
$child_dob1,
|
||||
$child_name2,
|
||||
$child_dob2,
|
||||
$child_name3,
|
||||
$child_dob3,
|
||||
$physical_address,
|
||||
$postal_address,
|
||||
$interests_hobbies,
|
||||
$vehicle_make,
|
||||
$vehicle_model,
|
||||
$vehicle_year,
|
||||
$vehicle_registration,
|
||||
$secondary_vehicle_make,
|
||||
$secondary_vehicle_model,
|
||||
$secondary_vehicle_year,
|
||||
$secondary_vehicle_registration
|
||||
);
|
||||
|
||||
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();
|
||||
|
||||
// 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', ?)");
|
||||
$stmt->bind_param("idssss", $user_id, $payment_amount, $payment_date, $membership_start_date, $membership_end_date, $eft_id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
// Commit the transaction
|
||||
$conn->commit();
|
||||
addSubsEFT($eft_id, $user_id, $status, $payment_amount, $description);
|
||||
sendInvoice(getEmail($user_id), getFullName($user_id), $eft_id, formatCurrency($payment_amount), $description);
|
||||
sendAdminNotification('4WDCSA.co.za - New Membership Application - '.$last_name , 'A new member has signed up, '.$first_name.' '.$last_name);
|
||||
header("Location:indemnity.php");
|
||||
// Success message
|
||||
$response = [
|
||||
'status' => 'success',
|
||||
'message' => 'Your membership application has been submitted successfully!'
|
||||
];
|
||||
} else {
|
||||
throw new Exception("Failed to insert membership fee. SQL error: " . $conn->error);
|
||||
}
|
||||
} else {
|
||||
throw new Exception("Failed to insert member application.SQL error: " . $conn->error);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Rollback the transaction in case of error
|
||||
$conn->rollback();
|
||||
|
||||
// Error response
|
||||
$response = [
|
||||
'status' => 'error',
|
||||
'message' => 'Error: ' . $e->getMessage()
|
||||
];
|
||||
}
|
||||
|
||||
// Return the response in JSON format
|
||||
echo json_encode($response);
|
||||
}
|
||||
?>
|
||||
@@ -1,93 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
// Start session to retrieve the logged-in user's ID
|
||||
session_start();
|
||||
|
||||
// Get user ID from session (assuming user is logged in)
|
||||
$user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
|
||||
|
||||
// Check if the form has been submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// CSRF Token Validation
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
auditLog($user_id, 'CSRF_VALIDATION_FAILED', 'bookings', null, ['endpoint' => 'process_booking.php']);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Security token validation failed. Please try again.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Validate dates and integers
|
||||
$from_date = validateDate($_POST['from_date'] ?? '');
|
||||
if ($from_date === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid from date format.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$to_date = validateDate($_POST['to_date'] ?? '');
|
||||
if ($to_date === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid to date format.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$num_vehicles = validateInteger($_POST['vehicles'] ?? 0, 1, 10);
|
||||
if ($num_vehicles === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid number of vehicles.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$num_adults = validateInteger($_POST['adults'] ?? 0, 0, 20);
|
||||
if ($num_adults === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid number of adults.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$num_children = validateInteger($_POST['children'] ?? 0, 0, 20);
|
||||
if ($num_children === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid number of children.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Get values from the form
|
||||
$add_firewood = isset($_POST['AddExtra']) ? 1 : 0; // Checkbox for extras
|
||||
$is_member = isset($_POST['is_member']) ? (int)$_POST['is_member'] : 0; // Hidden member status
|
||||
$type = "camping";
|
||||
|
||||
// Calculate the total number of nights
|
||||
$date1 = new DateTime($from_date);
|
||||
$date2 = new DateTime($to_date);
|
||||
$nights = $date2->diff($date1)->days;
|
||||
|
||||
// Determine rate per night
|
||||
$rate_per_night = ($is_member) ? 0 : 200; // Free for members, R200 for non-members
|
||||
|
||||
// Calculate the total cost
|
||||
$vehicle_cost = $rate_per_night * $num_vehicles * $nights;
|
||||
$firewood_cost = $add_firewood ? 50 : 0;
|
||||
$total_amount = $vehicle_cost + $firewood_cost;
|
||||
|
||||
// Calculate discount if the user is a member
|
||||
$discount_amount = ($is_member) ? $vehicle_cost : 0;
|
||||
|
||||
// Insert booking into the database
|
||||
$sql = "INSERT INTO bookings (booking_type, user_id, from_date, to_date, num_vehicles, num_adults, num_children, add_firewood, total_amount, discount_amount)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param('sissiiiidd', $type, $user_id, $from_date, $to_date, $num_vehicles, $num_adults, $num_children, $add_firewood, $total_amount, $discount_amount);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
// Redirect to success page or display success message
|
||||
echo "<script>alert('Booking successfully created!'); window.location.href = 'booking.php';</script>";
|
||||
} else {
|
||||
// Handle error if insert fails
|
||||
echo "<script>alert('Error processing booking. Please try again later.');</script>";
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
} else {
|
||||
echo "Invalid request.";
|
||||
}
|
||||
?>
|
||||
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
// Start session to retrieve the logged-in user's ID
|
||||
session_start();
|
||||
|
||||
// Get user ID from session (assuming user is logged in)
|
||||
$user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
|
||||
|
||||
// Validate user session
|
||||
if (!$user_id) {
|
||||
echo "<script>alert('User is not logged in. Please log in to make a booking.'); window.location.href = 'login.php';</script>";
|
||||
exit();
|
||||
}
|
||||
$is_member = getUserMemberStatus($user_id);
|
||||
|
||||
// Check if the form has been submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// CSRF Token Validation
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
auditLog($user_id, 'CSRF_VALIDATION_FAILED', 'bookings', null, ['endpoint' => 'process_camp_booking.php']);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Security token validation failed. Please try again.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Validate dates and integers
|
||||
$from_date = validateDate($_POST['from_date'] ?? '');
|
||||
if ($from_date === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid from date format.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$to_date = validateDate($_POST['to_date'] ?? '');
|
||||
if ($to_date === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid to date format.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$num_vehicles = validateInteger($_POST['vehicles'] ?? 1, 1, 10);
|
||||
if ($num_vehicles === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid number of vehicles.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$num_adults = validateInteger($_POST['adults'] ?? 0, 0, 20);
|
||||
if ($num_adults === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid number of adults.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$num_children = validateInteger($_POST['children'] ?? 0, 0, 20);
|
||||
if ($num_children === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid number of children.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Get values from the form
|
||||
$add_firewood = isset($_POST['AddExtra']) ? 1 : 0; // Checkbox for extras
|
||||
// $is_member = isset($_POST['is_member']) ? (int)$_POST['is_member'] : 0; // Hidden member status
|
||||
$type = "camping";
|
||||
|
||||
// Calculate the total number of nights
|
||||
$date1 = new DateTime($from_date);
|
||||
$date2 = new DateTime($to_date);
|
||||
$nights = $date2->diff($date1)->days;
|
||||
|
||||
// Validate date range
|
||||
if ($nights <= 0) {
|
||||
echo "<script>alert('Invalid date range. Please select valid dates.'); window.history.back();</script>";
|
||||
exit();
|
||||
}
|
||||
|
||||
// Determine rate per night
|
||||
$rate_per_night = 200; // Free for members, R200 for non-members
|
||||
|
||||
// Calculate the total cost
|
||||
$vehicle_cost = $rate_per_night * $num_vehicles * $nights;
|
||||
$total_discount = $is_member ? $vehicle_cost : 0;
|
||||
$firewood_cost = $add_firewood ? 50 : 0;
|
||||
$total_amount = $vehicle_cost + $firewood_cost;
|
||||
$payment_amount = $total_amount - $total_discount;
|
||||
$status = "AWAITING PAYMENT";
|
||||
$description = "BASE4 Camping";
|
||||
|
||||
$payment_id = uniqid();
|
||||
$eft_id = strtoupper($trip_code." ".getLastName($user_id));
|
||||
|
||||
// Insert booking into the database
|
||||
$sql = "INSERT INTO bookings (booking_type, user_id, from_date, to_date, num_vehicles, num_adults, num_children, add_firewood, total_amount, discount_amount, status, payment_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param('sissiiiiddss', $type, $user_id, $from_date, $to_date, $num_vehicles, $num_adults, $num_children, $add_firewood, $total_amount, $total_discount, $status, $payment_id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$booking_id = $conn->insert_id;
|
||||
|
||||
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 {
|
||||
addEFT($eft_id, $booking_id, $user_id, $status, $payment_amount, $description);
|
||||
header("Location: payment_confirmation.php?booking_id=".$booking_id);
|
||||
exit(); // Ensure no further code is executed after the redirect
|
||||
}
|
||||
} else {
|
||||
// Handle error if insert fails and echo the MySQL error
|
||||
$error_message = $stmt->error;
|
||||
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 {
|
||||
echo "Invalid request.";
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
session_start();
|
||||
|
||||
|
||||
// Get user ID from session (assuming user is logged in)
|
||||
$user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
|
||||
|
||||
// Validate user session
|
||||
if (!$user_id) {
|
||||
echo "<script>alert('User is not logged in. Please log in to make a booking.'); window.location.href = 'login.php';</script>";
|
||||
exit();
|
||||
}
|
||||
$is_member = getUserMemberStatus($user_id);
|
||||
$pending_member = getUserMemberStatusPending($user_id);
|
||||
|
||||
// Check if the form has been submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// CSRF Token Validation
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
auditLog($user_id, 'CSRF_VALIDATION_FAILED', 'bookings', null, ['endpoint' => 'process_course_booking.php']);
|
||||
http_response_code(403);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['error' => 'Security token validation failed.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Input variables from the form (use default values if not provided)
|
||||
$additional_members = validateInteger($_POST['members'] ?? 0, 0, 20);
|
||||
if ($additional_members === false) $additional_members = 0;
|
||||
|
||||
$num_adults = validateInteger($_POST['non-members'] ?? 0, 0, 20);
|
||||
if ($num_adults === false) $num_adults = 0;
|
||||
|
||||
$course_id = validateInteger($_POST['course_id'] ?? 0, 1, 999999);
|
||||
if ($course_id === false) {
|
||||
http_response_code(400);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['error' => 'Invalid course ID.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
checkAndRedirectCourseBooking($course_id);
|
||||
// Fetch trip costs from the database
|
||||
$query = "SELECT date, cost_members, cost_nonmembers, course_type FROM courses WHERE course_id = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->bind_param('i', $course_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Check if trip exists
|
||||
if ($result->num_rows === 0) {
|
||||
$response = ['error' => 'Trip not found.'];
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($response);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Fetch trip details
|
||||
$course = $result->fetch_assoc();
|
||||
$type = $course['course_type'];
|
||||
$date = $course['date'];
|
||||
$cost_members = intval($course['cost_members']);
|
||||
$cost_nonmembers = intval($course['cost_nonmembers']);
|
||||
|
||||
if ($type === "driver_training") {
|
||||
$description = "Basic 4X4 Driver Training Course " . $date;
|
||||
} elseif ($type === "bush_mechanics") {
|
||||
$description = "Bush Mechanics Course " . $date;
|
||||
} elseif ($type === "rescue_recovery") {
|
||||
$description = "Rescue & Recovery Training Course " . $date;
|
||||
} else {
|
||||
$description = "General Course " . $date; // Default fallback description
|
||||
}
|
||||
|
||||
// Initialize total and discount amount
|
||||
$total = 0;
|
||||
|
||||
// Calculate total based on membership
|
||||
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;
|
||||
$total = (($cost_nonmembers) + ($num_adults * $cost_nonmembers));
|
||||
$payment_amount = $total;
|
||||
$num_adults = $num_adults + 1;
|
||||
}
|
||||
|
||||
$status = "AWAITING PAYMENT";
|
||||
$type = 'course';
|
||||
$payment_id = uniqid();
|
||||
$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, notes)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $conn->prepare($sql);
|
||||
|
||||
if (!$stmt) {
|
||||
die("Preparation failed: " . $conn->error);
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
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 {
|
||||
addEFT($eft_id, $booking_id, $user_id, $status, $payment_amount, $description);
|
||||
sendInvoice(getEmail($user_id), getFullName($user_id), $eft_id, formatCurrency($payment_amount), $description);
|
||||
sendAdminNotification('New Course Booking - '.getFullName($user_id), getFullName($user_id).' has booked for '.$description);
|
||||
header("Location: payment_confirmation.php?token=".encryptData($booking_id, $salt));
|
||||
exit(); // Ensure no further code is executed after the redirect
|
||||
}
|
||||
} 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 {
|
||||
echo "Invalid request.";
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
checkAdmin();
|
||||
|
||||
// CSRF Token Validation for POST requests
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
auditLog($_SESSION['user_id'] ?? null, 'CSRF_VALIDATION_FAILED', 'efts', null, ['endpoint' => 'process_eft.php']);
|
||||
http_response_code(403);
|
||||
die('Security token validation failed.');
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($_GET['token']) || empty($_GET['token'])) {
|
||||
die("Invalid request.");
|
||||
}
|
||||
|
||||
$token = $_GET['token'];
|
||||
// echo $token;
|
||||
$eft_id = decryptData($token, $salt);
|
||||
$user = getUserIdFromEFT($eft_id);
|
||||
|
||||
// echo $eft_id;
|
||||
// Start transaction for atomicity
|
||||
$conn->begin_transaction();
|
||||
|
||||
try {
|
||||
// Update the efts table to set status = 'PAID'
|
||||
$updateEFT = "UPDATE efts SET status = 'PAID' WHERE eft_id = ?";
|
||||
$stmt = $conn->prepare($updateEFT);
|
||||
if (!$stmt) {
|
||||
throw new Exception("Prepare failed: " . $conn->error);
|
||||
}
|
||||
|
||||
$stmt->bind_param("s", $eft_id);
|
||||
if (!$stmt->execute()) {
|
||||
throw new Exception("EFT update failed: " . $stmt->error);
|
||||
}
|
||||
$stmt->close();
|
||||
|
||||
// Retrieve the booking_id from efts table
|
||||
$getBooking = "SELECT booking_id FROM efts WHERE eft_id = ?";
|
||||
$stmt = $conn->prepare($getBooking);
|
||||
if (!$stmt) {
|
||||
throw new Exception("Prepare failed: " . $conn->error);
|
||||
}
|
||||
|
||||
$stmt->bind_param("s", $eft_id);
|
||||
$stmt->execute();
|
||||
$stmt->bind_result($booking_id);
|
||||
$stmt->fetch();
|
||||
$stmt->close();
|
||||
|
||||
if (!empty($booking_id)) {
|
||||
// Update the bookings table if booking_id exists
|
||||
$updateBooking = "UPDATE bookings SET status = 'PAID' WHERE booking_id = ?";
|
||||
$stmt = $conn->prepare($updateBooking);
|
||||
if (!$stmt) {
|
||||
throw new Exception("Prepare failed: " . $conn->error);
|
||||
}
|
||||
|
||||
$stmt->bind_param("i", $booking_id);
|
||||
if (!$stmt->execute()) {
|
||||
throw new Exception("Booking update failed: " . $stmt->error);
|
||||
}
|
||||
} else {
|
||||
// If no booking_id is found, update membership_fees instead
|
||||
$updateMembership = "UPDATE membership_fees SET payment_status = 'PAID' WHERE payment_id = ?";
|
||||
$stmt = $conn->prepare($updateMembership);
|
||||
if (!$stmt) {
|
||||
throw new Exception("Prepare failed: " . $conn->error);
|
||||
}
|
||||
|
||||
$stmt->bind_param("s", $eft_id);
|
||||
if (!$stmt->execute()) {
|
||||
throw new Exception("Membership fee update failed: " . $stmt->error);
|
||||
}
|
||||
}
|
||||
$stmt->close();
|
||||
|
||||
// Commit transaction if everything was successful
|
||||
$conn->commit();
|
||||
sendPaymentConfirmation(getEmail($user), getFullName($user), getEftDescription($eft_id));
|
||||
header("Location: admin_efts.php");
|
||||
exit(); // Ensure no further code is executed after the redirect
|
||||
} catch (Exception $e) {
|
||||
// Rollback transaction if an error occurs
|
||||
$conn->rollback();
|
||||
echo "Error: " . $e->getMessage();
|
||||
}
|
||||
|
||||
|
||||
// Close database connection
|
||||
$conn->close();
|
||||
@@ -1,76 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
// Start session to retrieve the logged-in user's ID
|
||||
session_start();
|
||||
|
||||
// Get user ID from session (assuming user is logged in)
|
||||
$user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
|
||||
|
||||
// Validate user session
|
||||
if (!$user_id) {
|
||||
echo "<script>alert('User is not logged in. Please log in to make a booking.'); window.location.href = 'login.php';</script>";
|
||||
exit();
|
||||
}
|
||||
$is_member = getUserMemberStatus($user_id);
|
||||
|
||||
$query = "SELECT payment_amount, payment_status, membership_end_date FROM membership_fees WHERE user_id = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->bind_param('i', $user_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Check if trip exists
|
||||
if ($result->num_rows === 0) {
|
||||
$response = ['error' => 'Application Fee not found.'];
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($response);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Fetch trip details
|
||||
$fee = $result->fetch_assoc();
|
||||
$payment_status = $fee['payment_status'];
|
||||
$membership_end_date = $fee['membership_end_date'];
|
||||
$payment_amount = intval($fee['payment_amount']);
|
||||
|
||||
$description = "4WDCSA: Membership Fee " . getFullName($user_id) . " " . date("Y");
|
||||
$payment_id = uniqid();
|
||||
$eft_id = "SUBS 2025 ".getLastName($user_id);
|
||||
|
||||
// Update the membership_fees table to set payment_id
|
||||
$stmt = $conn->prepare("UPDATE membership_fees SET payment_id = ? WHERE user_id = ?");
|
||||
if ($stmt) {
|
||||
$stmt->bind_param("ss", $payment_id, $user_id);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
throw new Exception("Failed to update membership_fees table.");
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
} else {
|
||||
throw new Exception("Failed to prepare statement for membership_fees table: " . $conn->error);
|
||||
}
|
||||
|
||||
// Get the current date
|
||||
$current_date = new DateTime();
|
||||
|
||||
// Convert $membership_end_date to a DateTime object
|
||||
$membership_end_date_obj = DateTime::createFromFormat('Y-m-d', $membership_end_date);
|
||||
|
||||
// Check if the current date is after membership_end_date
|
||||
// OR if the current date is before or on membership_end_date AND payment_status is "PENDING"
|
||||
if (
|
||||
$current_date > $membership_end_date_obj ||
|
||||
($current_date <= $membership_end_date_obj && $payment_status === "PENDING")
|
||||
) {
|
||||
|
||||
// Call the processMembershipPayment function
|
||||
// processMembershipPayment($payment_id, $payment_amount, $description);
|
||||
addMembershipEFT($eft_id, $user_id, $status, $amount, $description, $membershipfee_id);
|
||||
header("Location: payment_confirmation.php?booking_id=" . $booking_id);
|
||||
exit(); // Ensure no further code is executed after the redirect
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
checkAdmin();
|
||||
checkUserSession();
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
?>
|
||||
<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 */
|
||||
}
|
||||
|
||||
.message-box {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
padding-right: 35px;
|
||||
/* Ensures text doesn't overlap with the close button */
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
/* Centers vertically */
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.close-btn:hover {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
<?php
|
||||
$status = "PROCESSING";
|
||||
$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 mb-50">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">Process Payments</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">Process Payments</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Tour List Area start -->
|
||||
<section class="tour-list-page py-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-12">
|
||||
<?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'">×</span>
|
||||
</div>
|
||||
<?php unset($_SESSION['message']); ?>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
// Query to retrieve data from the bookings table
|
||||
$sql = "SELECT * FROM efts WHERE status = ? ORDER BY timestamp DESC";
|
||||
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("s", $status);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
// Loop through each row
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$eft_id = $row['eft_id'];
|
||||
$file_name = str_replace(' ', '_', $eft_id);
|
||||
$eft_user = $row['user_id'];
|
||||
$eft_amount = $row['amount'];
|
||||
$eft_description = $row['description'];
|
||||
|
||||
// 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="p-4" >
|
||||
<iframe src="uploads/pop/'.$file_name.'.pdf#toolbar=0" width="400px" height="200px"></iframe>
|
||||
<p><a href="uploads/pop/'.$file_name.'.pdf" target="_new" class="theme-btn style-three" style="width:100%;">View Full PDF</a></p>
|
||||
|
||||
</div>
|
||||
<div style="width:100%;" class="content">
|
||||
<h5>' . htmlspecialchars($eft_description) . '</a></h5>
|
||||
<h5>' . getFullName($eft_user) . '</a></h5>
|
||||
<div class="destination-footer">
|
||||
<span class="price"><span>Booking Total: R ' . number_format($eft_amount, 2) . '</span></span>
|
||||
<a href="process_eft.php?token=' . encryptData($eft_id, $salt) . '" class="theme-btn style-three"><span data-hover="POP RECEIVED">PROCESS</span></a>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
} else {
|
||||
echo '<p>There are no pending payments for processing.</p>';
|
||||
}
|
||||
// Close connection
|
||||
$conn->close();
|
||||
?>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Tour List Area end -->
|
||||
|
||||
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
die(json_encode(['status' => 'error', 'message' => 'User not logged in']));
|
||||
}
|
||||
|
||||
if (isset($_POST['signature'])) {
|
||||
// CSRF Token Validation
|
||||
// if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
// auditLog($_SESSION['user_id'], 'CSRF_VALIDATION_FAILED', 'membership_application', null, ['endpoint' => 'process_signature.php']);
|
||||
// die(json_encode(['status' => 'error', 'message' => 'Security token validation failed']));
|
||||
// }
|
||||
|
||||
$user_id = $_SESSION['user_id']; // Get the user ID from the session
|
||||
$signature = $_POST['signature']; // Base64 image data
|
||||
|
||||
// Decode the base64 image
|
||||
$signature = str_replace('data:image/png;base64,', '', $signature);
|
||||
$signature = str_replace(' ', '+', $signature);
|
||||
$signatureData = base64_decode($signature);
|
||||
|
||||
// Create a file path for the signature image
|
||||
$fileName = 'signature_' . $user_id . '.png';
|
||||
$filePath = 'uploads/signatures/' . $fileName;
|
||||
|
||||
// Ensure the directory exists
|
||||
if (!is_dir('uploads/signatures')) {
|
||||
mkdir('uploads/signatures', 0777, true);
|
||||
}
|
||||
|
||||
// Save the image file
|
||||
if (file_put_contents($filePath, $signatureData)) {
|
||||
// Update the database
|
||||
|
||||
if ($conn->connect_error) {
|
||||
die(json_encode(['status' => 'error', 'message' => 'Database connection failed']));
|
||||
}
|
||||
|
||||
// Update the signature and indemnity acceptance in the membership application table
|
||||
$stmt = $conn->prepare("UPDATE membership_application SET sig = ?, accept_indemnity = 1 WHERE user_id = ?");
|
||||
$stmt->bind_param('si', $filePath, $user_id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
// Check the payment status
|
||||
$paymentStatus = checkMembershipPaymentStatus($user_id) ? 'PAID' : 'NOT_PAID';
|
||||
|
||||
// Respond with the appropriate redirect URL based on the payment status
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'message' => 'Signature saved successfully!',
|
||||
'paymentStatus' => $paymentStatus // Send payment status
|
||||
]);
|
||||
} else {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Database update failed']);
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
} else {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Failed to save signature']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Signature not provided']);
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
session_start();
|
||||
|
||||
// Get the trip_id from the request (ensure it's sanitized)
|
||||
$trip_id = isset($_POST['trip_id']) ? intval($_POST['trip_id']) : 0;
|
||||
|
||||
checkAndRedirectBooking($trip_id);
|
||||
|
||||
// Check available spaces
|
||||
$available_spaces = getAvailableSpaces($trip_id); // Assuming you're using MySQLi and the function is updated for it
|
||||
|
||||
if ($available_spaces < 1) {
|
||||
// Redirect back to trips.php with an error message
|
||||
header("Location: trips.php?error=fully_booked");
|
||||
exit();
|
||||
}
|
||||
|
||||
// Get user ID from session (assuming user is logged in)
|
||||
$user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
|
||||
|
||||
// Validate user session
|
||||
if (!$user_id) {
|
||||
echo "<script>alert('User is not logged in. Please log in to make a booking.'); window.location.href = 'login.php';</script>";
|
||||
exit();
|
||||
}
|
||||
$is_member = getUserMemberStatus($user_id);
|
||||
|
||||
// Check if the form has been submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// CSRF Token Validation
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
auditLog($user_id, 'CSRF_VALIDATION_FAILED', 'bookings', null, ['endpoint' => 'process_trip_booking.php']);
|
||||
http_response_code(403);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['error' => 'Security token validation failed.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Input variables from the form (use default values if not provided)
|
||||
$num_vehicles = validateInteger($_POST['vehicles'] ?? 1, 1, 10);
|
||||
if ($num_vehicles === false) $num_vehicles = 1;
|
||||
|
||||
$num_adults = validateInteger($_POST['adults'] ?? 1, 1, 20);
|
||||
if ($num_adults === false) $num_adults = 1;
|
||||
|
||||
$num_children = validateInteger($_POST['children'] ?? 0, 0, 20);
|
||||
if ($num_children === false) $num_children = 0;
|
||||
|
||||
$num_pensioners = validateInteger($_POST['pensioners'] ?? 0, 0, 20);
|
||||
if ($num_pensioners === false) $num_pensioners = 0;
|
||||
// Fetch trip costs from the database
|
||||
$query = "SELECT trip_name, cost_members, cost_nonmembers, cost_pensioner_member, cost_pensioner, booking_fee, start_date, end_date, trip_code FROM trips WHERE trip_id = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->bind_param('i', $trip_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Check if trip exists
|
||||
if ($result->num_rows === 0) {
|
||||
$response = ['error' => 'Trip not found.'];
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($response);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Fetch trip details
|
||||
$trip = $result->fetch_assoc();
|
||||
$trip_code = $trip['trip_code'];
|
||||
$trip_name = $trip['trip_name'];
|
||||
$cost_members = intval($trip['cost_members']);
|
||||
$cost_nonmembers = intval($trip['cost_nonmembers']);
|
||||
$cost_pensioner_member = intval($trip['cost_pensioner_member']);
|
||||
$cost_pensioner = intval($trip['cost_pensioner']);
|
||||
$member_discount = $cost_nonmembers - $cost_members;
|
||||
$member_discount_pensioner = $cost_pensioner - $cost_pensioner_member;
|
||||
$booking_fee = $trip['booking_fee'];
|
||||
$radioCost = $radio ? 50 : 0;
|
||||
$start_date = $trip['start_date']; // Start date of the trip
|
||||
$end_date = $trip['end_date']; // End date of the trip
|
||||
|
||||
|
||||
// Assume the membership status is determined elsewhere
|
||||
$is_member = getUserMemberStatus($user_id);
|
||||
|
||||
// Initialize total and discount amount
|
||||
$total = 0;
|
||||
$discountAmount = 0;
|
||||
|
||||
// Calculate total based on membership
|
||||
if ($is_member) {
|
||||
$total = (($num_adults + $num_children) * $cost_nonmembers) + ($num_pensioners * $cost_pensioner) + $radioCost + ($num_vehicles * $booking_fee);
|
||||
$discountAmount = (($num_adults + $num_children) * $member_discount) + ($num_pensioners * $member_discount_pensioner );
|
||||
$payment_amount = $total - $discountAmount;
|
||||
} else {
|
||||
$total = (($num_adults + $num_children) * $cost_nonmembers) + ($num_pensioners * $cost_pensioner) + $radioCost + ($num_vehicles * $booking_fee);
|
||||
$payment_amount = $total;
|
||||
}
|
||||
|
||||
$status = "AWAITING PAYMENT";
|
||||
$description = $trip_name;
|
||||
$type = 'trip';
|
||||
$payment_id = uniqid();
|
||||
// $eft_id = strtoupper(base_convert(time(), 10, 36)); // Convert timestamp to base36
|
||||
$eft_id = strtoupper($trip_code." ".getInitialSurname($user_id));
|
||||
|
||||
|
||||
// Insert booking into the database
|
||||
$sql = "INSERT INTO bookings (booking_type, user_id, from_date, to_date, num_vehicles, num_adults, num_children, total_amount, discount_amount, status, payment_id, trip_id, radio, eft_id, num_pensioners)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $conn->prepare($sql);
|
||||
|
||||
if (!$stmt) {
|
||||
die("Preparation failed: " . $conn->error);
|
||||
}
|
||||
|
||||
$stmt->bind_param('sissiiiddssiisi', $type, $user_id, $start_date, $end_date, $num_vehicles, $num_adults, $num_children, $total, $discountAmount, $status, $payment_id, $trip_id, $radio, $eft_id, $num_pensioners);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
// Get the generated booking_id
|
||||
$booking_id = $conn->insert_id;
|
||||
|
||||
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 {
|
||||
addEFT($eft_id, $booking_id, $user_id, $status, $payment_amount, $description);
|
||||
sendAdminNotification('New Trip Booking - '.getFullName($user_id), getFullName($user_id).' has booked for '.$description);
|
||||
header("Location: payment_confirmation.php?token=".encryptData($booking_id, $salt));
|
||||
exit(); // Ensure no further code is executed after the redirect
|
||||
}
|
||||
} else {
|
||||
// Handle error if insert fails and echo the MySQL error
|
||||
$error_message = $stmt->error;
|
||||
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 {
|
||||
echo "Invalid request.";
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
require_once "vendor/autoload.php";
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
// Create connection
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
// Check connection
|
||||
if ($conn->connect_error) {
|
||||
die("Connection failed: " . $conn->connect_error);
|
||||
}
|
||||
|
||||
|
||||
// Form processing
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// CSRF Token Validation
|
||||
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
||||
auditLog(null, 'CSRF_VALIDATION_FAILED', 'users', null, ['endpoint' => 'register_user.php']);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Security token validation failed. Please try again.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Check rate limiting on registration endpoint (by IP)
|
||||
$ip = getClientIPAddress();
|
||||
$cutoffTime = date('Y-m-d H:i:s', time() - (3600)); // Last hour
|
||||
|
||||
$stmt = $conn->prepare("SELECT COUNT(*) as count FROM audit_log WHERE action = 'REGISTRATION_ATTEMPT' AND ip_address = ? AND created_at > ?");
|
||||
$stmt->bind_param('ss', $ip, $cutoffTime);
|
||||
$stmt->execute();
|
||||
$stmt->bind_result($regAttempts);
|
||||
$stmt->fetch();
|
||||
$stmt->close();
|
||||
|
||||
// Allow max 5 registration attempts per IP per hour
|
||||
if ($regAttempts >= 5) {
|
||||
auditLog(null, 'REGISTRATION_RATE_LIMIT_EXCEEDED', 'users', null, ['ip' => $ip, 'attempts' => $regAttempts]);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Too many registration attempts. Please try again later.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Validate and sanitize first name
|
||||
$first_name = validateName($_POST['first_name'] ?? '');
|
||||
if ($first_name === false) {
|
||||
auditLog(null, 'REGISTRATION_INVALID_FIRST_NAME', 'users');
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid first name. Only letters, spaces, hyphens, and apostrophes allowed (2-100 characters).']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Validate and sanitize last name
|
||||
$last_name = validateName($_POST['last_name'] ?? '');
|
||||
if ($last_name === false) {
|
||||
auditLog(null, 'REGISTRATION_INVALID_LAST_NAME', 'users');
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid last name. Only letters, spaces, hyphens, and apostrophes allowed (2-100 characters).']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Validate and sanitize phone number
|
||||
$phone_number = validatePhoneNumber($_POST['phone_number'] ?? '');
|
||||
if ($phone_number === false) {
|
||||
auditLog(null, 'REGISTRATION_INVALID_PHONE', 'users');
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid phone number format.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Validate email
|
||||
$email = validateEmail($_POST['email'] ?? '');
|
||||
if ($email === false) {
|
||||
auditLog(null, 'REGISTRATION_INVALID_EMAIL', 'users');
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid email format.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$password = $_POST['password'] ?? '';
|
||||
$password_confirm = $_POST['password_confirm'] ?? '';
|
||||
|
||||
// Validate password strength (minimum 8 characters, must contain uppercase, lowercase, number, special char)
|
||||
if (strlen($password) < 8) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Password must be at least 8 characters long.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!preg_match('/[A-Z]/', $password) || !preg_match('/[a-z]/', $password) ||
|
||||
!preg_match('/[0-9]/', $password) || !preg_match('/[!@#$%^&*]/', $password)) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Password must contain uppercase, lowercase, number, and special character (!@#$%^&*).']);
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($password !== $password_confirm) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Passwords do not match.']);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Check if the email is already registered
|
||||
$stmt = $conn->prepare('SELECT user_id FROM users WHERE email = ?');
|
||||
$stmt->bind_param('s', $email);
|
||||
$stmt->execute();
|
||||
$stmt->store_result();
|
||||
|
||||
if ($stmt->num_rows > 0) {
|
||||
auditLog(null, 'REGISTRATION_EMAIL_EXISTS', 'users', null, ['email' => $email]);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Email is already registered.']);
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
exit();
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
// Hash password
|
||||
$hashed_password = password_hash($password, PASSWORD_BCRYPT);
|
||||
|
||||
// Generate email verification token
|
||||
$token = bin2hex(random_bytes(50));
|
||||
|
||||
// Prepare and execute query
|
||||
$stmt = $conn->prepare('INSERT INTO users (first_name, last_name, phone_number, email, password, token, is_verified, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
$is_verified = 0; // Not verified
|
||||
$type = 'credentials';
|
||||
$stmt->bind_param('ssssssis', $first_name, $last_name, $phone_number, $email, $hashed_password, $token, $is_verified, $type);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$newUser_id = $conn->insert_id;
|
||||
processLegacyMembership($newUser_id);
|
||||
auditLog($newUser_id, 'USER_REGISTRATION', 'users', $newUser_id, ['email' => $email]);
|
||||
|
||||
if (sendVerificationEmail($email, $first_name . ' ' . $last_name, $token)) {
|
||||
sendEmail($_ENV['ADMIN_EMAIL'], '4WDCSA: New User Registration', $first_name . ' ' . $last_name . ' (' . $email . ') has just created an account using Credentials.');
|
||||
echo json_encode(['status' => 'success', 'message' => 'Registration successful. Please check your email to verify your account.']);
|
||||
} else {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Failed to send verification email.']);
|
||||
}
|
||||
} else {
|
||||
auditLog(null, 'REGISTRATION_DATABASE_ERROR', 'users', null, ['email' => $email]);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Failed to register user.']);
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
$response = array('status' => 'error', 'message' => 'Something went wrong');
|
||||
|
||||
if (isset($_POST['email'])) {
|
||||
$email = $_POST['email'];
|
||||
|
||||
// Check if the email exists
|
||||
$sql = "SELECT user_id FROM users WHERE email = ?";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("s", $email);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
$user = $result->fetch_assoc();
|
||||
$user_id = $user['user_id'];
|
||||
|
||||
// Generate a unique token
|
||||
$token = bin2hex(random_bytes(50));
|
||||
|
||||
// Store the token and expiration time in the database
|
||||
$expiry = date("Y-m-d H:i:s", strtotime('+3 hour')); // Token expires in 1 hour
|
||||
$sql = "INSERT INTO password_resets (user_id, token, expires_at) VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE token = VALUES(token), expires_at = VALUES(expires_at)";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("iss", $user_id, $token, $expiry);
|
||||
$stmt->execute();
|
||||
|
||||
// Send the reset link to the user
|
||||
$reset_link = "https://www.4wdcsa.co.za/reset_password.php?token=$token";
|
||||
$subject = "Password Reset Request";
|
||||
$message = "Click the following link to reset your password: $reset_link";
|
||||
sendEmail($email, $subject, $message);
|
||||
|
||||
$response['status'] = 'success';
|
||||
$response['message'] = 'Password reset link has been sent to your email.';
|
||||
} else {
|
||||
$response['message'] = 'Email not found.';
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php include_once('connection.php');
|
||||
include_once('functions.php');
|
||||
require_once("env.php");
|
||||
<?php include_once('../config/connection.php');
|
||||
include_once('../config/functions.php');
|
||||
require_once("../config/env.php");
|
||||
session_start();
|
||||
$user_id = $_SESSION['user_id'] ?? null;
|
||||
|
||||
@@ -92,3 +92,4 @@ $stmt->close();
|
||||
|
||||
header("Location: campsites.php");
|
||||
?>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkAdmin();
|
||||
|
||||
?>
|
||||
@@ -223,4 +224,4 @@ if (!empty($bannerImages)) {
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkAdmin();
|
||||
|
||||
// Fetch all trips
|
||||
@@ -243,4 +244,4 @@ if (!empty($bannerImages)) {
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkAdmin();
|
||||
|
||||
?>
|
||||
@@ -223,4 +224,4 @@ if (!empty($bannerImages)) {
|
||||
<!-- Tour List Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkAdmin();
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['accept_indemnity'])) {
|
||||
@@ -234,4 +235,4 @@ if (!empty($bannerImages)) {
|
||||
<!-- Tour List Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkAdmin();
|
||||
|
||||
?>
|
||||
@@ -207,4 +208,4 @@ if (!empty($bannerImages)) {
|
||||
<!-- Tour List Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkAdmin();
|
||||
|
||||
// Fetch all trips
|
||||
@@ -236,4 +237,4 @@ if (!empty($bannerImages)) {
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkAdmin();
|
||||
// SQL query to fetch data
|
||||
$sql = "SELECT ip_address, user_id, page_url, referrer_url, visit_time, country FROM visitor_logs WHERE NOT (ip_address = '185.203.122.69' OR ip_address = '156.155.29.213') ORDER BY visit_time DESC";
|
||||
@@ -200,4 +201,4 @@ if (!empty($bannerImages)) {
|
||||
<!-- Tour List Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
checkSuperAdmin();
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkAdmin();
|
||||
// SQL query to fetch data
|
||||
$sql = "SELECT user_id, first_name, last_name, email, member, date_joined, token, is_verified, profile_pic FROM users";
|
||||
$result = $conn->query($sql);
|
||||
@@ -255,7 +256,7 @@ if (!empty($bannerImages)) {
|
||||
const name = this.dataset.name;
|
||||
const token = this.dataset.token;
|
||||
|
||||
fetch('resend_verification.php', {
|
||||
fetch('resend_verification', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -280,4 +281,4 @@ if (!empty($bannerImages)) {
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
require_once($rootPath . "/src/config/session.php");
|
||||
require_once($rootPath . "/src/config/connection.php");
|
||||
require_once($rootPath . "/src/config/functions.php");
|
||||
|
||||
// Prepare the SQL query to fetch bar tabs along with user details, including user_id
|
||||
$sql = "
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
|
||||
<?php
|
||||
require_once("connection.php");
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
require_once($rootPath . "/src/config/connection.php");
|
||||
|
||||
if (isset($_GET['tab_id'])) {
|
||||
$tab_id = (int) $_GET['tab_id']; // Convert to integer
|
||||
@@ -26,3 +27,4 @@ if (isset($_GET['tab_id'])) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Tab ID is required.']);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
require_once($rootPath . "/src/config/env.php");
|
||||
require_once($rootPath . "/src/config/session.php");
|
||||
require_once($rootPath . "/src/config/connection.php");
|
||||
require_once($rootPath . "/src/config/functions.php");
|
||||
|
||||
if ($conn->connect_error) {
|
||||
die(json_encode([])); // Return empty JSON on failure
|
||||
@@ -20,3 +21,4 @@ while ($row = $result->fetch_assoc()) {
|
||||
echo json_encode($users);
|
||||
$conn->close();
|
||||
?>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
include_once('connection.php');
|
||||
include_once('functions.php');
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
require_once($rootPath . "/src/config/env.php");
|
||||
include_once('../config/connection.php');
|
||||
include_once('../config/functions.php');
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
$stmt = $conn->prepare("SELECT
|
||||
@@ -35,3 +36,4 @@ while ($row = $result->fetch_assoc()) {
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($campsites);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
require_once($rootPath . "/src/config/env.php");
|
||||
require_once($rootPath . "/src/config/connection.php");
|
||||
|
||||
if (isset($_POST['tab_id'])) {
|
||||
$tab_id = (int) $_POST['tab_id']; // Ensure it's an integer
|
||||
@@ -20,3 +21,4 @@ if (isset($_POST['tab_id'])) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Missing tab ID.']);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
require_once 'google-client/vendor/autoload.php'; // Add this line for Google Client
|
||||
$rootPath = dirname(dirname(__DIR__));
|
||||
require_once($rootPath . "/src/config/env.php");
|
||||
require_once($rootPath . "/src/config/session.php");
|
||||
require_once($rootPath . "/src/config/connection.php");
|
||||
require_once($rootPath . "/src/config/functions.php");
|
||||
require_once($rootPath . '/google-client/vendor/autoload.php'); // Add this line for Google Client
|
||||
|
||||
// Check if connection is established
|
||||
if (!$conn) {
|
||||
@@ -142,3 +143,4 @@ if (isset($_POST['email']) && isset($_POST['password'])) {
|
||||
$conn->close();
|
||||
exit();
|
||||
?>
|
||||
|
||||
60
src/bootstrap.php
Normal file
60
src/bootstrap.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Bootstrap - Central configuration loader
|
||||
*
|
||||
* All PHP files should include this file first to set up:
|
||||
* - Path constants
|
||||
* - Database connection
|
||||
* - Session management
|
||||
* - Core functions
|
||||
*
|
||||
* Usage:
|
||||
* <?php require_once(__DIR__ . '/../../bootstrap.php'); ?>
|
||||
*
|
||||
* Then use constants:
|
||||
* - APP_ROOT: Root directory
|
||||
* - SRC_ROOT: src/ directory
|
||||
* - CONFIG_PATH: src/config/ directory
|
||||
* - CLASSES_PATH: src/classes/ directory
|
||||
* - COMPONENTS_PATH: components/ directory
|
||||
*
|
||||
* And use globals:
|
||||
* - $conn: MySQLi connection
|
||||
* - $db: DatabaseService instance
|
||||
*/
|
||||
|
||||
// Define root paths - adjust based on file location
|
||||
if (!defined('APP_ROOT')) {
|
||||
define('APP_ROOT', dirname(__DIR__));
|
||||
}
|
||||
if (!defined('SRC_ROOT')) {
|
||||
define('SRC_ROOT', APP_ROOT . '/src');
|
||||
}
|
||||
if (!defined('CONFIG_PATH')) {
|
||||
define('CONFIG_PATH', SRC_ROOT . '/config');
|
||||
}
|
||||
if (!defined('CLASSES_PATH')) {
|
||||
define('CLASSES_PATH', SRC_ROOT . '/classes');
|
||||
}
|
||||
if (!defined('COMPONENTS_PATH')) {
|
||||
define('COMPONENTS_PATH', APP_ROOT . '/components');
|
||||
}
|
||||
if (!defined('ASSETS_PATH')) {
|
||||
define('ASSETS_PATH', APP_ROOT . '/assets');
|
||||
}
|
||||
|
||||
// Load environment variables
|
||||
require_once(CONFIG_PATH . '/env.php');
|
||||
|
||||
// Load database connection
|
||||
require_once(CONFIG_PATH . '/connection.php');
|
||||
|
||||
// Load session management
|
||||
require_once(CONFIG_PATH . '/session.php');
|
||||
|
||||
// Load core functions
|
||||
require_once(CONFIG_PATH . '/functions.php');
|
||||
|
||||
// Optional: Set global timezone
|
||||
date_default_timezone_set($_ENV['TIMEZONE'] ?? 'Africa/Johannesburg');
|
||||
?>
|
||||
27
src/config/connection.php
Normal file
27
src/config/connection.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
// Disable mysqli exceptions so we can handle connection errors gracefully
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
|
||||
$dbhost = $_ENV['DB_HOST'];
|
||||
$dbuser = $_ENV['DB_USER'];
|
||||
$dbpass = $_ENV['DB_PASS'];
|
||||
$dbname = $_ENV['DB_NAME'];
|
||||
$salt = $_ENV['SALT'];
|
||||
|
||||
// echo "hello. ". $dbhost;
|
||||
|
||||
if(!$conn = @mysqli_connect($dbhost, $dbuser, $dbpass, $dbname)){
|
||||
// Log the error to file instead of stderr (no red output)
|
||||
@error_log("Database Connection Error: " . mysqli_connect_error(), 3, dirname(__DIR__) . "/logs/db_errors.log");
|
||||
$conn = null;
|
||||
$db = null;
|
||||
} else {
|
||||
date_default_timezone_set('Africa/Johannesburg');
|
||||
|
||||
// Initialize DatabaseService for modern queries
|
||||
require_once(__DIR__ . '/../../classes/DatabaseService.php');
|
||||
$db = new DatabaseService($conn);
|
||||
}
|
||||
|
||||
|
||||
6
src/config/env.php
Normal file
6
src/config/env.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../../');
|
||||
$dotenv->load();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once "vendor/autoload.php";
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
@@ -14,13 +14,16 @@ function openDatabaseConnection()
|
||||
$dbname = $_ENV['DB_NAME'];
|
||||
$salt = $_ENV['SALT'];
|
||||
|
||||
// Disable mysqli exceptions
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
|
||||
// Create connection
|
||||
$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
|
||||
$conn = @new mysqli($dbhost, $dbuser, $dbpass, $dbname);
|
||||
|
||||
// Check connection
|
||||
if ($conn->connect_error) {
|
||||
die("Connection failed: " . $conn->connect_error);
|
||||
@error_log("Database Connection Error in openDatabaseConnection: " . $conn->connect_error, 3, dirname(dirname(__DIR__)) . "/logs/db_errors.log");
|
||||
return null;
|
||||
}
|
||||
|
||||
return $conn;
|
||||
@@ -396,6 +399,11 @@ function getUserMemberStatus($user_id)
|
||||
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
// Return early if no database connection
|
||||
if ($conn === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 1: Check if the user is a member
|
||||
$queryUser = "SELECT member FROM users WHERE user_id = ?";
|
||||
$stmtUser = $conn->prepare($queryUser);
|
||||
@@ -481,6 +489,11 @@ function getUserMemberStatusPending($user_id)
|
||||
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
// Return early if no database connection
|
||||
if ($conn === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 1: Check if the user is a member
|
||||
$queryUser = "SELECT member FROM users WHERE user_id = ?";
|
||||
$stmtUser = $conn->prepare($queryUser);
|
||||
@@ -995,6 +1008,11 @@ function getUserRole()
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Return early if no database connection
|
||||
if ($conn === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if the user_id is set in the session
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
return null; // or handle the case where the user is not logged in
|
||||
@@ -1544,6 +1562,11 @@ function countUpcomingTrips()
|
||||
// Open database connection
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
// Return 0 if no database connection
|
||||
if ($conn === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("SELECT COUNT(*) AS trip_count FROM trips WHERE published = ? AND start_date > CURDATE()");
|
||||
$published = 1;
|
||||
$stmt->bind_param("i", $published);
|
||||
@@ -1567,6 +1590,11 @@ function logVisitor()
|
||||
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
// Return early if no database connection
|
||||
if ($conn === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Collect visitor data
|
||||
$ip_address = getUserIP();
|
||||
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
|
||||
@@ -2652,3 +2680,125 @@ function auditLog($user_id, $action, $resource_type = null, $resource_id = null,
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL Helper - Map page names to file paths
|
||||
* Centralizes all internal links for easy management
|
||||
*
|
||||
* Usage: url('login') → /src/pages/auth/login.php
|
||||
*/
|
||||
function url($page) {
|
||||
static $map = [
|
||||
// Home & Main
|
||||
'home' => '/index.php',
|
||||
'index' => '/index.php',
|
||||
|
||||
// Auth Pages
|
||||
'login' => '/src/pages/auth/login.php',
|
||||
'register' => '/src/pages/auth/register.php',
|
||||
'forgot' => '/src/pages/auth/forgot_password.php',
|
||||
'forgot_password' => '/src/pages/auth/forgot_password.php',
|
||||
'reset_password' => '/src/pages/auth/reset_password.php',
|
||||
'verify' => '/src/pages/auth/verify.php',
|
||||
'resend_verification' => '/src/pages/auth/resend_verification.php',
|
||||
'change_password' => '/src/pages/auth/change_password.php',
|
||||
'update_password' => '/src/pages/auth/update_password.php',
|
||||
|
||||
// Membership Pages
|
||||
'membership' => '/src/pages/memberships/membership.php',
|
||||
'membership_details' => '/src/pages/memberships/membership_details.php',
|
||||
'membership_application' => '/src/pages/memberships/membership_application.php',
|
||||
'membership_payment' => '/src/pages/memberships/membership_payment.php',
|
||||
'renew_membership' => '/src/pages/memberships/renew_membership.php',
|
||||
'member_info' => '/src/pages/memberships/member_info.php',
|
||||
|
||||
// Booking Pages
|
||||
'bookings' => '/src/pages/bookings/bookings.php',
|
||||
'campsites' => '/src/pages/bookings/campsites.php',
|
||||
'campsite_booking' => '/src/pages/bookings/campsite_booking.php',
|
||||
'trips' => '/src/pages/bookings/trips.php',
|
||||
'trip_details' => '/src/pages/bookings/trip-details.php',
|
||||
'course_details' => '/src/pages/bookings/course_details.php',
|
||||
'driver_training' => '/src/pages/bookings/driver_training.php',
|
||||
|
||||
// Shop Pages
|
||||
'view_cart' => '/src/pages/shop/view_cart.php',
|
||||
'add_to_cart' => '/src/pages/shop/add_to_cart.php',
|
||||
'bar_tabs' => '/src/pages/shop/bar_tabs.php',
|
||||
'payment_confirmation' => '/src/pages/shop/payment_confirmation.php',
|
||||
'confirm' => '/src/pages/shop/confirm.php',
|
||||
'confirm2' => '/src/pages/shop/confirm2.php',
|
||||
|
||||
// Events & Blog
|
||||
'events' => '/src/pages/events/events.php',
|
||||
'blog' => '/src/pages/events/blog.php',
|
||||
'blog_details' => '/src/pages/events/blog_details.php',
|
||||
'best_of_eastern_cape' => '/src/pages/events/best_of_the_eastern_cape_2024.php',
|
||||
'agm_minutes' => '/src/pages/events/2025_agm_minutes.php',
|
||||
'agm_content' => '/src/pages/events/agm_content.php',
|
||||
'instapage' => '/src/pages/events/instapage.php',
|
||||
|
||||
// Other Pages
|
||||
'about' => '/src/pages/other/about.php',
|
||||
'contact' => '/src/pages/other/contact.php',
|
||||
'privacy' => '/src/pages/other/privacy_policy.php',
|
||||
'privacy_policy' => '/src/pages/other/privacy_policy.php',
|
||||
'404' => '/src/pages/other/404.php',
|
||||
'account_settings' => '/src/pages/other/account_settings.php',
|
||||
'rescue_recovery' => '/src/pages/other/rescue_recovery.php',
|
||||
'bush_mechanics' => '/src/pages/other/bush_mechanics.php',
|
||||
'indemnity' => '/src/pages/other/indemnity.php',
|
||||
'indemnity_waiver' => '/src/pages/other/indemnity_waiver.php',
|
||||
'basic_indemnity' => '/src/pages/other/basic_indemnity.php',
|
||||
'view_indemnity' => '/src/pages/other/view_indemnity.php',
|
||||
|
||||
// Admin Pages (accessible only to admins)
|
||||
'admin_members' => '/src/admin/admin_members.php',
|
||||
'admin_payments' => '/src/admin/admin_payments.php',
|
||||
'admin_web_users' => '/src/admin/admin_web_users.php',
|
||||
'admin_course_bookings' => '/src/admin/admin_course_bookings.php',
|
||||
'admin_camp_bookings' => '/src/admin/admin_camp_bookings.php',
|
||||
'admin_trip_bookings' => '/src/admin/admin_trip_bookings.php',
|
||||
'admin_visitors' => '/src/admin/admin_visitors.php',
|
||||
'admin_efts' => '/src/admin/admin_efts.php',
|
||||
'add_campsite' => '/src/admin/add_campsite.php',
|
||||
|
||||
// API/AJAX Endpoints
|
||||
'fetch_users' => '/src/api/fetch_users.php',
|
||||
'fetch_drinks' => '/src/api/fetch_drinks.php',
|
||||
'fetch_bar_tabs' => '/src/api/fetch_bar_tabs.php',
|
||||
'get_campsites' => '/src/api/get_campsites.php',
|
||||
'get_tab_total' => '/src/api/get_tab_total.php',
|
||||
'google_validate_login' => '/src/api/google_validate_login.php',
|
||||
|
||||
// Processors
|
||||
'validate_login' => '/src/processors/validate_login.php',
|
||||
'register_user' => '/src/processors/register_user.php',
|
||||
'process_application' => '/src/processors/process_application.php',
|
||||
'process_booking' => '/src/processors/process_booking.php',
|
||||
'process_camp_booking' => '/src/processors/process_camp_booking.php',
|
||||
'process_course_booking' => '/src/processors/process_course_booking.php',
|
||||
'process_trip_booking' => '/src/processors/process_trip_booking.php',
|
||||
'process_membership_payment' => '/src/processors/process_membership_payment.php',
|
||||
'process_payments' => '/src/processors/process_payments.php',
|
||||
'process_eft' => '/src/processors/process_eft.php',
|
||||
'submit_order' => '/src/processors/submit_order.php',
|
||||
'submit_pop' => '/src/processors/submit_pop.php',
|
||||
'process_signature' => '/src/processors/process_signature.php',
|
||||
'create_bar_tab' => '/src/processors/create_bar_tab.php',
|
||||
'update_application' => '/src/processors/update_application.php',
|
||||
'update_user' => '/src/processors/update_user.php',
|
||||
'upload_profile_picture' => '/src/processors/upload_profile_picture.php',
|
||||
'send_reset_link' => '/src/processors/send_reset_link.php',
|
||||
'logout' => '/src/processors/logout.php',
|
||||
];
|
||||
|
||||
// Return mapped URL or fallback to simple filename
|
||||
if (isset($map[$page])) {
|
||||
return $map[$page];
|
||||
}
|
||||
|
||||
// Fallback: assume it's a root-level file
|
||||
return '/' . $page . '.php';
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
require_once($rootPath . '/src/config/env.php');
|
||||
require_once($rootPath . '/src/config/session.php');
|
||||
require_once($rootPath . '/src/config/connection.php');
|
||||
require_once($rootPath . '/src/config/functions.php');
|
||||
|
||||
$response = array('status' => 'error', 'message' => 'Something went wrong');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php') ?>
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php') ?>
|
||||
<style>
|
||||
@media (min-width: 991px) {
|
||||
.container {
|
||||
@@ -56,7 +56,7 @@ include_once('header.php') ?>
|
||||
event.preventDefault(); // Prevent the default form submission
|
||||
|
||||
$.ajax({
|
||||
url: 'send_reset_link.php',
|
||||
url: 'send_reset_link',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
dataType: 'json',
|
||||
@@ -81,4 +81,4 @@ include_once('header.php') ?>
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,8 +1,10 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
// Determine the correct path to header.php based on file location
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
// Include Google login PHP logic
|
||||
require_once 'google-client/vendor/autoload.php';
|
||||
require_once $rootPath . '/google-client/vendor/autoload.php';
|
||||
|
||||
$client = new Google_Client();
|
||||
$client->setClientId('948441222188-8qhboq2urr8o9n35mc70s5h2nhd52v0m.apps.googleusercontent.com');
|
||||
@@ -41,7 +43,7 @@ $login_url = $client->createAuthUrl();
|
||||
|
||||
<div class="">
|
||||
<div class="comment-form bgc-lighter z-1 rel mb-30 rmb-55">
|
||||
<form id="loginForm" class="loginForm" name="loginForm" action="assets/php/form-process.php" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form id="loginForm" class="loginForm" name="loginForm" action="validate_login" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title">
|
||||
<h2>Log in</h2>
|
||||
<div style="text-align: center;" id="responseMessage"></div> <!-- Message display area -->
|
||||
@@ -86,7 +88,7 @@ $login_url = $client->createAuthUrl();
|
||||
<button type="submit" class="theme-btn style-two" style="width:100%;">Log In</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-20" style="text-align: center;">Don't have an account? <a href="register.php"><b>Register here.</b> </a>| <a href="forgot_password.php"><b>Forgot your password?</b></a></div>
|
||||
<div class="pt-20" style="text-align: center;">Don't have an account? <a href="register"><b>Register here.</b> </a>| <a href="forgot_password"><b>Forgot your password?</b></a></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -102,13 +104,13 @@ $login_url = $client->createAuthUrl();
|
||||
event.preventDefault(); // Prevent the default form submission
|
||||
|
||||
$.ajax({
|
||||
url: 'validate_login.php',
|
||||
url: '<?= url("validate_login") ?>',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
if (response.status === 'success') {
|
||||
window.location.href = 'index.php';
|
||||
window.location.href = '<?= url("index") ?>';
|
||||
} else {
|
||||
$('#responseMessage').html('<div class="alert alert-danger">' + response.message + '</div>');
|
||||
}
|
||||
@@ -121,4 +123,4 @@ $login_url = $client->createAuthUrl();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php') ?>
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php') ?>
|
||||
<style>
|
||||
@media (min-width: 991px) {
|
||||
.container {
|
||||
@@ -27,7 +27,7 @@ include_once('header.php') ?>
|
||||
<div class="row align-items-center">
|
||||
<div class="">
|
||||
<div class="comment-form bgc-lighter z-1 rel mb-30 rmb-55">
|
||||
<form id="registerForm" name="registerForm" action="register_user.php" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form id="registerForm" name="registerForm" action="register_user" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title">
|
||||
<h2>Register</h2>
|
||||
|
||||
@@ -91,7 +91,7 @@ include_once('header.php') ?>
|
||||
</div>
|
||||
<div id="responseMessage"></div> <!-- Message display area -->
|
||||
</div>
|
||||
<div class="pt-20">Already have an account? <a href="login.php"><b>Log in here.</b></a></div>
|
||||
<div class="pt-20">Already have an account? <a href="login"><b>Log in here.</b></a></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -150,7 +150,7 @@ include_once('header.php') ?>
|
||||
|
||||
// If validation passes, proceed with AJAX
|
||||
$.ajax({
|
||||
url: 'register_user.php',
|
||||
url: 'register_user',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
dataType: 'json',
|
||||
@@ -171,4 +171,4 @@ include_once('header.php') ?>
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
require_once "vendor/autoload.php";
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
require_once($rootPath . '/src/config/connection.php');
|
||||
require_once($rootPath . '/src/config/functions.php');
|
||||
require_once($rootPath . '/vendor/autoload.php');
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
$token = $_GET['token'] ?? '';
|
||||
|
||||
if (empty($token)) {
|
||||
@@ -39,7 +39,7 @@ $user_id = $user['user_id'];
|
||||
|
||||
<div class="">
|
||||
<div class="comment-form bgc-lighter z-1 rel mb-30 rmb-55">
|
||||
<form id="changePasswordForm" class="loginForm" name="changePasswordForm" action="update_password.php" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form id="changePasswordForm" class="loginForm" name="changePasswordForm" action="update_password" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title">
|
||||
<h2>Reset Password</h2>
|
||||
<div class="pt-20" style="text-align: center;" id="responseMessage"></div> <!-- Message display area -->
|
||||
@@ -87,7 +87,7 @@ $user_id = $user['user_id'];
|
||||
event.preventDefault(); // Prevent default form submission
|
||||
|
||||
$.ajax({
|
||||
url: 'update_password.php',
|
||||
url: 'update_password',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function(response) {
|
||||
@@ -110,4 +110,4 @@ $user_id = $user['user_id'];
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.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');
|
||||
|
||||
$response = array('status' => 'error', 'message' => 'Something went wrong');
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.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');
|
||||
|
||||
// Create connection
|
||||
$conn = openDatabaseConnection();
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkUserSession();
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
@@ -61,7 +62,7 @@ $user_id = $_SESSION['user_id'];
|
||||
<?php
|
||||
$pageTitle = 'My Bookings';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Tour List Area start -->
|
||||
@@ -266,7 +267,7 @@ $user_id = $_SESSION['user_id'];
|
||||
<div class="destination-footer">
|
||||
<span class="price"><span>Booking Total: R ' . number_format($amount, 2) . '</span></span>';
|
||||
if ($status == "AWAITING PAYMENT") {
|
||||
echo '<a href="payment_confirmation.php?token=' . encryptData($booking_id, $salt) . '" class="theme-btn style-two style-three">
|
||||
echo '<a href="' . url('payment_confirmation') . '?token=' . encryptData($booking_id, $salt) . '" class="theme-btn style-two style-three">
|
||||
<span data-hover="PAYMENT INFO">' . $status . '</span>
|
||||
</a>';
|
||||
} else {
|
||||
@@ -321,4 +322,4 @@ $user_id = $_SESSION['user_id'];
|
||||
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
checkUserSession();
|
||||
?>
|
||||
|
||||
@@ -78,7 +78,7 @@ checkUserSession();
|
||||
</div>
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<h5 class="widget-title">Book your Campsite</h5>
|
||||
<form action="process_camp_booking.php" method="POST">
|
||||
<form action="process_camp_booking" method="POST">
|
||||
<div class="date mb-25">
|
||||
<b>From Date</b>
|
||||
<input type="date" id="from_date" name="from_date">
|
||||
@@ -214,4 +214,4 @@ checkUserSession();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
|
||||
$conn = openDatabaseConnection();
|
||||
$stmt = $conn->prepare("SELECT * FROM campsites");
|
||||
@@ -30,7 +31,7 @@ while ($row = $result->fetch_assoc()) {
|
||||
<?php
|
||||
$pageTitle = 'Campsites';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Tour List Area start -->
|
||||
@@ -48,7 +49,7 @@ while ($row = $result->fetch_assoc()) {
|
||||
</section>
|
||||
<div class="modal fade" id="addCampsiteModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<form id="addCampsiteForm" method="POST" action="add_campsite.php" enctype="multipart/form-data">
|
||||
<form id="addCampsiteForm" method="POST" action="add_campsite" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@@ -191,4 +192,4 @@ while ($row = $result->fetch_assoc()) {
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
|
||||
// SQL query to fetch dates for driver training
|
||||
$stmt = $conn->prepare("SELECT course_id, date FROM courses WHERE course_type = ?");
|
||||
@@ -15,7 +16,7 @@ $result = $stmt->get_result();
|
||||
<?php
|
||||
$pageTitle = 'Course Details';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
@@ -299,4 +300,4 @@ $result = $stmt->get_result();
|
||||
<!-- Shop Details Area end -->
|
||||
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkUserSession();
|
||||
|
||||
// SQL query to fetch dates for driver training
|
||||
@@ -29,7 +30,7 @@ $page_id = 'driver_training';
|
||||
</style><?php
|
||||
$pageTitle = 'Driver Training';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Product Details Start -->
|
||||
@@ -81,7 +82,7 @@ $page_id = 'driver_training';
|
||||
<hr class="mt-40">
|
||||
<div class="blog-sidebar tour-sidebar">
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form action="process_course_booking.php" method="POST">
|
||||
<form action="process_course_booking" method="POST">
|
||||
<ul class="tickets clearfix">
|
||||
<li>
|
||||
Select Date
|
||||
@@ -172,7 +173,7 @@ $page_id = 'driver_training';
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</button>
|
||||
<div class="text-center">
|
||||
<a href="contact.php">Need some help?</a>
|
||||
<a href="contact">Need some help?</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -385,4 +386,4 @@ $page_id = 'driver_training';
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
checkUserSession();
|
||||
|
||||
if (!isset($_GET['token']) || empty($_GET['token'])) {
|
||||
@@ -152,7 +152,7 @@ $conn->close();
|
||||
</style>
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
?>
|
||||
|
||||
<style>
|
||||
@@ -189,7 +189,7 @@ include_once('header.php');
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50"><?php echo $trip_name; ?></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"><a href="index">Home</a></li>
|
||||
<li class="breadcrumb-item active">4WDCSA Trips</li>
|
||||
</ol>
|
||||
</nav>
|
||||
@@ -437,7 +437,7 @@ include_once('header.php');
|
||||
<div class="blog-sidebar tour-sidebar">
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<h5 class="widget-title">Book your Trip</h5>
|
||||
<form action="process_trip_booking.php" method="POST">
|
||||
<form action="process_trip_booking" method="POST">
|
||||
<input type="hidden" name="trip_id" id="trip_id" value="<?php echo $trip_id; ?>">
|
||||
<ul class="radio-filter pt-5">
|
||||
<li>
|
||||
@@ -560,7 +560,7 @@ include_once('header.php');
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<div class="text-center">
|
||||
<a href="contact.php">Need some help?</a>
|
||||
<a href="contact">Need some help?</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -673,4 +673,4 @@ include_once('header.php');
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
// Determine the correct path to header.php based on file location
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
?>
|
||||
|
||||
<style>
|
||||
@@ -19,7 +21,7 @@ include_once('header.php');
|
||||
<?php
|
||||
$pageTitle = 'Trips';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Tour List Area start -->
|
||||
@@ -136,4 +138,4 @@ include_once('header.php');
|
||||
<!-- Tour List Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
$page_id = 'agm_minutes';
|
||||
?>
|
||||
|
||||
@@ -74,7 +75,7 @@ $page_id = 'agm_minutes';
|
||||
<?php
|
||||
$pageTitle = '2025 AGM Minutes';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Blog Detaisl Area start -->
|
||||
@@ -101,7 +102,7 @@ $page_id = 'agm_minutes';
|
||||
<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">Reports</a>
|
||||
<a href="blog">Reports</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -254,4 +255,4 @@ $page_id = 'agm_minutes';
|
||||
<!-- Blog Detaisl Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
$page_id = 'best_0f_ec';
|
||||
?>
|
||||
|
||||
@@ -74,7 +75,7 @@ $page_id = 'best_0f_ec';
|
||||
<?php
|
||||
$pageTitle = 'Best of the Eastern Cape 2024';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Blog Detaisl Area start -->
|
||||
@@ -336,10 +337,10 @@ $page_id = 'best_0f_ec';
|
||||
<h4>Richard M. Fudge</h4>
|
||||
<p>The world is a book, and those who do not travel read only one page. Every journey we undertake is a chapter filled with lessons, experiences, and stories.</p>
|
||||
<div class="social-icons">
|
||||
<a href="contact.php"><i class="fab fa-facebook-f"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-twitter"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-linkedin-in"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-instagram"></i></a>
|
||||
<a href="contact"><i class="fab fa-facebook-f"></i></a>
|
||||
<a href="contact"><i class="fab fa-twitter"></i></a>
|
||||
<a href="contact"><i class="fab fa-linkedin-in"></i></a>
|
||||
<a href="contact"><i class="fab fa-instagram"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -431,4 +432,4 @@ $page_id = 'best_0f_ec';
|
||||
<!-- Blog Detaisl Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php') ?>
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
?>
|
||||
|
||||
<style>
|
||||
.image {
|
||||
@@ -31,7 +33,7 @@ include_once('header.php') ?>
|
||||
</style><?php
|
||||
$pageTitle = 'Blogs';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
|
||||
@@ -89,7 +91,7 @@ include_once('header.php') ?>
|
||||
<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>
|
||||
<a href="' . url('blog') . '" class="category">' . $category . '</a>
|
||||
<h5><a href="' . $blog_link . '">' . $title . '</a></h5>
|
||||
<ul class="blog-meta">
|
||||
<li><i class="far fa-calendar-alt"></i> <a href="#">' . $date . '</a></li>
|
||||
@@ -203,7 +205,7 @@ include_once('header.php') ?>
|
||||
<div class="content text-white">
|
||||
<span class="h6">Explore The World</span>
|
||||
<h3>Become a Member</h3>
|
||||
<a href="membership.php" class="theme-btn style-two bgc-secondary">
|
||||
<a href="<?= url('membership') ?>" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Explore Now">Join Now</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
@@ -223,4 +225,4 @@ include_once('header.php') ?>
|
||||
<!-- Blog List Area end -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php') ?>
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
?>
|
||||
|
||||
<style>
|
||||
.image {
|
||||
@@ -34,7 +36,7 @@ include_once('header.php') ?>
|
||||
<?php
|
||||
$pageTitle = 'Blog Details';
|
||||
$breadcrumbs = [['Home' => 'index.php'], ['Blogs' => 'blog.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
|
||||
@@ -191,10 +193,10 @@ include_once('header.php') ?>
|
||||
<h4>Richard M. Fudge</h4>
|
||||
<p>The world is a book, and those who do not travel read only one page. Every journey we undertake is a chapter filled with lessons, experiences, and stories.</p>
|
||||
<div class="social-icons">
|
||||
<a href="contact.php"><i class="fab fa-facebook-f"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-twitter"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-linkedin-in"></i></a>
|
||||
<a href="contact.php"><i class="fab fa-instagram"></i></a>
|
||||
<a href="contact"><i class="fab fa-facebook-f"></i></a>
|
||||
<a href="contact"><i class="fab fa-twitter"></i></a>
|
||||
<a href="contact"><i class="fab fa-linkedin-in"></i></a>
|
||||
<a href="contact"><i class="fab fa-instagram"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -442,7 +444,7 @@ include_once('header.php') ?>
|
||||
<ul class="list-style-three">
|
||||
<li><a href="about.html">About Company</a></li>
|
||||
<li><a href="blog.html">Community Blog</a></li>
|
||||
<li><a href="contact.php">Jobs and Careers</a></li>
|
||||
<li><a href="contact">Jobs and Careers</a></li>
|
||||
<li><a href="blog.html">latest News Blog</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php') ?>
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
?>
|
||||
|
||||
<style>
|
||||
.image {
|
||||
@@ -59,7 +61,7 @@ include_once('header.php') ?>
|
||||
<?php
|
||||
$pageTitle = 'Events';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Tour List Area start -->
|
||||
@@ -191,4 +193,4 @@ include_once('header.php') ?>
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
include_once('header02.php');
|
||||
$headerStyle = 'light';
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
checkAdmin();
|
||||
if (!isset($_GET['token']) || empty($_GET['token'])) {
|
||||
die("Invalid request.");
|
||||
@@ -277,4 +278,4 @@ $stmt->close();
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,24 +1,24 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
|
||||
// Assuming you have the user ID stored in the session
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
if (isset($_SESSION['user_id']) && isset($conn) && $conn !== null) {
|
||||
$user_id = $_SESSION['user_id'];
|
||||
}
|
||||
|
||||
// Fetch user data from the database
|
||||
|
||||
$sql = "SELECT * FROM users WHERE user_id = ?";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("i", $user_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$user = $result->fetch_assoc();
|
||||
} else {
|
||||
$user = null;
|
||||
}
|
||||
?><?php
|
||||
$pageTitle = 'Membership';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once(dirname(dirname(dirname(__DIR__))) . '/components/banner.php');
|
||||
?>
|
||||
<!-- Contact Form Area start -->
|
||||
<section class="about-us-area py-100 rpb-90 rel z-1">
|
||||
@@ -42,7 +42,7 @@ $user = $result->fetch_assoc();
|
||||
<h2>R 2,500/year</h2>
|
||||
<p>We go above and beyond to make your travel dreams reality hidden gems and must-see
|
||||
attractions</p>
|
||||
<a href="membership_application.php" class="theme-btn mt-10 style-two">
|
||||
<a href="membership_application" class="theme-btn mt-10 style-two">
|
||||
<span data-hover="Start Application">Start Application</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
@@ -70,4 +70,4 @@ $user = $result->fetch_assoc();
|
||||
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkUserSession();
|
||||
|
||||
// Assuming you have the user ID stored in the session
|
||||
@@ -23,7 +24,7 @@ $user = $result->fetch_assoc();
|
||||
?><?php
|
||||
$pageTitle = 'Membership Application';
|
||||
$breadcrumbs = [['Home' => 'index.php'], ['Membership' => 'membership.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
|
||||
@@ -33,7 +34,7 @@ $user = $result->fetch_assoc();
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="comment-form bgc-lighter z-1 rel mb-30 rmb-55">
|
||||
<form id="registerForm" name="registerForm" action="process_application.php" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form id="registerForm" name="registerForm" action="process_application" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||
<div class="section-title">
|
||||
<div id="responseMessage"></div> <!-- Message display area -->
|
||||
@@ -280,4 +281,4 @@ $user = $result->fetch_assoc();
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
include_once('header02.php');
|
||||
$headerStyle = 'light';
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
|
||||
// Ensure the user is logged in
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
@@ -186,7 +187,7 @@ if (empty($application['id_number'])) {
|
||||
<td><?php echo htmlspecialchars($membership['payment_amount']); ?></td>
|
||||
<td><?php echo htmlspecialchars($membership['payment_id']); ?></td>
|
||||
<?php if ($membership['payment_status'] == "PENDING") { ?>
|
||||
<td><a href='membership_payment.php' class='theme-btn style-two style-three' style='padding: 0px 14px;'><span data-hover='VIEW PAYMENT INFO'>AWAITING PAYMENT</span></a></td>
|
||||
<td><a href='membership_payment' class='theme-btn style-two style-three' style='padding: 0px 14px;'><span data-hover='VIEW PAYMENT INFO'>AWAITING PAYMENT</span></a></td>
|
||||
<?php } else { ?>
|
||||
<td><?php echo htmlspecialchars($membership['payment_status']); ?></td>
|
||||
<?php } ?>
|
||||
@@ -209,13 +210,13 @@ if (empty($application['id_number'])) {
|
||||
|
||||
if ($membership_end_date && strtotime($today) > strtotime($membership_end_date)) {
|
||||
echo '
|
||||
<a href="renew_membership.php" class="theme-btn style-two bgc-secondary" style="width:100%; margin-top: 20px; background-color: #63ab45; padding: 10px 20px; color: white; text-decoration: none; border-radius: 25px;">
|
||||
<a href="renew_membership" class="theme-btn style-two bgc-secondary" style="width:100%; margin-top: 20px; background-color: #63ab45; padding: 10px 20px; color: white; text-decoration: none; border-radius: 25px;">
|
||||
<span data-hover="Renew Membership">Renew Membership</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>';
|
||||
}
|
||||
?>
|
||||
<form id="infoForm" name="registerForm" action="update_application.php" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form id="infoForm" name="registerForm" action="update_application" method="post" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title">
|
||||
<div id="responseMessage"></div> <!-- Message display area -->
|
||||
</div>
|
||||
@@ -475,7 +476,7 @@ if (empty($application['id_number'])) {
|
||||
formData.append('profile_picture', $('#profile_picture')[0].files[0]);
|
||||
|
||||
$.ajax({
|
||||
url: 'upload_profile_picture.php',
|
||||
url: 'upload_profile_picture',
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
contentType: false,
|
||||
@@ -508,7 +509,7 @@ if (empty($application['id_number'])) {
|
||||
event.preventDefault(); // Prevent default form submission
|
||||
|
||||
$.ajax({
|
||||
url: 'update_user.php',
|
||||
url: 'update_user',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function(response) {
|
||||
@@ -535,7 +536,7 @@ if (empty($application['id_number'])) {
|
||||
event.preventDefault(); // Prevent default form submission
|
||||
|
||||
$.ajax({
|
||||
url: 'change_password.php',
|
||||
url: 'change_password',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function(response) {
|
||||
@@ -558,4 +559,4 @@ if (empty($application['id_number'])) {
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
// Assuming you have the user ID stored in the session
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
$user_id = $_SESSION['user_id'];
|
||||
@@ -70,7 +71,7 @@ $conn->close();
|
||||
?><?php
|
||||
$pageTitle = 'Membership Payment';
|
||||
$breadcrumbs = [['Home' => 'index.php'], ['Membership' => 'membership.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
<!-- Contact Form Area start -->
|
||||
<section class="about-us-area py-100 rpb-90 rel z-1">
|
||||
@@ -85,7 +86,7 @@ $conn->close();
|
||||
<p>Your invoice has been sent to <b><?php echo htmlspecialchars($user_email); ?></b>. Please upload your proof of payment below.</p>
|
||||
<h5>Payment Details:</h5>
|
||||
<p>The Four Wheel Drive Club of Southern Africa<br>FNB<br>Account Number: 58810022334<br>Branch code: 250655<br>Reference: <?php echo htmlspecialchars($eft_id); ?><br>Amount: R <?php echo number_format($payment_amount, 2); ?></p>
|
||||
<a href="submit_pop.php" class="theme-btn style-two style-three" style="width:100%;">
|
||||
<a href="submit_pop" class="theme-btn style-two style-three" style="width:100%;">
|
||||
<span data-hover="Submit Proof of Payment">Submit Proof of Payment</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
@@ -101,4 +102,4 @@ $conn->close();
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
?>
|
||||
|
||||
|
||||
@@ -43,4 +43,4 @@ include_once('header.php');
|
||||
</section>
|
||||
<!-- 404 Error Area end -->
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
284
src/pages/other/about.php
Normal file
284
src/pages/other/about.php
Normal file
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
// Determine the correct path to header.php based on file location
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
?>
|
||||
|
||||
<style>
|
||||
.gallery-slider-active {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
/* spacing between images */
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.gallery-three-item {
|
||||
width: 520px;
|
||||
height: 300px;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
background: #f9f9f9;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.gallery-three-item .image {
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gallery-three-item img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
/* ensures aspect ratio while filling container */
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
<?php
|
||||
$pageTitle = 'About';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
<!-- Benefit Area start -->
|
||||
<section class="benefit-area mt-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row align-items-center justify-content-between">
|
||||
<div class="col-xl-5 col-lg-6">
|
||||
<div class="mobile-app-content rmb-55" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title counter-text-wrap mb-40">
|
||||
<h2>Welcome to the Four Wheel Drive Club of Southern Africa!</h2>
|
||||
</div>
|
||||
<p style="max-width: 600px; margin: 0 auto;">
|
||||
We're a family-friendly outdoor adventure club passionate about exploring the great outdoors through off-road driving, camping, overlanding, cross-border trips, day trips, and unforgettable events. Whether you're new to 4x4 adventures or a seasoned explorer, our community is all about camaraderie, responsible adventure, and creating lasting memories—on and off the road.
|
||||
</p>
|
||||
<ul class="list-style-two mt-35 mb-30">
|
||||
<li>Overlanding</li>
|
||||
<li>Camping</li>
|
||||
<li>Day Trips</li>
|
||||
<li>4x4 Driver Training</li>
|
||||
<li>Family Events</li>
|
||||
<li>Monthly Open Days</li>
|
||||
<li>Guest Speakers</li>
|
||||
<li>4x4 Driving Track</li>
|
||||
</ul>
|
||||
<!-- <a href="about.html" class="theme-btn style-two">
|
||||
<span data-hover="Explore Guides">Explore Guides</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="benefit-image-part style-two">
|
||||
<div class="image-one" data-aos="fade-down" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
<img src="assets/images/benefit/benefit1.png" alt="Benefit">
|
||||
</div>
|
||||
<div class="image-two" data-aos="fade-up" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
<img src="assets/images/benefit/benefit2.png" alt="Benefit">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Benefit Area end -->
|
||||
|
||||
<!-- Hotel Area start -->
|
||||
<section class="hotel-area bgc-black py-100 rel z-1">
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="section-title text-white text-center counter-text-wrap mb-70" data-aos="fade-up"
|
||||
data-aos-duration="1500" data-aos-offset="50">
|
||||
<h2>BASE4 Open Days</h2>
|
||||
<p style="max-width: 60%; margin: auto;">Whether you're a member or just curious, everyone's welcome at our monthly open events. Come camp with us, enjoy guest speakers, take your rig for a spin on the 4x4 track, or just relax by the swimming pool. Saturday’s Open Day includes breakfast and lunch for sale, plus braai fires ready to go—just bring your tongs! It’s the perfect way to experience the spirit of the club and connect with fellow adventurers. </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gallery-slider-active">
|
||||
<?php
|
||||
$folder = $rootPath . '/assets/images/opendays/';
|
||||
$images = glob($folder . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
|
||||
// Convert absolute paths to web-relative paths
|
||||
$images = array_map(function($path) use ($rootPath) {
|
||||
return str_replace($rootPath, '', $path);
|
||||
}, $images);
|
||||
|
||||
// Shuffle and pick first 5
|
||||
shuffle($images);
|
||||
$selected = array_slice($images, 0, 10);
|
||||
|
||||
foreach ($selected as $image) {
|
||||
echo '<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="' . $image . '" alt="Gallery">
|
||||
</div>
|
||||
|
||||
</div>';
|
||||
}
|
||||
?>
|
||||
</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 -->
|
||||
|
||||
|
||||
<!-- Features Area start -->
|
||||
<section class="features-area pt-100 pb-45 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-xl-6">
|
||||
<div class="features-content-part mb-55" data-aos="fade-left" data-aos-duration="1500"
|
||||
data-aos-offset="50">
|
||||
<div class="section-title mb-20">
|
||||
<h2>Want to get involved?<b>JOIN THE COMMITTEE!</b></h2>
|
||||
<p>Want to be more involved in the adventure? Join our committee and help shape the future of the club! Whether it’s planning epic trips, organizing fun events, or assisting with training, your energy and ideas make all the difference. The club runs on the passion of its members—get stuck in, meet awesome people, and be part of what makes it all happen!</p>
|
||||
<div class="image">
|
||||
<img style="border-radius:10px;" src="assets/images/memories/40.jpg" alt="Hotel">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-6" data-aos="fade-right" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="row pb-25">
|
||||
<div class="section-title text-center counter-text-wrap mb-70" data-aos="fade-up"
|
||||
data-aos-duration="1500" data-aos-offset="50">
|
||||
<h2>4WDCSA Committee and Other Office Bearers</h2>
|
||||
<div>
|
||||
<h3>Committee</h3>
|
||||
<li>Chairman - John Runciman</li>
|
||||
<li>National Liaison - Peter Hutchison</li>
|
||||
<li>Treasurer - Doug Timm</li>
|
||||
<li>Outings - John Runciman</li>
|
||||
<li>Events - Noelene Runciman</li>
|
||||
<li>Driver Training - John Runciman</li>
|
||||
<li>Digital Media - Christopher Pinto</li>
|
||||
|
||||
</div>
|
||||
<div class="pt-30 pb-20">
|
||||
<h3>Administration</h3>
|
||||
<li>Secretary - Jacqui Boshoff</li>
|
||||
|
||||
</div>
|
||||
<p style="font-size:0.8rem;">
|
||||
All portfolio holders/committee members of the 4WDCSA are volunteers and are not paid for their services.<br>The secretary is paid for administrative duties only.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Features Area end -->
|
||||
|
||||
|
||||
<!-- Hotel Area start -->
|
||||
<section class="hotel-area bgc-black py-100 rel z-1">
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="section-title text-white text-center counter-text-wrap mb-70" data-aos="fade-up"
|
||||
data-aos-duration="1500" data-aos-offset="50">
|
||||
<h2>4x4 Memories</h2>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gallery-slider-active"><?php
|
||||
$folder = $rootPath . '/assets/images/memories/';
|
||||
$images = glob($folder . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
|
||||
// Convert absolute paths to web-relative paths
|
||||
$images = array_map(function($path) use ($rootPath) {
|
||||
return str_replace($rootPath, '', $path);
|
||||
}, $images);
|
||||
|
||||
// Shuffle and pick first 5
|
||||
shuffle($images);
|
||||
$selected = array_slice($images, 0, 20);
|
||||
|
||||
foreach ($selected as $image) {
|
||||
echo '<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="' . $image . '" alt="Gallery">
|
||||
</div>
|
||||
|
||||
</div>';
|
||||
}
|
||||
?>
|
||||
</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/trips/1_01.jpg);">
|
||||
<span class="category">Extended Trips</span>
|
||||
<h2>Come and Explore Africa and beyond</h2>
|
||||
<a href="<?= url('trips') ?>" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Explore Tours">Explore Trips</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/courses/driver_training.png);">
|
||||
<span class="category">Driver Training</span>
|
||||
<h2>Level up your 4x4 Driving Skills</h2>
|
||||
<a href="<?= url('driver_training') ?>" class="theme-btn style-two">
|
||||
<span data-hover="Explore Tours">Explore Training</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/base4/camping.jpg);">
|
||||
<span class="category">Events</span>
|
||||
<h2>See whats cooking at BASE4!</h2>
|
||||
<a href="<?= url('events') ?>" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Explore Tours">Explore Events</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- CTA Area end -->
|
||||
|
||||
|
||||
<!-- Blog Area start -->
|
||||
<section class="blog-area pt-70 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Blog Area end -->
|
||||
|
||||
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
include_once('header02.php');
|
||||
$headerStyle = 'light';
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
|
||||
// Assuming you have the user ID stored in the session
|
||||
$user_id = $_SESSION['user_id'];
|
||||
@@ -59,7 +60,7 @@ $user = $result->fetch_assoc();
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="comment-form bgc-lighter z-1 rel mb-30 rmb-55">
|
||||
<form id="accountForm" name="accountForm" method="post" action="update_user.php">
|
||||
<form id="accountForm" name="accountForm" method="post" action="update_user">
|
||||
<div class="section-title py-20">
|
||||
<h2>Account Settings</h2>
|
||||
<div id="responseMessage"></div> <!-- Message display area -->
|
||||
@@ -113,7 +114,7 @@ $user = $result->fetch_assoc();
|
||||
|
||||
|
||||
<!-- Change Password Form -->
|
||||
<form id="changePasswordForm" name="changePasswordForm" action="change_password.php" method="post">
|
||||
<form id="changePasswordForm" name="changePasswordForm" action="change_password" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||
<div class="col-md-12 mt-20">
|
||||
<h4>Change Password</h4>
|
||||
@@ -162,7 +163,7 @@ $user = $result->fetch_assoc();
|
||||
formData.append('profile_picture', $('#profile_picture')[0].files[0]);
|
||||
|
||||
$.ajax({
|
||||
url: 'upload_profile_picture.php',
|
||||
url: 'upload_profile_picture',
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
contentType: false,
|
||||
@@ -195,7 +196,7 @@ $user = $result->fetch_assoc();
|
||||
event.preventDefault(); // Prevent default form submission
|
||||
|
||||
$.ajax({
|
||||
url: 'update_user.php',
|
||||
url: 'update_user',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function(response) {
|
||||
@@ -222,7 +223,7 @@ $user = $result->fetch_assoc();
|
||||
event.preventDefault(); // Prevent default form submission
|
||||
|
||||
$.ajax({
|
||||
url: 'change_password.php',
|
||||
url: 'change_password',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function(response) {
|
||||
@@ -245,4 +246,4 @@ $user = $result->fetch_assoc();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
// Assuming you have the user ID stored in the session
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
$user_id = $_SESSION['user_id'];
|
||||
@@ -41,7 +42,7 @@ if (isset($_SESSION['user_id'])) {
|
||||
<?php
|
||||
$pageTitle = 'Indemnity';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
@@ -93,7 +94,7 @@ if (isset($_SESSION['user_id'])) {
|
||||
var dataUrl = signaturePad.toDataURL(); // Get signature as base64 image
|
||||
|
||||
$.ajax({
|
||||
url: 'process_signature.php',
|
||||
url: 'process_signature',
|
||||
type: 'POST',
|
||||
data: {
|
||||
signature: dataUrl // Send the base64 signature image
|
||||
@@ -129,4 +130,4 @@ if (isset($_SESSION['user_id'])) {
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkUserSession();
|
||||
|
||||
// SQL query to fetch dates for bush mechanics
|
||||
@@ -26,7 +27,7 @@ $page_id = 'bush_mechanics';
|
||||
</style><?php
|
||||
$pageTitle = 'Bush Mechanics';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Product Details Start -->
|
||||
@@ -78,7 +79,7 @@ $page_id = 'bush_mechanics';
|
||||
<hr class="mt-40">
|
||||
<div class="blog-sidebar tour-sidebar">
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form action="process_course_booking.php" method="POST">
|
||||
<form action="process_course_booking" method="POST">
|
||||
<ul class="tickets clearfix">
|
||||
<li>
|
||||
Select Date
|
||||
@@ -167,7 +168,7 @@ $page_id = 'bush_mechanics';
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</button>
|
||||
<div class="text-center">
|
||||
<a href="contact.php">Need some help?</a>
|
||||
<a href="contact">Need some help?</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -381,4 +382,4 @@ $page_id = 'bush_mechanics';
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php') ?>
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
?>
|
||||
|
||||
<style>
|
||||
.image {
|
||||
@@ -29,7 +31,7 @@ include_once('header.php') ?>
|
||||
</style><?php
|
||||
$pageTitle = 'Contact Us';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
|
||||
@@ -108,4 +110,4 @@ include_once('header.php') ?>
|
||||
<!-- Contact Map End -->
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
// Assuming you have the user ID stored in the session
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
$user_id = $_SESSION['user_id'];
|
||||
@@ -41,7 +42,7 @@ if (isset($_SESSION['user_id'])) {
|
||||
<?php
|
||||
$pageTitle = 'Indemnity';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
@@ -93,7 +94,7 @@ if (isset($_SESSION['user_id'])) {
|
||||
var dataUrl = signaturePad.toDataURL(); // Get signature as base64 image
|
||||
|
||||
$.ajax({
|
||||
url: 'process_signature.php',
|
||||
url: 'process_signature',
|
||||
type: 'POST',
|
||||
data: {
|
||||
signature: dataUrl // Send the base64 signature image
|
||||
@@ -129,4 +130,4 @@ if (isset($_SESSION['user_id'])) {
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'dark';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
$indemnityPending = false;
|
||||
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
@@ -55,7 +55,7 @@ if (!empty($bannerImages)) {
|
||||
<h1 class="hero-title" data-aos="flip-up" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
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;">
|
||||
<a href="membership" 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>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
@@ -157,7 +157,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
<p>We go above and beyond to make your travel dreams reality hidden gems and must-see
|
||||
attractions</p>
|
||||
|
||||
<a href="membership.php" class="theme-btn mt-10 style-two">
|
||||
<a href="membership" class="theme-btn mt-10 style-two">
|
||||
<span data-hover="Become A Member">Become A Member</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
@@ -183,7 +183,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
<section class="hotel-area bgc-black py-100 rel z-1">
|
||||
<div class="countdown-container">
|
||||
<h1 style="color: #e5f5e0;" id="countdown">Loading countdown...</h1>
|
||||
<a href="events.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;">
|
||||
<a href="events" 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="Events">Find out more!</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
@@ -311,7 +311,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
</a>
|
||||
</div>
|
||||
<!-- <div class="menu-btns py-10">
|
||||
<a href="campsite_booking.php" class="theme-btn style-two bgc-secondary">
|
||||
<a href="campsite_booking" 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>
|
||||
@@ -409,7 +409,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="location"><i class="fal fa-map-marker-alt"></i> BASE4, Hennops</span>
|
||||
<h5><a href="driver_training.php">Basic 4X4 Driver Training</a></h5>
|
||||
<h5><a href="driver_training">Basic 4X4 Driver Training</a></h5>
|
||||
<ul class="list-style-three">
|
||||
<li>Master Off-Road Confidence</li>
|
||||
<li>Hands-On Training</li>
|
||||
@@ -419,7 +419,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
<div class="destination-footer">
|
||||
<span class="price"><span>R <?= getPrice('driver_training', 'member'); ?></span>/for members</span>
|
||||
<span class="price"><span>R <?= getPrice('driver_training', 'nonmember'); ?></span>/for non-members</span>
|
||||
<a href="driver_training.php" class="read-more">Book Now <i class="fal fa-angle-right"></i></a>
|
||||
<a href="driver_training" class="read-more">Book Now <i class="fal fa-angle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -434,7 +434,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="location"><i class="fal fa-map-marker-alt"></i> BASE4, Hennops</span>
|
||||
<h5><a href="bush_mechanics.php">Bush Mechanics Course</a></h5>
|
||||
<h5><a href="bush_mechanics">Bush Mechanics Course</a></h5>
|
||||
<ul class="list-style-three">
|
||||
<li>Fix Your Vehicle in the Wild</li>
|
||||
<li>Survival Skills for Off-Roaders</li>
|
||||
@@ -444,7 +444,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
<div class="destination-footer">
|
||||
<span class="price"><span>R <?= getPrice('bush_mechanics', 'member'); ?></span>/for members</span>
|
||||
<span class="price"><span>R <?= getPrice('bush_mechanics', 'nonmember'); ?></span>/for non-members</span>
|
||||
<a href="bush_mechanics.php" class="read-more">Book Now <i class="fal fa-angle-right"></i></a>
|
||||
<a href="bush_mechanics" class="read-more">Book Now <i class="fal fa-angle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -454,7 +454,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
data-aos-offset="50">
|
||||
<div class="content">
|
||||
<span class="location"><i class="fal fa-map-marker-alt"></i> BASE4, Hennops</span>
|
||||
<h5><a href="rescue_recovery.php">Rescue & Recovery Course</a></h5>
|
||||
<h5><a href="rescue_recovery">Rescue & Recovery Course</a></h5>
|
||||
<ul class="list-style-three">
|
||||
<li>Master Advanced Recovery Techniques</li>
|
||||
<li>Gain Confidence in High-Stress Situations</li>
|
||||
@@ -464,7 +464,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
<div class="destination-footer">
|
||||
<span class="price"><span>R <?= getPrice('rescue_recovery', 'member'); ?></span>/for members</span>
|
||||
<span class="price"><span>R <?= getPrice('rescue_recovery', 'nonmember'); ?></span>/for non-members</span>
|
||||
<a href="rescue_recovery.php" class="read-more">Book Now <i class="fal fa-angle-right"></i></a>
|
||||
<a href="rescue_recovery" class="read-more">Book Now <i class="fal fa-angle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="image">
|
||||
@@ -701,7 +701,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
</div>
|
||||
<div class="col-lg-7 text-center text-lg-end">
|
||||
<ul class="footer-bottom-nav">
|
||||
<li><a href="privacy_policy.php">Privacy Policy</a></li>
|
||||
<li><a href="privacy_policy">Privacy Policy</a></li>
|
||||
<!-- <li><a href="about.html">Terms</a></li> -->
|
||||
<!-- <li><a href="about.html">Privacy Policy</a></li> -->
|
||||
<!-- <li><a href="about.html">Legal notice</a></li> -->
|
||||
@@ -731,7 +731,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
To link your existing FWDCSA membership, you need to sign and accept the indemnity aggreement before proceeding.<br>
|
||||
<a style="width:100%; border-radius:20px;" href="indemnity.php" class="btn btn-danger mt-3">Review and Accept</a>
|
||||
<a style="width:100%; border-radius:20px;" href="indemnity" class="btn btn-danger mt-3">Review and Accept</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,7 +51,7 @@ $(document).ready(function () {
|
||||
// Load users into dropdown when modal opens
|
||||
$('#userModal').on('shown.bs.modal', function () {
|
||||
$.ajax({
|
||||
url: 'fetch_users.php',
|
||||
url: 'fetch_users',
|
||||
method: 'GET',
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
@@ -72,7 +72,7 @@ $(document).ready(function () {
|
||||
$('#barTabForm').submit(function (e) {
|
||||
e.preventDefault(); // Prevent default form submission
|
||||
$.ajax({
|
||||
url: 'create_bar_tab.php',
|
||||
url: 'create_bar_tab',
|
||||
method: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function (response) {
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
?>
|
||||
|
||||
|
||||
@@ -809,7 +809,7 @@ include_once('header.php');
|
||||
event.preventDefault(); // Prevent the default form submission
|
||||
|
||||
$.ajax({
|
||||
url: 'validate_login.php',
|
||||
url: 'validate_login',
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
dataType: 'json',
|
||||
@@ -828,4 +828,4 @@ include_once('header.php');
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkUserSession();
|
||||
|
||||
// SQL query to fetch dates for rescue & recovery
|
||||
@@ -25,7 +26,7 @@ $page_id = 'rescue_recovery';
|
||||
</style><?php
|
||||
$pageTitle = 'Rescue & Recovery';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once('components/banner.php');
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Product Details Start -->
|
||||
@@ -77,7 +78,7 @@ $page_id = 'rescue_recovery';
|
||||
<hr class="mt-40">
|
||||
<div class="blog-sidebar tour-sidebar">
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form action="process_course_booking.php" method="POST">
|
||||
<form action="process_course_booking" method="POST">
|
||||
<ul class="tickets clearfix">
|
||||
<li>
|
||||
Select Date
|
||||
@@ -313,4 +314,4 @@ $page_id = 'rescue_recovery';
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once('header.php');
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
// Assuming you have the user ID stored in the session
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
$user_id = $_SESSION['user_id'];
|
||||
@@ -54,7 +54,7 @@ if (!empty($bannerImages)) {
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">Indemnity</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"><a href="index">Home</a></li>
|
||||
<li class="breadcrumb-item ">Membership</li>
|
||||
<li class="breadcrumb-item active">Indemnity</li>
|
||||
</ol>
|
||||
@@ -101,4 +101,4 @@ if (!empty($bannerImages)) {
|
||||
<script src="https://cdn.jsdelivr.net/npm/signature_pad@4.0.0/dist/signature_pad.umd.min.js"></script>
|
||||
|
||||
|
||||
<?php include_once('insta_footer.php') ?>
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user