Files
4WDCSA.co.za/functions.php
2025-12-02 17:41:24 +02:00

1801 lines
52 KiB
PHP

<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
function openDatabaseConnection()
{
// Database connection parameters
$dbhost = $_ENV['DB_HOST'];
$dbuser = $_ENV['DB_USER'];
$dbpass = $_ENV['DB_PASS'];
$dbname = $_ENV['DB_NAME'];
$salt = $_ENV['SALT'];
// Create connection
$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
return $conn;
}
function getTripCount()
{
// Database connection
$conn = openDatabaseConnection();
// SQL query to count the number of rows
$sql = "SELECT COUNT(*) AS total FROM trips WHERE published = 1 AND start_date > CURDATE()";
$result = $conn->query($sql);
// Fetch the count from the result
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$totalTrips = $row['total'];
} else {
$totalTrips = 0;
}
// Close connection
$conn->close();
// Return the number of rows
return $totalTrips;
}
function convertDate($dateString)
{
// Create a DateTime object from the input date string
$date = DateTime::createFromFormat('Y-m-d', $dateString);
// Check if the date is valid
if ($date) {
// Format the date as 'D, d M Y'
return $date->format('D, d M Y');
} else {
// Return an error message if the date is invalid
return "Invalid date format";
}
}
function calculateDaysAndNights($startDate, $endDate)
{
// Create DateTime objects for both start and end dates
$start = DateTime::createFromFormat('Y-m-d', $startDate);
$end = DateTime::createFromFormat('Y-m-d', $endDate);
// Check if both dates are valid
if ($start && $end) {
// Calculate the difference between the two dates
$interval = $start->diff($end);
// Number of days includes the start date, so we add 1 day to the difference
$days = $interval->days + 1;
// Number of nights is one less than the number of days
$nights = $days - 1;
// Return the formatted result
return "$days days $nights nights";
} else {
// Return an error message if the dates are invalid
return "Invalid date format";
}
}
function sendVerificationEmail($email, $name, $token)
{
global $mailjet;
$message = [
'Messages' => [
[
'From' => [
'Email' => "info@4wdcsa.co.za",
'Name' => "4WDCSA"
],
'To' => [
[
'Email' => $email,
'Name' => $name
]
],
'TemplateID' => 6689736,
'TemplateLanguage' => true,
'Subject' => "4WDCSA - Verify your Email",
'Variables' => [
'token' => $token,
'first_name' => $name
]
]
]
];
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.mailjet.com/v3.1/',
]);
$response = $client->request('POST', 'send', [
'json' => $message,
'auth' => ['1a44f8d5e847537dbb8d3c76fe73a93c', 'ec98b45c53a7694c4f30d09eee9ad280']
]);
if ($response->getStatusCode() == 200) {
$body = $response->getBody();
$response = json_decode($body);
if ($response->Messages[0]->Status == 'success') {
return True;
} else {
return False;
}
}
}
function sendInvoice($email, $name, $eft_id, $amount, $description)
{
global $mailjet;
$message = [
'Messages' => [
[
'From' => [
'Email' => "info@4wdcsa.co.za",
'Name' => "4WDCSA"
],
'To' => [
[
'Email' => $email,
'Name' => $name
]
],
'TemplateID' => 6891432,
'TemplateLanguage' => true,
'Subject' => "4WDCSA - Thank you for your booking.",
'Variables' => [
'eft_id' => $eft_id,
'amount' => $amount,
'description' => $description,
]
]
]
];
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.mailjet.com/v3.1/',
]);
$response = $client->request('POST', 'send', [
'json' => $message,
'auth' => ['1a44f8d5e847537dbb8d3c76fe73a93c', 'ec98b45c53a7694c4f30d09eee9ad280']
]);
if ($response->getStatusCode() == 200) {
$body = $response->getBody();
$response = json_decode($body);
if ($response->Messages[0]->Status == 'success') {
return True;
} else {
return False;
}
}
}
function sendEmail($email, $subject, $message)
{
global $mailjet;
$message = [
'Messages' => [
[
'From' => [
'Email' => "info@4wdcsa.co.za",
'Name' => "4WDCSA"
],
'To' => [
[
'Email' => $email
]
],
'Subject' => $subject,
'TextPart' => $message
]
]
];
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.mailjet.com/v3.1/',
]);
$response = $client->request('POST', 'send', [
'json' => $message,
'auth' => ['1a44f8d5e847537dbb8d3c76fe73a93c', 'ec98b45c53a7694c4f30d09eee9ad280']
]);
if ($response->getStatusCode() == 200) {
$body = $response->getBody();
$response = json_decode($body);
if ($response->Messages[0]->Status == 'success') {
return True;
} else {
return False;
}
}
}
function sendAdminNotification($subject, $message)
{
global $mailjet;
$mail = [
'Messages' => [
[
'From' => [
'Email' => "info@4wdcsa.co.za",
'Name' => "4WDCSA"
],
'To' => [
[
'Email' => $_ENV['NOTIFICATION_ADDR'],
'Name' => 'Jacqui Boshoff'
]
],
'TemplateID' => 6896720,
'TemplateLanguage' => true,
'Subject' => $subject,
'Variables' => [
'message' => $message,
]
]
]
];
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.mailjet.com/v3.1/',
]);
$response = $client->request('POST', 'send', [
'json' => $mail,
'auth' => ['1a44f8d5e847537dbb8d3c76fe73a93c', 'ec98b45c53a7694c4f30d09eee9ad280']
]);
if ($response->getStatusCode() == 200) {
$body = $response->getBody();
$response = json_decode($body);
if ($response->Messages[0]->Status == 'success') {
return True;
} else {
return False;
}
}
}
function sendPaymentConfirmation($email, $name, $description)
{
global $mailjet;
$message = [
'Messages' => [
[
'From' => [
'Email' => "info@4wdcsa.co.za",
'Name' => "4WDCSA"
],
'To' => [
[
'Email' => $email,
'Name' => $name
]
],
'TemplateID' => 6896744,
'TemplateLanguage' => true,
'Subject' => '4WDCSA - Payment Confirmation',
'Variables' => [
'description' => $description,
'name' => $name,
]
]
]
];
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.mailjet.com/v3.1/',
]);
$response = $client->request('POST', 'send', [
'json' => $message,
'auth' => ['1a44f8d5e847537dbb8d3c76fe73a93c', 'ec98b45c53a7694c4f30d09eee9ad280']
]);
if ($response->getStatusCode() == 200) {
$body = $response->getBody();
$response = json_decode($body);
if ($response->Messages[0]->Status == 'success') {
return True;
} else {
return False;
}
}
}
function getUserMemberStatus($user_id)
{
$conn = openDatabaseConnection();
// Step 1: Check if the user is a member
$queryUser = "SELECT member FROM users WHERE user_id = ?";
$stmtUser = $conn->prepare($queryUser);
if (!$stmtUser) {
error_log("Failed to prepare user query: " . $conn->error);
return false;
}
$stmtUser->bind_param('i', $user_id);
$stmtUser->execute();
$resultUser = $stmtUser->get_result();
$stmtUser->close();
if ($resultUser->num_rows === 0) {
error_log("User not found for user_id: $user_id");
return false;
}
// Step 3: Check the membership_application table for accept_indemnity status
$queryApplication = "SELECT accept_indemnity FROM membership_application WHERE user_id = ?";
$stmtApplication = $conn->prepare($queryApplication);
if (!$stmtApplication) {
error_log("Failed to prepare application query: " . $conn->error);
return false;
}
$stmtApplication->bind_param('i', $user_id);
$stmtApplication->execute();
$resultApplication = $stmtApplication->get_result();
$stmtApplication->close();
if ($resultApplication->num_rows === 0) {
error_log("No membership application found for user_id: $user_id");
return false;
}
$application = $resultApplication->fetch_assoc();
$accept_indemnity = $application['accept_indemnity'];
// Validate accept_indemnity
if ($accept_indemnity !== 1) {
error_log("User has not accepted indemnity for user_id: $user_id");
return false;
}
// Step 2: Check membership fees table for valid payment status and membership_end_date
$queryFees = "SELECT payment_status, membership_end_date FROM membership_fees WHERE user_id = ?";
$stmtFees = $conn->prepare($queryFees);
if (!$stmtFees) {
error_log("Failed to prepare fees query: " . $conn->error);
return false;
}
$stmtFees->bind_param('i', $user_id);
$stmtFees->execute();
$resultFees = $stmtFees->get_result();
$stmtFees->close();
if ($resultFees->num_rows === 0) {
error_log("Membership fees not found for user_id: $user_id");
return false;
}
$fees = $resultFees->fetch_assoc();
$payment_status = $fees['payment_status'];
$membership_end_date = $fees['membership_end_date'];
// Validate payment status and membership_end_date
$current_date = new DateTime();
$membership_end_date_obj = DateTime::createFromFormat('Y-m-d', $membership_end_date);
if ($payment_status === "PAID" && $current_date <= $membership_end_date_obj) {
return true; // Membership is active
} else {
return false;
}
return false; // Membership is not active
}
function checkUserSession()
{
// Check if user_id is set in the session
if (!isset($_SESSION['user_id'])) {
// Redirect to login.php if user_id is not set
header('Location: login.php');
exit(); // Stop further script execution
}
}
function processPayment($payment_id, $amount, $description)
{
$conn = openDatabaseConnection();
$status = "AWAITING PAYMENT";
$domain = 'www.thepinto.co.za/4wdcsa';
$user_id = $_SESSION['user_id'];
// Insert the order into the orders table
$stmt = $conn->prepare("
INSERT INTO payments (payment_id, user_id, amount, status, description)
VALUES (?, ?, ?, ?, ?)
");
$stmt->bind_param(
'ssdss',
$payment_id,
$user_id,
$amount,
$status,
$description
);
if (!$stmt->execute()) {
echo json_encode([
'status' => 'error',
'message' => $stmt->error,
'error' => $stmt->error
]);
exit();
}
// Get the last inserted order ID
$encryptedId = base64_encode($payment_id);
// Return success response
/**
* @param array $data
* @param null $passPhrase
* @return string
*/
function generateSignature($data, $passPhrase = 'SheSells7Shells')
{
// Create parameter string
$pfOutput = '';
foreach ($data as $key => $val) {
if (!empty($val)) {
$pfOutput .= $key . '=' . urlencode(trim($val)) . '&';
}
}
// Remove last ampersand
$getString = substr($pfOutput, 0, -1);
if ($passPhrase !== null) {
$getString .= '&passphrase=' . urlencode(trim($passPhrase));
}
return md5($getString);
}
// Construct variables
$data = array(
// Merchant details
'merchant_id' => '10021495',
'merchant_key' => 'yzpdydo934j92',
'return_url' => 'https://' . $domain . '/bookings.php',
'cancel_url' => 'https://' . $domain . '/cancel_booking.php?booking_id=' . $encryptedId,
'notify_url' => 'https://' . $domain . '/confirm.php',
// Buyer details
'name_first' => get_user_info('first_name'), // You should have these values from your order process
'name_last' => get_user_info('last_name'),
'email_address' => get_user_info('email'),
// Transaction details
'm_payment_id' => $payment_id, // The unique order ID you generated
'amount' => number_format(sprintf('%.2f', $amount), 2, '.', ''),
'item_name' => '4WDCSA: ' . $description // Describe the item(s) or use a generic description
);
$signature = generateSignature($data); // Assuming you have this function defined
$data['signature'] = $signature;
// Determine the PayFast URL based on the mode
$testingMode = true;
$pfHost = $testingMode ? 'sandbox.payfast.co.za' : 'www.payfast.co.za';
// Generate the HTML form with hidden inputs and an auto-submit script
$htmlForm = '<form id="payfastForm" action="https://' . $pfHost . '/eng/process" method="post">';
foreach ($data as $name => $value) {
$htmlForm .= '<input name="' . $name . '" type="hidden" value="' . $value . '" />';
}
// $htmlForm .= '<input class="btn mr-0" style="width: 100%;" type="submit" name="submit" value="PAY NOW">';
$htmlForm .= '</form>';
// JavaScript to automatically submit the form
$htmlForm .= '<script type="text/javascript">
document.getElementById("payfastForm").submit();
</script>';
// Output the form and script to the browser
echo $htmlForm;
ob_end_flush(); // Ensure any buffered output is sent to the browser
}
function processMembershipPayment($payment_id, $amount, $description)
{
$conn = openDatabaseConnection();
$status = "AWAITING PAYMENT";
$domain = 'www.thepinto.co.za/4wdcsa';
$user_id = $_SESSION['user_id'];
// Insert the order into the orders table
$stmt = $conn->prepare("
INSERT INTO payments (payment_id, user_id, amount, status, description)
VALUES (?, ?, ?, ?, ?)
");
$stmt->bind_param(
'ssdss',
$payment_id,
$user_id,
$amount,
$status,
$description
);
if (!$stmt->execute()) {
echo json_encode([
'status' => 'error',
'message' => $stmt->error,
'error' => $stmt->error
]);
exit();
}
// Get the last inserted order ID
$encryptedId = base64_encode($payment_id);
// Return success response
/**
* @param array $data
* @param null $passPhrase
* @return string
*/
function generateSignature($data, $passPhrase = 'SheSells7Shells')
{
// Create parameter string
$pfOutput = '';
foreach ($data as $key => $val) {
if (!empty($val)) {
$pfOutput .= $key . '=' . urlencode(trim($val)) . '&';
}
}
// Remove last ampersand
$getString = substr($pfOutput, 0, -1);
if ($passPhrase !== null) {
$getString .= '&passphrase=' . urlencode(trim($passPhrase));
}
return md5($getString);
}
// Construct variables
$data = array(
// Merchant details
'merchant_id' => '10021495',
'merchant_key' => 'yzpdydo934j92',
'return_url' => 'https://' . $domain . '/account_settings.php',
'cancel_url' => 'https://' . $domain . '/cancel_application.php?id=' . $encryptedId,
'notify_url' => 'https://' . $domain . '/confirm2.php',
// Buyer details
'name_first' => get_user_info('first_name'), // You should have these values from your order process
'name_last' => get_user_info('last_name'),
'email_address' => get_user_info('email'),
// Transaction details
'm_payment_id' => $payment_id, // The unique order ID you generated
'amount' => number_format(sprintf('%.2f', $amount), 2, '.', ''),
'item_name' => $description // Describe the item(s) or use a generic description
);
$signature = generateSignature($data); // Assuming you have this function defined
$data['signature'] = $signature;
// Determine the PayFast URL based on the mode
$testingMode = true;
$pfHost = $testingMode ? 'sandbox.payfast.co.za' : 'www.payfast.co.za';
// Generate the HTML form with hidden inputs and an auto-submit script
$htmlForm = '<form id="payfastForm" action="https://' . $pfHost . '/eng/process" method="post">';
foreach ($data as $name => $value) {
$htmlForm .= '<input name="' . $name . '" type="hidden" value="' . $value . '" />';
}
// $htmlForm .= '<input class="btn mr-0" style="width: 100%;" type="submit" name="submit" value="PAY NOW">';
$htmlForm .= '</form>';
// JavaScript to automatically submit the form
$htmlForm .= '<script type="text/javascript">
document.getElementById("payfastForm").submit();
</script>';
// Output the form and script to the browser
echo $htmlForm;
ob_end_flush(); // Ensure any buffered output is sent to the browser
}
function processPaymentTest($payment_id, $amount, $description)
{
$conn = openDatabaseConnection();
$status = "PAID";
$domain = 'www.thepinto.co.za/4wdcsa';
$user_id = $_SESSION['user_id'];
// Insert the order into the payments table
$stmt = $conn->prepare("
INSERT INTO payments (payment_id, user_id, amount, status, description)
VALUES (?, ?, ?, ?, ?)
");
$stmt->bind_param(
'ssdss',
$payment_id,
$user_id,
$amount,
$status,
$description
);
if (!$stmt->execute()) {
echo json_encode([
'status' => 'error',
'message' => $stmt->error,
'error' => $stmt->error
]);
exit();
}
// Update the bookings table to set the status to "PAID"
$updateStmt = $conn->prepare("
UPDATE bookings
SET status = 'PAID'
WHERE payment_id = ?
");
$updateStmt->bind_param('s', $payment_id);
if (!$updateStmt->execute()) {
echo json_encode([
'status' => 'error',
'message' => $updateStmt->error,
'error' => $updateStmt->error
]);
exit();
}
// Success response
echo json_encode([
'status' => 'success',
'message' => 'Payment processed and booking status updated.'
]);
$stmt->close();
$updateStmt->close();
$conn->close();
// Redirect to bookings.php with the booking_id parameter
header("Location: bookings.php");
exit(); // Ensure no further code is executed after the redirect
}
function processZeroPayment($payment_id, $amount, $description)
{
$conn = openDatabaseConnection();
$status = "BOOKED";
$user_id = $_SESSION['user_id'];
// Update the bookings table to set the status to "PAID"
$updateStmt = $conn->prepare("
UPDATE bookings
SET status = 'PAID'
WHERE payment_id = ?
");
$updateStmt->bind_param('s', $payment_id);
if (!$updateStmt->execute()) {
echo json_encode([
'status' => 'error',
'message' => $updateStmt->error,
'error' => $updateStmt->error
]);
exit();
}
// Success response
echo json_encode([
'status' => 'success',
'message' => 'Payment processed and booking status updated.'
]);
$updateStmt->close();
$conn->close();
// Redirect to bookings.php with the booking_id parameter
header("Location: bookings.php");
exit(); // Ensure no further code is executed after the redirect
}
function get_user_info($info)
{
if (!isset($_SESSION['user_id'])) {
return "User is not logged in.";
}
// Get the user_id from the session
$user_id = $_SESSION['user_id'];
$conn = openDatabaseConnection();
$query = "SELECT $info FROM users WHERE user_id = ?";
// Prepare the statement
if ($stmt = $conn->prepare($query)) {
// Bind the user_id parameter
$stmt->bind_param("i", $user_id);
// Execute the query
$stmt->execute();
// Bind the result to a variable
$stmt->bind_result($info);
// Fetch the result
if ($stmt->fetch()) {
// Return the requested variable
return $info;
} else {
// Return null if no result is found
return null;
}
// Close the statement
$stmt->close();
} else {
// Handle query preparation error
die("Query preparation failed: " . $conn->error);
}
}
function getAvailableSpaces($trip_id)
{
$conn = openDatabaseConnection();
try {
// Ensure trip_id is an integer to prevent SQL injection
$trip_id = intval($trip_id);
// Step 1: Get the vehicle capacity for the trip from the trips table
$query = "SELECT vehicle_capacity FROM trips WHERE trip_id = $trip_id";
$result = $conn->query($query);
// Check if the trip exists
if ($result->num_rows === 0) {
return "Trip not found.";
}
// Fetch the vehicle capacity
$trip = $result->fetch_assoc();
$vehicle_capacity = $trip['vehicle_capacity'];
// Step 2: Get the total number of booked vehicles for this trip from the bookings table
$query = "SELECT SUM(num_vehicles) as total_booked FROM bookings WHERE trip_id = $trip_id";
$result = $conn->query($query);
// Fetch the total number of vehicles booked
$bookings = $result->fetch_assoc();
$total_booked = $bookings['total_booked'] ?? 0; // Default to 0 if no bookings
// Step 3: Calculate the available spaces
$available_spaces = $vehicle_capacity - $total_booked;
// Return the result (available spaces)
return max($available_spaces, 0); // Ensure that available spaces cannot be negative
} catch (Exception $e) {
// If there's an error, return the error message
return "Error: " . $e->getMessage();
}
}
function countUpcomingBookings($user_id)
{
$conn = openDatabaseConnection();
// Prepare the SQL query to count upcoming bookings
$sql = "SELECT COUNT(*) AS upcoming_count
FROM bookings
WHERE user_id = ? AND to_date >= CURDATE()";
// Prepare the statement
$stmt = $conn->prepare($sql);
if ($stmt === false) {
return "Error preparing statement: " . $conn->error;
}
// Bind parameters
$stmt->bind_param("i", $user_id);
// Execute the query
$stmt->execute();
// Get the result
$result = $stmt->get_result();
if ($result) {
$row = $result->fetch_assoc();
return $row['upcoming_count'];
} else {
return "Error executing query: " . $stmt->error;
}
}
function getUserRole()
{
$conn = openDatabaseConnection();
// Start the session if not already started
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// 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
}
$user_id = $_SESSION['user_id'];
$role = null;
// Prepare the SQL statement
$stmt = $conn->prepare("SELECT role FROM users WHERE user_id = ?");
if ($stmt) {
// Bind the user_id parameter to the query
$stmt->bind_param("i", $user_id);
// Execute the query
$stmt->execute();
// Bind the result to a variable
$stmt->bind_result($role);
// Fetch the result
$stmt->fetch();
// Close the statement
$stmt->close();
} else {
// Handle errors in statement preparation
error_log("Database error: " . $conn->error);
}
return $role;
}
function checkAdmin()
{
$conn = openDatabaseConnection();
// Ensure the user is logged in
if (!isset($_SESSION['user_id'])) {
header('Location: index.php');
// echo "user not logged in";
exit;
}
$userId = $_SESSION['user_id'];
// Query to check the role
$stmt = $conn->prepare("SELECT role FROM users WHERE user_id = ?");
$stmt->bind_param('i', $userId);
$stmt->execute();
$result = $stmt->get_result();
// Fetch the result
if ($row = $result->fetch_assoc()) {
$role = $row['role'];
// If the role is not admin or superadmin, redirect to index.php
if ($role !== 'admin' && $role !== 'superadmin') {
header('Location: index.php');
// echo "user is not admin or superadmin";
exit;
}
} else {
// No user found, redirect to index.php
header('Location: index.php');
// echo "No user found";
exit;
}
// Close the statement and connection
$stmt->close();
$conn->close();
}
function checkSuperAdmin()
{
$conn = openDatabaseConnection();
// Ensure the user is logged in
if (!isset($_SESSION['user_id'])) {
header('Location: index.php');
// echo "user not logged in";
exit;
}
$userId = $_SESSION['user_id'];
// Query to check the role
$stmt = $conn->prepare("SELECT role FROM users WHERE user_id = ?");
$stmt->bind_param('i', $userId);
$stmt->execute();
$result = $stmt->get_result();
// Fetch the result
if ($row = $result->fetch_assoc()) {
$role = $row['role'];
// If the role is not admin or superadmin, redirect to index.php
if ($role !== 'superadmin') {
header('Location: index.php');
// echo "user is not admin or superadmin";
exit;
}
} else {
// No user found, redirect to index.php
header('Location: index.php');
// echo "No user found";
exit;
}
// Close the statement and connection
$stmt->close();
$conn->close();
}
function calculateProrata($prorata)
{
// Get the current month as a number (1 = January, 12 = December)
$currentMonth = date('n');
// Total months in a year
$totalMonths = 12;
// Calculate the remaining months including the current month
$remainingMonths = $totalMonths - $currentMonth + 1;
// Multiply by prorata value
$prorataAmount = $remainingMonths * $prorata;
return $prorataAmount;
}
function getFullName($user_id)
{
$conn = openDatabaseConnection();
// Prepare the SQL query to get first_name and last_name
$query = "SELECT first_name, last_name FROM users WHERE user_id = ?";
// Prepare the statement
if ($stmt = $conn->prepare($query)) {
// Bind the user_id parameter to the query
$stmt->bind_param("i", $user_id);
// Execute the query
$stmt->execute();
// Bind the result to variables
$stmt->bind_result($first_name, $last_name);
// Fetch the data
if ($stmt->fetch()) {
// Return the full name by concatenating first_name and last_name
return $first_name . " " . $last_name;
} else {
// Handle case where no records are found
return null; // No user found with the given user_id
}
// Close the statement
$stmt->close();
} else {
// Handle query preparation failure
throw new Exception("Query preparation failed: " . $conn->error);
}
}
function getEmail($user_id)
{
$conn = openDatabaseConnection();
// Prepare the SQL query to get first_name and last_name
$query = "SELECT email FROM users WHERE user_id = ?";
// Prepare the statement
if ($stmt = $conn->prepare($query)) {
// Bind the user_id parameter to the query
$stmt->bind_param("i", $user_id);
// Execute the query
$stmt->execute();
// Bind the result to variables
$stmt->bind_result($email);
// Fetch the data
if ($stmt->fetch()) {
// Return the full name by concatenating first_name and last_name
return $email;
} else {
// Handle case where no records are found
return null; // No user found with the given user_id
}
// Close the statement
$stmt->close();
} else {
// Handle query preparation failure
throw new Exception("Query preparation failed: " . $conn->error);
}
}
function getProfilePic($user_id)
{
$conn = openDatabaseConnection();
// Prepare the SQL query to get first_name and last_name
$query = "SELECT profile_pic FROM users WHERE user_id = ?";
// Prepare the statement
if ($stmt = $conn->prepare($query)) {
// Bind the user_id parameter to the query
$stmt->bind_param("i", $user_id);
// Execute the query
$stmt->execute();
// Bind the result to variables
$stmt->bind_result($profilepic);
// Fetch the data
if ($stmt->fetch()) {
// Return the full name by concatenating first_name and last_name
return $profilepic;
} else {
// Handle case where no records are found
return null; // No user found with the given user_id
}
// Close the statement
$stmt->close();
} else {
// Handle query preparation failure
throw new Exception("Query preparation failed: " . $conn->error);
}
}
function getInitialSurname($user_id)
{
$conn = openDatabaseConnection();
$query = "SELECT first_name, last_name FROM users WHERE user_id = ?";
if ($stmt = $conn->prepare($query)) {
$stmt->bind_param("i", $user_id);
$stmt->execute();
$stmt->bind_result($first_name, $last_name);
if ($stmt->fetch()) {
$initial = strtoupper(substr($first_name, 0, 1));
return $initial . ". " . $last_name;
} else {
return null;
}
$stmt->close();
} else {
throw new Exception("Query preparation failed: " . $conn->error);
}
}
function getLastName($user_id)
{
$conn = openDatabaseConnection();
// Prepare the SQL query to get first_name and last_name
$query = "SELECT last_name FROM users WHERE user_id = ?";
// Prepare the statement
if ($stmt = $conn->prepare($query)) {
// Bind the user_id parameter to the query
$stmt->bind_param("i", $user_id);
// Execute the query
$stmt->execute();
// Bind the result to variables
$stmt->bind_result($last_name);
// Fetch the data
if ($stmt->fetch()) {
return $last_name;
} else {
// Handle case where no records are found
return null; // No user found with the given user_id
}
// Close the statement
$stmt->close();
} else {
// Handle query preparation failure
throw new Exception("Query preparation failed: " . $conn->error);
}
}
function addEFT($eft_id, $booking_id, $user_id, $status, $amount, $description)
{
// Database connection
$conn = openDatabaseConnection();
// Prepare the SQL statement
$stmt = $conn->prepare("INSERT INTO efts (eft_id, booking_id, user_id, status, amount, description) VALUES (?, ?, ?, ?, ?, ?)");
if (!$stmt) {
die("Prepare failed: " . $conn->error);
}
// Bind parameters
$stmt->bind_param("siisds", $eft_id, $booking_id, $user_id, $status, $amount, $description);
// Execute the statement and check for errors
if ($stmt->execute()) {
// echo "EFT record added successfully.";
} else {
// echo "Error inserting EFT: " . $stmt->error;
}
// Close the statement and connection
$stmt->close();
$conn->close();
}
function addSubsEFT($eft_id, $user_id, $status, $amount, $description)
{
// Database connection
$conn = openDatabaseConnection();
// Prepare the SQL statement
$stmt = $conn->prepare("INSERT INTO efts (eft_id, user_id, status, amount, description) VALUES (?, ?, ?, ?, ?)");
if (!$stmt) {
die("Prepare failed: " . $conn->error);
}
// Bind parameters
$stmt->bind_param("sisds", $eft_id, $user_id, $status, $amount, $description);
// Execute the statement and check for errors
if ($stmt->execute()) {
// echo "EFT record added successfully.";
} else {
// echo "Error inserting EFT: " . $stmt->error;
}
// Close the statement and connection
$stmt->close();
$conn->close();
}
function encryptData($input, $salt)
{
$method = "AES-256-CBC";
$key = hash('sha256', $salt, true);
$iv = substr(hash('sha256', $salt . 'iv'), 0, 16); // Generate IV from salt
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(openssl_encrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv)));
}
function decryptData($encrypted, $salt)
{
$method = "AES-256-CBC";
$key = hash('sha256', $salt, true);
$iv = substr(hash('sha256', $salt . 'iv'), 0, 16); // Generate IV from salt
$encrypted = str_replace(['-', '_'], ['+', '/'], $encrypted);
return openssl_decrypt(base64_decode($encrypted), $method, $key, OPENSSL_RAW_DATA, $iv);
}
function hasAcceptedIndemnity($user_id)
{
// Database connection
$conn = openDatabaseConnection();
// Prepare the SQL statement
$stmt = $conn->prepare("SELECT accept_indemnity FROM membership_application WHERE user_id = ?");
if (!$stmt) {
return false; // Query preparation failed
}
// Bind the parameter and execute the statement
$stmt->bind_param("i", $user_id);
$stmt->execute();
// Get the result
$stmt->bind_result($accepted_indemnity);
$stmt->fetch();
// Close the statement
$stmt->close();
// Return true if indemnity is accepted (assuming 1 means accepted)
return (bool) $accepted_indemnity;
}
function checkMembershipApplication($user_id)
{
// Database connection
$conn = openDatabaseConnection();
// Prepare the SQL query to check if the record exists
$sql = "SELECT COUNT(*) FROM membership_application WHERE user_id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $user_id); // "i" is the type for integer
// Execute the query
$stmt->execute();
$stmt->bind_result($count);
$stmt->fetch();
// Close the prepared statement and connection
$stmt->close();
$conn->close();
// Check if the record exists and redirect
if ($count > 0) {
header("Location: membership_details.php");
exit();
}
}
function checkMembershipApplication2($user_id)
{
// Database connection
$conn = openDatabaseConnection();
// Prepare the SQL query to check if the record exists
$sql = "SELECT COUNT(*) FROM membership_application WHERE user_id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $user_id); // "i" is the type for integer
// Execute the query
$stmt->execute();
$stmt->bind_result($count);
$stmt->fetch();
// Close the prepared statement and connection
$stmt->close();
$conn->close();
// Check if the record exists and redirect
if ($count < 1) {
header("Location: membership.php");
exit();
}
}
function checkMembershipPaymentStatus($user_id)
{
// Open database connection
$conn = openDatabaseConnection();
// Query to check the payment status for the given user_id
$query = "SELECT payment_status FROM membership_fees WHERE user_id = ?";
$stmt = $conn->prepare($query);
// Check if the query preparation was successful
if (!$stmt) {
error_log("Failed to prepare payment status query: " . $conn->error);
return false;
}
// Bind the user_id parameter to the query
$stmt->bind_param('i', $user_id);
// Execute the query
$stmt->execute();
// Get the result
$result = $stmt->get_result();
// Close the prepared statement
$stmt->close();
// Check if any record is found for the user_id
if ($result->num_rows === 0) {
error_log("No payment record found for user_id: $user_id");
return false; // No payment record found
}
// Fetch the payment status
$payment = $result->fetch_assoc();
$payment_status = $payment['payment_status'];
// Check if the payment status is "PAID"
if ($payment_status === 'PAID') {
return true; // Payment has been made
}
return false; // Payment has not been made
}
function checkAndRedirectBooking($trip_id)
{
// Open database connection
$conn = openDatabaseConnection();
if (!isset($_SESSION['user_id'])) {
die("User not logged in.");
}
$user_id = $_SESSION['user_id'];
// Prepare and execute the SQL query
$stmt = $conn->prepare("SELECT COUNT(*) FROM bookings WHERE user_id = ? AND trip_id = ?");
$stmt->bind_param("ii", $user_id, $trip_id);
$stmt->execute();
$stmt->bind_result($count);
$stmt->fetch();
$stmt->close();
// Redirect if booking exists
if ($count > 0) {
$_SESSION['message'] = "You already have an active booking for this trip. Please contact info@4wdcsa.co.za for further assistance.";
header("Location: bookings.php");
exit();
}
}
function checkAndRedirectCourseBooking($course_id)
{
// Open database connection
$conn = openDatabaseConnection();
if (!isset($_SESSION['user_id'])) {
die("User not logged in.");
}
$user_id = $_SESSION['user_id'];
// Prepare and execute the SQL query
$stmt = $conn->prepare("SELECT COUNT(*) FROM bookings WHERE user_id = ? AND course_id = ?");
$stmt->bind_param("ii", $user_id, $course_id);
$stmt->execute();
$stmt->bind_result($count);
$stmt->fetch();
$stmt->close();
// Redirect if booking exists
if ($count > 0) {
$_SESSION['message'] = "You already have an active booking for this course. Please contact info@4wdcsa.co.za for further assistance.";
header("Location: bookings.php");
exit();
}
}
function countUpcomingTrips()
{
// Open database connection
$conn = openDatabaseConnection();
$query = "SELECT COUNT(*) AS trip_count FROM trips WHERE published = 1 AND start_date > CURDATE()";
if ($result = $conn->query($query)) {
$row = $result->fetch_assoc();
return (int)$row['trip_count'];
} else {
// Optional: Handle query error
error_log("MySQL Error: " . $conn->error);
return 0;
}
}
function logVisitor()
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$conn = openDatabaseConnection();
// Collect visitor data
$ip_address = getUserIP();
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$country = guessCountry($ip_address);
$page_url = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$referrer_url = $_SERVER['HTTP_REFERER'] ?? null;
$visit_time = date("Y-m-d H:i:s");
$user_id = $_SESSION['user_id'] ?? null;
// BOT DETECTION: Filter based on user-agent
$bot_keywords = ['bot', 'crawl', 'spider', 'slurp', 'wget', 'curl', 'python-requests', 'scrapy', 'httpclient'];
foreach ($bot_keywords as $bot_keyword) {
if (stripos($user_agent, $bot_keyword) !== false) {
return; // Stop logging, it's a bot
}
}
// BOT DETECTION: Check for JavaScript-executed cookie
if (!isset($_COOKIE['js_enabled'])) {
return; // Could be a bot that doesn't execute JS
}
// BOT DETECTION (optional): IP blacklist (custom)
$blacklisted_ips = ['1.2.3.4', '5.6.7.8']; // Populate with real IPs or from a service
if (in_array($ip_address, $blacklisted_ips)) {
return;
}
// Check if IP has accessed the site in the last 30 minutes
$stmt = $conn->prepare("
SELECT id FROM visitor_logs
WHERE ip_address = ?
AND visit_time >= NOW() - INTERVAL 30 MINUTE
LIMIT 1
");
if ($stmt) {
$stmt->bind_param("s", $ip_address);
$stmt->execute();
$stmt->store_result();
$seen_recently = $stmt->num_rows > 0;
$stmt->close();
if (!$seen_recently) {
// sendEmail('chrispintoza@gmail.com', '4WDCSA: New Visitor', 'A new IP ' . $ip_address . ', has just accessed ' . $page_url);
}
}
// Prepare and insert log
$stmt = $conn->prepare("INSERT INTO visitor_logs (ip_address, page_url, referrer_url, visit_time, user_id, country) VALUES (?, ?, ?, ?, ?, ?)");
if ($stmt) {
$stmt->bind_param("ssssis", $ip_address, $page_url, $referrer_url, $visit_time, $user_id, $country);
$stmt->execute();
$stmt->close();
}
}
function getUserIP()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
}
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// In case of multiple IPs (e.g. "client, proxy1, proxy2"), take the first
return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
}
return $_SERVER['REMOTE_ADDR'];
}
function getNextOpenDayDate()
{
$conn = openDatabaseConnection();
$sql = "
SELECT date
FROM events
WHERE name = '4WDCSA Open Day'
AND date >= NOW()
ORDER BY date ASC
LIMIT 1
";
$result = $conn->query($sql);
if ($result && $row = $result->fetch_assoc()) {
return $row['date']; // e.g. "2025-05-01 10:00:00"
}
return null; // No upcoming events found
}
function formatCurrency($amount, $currency = 'R')
{
return strtoupper($currency) . ' ' . number_format($amount, 2, '.', ',');
}
function guessCountry($ip)
{
$response = file_get_contents("http://ip-api.com/json/$ip");
$data = json_decode($response, true);
if ($data['status'] == 'success') {
return $data['country']; // e.g., South Africa
}
}
function getUserIdFromEFT($eft_id)
{
$conn = openDatabaseConnection();
$stmt = $conn->prepare("SELECT user_id FROM efts WHERE eft_id = ?");
if (!$stmt) {
// Optional: handle prepare error
return null;
}
$stmt->bind_param("s", $eft_id); // "i" for integer
$stmt->execute();
$stmt->bind_result($user_id);
if ($stmt->fetch()) {
$stmt->close();
return $user_id;
} else {
$stmt->close();
return null;
}
}
function getEftDescription($eft_id)
{
$conn = openDatabaseConnection();
$stmt = $conn->prepare("SELECT description FROM efts WHERE eft_id = ?");
$stmt->bind_param("s", $eft_id); // "i" for integer
$stmt->execute();
$stmt->bind_result($description);
if ($stmt->fetch()) {
$stmt->close();
return $description;
} else {
$stmt->close();
return null;
}
}
function getPrice($description, $memberType)
{
$conn = openDatabaseConnection();
// Validate member type
if (!in_array($memberType, ['member', 'nonmember'])) {
throw new InvalidArgumentException("Invalid member type. Must be 'member' or 'nonmember'.");
}
// Prepare column name based on member type
$column = $memberType === 'member' ? 'amount' : 'amount_nonmembers';
// Prepare and execute the SQL query
$stmt = $conn->prepare("SELECT $column FROM prices WHERE description = ?");
if (!$stmt) {
throw new Exception("Prepare failed: " . $conn->error);
}
$stmt->bind_param("s", $description);
$stmt->execute();
$stmt->bind_result($price);
// Fetch and return the result
if ($stmt->fetch()) {
$stmt->close();
return $price;
} else {
$stmt->close();
return null; // Or throw an exception if preferred
}
}
function getDetail($description)
{
$conn = openDatabaseConnection();
// Prepare and execute the SQL query
$stmt = $conn->prepare("SELECT detail FROM prices WHERE description = ?");
if (!$stmt) {
throw new Exception("Prepare failed: " . $conn->error);
}
$stmt->bind_param("s", $description);
$stmt->execute();
$stmt->bind_result($detail);
// Fetch and return the result
if ($stmt->fetch()) {
$stmt->close();
return $detail;
} else {
$stmt->close();
return null; // Or throw an exception if preferred
}
}
function getUserType($user_id)
{
// Prepare the statement to prevent SQL injection
$conn = openDatabaseConnection();
$stmt = $conn->prepare("SELECT type FROM users WHERE user_id = ?");
if (!$stmt) {
return false; // or handle error
}
// Bind the parameter
$stmt->bind_param("i", $user_id);
// Execute the statement
$stmt->execute();
// Bind result variable
$stmt->bind_result($type);
// Fetch the result
if ($stmt->fetch()) {
$stmt->close();
return $type;
} else {
$stmt->close();
return null; // or false depending on your error handling preference
}
}
function matchLegacyMember($userId)
{
$conn = openDatabaseConnection();
// Get the applicant's details
$stmt = $conn->prepare("SELECT first_name, last_name, email FROM users WHERE user_id = ?");
$stmt->bind_param("i", $userId);
$stmt->execute();
$applicantResult = $stmt->get_result();
if ($applicantResult->num_rows === 0) {
return null; // No such user_id
}
$applicant = $applicantResult->fetch_assoc();
// Fetch all legacy members
$result = $conn->query("SELECT * FROM legacy_members");
$bestMatch = null;
$highestScore = 0;
while ($member = $result->fetch_assoc()) {
// Compare full names
$nameScore = 0;
similar_text(
strtolower($applicant['first_name'] . ' ' . $applicant['last_name']),
strtolower($member['first_name'] . ' ' . $member['last_name']),
$nameScore
);
// Compare email
$emailScore = 0;
if (!empty($applicant['email']) && !empty($member['email'])) {
similar_text(
strtolower($applicant['email']),
strtolower($member['email']),
$emailScore
);
}
// Weighted total score
$totalScore = ($nameScore * 0.7) + ($emailScore * 0.3);
if ($totalScore > $highestScore && $totalScore >= 70) {
$highestScore = $totalScore;
$bestMatch = $member;
$bestMatch['match_score'] = round($totalScore, 2); // Add score to result
}
}
return $bestMatch; // Returns array or null
}
function processLegacyMembership($user_id) {
// Get legacy match
$conn = openDatabaseConnection();
$match = matchLegacyMember($user_id);
if ($match) {
$legacy_id = $match['legacy_id'];
$eftamount = getResultFromTable('legacy_members', 'amount', 'legacy_id', $legacy_id);
// Get user info from users table
$stmt = $conn->prepare('SELECT first_name, last_name, phone_number, email FROM users WHERE user_id = ?');
$stmt->bind_param('i', $user_id);
$stmt->execute();
$stmt->bind_result($first_name, $last_name, $tel_cell, $email);
$stmt->fetch();
$stmt->close();
// Insert into membership_application
$stmt = $conn->prepare('INSERT INTO membership_application (user_id, first_name, last_name, tel_cell, email) VALUES (?, ?, ?, ?, ?)');
$stmt->bind_param('issss', $user_id, $first_name, $last_name, $tel_cell, $email);
$stmt->execute();
$stmt->close();
// Prepare membership fees info
$payment_status = "PAID";
$membership_start_date = "2025-01-01";
$membership_end_date = "2025-12-31";
$initial_surname = getInitialSurname($user_id);
$payment_id = strtoupper($user_id . " SUBS " . date("Y") . " " . $initial_surname);
$description = 'Membership Fees ' . date("Y") . " " . $initial_surname;
// Insert into membership_fees
$stmt = $conn->prepare('INSERT INTO membership_fees (user_id, payment_amount, payment_status, membership_start_date, membership_end_date, payment_id) VALUES (?, ?, ?, ?, ?, ?)');
$stmt->bind_param('idssss', $user_id, $eftamount, $payment_status, $membership_start_date, $membership_end_date, $payment_id);
$stmt->execute();
$stmt->close();
// Add to EFT
addSubsEFT($payment_id, $user_id, $payment_status, $eftamount, $description);
}
}
function getResultFromTable($table, $column, $match, $identifier) {
$conn = openDatabaseConnection();
$sql = "SELECT `$column` FROM `$table` WHERE `$match` = ?";
$stmt = $conn->prepare($sql);
if (!$stmt) {
return null;
}
$stmt->bind_param('i', $identifier);
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
$stmt->close();
return $result;
}
function blockBlacklistedIP() {
// Get the visitor's IP
$conn = openDatabaseConnection();
$ip = getUserIP();
// Prepare and execute the SQL query
$stmt = $conn->prepare("SELECT 1 FROM blacklist WHERE ip_address = ?");
$stmt->bind_param("s", $ip);
$stmt->execute();
$stmt->store_result();
// If IP is found in blacklist, block access
if ($stmt->num_rows > 0) {
http_response_code(403);
echo "Access denied.";
exit;
}
$stmt->close();
}
function getCommentCount($page_id) {
// Database connection
$conn = openDatabaseConnection();
// Prepare statement to avoid SQL injection
$stmt = $conn->prepare("SELECT COUNT(*) FROM comments WHERE `page_id` = ?");
$stmt->bind_param("s", $page_id);
$stmt->execute();
// Get result
$stmt->bind_result($count);
$stmt->fetch();
// Close connections
$stmt->close();
$conn->close();
return $count;
}