File: /var/www/html/video-rental/wp-content/themes/video-rental/functions.php
<?php
require_once get_template_directory() . '/templates/country-codes.php';
function theme_enqueue_styles()
{
$template_dir = get_template_directory_uri();
// Always-loaded common styles
wp_enqueue_style('common-style', $template_dir . '/css/common.css');
wp_enqueue_style('header-style', $template_dir . '/css/header.css');
wp_enqueue_style('footer-style', $template_dir . '/css/footer.css');
wp_enqueue_style('home-style', $template_dir . '/css/home.css');
wp_enqueue_style('modal-style', $template_dir . '/css/modal.css');
if (is_page('login')) {
wp_enqueue_style('login-style', $template_dir . '/css/login.css');
}
if (is_page('contact-us')) {
wp_enqueue_style('contact-style', $template_dir . '/css/contact.css');
}
if (is_page('profile')) {
wp_enqueue_style('my-rentals-style', $template_dir . '/css/my-rentals.css');
}
// Toastr CSS
wp_enqueue_style(
'toastr-css',
'https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css',
[],
null
);
}
add_action('wp_enqueue_scripts', 'theme_enqueue_styles');
function cw_enqueue_parsley_validation()
{
// Load Parsley CSS (optional but good for styling)
wp_enqueue_style(
'parsley-css',
'https://cdn.jsdelivr.net/npm/parsleyjs/src/parsley.css',
[],
null
);
// Load Parsley JS
wp_enqueue_script(
'parsley-js',
'https://cdn.jsdelivr.net/npm/parsleyjs',
['jquery'], // depends on jQuery
null,
true
);
// Toastr JS
wp_enqueue_script(
'toastr-js',
'https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js',
['jquery'],
null,
true
);
// html2pdf external library
wp_enqueue_script(
'html2pdf-js',
'https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js',
[],
null,
true
);
}
add_action('wp_enqueue_scripts', 'cw_enqueue_parsley_validation');
// Enqueue custom JS and localize ajax data
function enqueue_custom_login_script()
{
wp_enqueue_script(
'custom-ajax-script',
get_template_directory_uri() . '/js/custom_js.js',
['jquery'],
time(),
true
);
wp_localize_script('custom-ajax-script', 'ajax_obj', [
'ajaxurl' => admin_url('admin-ajax.php'),
'is_logged_in' => is_user_logged_in(),
'site_url' => get_site_url(),
'redirect_url' => home_url()
]);
}
add_action('wp_enqueue_scripts', 'enqueue_custom_login_script');
add_filter('show_admin_bar', '__return_false');
function enqueue_password_toggle_script()
{
wp_enqueue_script(
'password-toggle-js',
get_stylesheet_directory_uri() . '/js/password-toggle.js',
array('jquery'),
null,
true
);
// Pass PHP variables to JS
wp_localize_script(
'password-toggle-js',
'passwordToggleVars',
array(
'eyeOpen' => get_stylesheet_directory_uri() . '/img/eye-ico.svg',
'eyeClose' => get_stylesheet_directory_uri() . '/img/eye_ico_close.svg',
)
);
}
add_action('wp_enqueue_scripts', 'enqueue_password_toggle_script');
add_action('admin_enqueue_scripts', function () {
wp_enqueue_script('select2', 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js', ['jquery'], null, true);
wp_enqueue_style('select2-css', 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css');
// Custom init script
wp_add_inline_script('select2', "
jQuery(document).ready(function($) {
$('.select2-users, .select2-videos').select2({
placeholder: 'Select options',
allowClear: true,
width: '25%'
});
// Automatically deselect others when 'All' is selected
$('.select2-users, .select2-videos').on('change', function(e) {
const selected = $(this).val();
if (selected && selected.includes('all')) {
$(this).val(['all']).trigger('change');
} else {
const newSelection = selected?.filter(v => v !== 'all') || [];
$(this).val(newSelection).trigger('change.select2');
}
});
});
");
});
//User Registration
add_action('wp_ajax_nopriv_register_user', 'handle_user_registration');
add_action('wp_ajax_register_user', 'handle_user_registration');
function handle_user_registration()
{
// Sanitize and validate input
$first_name = sanitize_text_field($_POST['first_name']);
$last_name = sanitize_text_field($_POST['last_name']);
$email = sanitize_email($_POST['email']);
$country_code = sanitize_text_field($_POST['country_code']);
$phone = sanitize_text_field($_POST['phone']);
$password = sanitize_text_field($_POST['password']);
$confirm_password = sanitize_text_field($_POST['confirm_password']);
$terms = isset($_POST['terms']) ? true : false;
// Validate email
if (!is_email($email)) {
wp_send_json_error(['message' => 'Invalid email address.']);
}
// Check if email already exists
if (email_exists($email)) {
wp_send_json_error(['message' => 'Email already exists']);
// wp_send_json_success(['message' => 'If the provided email was not already registered, you have been successfully registered, and a verification email has been sent.']);
}
// Check password match
if ($password !== $confirm_password) {
wp_send_json_error(['message' => 'Passwords do not match.']);
}
// Generate username
$user_login = strstr($email, '@', true); // Part before @ in email
$user_nicename = sanitize_title($first_name . '-' . $last_name);
$display_name = trim($first_name . ' ' . $last_name);
$phone_no = trim($country_code . ' ' . $phone);
// Prepare user data
$user_data = [
'user_login' => $user_login,
'user_pass' => $password,
'user_email' => $email,
'first_name' => $first_name,
'last_name' => $last_name,
'user_nicename' => $user_nicename,
'display_name' => $display_name,
// 'email_verified' => 0,
];
// Insert user into database
$user_id = wp_insert_user($user_data);
// Handle errors during user creation
if (is_wp_error($user_id)) {
wp_send_json_error(['message' => $user_id->get_error_message()]);
}
update_user_meta($user_id, 'phone', $phone);
// update_user_meta($user_id, 'email_verified', 0);
update_user_meta($user_id, 'phone_country_code', $country_code);
// Email Verification Logic
// $verification_code = wp_generate_password(20, false); // Generate a secure random code
// update_user_meta($user_id, 'email_verification_code', $verification_code);
// $token = base64_encode(json_encode([
// 'user_id' => $user_id,
// 'code' => $verification_code,
// 'timestamp' => time(),
// ]));
// // Generate verification link
// $verification_link = add_query_arg('token', $token, site_url('/email-verification/'));
$base_url = get_template_directory_uri();
// // Load the email template
// $template_path = __DIR__ . '/emails/email-verification.php';
// if (!file_exists($template_path)) {
// wp_send_json_error(['message' => 'Email template not found.']);
// }
// $email_body = file_get_contents($template_path);
// // Replace placeholders with dynamic data
// $email_body = str_replace('{{verification_link}}', esc_url($verification_link), $email_body);
// $email_body = str_replace('{{display_name}}', esc_html($display_name), $email_body);
// $email_body = str_replace('{{base_url}}', $base_url, $email_body);
// // Send email
// $subject = "Verify Your Email Address";
$headers = ['Content-Type: text/html; charset=UTF-8'];
// if (!wp_mail($email, $subject, $email_body, $headers)) {
// wp_send_json_error(['message' => 'Failed to send verification email.']);
// }
$admin_email = get_option('admin_email');
$admin_subject = "New User Registration: " . $display_name;
$admin_panel_url = admin_url('user-edit.php?user_id=' . $user_id);
$user_info = get_userdata($user_id);
$registered_date = $user_info->user_registered;
$registered_date_formatted = date('F j, Y \a\t g:i A', strtotime($registered_date));
// Load the email template
$template_path = __DIR__ . '/emails/admin-new-user.php';
if (!file_exists($template_path)) {
wp_send_json_error(['message' => 'Admin email template not found.']);
}
$admin_message = file_get_contents($template_path);
// Replace placeholders with dynamic data
$admin_message = str_replace('{{display_name}}', esc_html($display_name), $admin_message);
$admin_message = str_replace('{{email}}', esc_html($email), $admin_message);
$admin_message = str_replace('{{user_login}}', esc_html($user_login), $admin_message);
$admin_message = str_replace('{{phone_no}}', esc_html($phone_no), $admin_message);
$admin_message = str_replace('{{admin_panel_url}}', esc_url($admin_panel_url), $admin_message);
$admin_message = str_replace('{{base_url}}', $base_url, $admin_message);
$admin_message = str_replace('{{registered_date}}', esc_html($registered_date_formatted), $admin_message);
// Send the email
wp_mail($admin_email, $admin_subject, $admin_message, $headers);
// Auto-login the user after registration
wp_set_current_user($user_id);
wp_set_auth_cookie($user_id);
// Optional: Call any custom login logic
if (function_exists('main_site_login')) {
main_site_login($user_id);
}
// Final success response
wp_send_json_success([
'message' => 'You have been successfully registered and logged in.',
'redirect' => site_url('/profile') // or trigger modal from frontend using JS
]);
// wp_send_json_success(['message' => 'You have been successfully registered.']);
}
//email verification
// add_action('init', 'verify_user_email');
// function verify_user_email()
// {
// // Check if the verification parameters are present
// if (isset($_GET['token']) && !empty($_GET['token'])) {
// $token = sanitize_text_field($_GET['token']);
// $data = json_decode(base64_decode($token), true);
// // Validate the token structure and verify the code
// if (isset($data['user_id'], $data['code']) && valid_code($data['user_id'], $data['code'])) {
// $user_id = intval($data['user_id']);
// $code = sanitize_text_field($data['code']);
// // Retrieve user using meta key and value
// $user_query = new WP_User_Query([
// 'meta_key' => 'email_verification_code',
// 'meta_value' => $code,
// ]);
// update_user_meta($user_id, 'email_verified', 1);
// if (!empty($user_query->results)) {
// $user = $user_query->results[0];
// // Clean up meta data and mark email as verified
// delete_user_meta($user->ID, 'email_verification_code');
// update_user_meta($user->ID, 'email_verified', true);
// // Redirect to login page with success message
// wp_redirect(site_url('/login?verified=success'));
// exit;
// }
// }
// // Invalid or expired token
// wp_die("Invalid or expired verification link.");
// }
// }
// Helper function to validate the code against the user ID
// function valid_code($user_id, $code)
// {
// $stored_code = get_user_meta($user_id, 'email_verification_code', true);
// return !empty($stored_code) && hash_equals($stored_code, $code);
// }
// Register the AJAX handler for guests and logged-in users
add_action('wp_ajax_nopriv_login_user', 'login_user');
add_action('wp_ajax_login_user', 'login_user');
// Login handler function
function login_user()
{
// Sanitize input
$email = isset($_POST['email']) ? sanitize_email($_POST['email']) : '';
$password = isset($_POST['password']) ? sanitize_text_field($_POST['password']) : '';
$remember = isset($_POST['remember']) && $_POST['remember'] === 'true';
// Validate input
if (empty($email) || empty($password)) {
wp_send_json_error(['message' => 'Email and password are required.']);
}
// Get user by email
$user = get_user_by('email', $email);
// if (!$user || !wp_check_password($password, $user->user_pass, $user->ID)) {
// wp_send_json_error(['message' => 'Invalid email or password.']);
// }
// Optional: Check if email is verified (remove if not using this feature)
// $email_verified = get_user_meta($user->ID, 'email_verified', true);
// if ($email_verified !== '1') {
// wp_send_json_error(['message' => 'Please verify your email before logging in.']);
// }
// Set login credentials
$creds = [
'user_login' => $user->user_login,
'user_password' => $password,
'remember' => $remember,
];
// Attempt login
$user_signon = wp_signon($creds, false);
if (is_wp_error($user_signon)) {
$error = $user_signon->get_error_message();
wp_send_json_error(['message' => strip_tags($error)]);
}
// Optional: Custom login logic
if (function_exists('main_site_login')) {
main_site_login($user->ID);
}
// Send success response
wp_send_json_success([
'message' => 'Login successful.',
'redirect' => site_url('/profile') // Change to your desired URL
]);
}
add_action('wp_ajax_update_user_profile', function () {
parse_str($_POST['form_data'], $form_data);
$user_id = get_current_user_id();
if (!$user_id) {
wp_send_json_error('User not logged in');
}
$first_name = sanitize_text_field($form_data['first_name']);
$last_name = sanitize_text_field($form_data['last_name']);
$phone = sanitize_text_field($form_data['phone']);
$email = sanitize_email($form_data['email']);
$country_code = sanitize_text_field($form_data['country_code']);
if (!is_email($email)) {
wp_send_json_error('Invalid email');
}
$current_email = wp_get_current_user()->user_email;
if ($email != $current_email && email_exists($email)) {
wp_send_json_error('Email already exists');
}
// Update user fields
wp_update_user([
'ID' => $user_id,
'user_email' => $email,
'first_name' => $first_name,
'last_name' => $last_name
]);
// update_user_meta($user_id, 'phone', $country_code . ' ' . $phone);
update_user_meta($user_id, 'phone', sanitize_text_field($phone));
update_user_meta($user_id, 'phone_country_code', sanitize_text_field($country_code));
wp_send_json_success();
});
add_action('wp_ajax_upload_profile_image', 'upload_profile_image_callback');
function upload_profile_image_callback()
{
// check_ajax_referer('profile_image_nonce');
if (!is_user_logged_in()) {
wp_send_json_error(['message' => 'User not logged in']);
}
if (!isset($_FILES['profile_image'])) {
wp_send_json_error(['message' => 'No file uploaded']);
}
$file = $_FILES['profile_image'];
require_once(ABSPATH . 'wp-admin/includes/file.php');
$upload = wp_handle_upload($file, ['test_form' => false]);
if (isset($upload['error'])) {
wp_send_json_error(['message' => $upload['error']]);
}
// Save URL to user meta
$user_id = get_current_user_id();
update_user_meta($user_id, 'profile_picture', $upload['url']);
wp_send_json_success(['image_url' => $upload['url']]);
}
add_action('wp_ajax_change_user_password', 'handle_password_change');
function handle_password_change()
{
if (!is_user_logged_in()) {
wp_send_json_error(['message' => 'Unauthorized.']);
}
$current_password = $_POST['current_password'];
$new_password = $_POST['new_password'];
if (empty($current_password) || empty($new_password)) {
wp_send_json_error(['message' => 'Both current and new passwords are required.']);
}
$user_id = get_current_user_id();
$user = get_userdata($user_id);
if (!wp_check_password($current_password, $user->user_pass, $user_id)) {
wp_send_json_error(['message' => 'Current password is incorrect.']);
}
if ($current_password === $new_password) {
wp_send_json_error(['message' => 'New password cannot be the same as the current password.']);
}
wp_set_password($new_password, $user_id);
wp_logout();
wp_send_json_success([
'message' => 'Password updated successfully.',
'logout_url' => site_url('/login/')
]);
}
function handle_forgot_password()
{
if (!isset($_POST['user_email']) || empty($_POST['user_email'])) {
wp_send_json_error(['message' => 'Please enter a valid email address']);
return;
}
$email = sanitize_email($_POST['user_email']);
$user = get_user_by('email', $email);
if (!$user) {
wp_send_json_success(['message' => 'If this email is registered, you will receive a password reset link.']);
return;
}
// 1. Delete any previous password reset meta
delete_user_meta($user->ID, 'rp_key');
delete_user_meta($user->ID, 'password_reset_status');
delete_user_meta($user->ID, 'rp_expiration');
// 2. Generate a new reset key and store it
$reset_key = get_password_reset_key($user);
if (is_wp_error($reset_key)) {
wp_send_json_error(['message' => 'Unable to generate reset link. Please try again later.']);
return;
}
// 3. Force update the password reset key and expiration manually
update_user_meta($user->ID, 'password_reset_status', 0); // Mark as unused
update_user_meta($user->ID, 'rp_key', $reset_key);
update_user_meta($user->ID, 'rp_expiration', time() + HOUR_IN_SECONDS * 24); // 24-hour expiry
// 4. Create the reset URL
// $reset_url = site_url("/password-reset?action=rp&key=" . urlencode($reset_key) . "&login=" . urlencode($user->user_login));
$reset_url = site_url("/login?action=rp&key=" . urlencode($reset_key) . "&login=" . urlencode($user->user_login));
// 5. Load and replace the email template
$template_path = __DIR__ . '/emails/change_pwd.php';
if (!file_exists($template_path)) {
wp_send_json_error(['message' => 'Email template not found.']);
return;
}
$email_body = file_get_contents($template_path);
$email_body = str_replace('{{reset_link}}', esc_url($reset_url), $email_body);
$base_url = get_template_directory_uri();
$email_body = str_replace('{{base_url}}', $base_url, $email_body);
// 6. Send the email
$subject = "Password Reset Request";
$headers = ['Content-Type: text/html; charset=UTF-8'];
if (wp_mail($email, $subject, $email_body, $headers)) {
wp_send_json_success(['message' => 'If this email is registered, you will receive a password reset link.']);
} else {
wp_send_json_error(['message' => 'Failed to send email. Please try again.']);
}
}
add_action('wp_ajax_handle_forgot_password', 'handle_forgot_password');
add_action('wp_ajax_nopriv_handle_forgot_password', 'handle_forgot_password');
function handle_password_reset()
{
if (!isset($_POST['new_password'], $_POST['reset_key'], $_POST['user_login'])) {
wp_send_json_error(array('message' => 'Invalid request.'));
return;
}
$user_login = sanitize_text_field($_POST['user_login']);
$new_password = $_POST['new_password'];
$reset_key = sanitize_text_field($_POST['reset_key']);
// Get user by login
$user = get_user_by('login', $user_login);
if (!$user) {
wp_send_json_error(array('message' => 'User not found.'));
return;
}
// Validate reset key
$check_key = check_password_reset_key($reset_key, $user->user_login);
if (is_wp_error($check_key)) {
wp_send_json_error(array('message' => 'The reset link is invalid or has expired'));
return;
}
// Prevent using the same password
if (wp_check_password($new_password, $user->user_pass, $user->ID)) {
wp_send_json_error(array('message' => 'New password cannot be the same as the old password.'));
return;
}
// Reset password
reset_password($user, $new_password);
// Delete reset key to prevent reuse
delete_user_meta($user->ID, 'rp_key');
delete_user_meta($user->ID, 'password_reset_status');
delete_user_meta($user->ID, 'rp_expiration');
wp_send_json_success(array('message' => 'Password reset successfully. You can now log in.'));
}
add_action('wp_ajax_handle_password_reset', 'handle_password_reset');
add_action('wp_ajax_nopriv_handle_password_reset', 'handle_password_reset');
function create_video_rentals_table()
{
global $wpdb;
$table = $wpdb->prefix . 'video_rentals';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $table (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
user_id BIGINT NOT NULL,
name VARCHAR(255),
address TEXT,
state VARCHAR(100),
city VARCHAR(100),
zip VARCHAR(20),
phone VARCHAR(50),
card_number VARCHAR(30),
expiry VARCHAR(10),
cvv VARCHAR(10),
country VARCHAR(100),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_video_rentals_table');
//----------------------------------Rent Now---------------------------------------------------------
add_action('wp_ajax_rent_video', 'handle_rent_video');
add_action('wp_ajax_nopriv_rent_video', 'handle_rent_video');
add_action('wp_ajax_handle_rent_video', 'handle_rent_video');
add_action('wp_ajax_nopriv_handle_rent_video', 'handle_rent_video');
function handle_rent_video() {
global $wpdb;
if (!is_user_logged_in()) {
wp_send_json_error(['message' => 'You must be logged in.']);
}
// print_r($_POST);die();
$user_id = get_current_user_id();
$video_id = intval($_POST['video_id']);
$vm_rental = get_post_meta($video_id, 'vm_rental', true);
$postedAmount = floatval($_POST['amount']);
$affiliate_code = sanitize_text_field($_POST['affiliate_code']);
$coupon_code = sanitize_text_field($_POST['coupon_code'] ?? '');
// $name = sanitize_text_field($_POST['name']);
// $address = sanitize_text_field($_POST['address']);
// $state = sanitize_text_field($_POST['state']);
// $city = sanitize_text_field($_POST['city']);
// $country = sanitize_text_field($_POST['country']);
$zip = sanitize_text_field($_POST['zip']);
$phone = sanitize_text_field($_POST['phone']);
$package_type = isset($_POST['package_types']) ? sanitize_text_field($_POST['package_types']) : '';
// STEP 1: Get original price by package
// $license_prices = [
// 'single' => 18,
// 'family' => 36,
// 'group' => 299
// ];
$license_prices = [
'single' => floatval(get_option('individual_price', 18)),
'family' => floatval(get_option('family_price', 36)),
'group' => floatval(get_option('group_price', 299))
];
if (!isset($license_prices[$package_type])) {
wp_send_json_error(['message' => 'Invalid package type.']);
}
$originalAmount = $license_prices[$package_type];
$discount = 0;
$finalAmount = $originalAmount;
// STEP 2: Validate coupon if any
if (!empty($coupon_code)) {
$coupon_row = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}video_coupons WHERE code = %s", $coupon_code
));
if (!$coupon_row || intval($coupon_row->is_active) !== 1) {
wp_send_json_error(['message' => 'Invalid or inactive coupon']);
}
$now = new DateTime('now', wp_timezone());
if (!empty($coupon_row->expires_at) && $coupon_row->expires_at !== '0000-00-00 00:00:00') {
$expiry = DateTime::createFromFormat('Y-m-d H:i:s', $coupon_row->expires_at, wp_timezone());
if ($expiry && $expiry < $now) {
wp_send_json_error(['message' => 'Coupon expired']);
}
}
if (!empty($coupon_row->user_ids)) {
$allowed_ids = array_map('trim', explode(',', $coupon_row->user_ids));
if (!in_array('all', $allowed_ids) && !in_array((string)$user_id, $allowed_ids)) {
wp_send_json_error(['message' => 'You are not eligible for this coupon']);
}
}
// Usage limit check — if limit is not 0
$usage_table = $wpdb->prefix . 'video_coupon_usages';
$usage_count = $wpdb->get_var(
$wpdb->prepare("SELECT COUNT(*) FROM $usage_table WHERE coupon_code = %s", $coupon_code)
);
$usage_limit = intval($row->usage_limit);
if ($usage_limit > 0 && $usage_count >= $usage_limit) {
wp_send_json_error(['message' => 'You have already used this coupon the maximum number of times']);
}
// Apply discount
if ($coupon_row->discount_type === 'percentage') {
$discount = $originalAmount * (floatval($coupon_row->discount_value) / 100);
} elseif ($coupon_row->discount_type === 'flat') {
$discount = floatval($coupon_row->discount_value);
}
$finalAmount = max(0, $originalAmount - $discount);
}
$amount = round($finalAmount, 2); // final amount to charge
// Step 3: Validate mismatch between server amount and frontend amount
if (!is_null($postedAmount) && abs($postedAmount - $amount) > 0.01) {
error_log("Tampered amount detected for video ID $video_id. Posted: $postedAmount, Expected: $amount");
wp_send_json_error([
'message' => 'The payment amount did not match. Please refresh the page and try again.'
]);
}
if ($amount > 0) {
$card_number = sanitize_text_field($_POST['card_number']);
$expiry = sanitize_text_field($_POST['expiry']); // MM/YY
$cvv = sanitize_text_field($_POST['cvv']);
// ✅ Validate and format expiry
if (strpos($expiry, '/') === false) {
wp_send_json_error(['message' => 'Invalid expiry format']);
}
list($exp_month, $exp_year) = array_map('trim', explode('/', $expiry));
$exp_month = str_pad($exp_month, 2, '0', STR_PAD_LEFT);
$exp_year = (strlen($exp_year) === 2) ? ('20' . $exp_year) : $exp_year;
$xExp = $exp_month . substr($exp_year, -2); // MMYY format
// ✅ Cardknox API call
$cardknox_key = 'spericorndev272f621906bc45d4871c84f57f7b99b2';
// $cardknox_key = get_option('cardknox_api_key');
$payload = [
'xKey' => $cardknox_key,
'xVersion' => '4.5.0',
'xCommand' => 'cc:Sale',
'xAmount' => $amount,
'xCardNum' => $card_number,
'xExp' => $xExp,
'xCVV' => $cvv,
'xEmail' => wp_get_current_user()->user_email,
'xBillFirstName' => $name,
'xBillZip' => $zip,
];
$response = wp_remote_post('https://x1.cardknox.com/gateway', [
'timeout' => 30,
'body' => $payload
]);
if (is_wp_error($response)) {
error_log('Cardknox Error: ' . $response->get_error_message());
wp_send_json_error(['message' => 'Cardknox error: ' . $response->get_error_message()]);
}
$body = wp_remote_retrieve_body($response);
if (empty($body)) {
error_log('Cardknox response body was empty. Full response: ' . print_r($response, true));
}
// Log raw response
error_log('Raw Response from Cardknox: ' . $body);
// Parse response
parse_str($body, $parsed);
// Log parsed response
if (!empty($parsed)) {
foreach ($parsed as $key => $value) {
error_log($key . ': ' . $value);
}
} else {
error_log('Cardknox response parsing failed or returned empty data.');
}
// Validate transaction result
if (!isset($parsed['xResult']) || $parsed['xResult'] !== 'A') {
wp_send_json_error(['message' => $parsed['xError'] ?? 'Transaction failed']);
}
$transaction_id = $parsed['xRefNum'] ?? '';
} else {
$transaction_id = 'NO_CHARGE';
}
global $wpdb;
if (!empty($coupon_code)) {
$coupon_usage_table = $wpdb->prefix . 'video_coupon_usages';
$wpdb->insert($coupon_usage_table, [
'transaction_id' => $transaction_id,
'coupon_code' => $coupon_code,
'used_at' => current_time('mysql')
]);
}
// ✅ Save successful transaction
$table = $wpdb->prefix . 'video_rentals';
// Fetch all published videos
$args = [
'post_type' => 'vm_video',
'posts_per_page' => -1,
'post_status' => 'publish'
];
$video_query = new WP_Query($args);
if ($video_query->have_posts()) {
while ($video_query->have_posts()) {
$video_query->the_post();
$video_id = get_the_ID();
$vm_rental = get_post_meta($video_id, 'vm_rental', true);
$vm_rental_data = [
'user_id' => $user_id,
'video_id' => $video_id,
'cardknox_transaction_id' => $transaction_id,
'amount' => $amount,
'rental_duration' => $vm_rental,
'name' => $name,
// 'address' => $address,
// 'state' => $state,
// 'city' => $city,
// 'country' => $country,
'zip' => $zip,
'phone' => $phone,
'license_type' => $package_type,
'affiliate_code' => $affiliate_code,
'rented_at' => current_time('mysql'),
];
$vm_rental_insert = $wpdb->insert($table, $vm_rental_data);
if ($vm_rental_insert === false) {
error_log('VM Rental Insert Error: ' . $wpdb->last_error);
error_log('VM Rental Insert Data: ' . print_r($vm_rental_data, true));
error_log('Last Query: ' . $wpdb->last_query);
}
}
wp_reset_postdata();
}
$rental_id = $wpdb->insert_id;
// Insert into transactions table
$transactions_table = $wpdb->prefix . 'video_transactions';
$transaction_data = [
'rental_id' => $rental_id,
'transaction_id' => $transaction_id,
'amount' => $amount,
'license' => $package_type,
'coupon_code' => $coupon_code,
'created_at' => current_time('mysql'),
];
$transaction_insert = $wpdb->insert($transactions_table, $transaction_data);
if ($transaction_insert === false) {
error_log('Transaction Insert Error: ' . $wpdb->last_error);
error_log('Transaction Insert Data: ' . print_r($transaction_data, true));
error_log('Last Query: ' . $wpdb->last_query);
}
// Update user meta only if affiliate_code is not empty
update_user_meta($user_id, 'referred_by_affiliate', null);
// Load the email template
$template_path = __DIR__ . '/emails/purchase_confirmation.php';
if (!file_exists($template_path)) {
wp_send_json_error(['message' => 'Email template not found.']);
}
$verification_link = site_url('/profile/');
$email_body = file_get_contents($template_path);
$base_url = get_template_directory_uri();
$email = wp_get_current_user()->user_email;
$display_name = wp_get_current_user()->display_name;
// Replace placeholders with dynamic data
$email_body = str_replace('{{verification_link}}', esc_url($verification_link), $email_body);
$email_body = str_replace('{{display_name}}', esc_html($display_name), $email_body);
$email_body = str_replace('{{amount}}', esc_html($amount), $email_body);
$email_body = str_replace('{{base_url}}', $base_url, $email_body);
// Send email
$subject = "Thank You for Your Purchase";
$headers = ['Content-Type: text/html; charset=UTF-8'];
if (!wp_mail($email, $subject, $email_body, $headers)) {
wp_send_json_error(['message' => 'Failed to send verification email.']);
}
// 🎉 Success
wp_send_json_success(['message' => 'Payment successful! Video added to your rentals.']);
}
//----------------------Common Rental Settings--------------------------------------------
// 1. Add Admin Menu Page
add_action('admin_menu', function () {
add_menu_page(
'Rental Settings', // Page title
'Rental Settings', // Menu title
'manage_options', // Capability
'rental-settings', // Menu slug
'rental_settings_page', // Callback function
'dashicons-controls-repeat', // Icon
100
);
});
// 2. Admin Page Callback
function rental_settings_page()
{
?>
<div class="wrap">
<h1>Rental Settings</h1>
<form method="post" action="options.php">
<?php
settings_fields('rental_settings_group');
do_settings_sections('rental-settings');
submit_button();
?>
</form>
</div>
<?php
}
// 3. Register Settings and Fields
add_action('admin_init', function () {
// Register options
register_setting('rental_settings_group', 'individual_price');
register_setting('rental_settings_group', 'family_price');
register_setting('rental_settings_group', 'group_price');
register_setting('rental_settings_group', 'rental_period_days');
// ✅ new setting
// Add section
add_settings_section(
'rental_main_section',
'Rental Options',
null,
'rental-settings'
);
// Individual price field
add_settings_field(
'individual_price',
'Individual Price ($)',
function () {
$value = esc_attr(get_option('individual_price', '18'));
echo "<input type='number' name='individual_price' value='{$value}' min='0' step='0.01'>";
},
'rental-settings',
'rental_main_section'
);
// Family price field
add_settings_field(
'family_price',
'Family Price ($)',
function () {
$value = esc_attr(get_option('family_price', '36'));
echo "<input type='number' name='family_price' value='{$value}' min='0' step='0.01'>";
},
'rental-settings',
'rental_main_section'
);
// Group price field
add_settings_field(
'group_price',
'Group Price ($)',
function () {
$value = esc_attr(get_option('group_price', '299'));
echo "<input type='number' name='group_price' value='{$value}' min='0' step='0.01'>";
},
'rental-settings',
'rental_main_section'
);
// ✅ Rental period field
add_settings_field(
'rental_period_days',
'Rental Period (in days)',
function () {
$value = esc_attr(get_option('rental_period_days', '7'));
echo "<input type='number' name='rental_period_days' value='{$value}' min='1' step='1'>";
},
'rental-settings',
'rental_main_section'
);
});
function get_package_price_ajax() {
$type = sanitize_text_field($_GET['type']);
if ($type === 'single') {
$amount = get_option('individual_price', 18);
} elseif ($type === 'family') {
$amount = get_option('family_price', 36);
} elseif ($type === 'group') {
$amount = get_option('group_price', 299);
} else {
wp_send_json_error(['message' => 'Invalid package type']);
}
wp_send_json_success(['amount' => $amount]);
}
add_action('wp_ajax_get_package_price', 'get_package_price_ajax');
add_action('wp_ajax_nopriv_get_package_price', 'get_package_price_ajax');
function handle_ajax_contact_form() {
// Sanitize input values based on new field names
$first_name = sanitize_text_field($_POST['first_name'] ?? '');
$email = sanitize_email($_POST['email'] ?? '');
$phone = sanitize_text_field($_POST['phone'] ?? '');
$subject = sanitize_text_field($_POST['subject'] ?? '');
$description = sanitize_textarea_field($_POST['description'] ?? '');
// Validate required fields (optional fallback if JS validation fails)
if (empty($first_name) || empty($email) || empty($phone) || empty($description)) {
wp_send_json_error(['success' => false, 'message' => 'All fields are required.']);
}
// Admin email
$admin_email = 'dakosher@gmail.com';
$headers = [
'Content-Type: text/html; charset=UTF-8',
'Reply-To: ' . $first_name . ' <' . $email . '>'
];
// Load the email template
$template_path = __DIR__ . '/emails/contact-email.php';
if (!file_exists($template_path)) {
wp_send_json_error(['success' => false, 'message' => 'Contact email template not found.']);
}
$admin_message = file_get_contents($template_path);
$base_url = get_template_directory_uri();
// Set default subject if empty
if (empty($subject)) {
$email_subject = "New contact form submission from $first_name";
} else {
$email_subject = sanitize_text_field($_POST['subject'] ?? '');
}
// Replace template placeholders
$admin_message = str_replace('{{display_name}}', esc_html($first_name), $admin_message);
$admin_message = str_replace('{{email}}', esc_html($email), $admin_message);
$admin_message = str_replace('{{phone_no}}', esc_html($phone), $admin_message);
$admin_message = str_replace('{{subject}}', esc_html($subject), $admin_message);
$admin_message = str_replace('{{message}}', esc_html($description), $admin_message);
$admin_message = str_replace('{{base_url}}', esc_url($base_url), $admin_message);
// Send the email
$sent = wp_mail($admin_email, $email_subject, $admin_message, $headers);
if ($sent) {
wp_send_json_success(['success' => true, 'message' => 'Thank you for contacting us. We will be in touch shortly!']);
} else {
wp_send_json_error(['success' => false, 'message' => 'Failed to send the message. Please try again later.']);
}
wp_die();
}
add_action('wp_ajax_submit_contact_form', 'handle_ajax_contact_form');
add_action('wp_ajax_nopriv_submit_contact_form', 'handle_ajax_contact_form');
function create_video_transactions_table()
{
global $wpdb;
$table = $wpdb->prefix . 'video_transactions';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $table (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
rental_id BIGINT(20) UNSIGNED NOT NULL,
transaction_id VARCHAR(100),
amount DECIMAL(10,2),
license VARCHAR(50) DEFAULT 'standard',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY rental_id (rental_id)
) $charset_collate;";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_video_transactions_table');
//-----------------------Affiliate-----------------------------------------------------------
add_action('init', function () {
if (isset($_GET['aff'])) {
setcookie(
'affiliate_ref',
sanitize_text_field($_GET['aff']),
time() + DAY_IN_SECONDS, // 1 day
COOKIEPATH,
COOKIE_DOMAIN,
is_ssl(),
true
);
}
});
// Show affiliate code field on user edit page
add_action('show_user_profile', 'add_affiliate_code_field');
add_action('edit_user_profile', 'add_affiliate_code_field');
function add_affiliate_code_field($user)
{
if (!current_user_can('edit_users'))
return;
?>
<h3>Affiliate Settings</h3>
<table class="form-table">
<tr>
<th><label for="affiliate_code">Affiliate Code</label></th>
<td>
<input type="text" name="affiliate_code" id="affiliate_code"
value="<?php echo esc_attr(get_user_meta($user->ID, 'affiliate_code', true)); ?>"
class="regular-text" />
<p class="description">Set a custom affiliate code for this user (used in URLs like <code>?aff=code</code>).
</p>
</td>
</tr>
</table>
<?php
}
// Save affiliate code field
add_action('personal_options_update', 'save_affiliate_code_field');
add_action('edit_user_profile_update', 'save_affiliate_code_field');
function save_affiliate_code_field($user_id)
{
if (!current_user_can('edit_users'))
return;
if (isset($_POST['affiliate_code'])) {
$new_code = sanitize_text_field($_POST['affiliate_code']);
update_user_meta($user_id, 'affiliate_code', $new_code);
}
}
add_action('admin_menu', 'register_affiliate_sales_menu');
function register_affiliate_sales_menu()
{
add_menu_page(
'Affiliate Sales',
'Affiliate Sales',
'manage_options',
'affiliate-sales',
'render_affiliate_sales_page',
'dashicons-chart-line',
26
);
}
function render_affiliate_sales_page()
{
global $wpdb;
$per_page = 20;
$paged = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
$offset = ($paged - 1) * $per_page;
$where = "WHERE vr.affiliate_code IS NOT NULL AND vr.affiliate_code != ''";
$params = [];
if (!empty($_GET['affiliate'])) {
$where .= " AND vr.affiliate_code = %s";
$params[] = sanitize_text_field($_GET['affiliate']);
}
if (!empty($_GET['start_date']) && !empty($_GET['end_date'])) {
$where .= " AND DATE(vt.created_at) BETWEEN %s AND %s";
$params[] = sanitize_text_field($_GET['start_date']);
$params[] = sanitize_text_field($_GET['end_date']);
}
$base_query = "
FROM {$wpdb->prefix}video_rentals vr
LEFT JOIN {$wpdb->prefix}video_transactions vt ON vr.id = vt.rental_id
$where
";
// Count total unique affiliate codes for pagination
$total = $wpdb->get_var($wpdb->prepare("
SELECT COUNT(DISTINCT vr.affiliate_code) $base_query
", ...$params));
// Count total sales that have affiliate attribution
$total_sales_amount = $wpdb->get_var($wpdb->prepare("
SELECT SUM(vt.amount)
FROM {$wpdb->prefix}video_rentals vr
LEFT JOIN {$wpdb->prefix}video_transactions vt ON vr.id = vt.rental_id
$where
", ...$params));
// Get affiliate sales summary
$results = $wpdb->get_results($wpdb->prepare("
SELECT vr.affiliate_code, SUM(vt.amount) as total_sales, COUNT(vt.id) as total_transactions
$base_query
GROUP BY vr.affiliate_code
ORDER BY total_sales DESC
LIMIT %d OFFSET %d
", ...array_merge($params, [$per_page, $offset])));
$total_pages = ceil($total / $per_page);
echo '<div class="wrap">';
echo '<h1>Affiliate Sales Summary</h1>';
echo '<h2>Total Affiliate Sales: $' . number_format((float)$total_sales_amount, 2) . '</h2>';
echo '<form method="get" class="affiliate-filters">';
echo '<input type="hidden" name="page" value="affiliate-sales" />';
echo '<input type="text" name="affiliate" placeholder="Affiliate Code" value="' . esc_attr($_GET['affiliate'] ?? '') . '" /> ';
echo '<input type="date" name="start_date" value="' . esc_attr($_GET['start_date'] ?? '') . '" /> to ';
echo '<input type="date" name="end_date" value="' . esc_attr($_GET['end_date'] ?? '') . '" /> ';
echo '<input type="submit" class="button button-primary" value="Filter" />';
echo '<a href="' . admin_url('admin.php?page=affiliate-sales') . '" class="button">Reset</a>';
echo '</form>';
echo '<table class="widefat striped">';
echo '<thead><tr><th>Affiliate Code</th><th>Total Sales</th><th>Total Transactions</th><th>Details</th></tr></thead><tbody>';
if ($results) {
foreach ($results as $row) {
$code = esc_html($row->affiliate_code);
echo '<tr>';
echo '<td>' . $code . '</td>';
echo '<td>$' . number_format($row->total_sales, 2) . '</td>';
echo '<td>' . intval($row->total_transactions) . '</td>';
echo '<td><a href="' . esc_url(admin_url('admin.php?page=transaction-listing&type=affiliate&affiliate=' . urlencode($code))) . '" class="button">View Transactions</a></td>';
echo '</tr>';
}
} else {
echo '<tr><td colspan="4">No affiliate sales found.</td></tr>';
}
echo '</tbody></table>';
// Pagination
if ($total_pages > 1) {
echo '<div class="tablenav"><div class="tablenav-pages">';
$current_url = remove_query_arg('paged');
for ($i = 1; $i <= $total_pages; $i++) {
if ($i == $paged) {
echo "<span class='page-numbers current'>$i</span> ";
} else {
echo '<a class="page-numbers" href="' . esc_url(add_query_arg('paged', $i, $current_url)) . '">' . $i . '</a> ';
}
}
echo '</div></div>';
}
echo '</div>';
}
function enqueue_invoice_download_scripts()
{
// html2pdf external library
wp_enqueue_script(
'html2pdf-js',
'https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js',
[],
null,
true
);
// Your custom script
wp_enqueue_script(
'download-invoice',
get_template_directory_uri() . '/js/download-invoice.js',
['jquery', 'html2pdf-js'],
time(),
true
);
// Pass PHP variable to JS
wp_localize_script('download-invoice', 'download_invoice_vars', [
'invoice_template_url' => get_template_directory_uri() . '/invoices/affiliate-invoice.php',
'trans_invoice_template_url' => get_template_directory_uri() . '/invoices/transaction_invoice.php',
]);
}
add_action('wp_enqueue_scripts', 'enqueue_invoice_download_scripts'); // For frontend
add_action('admin_enqueue_scripts', 'enqueue_invoice_download_scripts'); // For admin
add_action('admin_menu', function () {
add_menu_page(
'Transactions',
'Transactions',
'manage_options',
'transaction-listing',
'render_transaction_listing_page',
'dashicons-list-view',
25
);
});
function render_transaction_listing_page()
{
global $wpdb;
$per_page = 20;
$paged = max(1, intval($_GET['paged'] ?? 1));
$offset = ($paged - 1) * $per_page;
// Build WHERE clause based on filters
$where = "WHERE 1=1";
$params = [];
if ($f = sanitize_text_field($_GET['f_022a'] ?? '')) {
$where .= " AND t.transaction_id LIKE %s";
$params[] = "%{$f}%";
}
if ($u = sanitize_text_field($_GET['user'] ?? '')) {
$where .= " AND u.display_name LIKE %s";
$params[] = "%{$u}%";
}
if (!empty($_GET['start_date']) && !empty($_GET['end_date'])) {
$where .= " AND DATE(t.created_at) BETWEEN %s AND %s";
$params[] = $_GET['start_date'];
$params[] = $_GET['end_date'];
}
if (!empty($_GET['affiliate'])) {
$affiliate = sanitize_text_field($_GET['affiliate']);
$where .= " AND r.affiliate_code = %s";
$params[] = $affiliate;
} elseif ($type = sanitize_text_field($_GET['type'] ?? '')) {
if ($type === 'affiliate') {
$where .= " AND r.affiliate_code != ''";
} elseif ($type === 'regular') {
$where .= " AND (r.affiliate_code = '' OR r.affiliate_code IS NULL)";
}
}
if ($p = sanitize_text_field($_GET['product'] ?? '')) {
$where .= " AND p.post_title LIKE %s";
$params[] = "%{$p}%";
}
// Base query with joins
$base = "
FROM {$wpdb->prefix}video_transactions t
LEFT JOIN {$wpdb->prefix}video_rentals r ON t.rental_id = r.id
LEFT JOIN {$wpdb->prefix}users u ON r.user_id = u.ID
LEFT JOIN {$wpdb->prefix}posts p ON r.video_id = p.ID
$where
";
$total = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) $base", ...$params));
$total_sales = $wpdb->get_var($wpdb->prepare("SELECT SUM(t.amount) $base", ...$params));
$rows = $wpdb->get_results($wpdb->prepare("
SELECT t.*, u.ID AS user_id, u.display_name AS user_name, p.post_title AS product_name,
r.affiliate_code
$base
ORDER BY t.created_at DESC
LIMIT %d OFFSET %d
", ...array_merge($params, [$per_page, $offset])));
$total_pages = ceil($total / $per_page);
// Filters form
echo '<div class="wrap"><h1>Transactions</h1>';
echo '<h2>Total Sales: $' . number_format((float)$total_sales, 2) . '</h2>';
echo '<form method="get">';
echo '<input type="hidden" name="page" value="transaction-listing" />';
echo '<input placeholder="Trans ID (F_022a)" name="f_022a" value="' . esc_attr($_GET['f_022a'] ?? '') . '" />';
echo '<input placeholder="User Name" name="user" value="' . esc_attr($_GET['user'] ?? '') . '" />';
echo '<input type="date" name="start_date" value="' . esc_attr($_GET['start_date'] ?? '') . '" />';
echo ' to <input type="date" name="end_date" value="' . esc_attr($_GET['end_date'] ?? '') . '" />';
echo '<select name="type">
<option value="">All</option>
<option value="affiliate" ' . selected($_GET['type'] ?? '', 'affiliate', false) . '>Affiliate</option>
<option value="regular" ' . selected($_GET['type'] ?? '', 'regular', false) . '>Regular</option>
</select>';
echo '<input placeholder="Product Name" name="product" value="' . esc_attr($_GET['product'] ?? '') . '" />';
echo '<input type="submit" class="button button-primary" value="Filter" />';
echo '<a href="' . admin_url('admin.php?page=transaction-listing') . '" class="button">Reset</a>';
echo '</form>';
// Table header
echo '<table class="widefat striped"><thead><tr>
<th>User</th><th>Date & Time</th><th>Product</th><th>F_022</th>
<th>Amount</th><th>Trans ID</th><th>Coupon</th><th>Type</th><th>Invoice</th></tr></thead><tbody>';
if ($rows)
foreach ($rows as $r) {
$link_user = admin_url('user-edit.php?user_id=' . $r->user_id);
$affiliate_link = $r->affiliate_code
? admin_url('admin.php?page=affiliate-sales&affiliate=' . urlencode($r->affiliate_code))
: '';
echo '<tr>';
echo '<td><a href="' . esc_url($link_user) . '">' . esc_html($r->user_name) . '</a></td>';
echo '<td>' . esc_html($r->created_at) . '</td>';
echo '<td>' . esc_html($r->product_name) . '</td>';
echo '<td><code>' . esc_html($r->transaction_id) . '</code></td>';
echo '<td>' . esc_html(number_format($r->amount, 2)) . '</td>';
echo '<td>' . esc_html($r->transaction_id) . '</td>';
echo '<td>' . esc_html($r->coupon_code ?? '') . '</td>';
echo '<td>' . ($affiliate_link
? '<a href="' . esc_url($affiliate_link) . '">Affiliate</a>'
: 'Regular') . '</td>';
echo '<td><button class="button download-invoice-btn-txn" data-tid="' . esc_attr($r->rental_id) . '">Download Invoice</button></td>';
echo '</tr>';
} else {
echo '<tr><td colspan="8">No transactions found.</td></tr>';
}
echo '</tbody></table>';
// Pagination
if ($total_pages > 1) {
echo '<div class="tablenav"><div class="tablenav-pages">';
$base_url = remove_query_arg('paged');
for ($i = 1; $i <= $total_pages; $i++) {
if ($i === $paged)
echo "<span class='page-numbers current'>$i</span> ";
else
echo '<a href="' . esc_url(add_query_arg('paged', $i, $base_url)) . '" class="page-numbers">' . $i . '</a> ';
}
echo '</div></div>';
}
echo '</div>';
}
//-------------------------Generate Afiiliate code---------------------------------
register_activation_hook(__FILE__, 'create_affiliate_code_table');
add_action('admin_menu', function () {
add_menu_page(
'Affiliate Codes',
'Affiliates',
'manage_options',
'affiliate-codes',
'render_affiliate_admin_page',
'dashicons-admin-users',
30
);
});
function render_affiliate_admin_page()
{
global $wpdb;
$table = $wpdb->prefix . 'affiliate_codes';
// Handle form submission
if (isset($_POST['affiliate_code'])) {
$code = sanitize_text_field($_POST['affiliate_code']);
if ($code) {
$wpdb->insert($table, ['code' => $code]);
echo '<div class="notice notice-success"><p>Affiliate code added!</p></div>';
}
}
// Fetch all affiliate codes
$codes = $wpdb->get_results("SELECT * FROM $table ORDER BY id DESC");
?>
<div class="wrap">
<h1>Affiliate Codes</h1>
<form method="post">
<input type="text" name="affiliate_code" placeholder="Enter new code" required />
<input type="submit" class="button button-primary" value="Add Code">
</form>
<hr>
<h2>Existing Codes</h2>
<table class="widefat">
<thead>
<tr>
<th>Code</th>
<th>Share Link</th>
<th>Created</th>
</tr>
</thead>
<tbody>
<?php foreach ($codes as $row): ?>
<tr>
<td><strong><?php echo esc_html($row->code); ?></strong></td>
<td><a href="<?php echo esc_url(home_url('/?aff=' . $row->code)); ?>"
target="_blank"><?php echo esc_url(home_url('/?aff=' . $row->code)); ?></a></td>
<td><?php echo esc_html($row->created_at); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php
}
add_action('user_register', function ($user_id) {
if (isset($_COOKIE['affiliate_ref'])) {
update_user_meta($user_id, 'referred_by_affiliate', sanitize_text_field($_COOKIE['affiliate_ref']));
}
});
add_action('wp_ajax_validate_discount_code', 'validate_discount_code');
add_action('wp_ajax_nopriv_validate_discount_code', 'validate_discount_code');
function validate_discount_code()
{
$code = sanitize_text_field($_POST['code']);
$video_id = intval($_POST['video_id']);
$package_type = sanitize_text_field($_POST['package_type']);
$user_id = get_current_user_id();
if (!$user_id) {
wp_send_json_error(['message' => 'You must be logged in to use a coupon code.']);
}
global $wpdb;
$table = $wpdb->prefix . 'video_coupons';
$row = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE code = %s", $code));
if (!$row || intval($row->is_active) !== 1) {
wp_send_json_error(['message' => 'Invalid or inactive coupon code']);
}
// Use WP timezone
$wp_timezone = wp_timezone(); // returns a DateTimeZone object
$now = new DateTime('now', $wp_timezone);
// Expiry date check — treat empty or '0000-00-00 00:00:00' as "never expires"
if (!empty($row->expires_at) && $row->expires_at !== '0000-00-00 00:00:00') {
$expiry = DateTime::createFromFormat('Y-m-d H:i:s', $row->expires_at, $wp_timezone);
if ($expiry && $expiry < $now) {
wp_send_json_error(['message' => 'Coupon has expired']);
}
}
// User eligibility — must be explicitly "All" or contain current user
if (!empty($row->user_ids)) {
$allowed_user_ids = array_map('trim', explode(',', $row->user_ids));
if (!in_array('all', $allowed_user_ids) && !in_array(strval($user_id), $allowed_user_ids)) {
wp_send_json_error(['message' => 'You are not eligible to use this coupon']);
}
}
// Usage limit check — if limit is not 0
$usage_table = $wpdb->prefix . 'video_coupon_usages';
$usage_count = $wpdb->get_var(
$wpdb->prepare("SELECT COUNT(*) FROM $usage_table WHERE coupon_code = %s", $code)
);
$usage_limit = intval($row->usage_limit);
if ($usage_limit > 0 && $usage_count >= $usage_limit) {
wp_send_json_error(['message' => 'You have already used this coupon the maximum number of times']);
}
// Original price based on package type
// if ($package_type === 'single') {
// $originalAmount = 18;
// } elseif ($package_type === 'family') {
// $originalAmount = 36;
// } elseif ($package_type === 'group') {
// $originalAmount = 299;
// }
if ($package_type === 'single') {
$originalAmount = floatval(get_option('individual_price', 18));
} elseif ($package_type === 'family') {
$originalAmount = floatval(get_option('family_price', 36));
} elseif ($package_type === 'group') {
$originalAmount = floatval(get_option('group_price', 299));
}
// Discount calculation
$discount = 0;
if ($row->discount_type === 'percentage') {
$discount = $originalAmount * (floatval($row->discount_value) / 100);
} elseif ($row->discount_type === 'flat') {
$discount = floatval($row->discount_value);
}
$newAmount = max(0, $originalAmount - $discount);
wp_send_json_success([
'message' => 'Coupon applied successfully!',
'discounted_amount' => $newAmount,
'discount' => round($discount, 2),
'original_amount' => $originalAmount
]);
}