File: /mnt/data/doccure-wp/wp-content/themes/doccure/functions.php
<?php
/**
* doccure functions and definitions
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package doccure
*/
if ( ! defined('ABSPATH') ) {
exit;
}
add_action('after_setup_theme', 'doccure_load_textdomain_new');
function doccure_load_textdomain_new() {
load_theme_textdomain('doccure', get_template_directory() . '/languages');
}
// Theme utility functions
require get_template_directory() . '/inc/scripts.php'; //Theme styles and scripts
require get_template_directory() . '/inc/functions-utilities.php';
// Theme Setup
require get_template_directory() . '/inc/functions-setup.php';
// Theme Scripts/Styles
require get_template_directory() . '/inc/functions-scripts.php';
// Custom template tags for this theme.
require get_template_directory() . '/inc/template-tags.php';
// Functions which enhance the theme by hooking into WordPress.
require get_template_directory() . '/inc/template-functions.php';
// Social Media Functions
require get_template_directory() . '/inc/functions-social.php';
// Dynamic Css
require get_template_directory() . '/inc/color-customizer.php';
// Subheader Functions
require get_template_directory() . '/inc/functions-subheader.php';
// Sidebar Functions
require get_template_directory() . '/inc/functions-sidebars.php';
add_action('after_setup_theme', 'doccure_load_textdomain_sc1');
function doccure_load_textdomain_sc1() {
// WooCommerce Functions
require get_template_directory() . '/inc/functions-woocommerce.php';
// Responsible for edd options
require get_template_directory() . '/inc/functions-edd.php';
// Load theme options.
}
add_action('after_setup_theme', 'doccure_load_redux_options');
function doccure_load_redux_options() {
if (class_exists('Redux')) {
require get_template_directory() . '/inc/redux-options/redux-config.php';
}
}
// TGM plugin activation.
require get_template_directory() . '/inc/tgm-plugin-activation/required-plugin.php';
// Responsible for post functions
require get_template_directory() . '/inc/classes/class-doccure-blog-functions.php';
// Responsible for portfolio functions
require get_template_directory() . '/inc/classes/class-doccure-portfolio-functions.php';
// Responsible for service functions
require get_template_directory() . '/inc/classes/class-doccure-service-functions.php';
// Responsible for lazy load functions
require get_template_directory() . '/inc/classes/class-doccure-lazy-load-functions.php';
require get_template_directory() . '/widgets/recent-posts-widgets.php';
// Responsible for bfi thumb functions
require get_template_directory() . '/inc/classes/BFI_Thumb.php';
// Subheader Functions
require get_template_directory() . '/inc/functions-popup.php';
/*========================
CUSTOM WALKERS
========================*/
// Comment walker.
require get_template_directory() . '/classes/class-doccure-walker-comment.php';
// Category Widget walker.
require get_template_directory() . '/classes/class-doccure-walker-category.php';
require_once ( get_template_directory() . '/inc/class-notifications.php'); //Theme notifications
require_once ( get_template_directory() . '/inc/sidebars.php'); //Theme sidebars
require_once ( get_template_directory() . '/directory/front-end/hooks.php');
require_once ( get_template_directory() . '/directory/front-end/hooks-extra.php');
require_once ( get_template_directory() . '/inc/functions.php'); //Theme functionalty
require_once doccure_override_templates('/inc/class-headers.php'); //headers
require_once doccure_override_templates('/inc/class-titlebars.php'); //Sub headers
require_once ( get_template_directory() . '/inc/constants.php'); //Constants
require_once ( get_template_directory() . '/inc/class-woocommerce.php'); //Woocommerce
require_once ( get_template_directory() . '/inc/languages.php');
require_once ( get_template_directory() . '/inc/typo.php');
require_once ( get_template_directory() . '/inc/google_fonts.php'); // goolge fonts
require_once ( get_template_directory() . '/inc/hooks.php'); //Hooks
require_once ( get_template_directory() . '/inc/template-tags.php'); //Tags
require_once ( get_template_directory() . '/directory/front-end/class-dashboard-menu.php');
require_once ( get_template_directory() . '/directory/front-end/functions.php');
require_once ( get_template_directory() . '/directory/front-end/woo-hooks.php');
require_once ( get_template_directory() . '/directory/back-end/dashboard.php');
require_once ( get_template_directory() . '/directory/back-end/functions.php');
require_once ( get_template_directory() . '/directory/front-end/ajax-hooks1.php');
require_once ( get_template_directory() . '/directory/front-end/ajax-hooks2.php');
require_once ( get_template_directory() . '/directory/front-end/ajax-hooks3.php');
require_once ( get_template_directory() . '/directory/front-end/term_walkers.php'); //Term walkers
if( class_exists( 'doccureGlobalSettings' ) ) {
require_once ( get_template_directory() . '/inc/class-pdf.php'); //Hooks
}
require_once ( get_template_directory() . '/directory/front-end/functions-pdf.php');
function my_custom_styles() {
wp_register_style('custom-styles', get_template_directory_uri(). '/assets/css/dashboard.css');
wp_enqueue_style('custom-styles');
}
add_action('wp_enqueue_scripts', 'my_custom_styles');
function doccure_paginationblog() {
if( is_singular() )
return;
global $wp_query;
/** Stop execution if there's only 1 page */
if( $wp_query->max_num_pages <= 1 )
return;
$paged = get_query_var( 'paged' ) ? absint( get_query_var( 'paged' ) ) : 1;
$max = intval( $wp_query->max_num_pages );
/** Add current page to the array */
if ( $paged >= 1 )
$links[] = $paged;
/** Add the pages around the current page to the array */
if ( $paged >= 3 ) {
$links[] = $paged - 1;
$links[] = $paged - 2;
}
if ( ( $paged + 2 ) <= $max ) {
$links[] = $paged + 2;
$links[] = $paged + 1;
}
if ( $paged >= 1 ){
echo '
<div class="col-md-12 ">
<div class="post-pagination">
<ul class="paginations">' . "\n";
/** Previous Post Link */
if ( get_previous_posts_link() )
printf( '<li class="arrow">%s</li>' . "\n", get_previous_posts_link( __( '<i class="fas fa-angle-double-left"></i>', 'doccure' ) ) );
/** Link to first page, plus ellipses if necessary */
if ( ! in_array( 1, $links ) ) {
$class = 1 == $paged ? ' class="active"' : '';
printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( get_pagenum_link( 1 ) ), '1' );
if ( ! in_array( 2, $links ) )
echo '<li>…</li>';
}
/** Link to current page, plus 2 pages in either direction if necessary */
sort( $links );
foreach ( (array) $links as $link ) {
$class = $paged == $link ? ' class="active"' : '';
printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( get_pagenum_link( $link ) ), $link );
}
/** Link to last page, plus ellipses if necessary */
if ( ! in_array( $max, $links ) ) {
if ( ! in_array( $max - 1, $links ) )
echo '<li>…</li>' . "\n";
$class = $paged == $max ? ' class="active"' : '';
printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( get_pagenum_link( $max ) ), $max );
}
/** Next Post Link */
if ( get_next_posts_link() )
printf( '<li class="arrow">%s</li>' . "\n", get_next_posts_link( __( '<i class="fas fa-angle-double-right"></i>', 'doccure' ) ) );
echo '</ul></div></div>' . "\n";
}
}
add_filter('wpcf7_autop_or_not', '__return_false');
// Remove `Payment Methods` from `woocommerce_checkout_order_review` hook
remove_action('woocommerce_checkout_order_review', 'woocommerce_checkout_payment', 20 );
require_once get_template_directory(). '/inc/doccure-demo-content.php';
function enqueue_otp_scripts() {
global $doccure_options;
$otp_switch = isset($doccure_options['otp_switch']) ? $doccure_options['otp_switch'] : 0;
wp_enqueue_script('otp-script', get_template_directory_uri() . '/assets/js/otp-script.js', array('jquery'), null, true);
// Pass AJAX URL, nonce, and otp_switch value to the script
wp_localize_script('otp-script', 'ajax_object', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('send_otp_nonce'),
'otp_switch' => $otp_switch,
));
}
add_action('wp_enqueue_scripts', 'enqueue_otp_scripts');
function doccure_custom_header_setup() {
$args = array(
'default-image' => '',
'default-text-color' => '',
'width' => 0,
'height' => 0,
'flex-width' => true,
'flex-height' => true,
'uploads' => true,
'random-default' => false,
'header-text' => true,
'default-text-color' => '',
'wp-head-callback' => '',
'admin-head-callback' => '',
'admin-preview-callback' => '',
);
add_theme_support( 'custom-header', $args );
}
add_action( 'after_setup_theme', 'doccure_custom_header_setup' );
function doccure_custom_block_styles() {
add_theme_support( 'wp-block-styles' );
}
add_action( 'after_setup_theme', 'doccure_custom_block_styles' );
function doccure_register_block_patterns() {
register_block_pattern(
'doccure/hero',
array(
'title' => __( 'Hero Section', 'doccure' ),
'description' => __( 'A hero section with a background image and a heading.', 'doccure' ),
'categories' => array( 'featured' ),
'content' => '
<!-- wp:cover {"url":"https://example.com/background-image.jpg","id":1,"dimRatio":50,"focalPoint":{"x":"0.50","y":"0.50"},"minHeight":100,"minHeightUnit":"vh","contentPosition":"center center","align":"full","className":"is-style-full-screen-hero"} -->
<div class="wp-block-cover alignfull is-style-full-screen-hero" style="background-image:url(https://example.com/background-image.jpg);background-position:50% 50%;background-size:cover;height:100vh;min-height:100vh"><div class="wp-block-cover__inner-container"><!-- wp:heading {"textAlign":"center","level":1} -->
<h1 class="has-text-align-center">Hero Section</h1>
<!-- /wp:heading --></div></div>
<!-- /wp:cover -->
',
)
);
}
add_action( 'init', 'doccure_register_block_patterns' );
function doccure_enqueue_scripts() {
wp_enqueue_script('doccure-ajax', get_template_directory_uri() . '/assets/js/doccure-ajax.js', ['jquery'], null, true);
wp_localize_script('doccure-ajax', 'doccure_ajax_obj', [
'ajax_url' => admin_url('admin-ajax.php'),
'security' => wp_create_nonce('remove_saved_doctor_nonce'),
]);
}
add_action('wp_enqueue_scripts', 'doccure_enqueue_scripts');
add_action('wp_ajax_remove_saved_doctor', 'doccure_remove_saved_doctor');
add_action('wp_ajax_nopriv_remove_saved_doctor', 'doccure_remove_saved_doctor');
function doccure_remove_saved_doctor() {
// Verify nonce for security
check_ajax_referer('remove_saved_doctor_nonce', 'security');
// Get doctor ID and user ID
$doctor_id = isset($_POST['doctor_id']) ? intval($_POST['doctor_id']) : 0;
$user_id = get_current_user_id();
if (!$user_id || !$doctor_id) {
wp_send_json_error(['message' => 'Invalid data']);
}
// Get the linked profile
$linked_profile = doccure_get_linked_profile_id($user_id);
if (!$linked_profile) {
wp_send_json_error(['message' => 'Linked profile not found']);
}
// Get saved doctors and remove the selected one
$saved_doctors = get_post_meta($linked_profile, '_saved_doctors', true);
if (!is_array($saved_doctors)) {
$saved_doctors = [];
}
if (($key = array_search($doctor_id, $saved_doctors)) !== false) {
unset($saved_doctors[$key]);
update_post_meta($linked_profile, '_saved_doctors', $saved_doctors);
wp_send_json_success(['message' => 'Doctor removed successfully']);
}
wp_send_json_error(['message' => 'Doctor not found']);
}
add_action('wp_ajax_fetch_invoice_details', 'fetch_invoice_details');
add_action('wp_ajax_nopriv_fetch_invoice_details', 'fetch_invoice_details');
function fetch_invoice_details() {
check_ajax_referer('remove_saved_doctor_nonce', 'security');
if (!isset($_POST['order_id'])) {
wp_send_json_error('Invalid request');
}
$order_id = intval($_POST['order_id']);
$order = wc_get_order($order_id);
if (!$order) {
wp_send_json_error('Order not found');
}
// Generate the invoice content dynamically
ob_start(); ?>
<div class="printable">
<div class="view-prescribe invoice-content mb-0">
<div class="invoice-item">
<div class="row">
<div class="col-md-6">
<div class="invoice-logo">
<?php
global $current_user;
$user_id = $current_user->ID;
$profile_id = doccure_get_linked_profile_id( $user_id );
$location_id = get_post_meta( $profile_id, '_doctor_location', true );
$clinic_logo_url = '';
// Get clinic featured image
if ( ! empty( $location_id ) && has_post_thumbnail( $location_id ) ) {
$clinic_logo_url = get_the_post_thumbnail_url( $location_id, 'thumbnail' );
}
// Fallback to site logo
if ( empty( $clinic_logo_url ) ) {
$logo_obj = doccure_get_option('site-logo');
$clinic_logo_url = ! empty( $logo_obj['url'] )
? $logo_obj['url']
: get_template_directory_uri() . '/assets/images/logo.svg';
}
?>
<img src="<?php echo esc_url( $clinic_logo_url ); ?>" alt="Clinic Logo" style="max-width:200px;height:auto;">
</div>
</div>
</div>
</div>
<div class="invoice-item mt-3">
<div class="row">
<div class="col-md-8">
<div class="invoice-info">
<h6 class="customer-text"><?php echo esc_html_e('Billing From','doccure'); ?></h6>
<p class="invoice-details invoice-details-two">
<?php echo esc_html($order->get_billing_first_name() . ' ' . $order->get_billing_last_name()); ?><br>
<?php echo esc_html($order->get_billing_address_1()); ?><br>
<?php echo esc_html($order->get_billing_city() . ', ' . $order->get_billing_state() . ', ' . $order->get_billing_postcode()); ?>
</p>
</div>
</div>
<div class="col-md-4">
<p class="invoice-details">
<?php echo esc_html_e('Invoice No','doccure'); ?>: <span>#<?php echo esc_attr($order->get_id()); ?></span><br>
<?php echo esc_html_e('Issued','doccure'); ?>: <span><?php echo esc_html($order->get_date_created()->date('d M Y')); ?></span>
</p>
</div>
</div>
</div>
<div class="invoice-item invoice-table-wrap">
<div class="row">
<div class="col-md-12">
<h6><?php echo esc_html_e('Invoice Details', 'doccure'); ?></h6>
<div class="invoice-table">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th><?php echo esc_html_e('Product', 'doccure'); ?></th>
<th><?php echo esc_html_e('Total', 'doccure'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($order->get_items() as $item_id => $item) :
$order_detail = wc_get_order_item_meta($item_id, 'cus_woo_product_data', true);
$payment_type = wc_get_order_item_meta($item_id, 'payment_type', true);
if ($order_detail) {
$order_detail = maybe_unserialize($order_detail); // U
}
?>
<tr>
</tr>
<?php
foreach ($order_detail as $key => $value) {
if (!empty($payment_type) && $payment_type === 'bookings') {
if ($key === 'service') { }
else if ($key === 'merged_service') {
if ( !empty($order_detail['merged_service']) ) {
?>
<tr>
<td><?php echo doccure_get_booking_payment_title( $key );?></td>
<td>
<?php
foreach( $value as $key => $vals ) {
foreach( $vals as $k => $v ) {
?>
<p class="p-0 mb-1"><span class="style-lable p-0"><?php echo doccure_get_term_name($k ,'services');?> -<?php echo get_woocommerce_currency_symbol(); ?><?php echo esc_html($v['price']);?></span></p>
<?php } ?>
<?php } ?></td>
</tr>
<?php } } else { ?>
<tr>
<td><?php echo doccure_get_booking_payment_title($key); ?></td>
<td><?php echo doccure_get_booking_value($value, $key, $order_detail); ?></td>
</tr>
<?php }
} else if (!empty($payment_type) && $payment_type === 'subscription') { ?>
<tr>
<td><?php echo doccure_get_package_features($key); ?></td>
<td><?php echo doccure_get_package_feature_value($value, $key); ?></td>
</tr>
<?php }
} ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-md-6 col-xl-4 ms-auto">
<div class="table-responsive">
<table class="invoice-table-two table">
<tbody>
<tr>
<th><?php echo esc_html__('Subtotal', 'doccure'); ?>:</th>
<td><span><?php echo wc_price($order->get_subtotal()); ?></span></td>
</tr>
<tr>
<th><?php echo esc_html__('Total', 'doccure'); ?>:</th>
<td><span><?php echo wc_price($order->get_total()); ?></span></td>
</tr>
<tr>
<th><?php echo esc_html__('Payment Method', 'doccure'); ?>:</th>
<td><span><?php echo esc_html($order->get_payment_method_title()); ?></span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- /Invoice Item -->
</div>
</div>
<?php
$content = ob_get_clean();
wp_send_json_success($content);
}
function custom_send_email($to, $subject, $message, $headers) {
// Send the email using wp_mail
wp_mail($to, $subject, $message, $headers);
}
function add_user_status_filter($views) {
global $wpdb;
$all_count = count_users();
$prefix = $wpdb->prefix; // Get dynamic prefix
// Count users where `_is_verified` is not 'yes' AND role is 'doctors'
$pending_count = $wpdb->get_var($wpdb->prepare("
SELECT COUNT(DISTINCT u.ID)
FROM {$wpdb->users} u
INNER JOIN {$wpdb->usermeta} um1 ON u.ID = um1.user_id
INNER JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id
WHERE um1.meta_key = '_is_verified'
AND um1.meta_value != %s
AND um2.meta_key = %s
AND um2.meta_value LIKE %s
", 'yes', $prefix . 'capabilities', '%doctors%'));
$current = isset($_GET['user_status']) ? $_GET['user_status'] : '';
$views['all'] = "<a href='users.php' class='" . ($current == '' ? 'current' : '') . "'>All ({$all_count['total_users']})</a>";
$views['pending'] = "<a href='users.php?user_status=pending' class='" . ($current == 'pending' ? 'current' : '') . "'>Pending ({$pending_count})</a>";
return $views;
}
add_filter('views_users', 'add_user_status_filter');
function filter_users_by_status($query) {
global $pagenow, $wpdb;
if (is_admin() && $pagenow == 'users.php' && isset($_GET['user_status'])) {
$meta_query = [];
$prefix = $wpdb->prefix; // Get dynamic prefix
if ($_GET['user_status'] == 'pending') {
$meta_query[] = [
'key' => '_is_verified',
'value' => 'yes',
'compare' => '!=' // Only show users where _is_verified is NOT 'yes'
];
// Ensure only users with the role 'doctors'
$meta_query[] = [
'key' => $prefix . 'capabilities',
'value' => 'doctors',
'compare' => 'LIKE'
];
}
if (!empty($meta_query)) {
$query->set('meta_query', $meta_query);
}
}
}
add_action('pre_get_users', 'filter_users_by_status');
add_action('wp_ajax_get_doctor_id_info', 'get_doctor_id_info_callback');
add_action('wp_ajax_nopriv_get_doctor_id_info', 'get_doctor_id_info_callback'); // if not logged in
function get_doctor_id_info_callback() {
global $wpdb;
//security check
$do_check = check_ajax_referer('ajax_nonce', 'security', false);
if ($do_check == false) {
$json['type'] = 'error';
$json['message'] = esc_html__('Security check failed, this could be because of your browser cache. Please clear the cache and check it againe', 'doccure_core');
wp_send_json($json);
}
$doctor_id = isset($_POST['doctor_id_resch']) ? intval($_POST['doctor_id_resch']) : 0;
$table_name = $wpdb->prefix . "dc_schedule";
if (!$doctor_id) {
echo '<option value="">' . esc_html__('No Doctor ID provided.', 'doccure') . '</option>';
wp_die();
}
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM $table_name WHERE doctor_id = %d",
$doctor_id
),
ARRAY_A
);
if ($results) {
echo '<option value="">' . esc_html__('Where to visit?*', 'doccure') . '</option>';
foreach ($results as $row) {
$location_title = get_the_title($row['doctor_location']);
echo '<option data-slot_id="' . intval($row['id']) . '" value="' . esc_attr($row['doctor_id']) . '">' . esc_html($location_title) . '</option>';
}
} else {
echo '<option value="">' . esc_html__('No records found.', 'doccure') . '</option>';
}
wp_die();
}
add_filter( 'site_status_tests', function( $tests ) {
unset( $tests['direct']['persistent_object_cache'] );
return $tests;
});
add_filter( 'site_status_tests', function( $tests ) {
unset( $tests['async']['background_updates'] );
return $tests;
});
add_filter( 'site_status_tests', function( $tests ) {
// Remove WooCommerce Action Scheduler late cron check
if ( isset( $tests['async']['action_scheduler_queue_runner'] ) ) {
unset( $tests['async']['action_scheduler_queue_runner'] );
}
return $tests;
}, 20 );
// AJAX: get existing insurance notes for a booking
add_action('wp_ajax_doccure_get_insurance_notes', function() {
if (!wp_verify_nonce($_POST['security'], 'ajax_nonce')) {
wp_send_json_error('Security check failed');
}
$booking_id = isset($_POST['booking_id']) ? intval($_POST['booking_id']) : 0;
if (!$booking_id) {
wp_send_json_error('Invalid booking id');
}
$notes = get_post_meta($booking_id, '_insurance_notes', true);
wp_send_json_success(array('notes' => (string) $notes));
});
function custom_place_order_button_text( $button_text ) {
if( is_checkout() ) {
$button_text = 'Book Appointment';
}
return $button_text;
}
add_filter( 'woocommerce_order_button_text', 'custom_place_order_button_text' );
function custom_cod_payment_button_text( $label, $payment_id ) {
if( 'cod' === $payment_id ) {
$label = 'Pay when visit';
}
return $label;
}
add_filter( 'woocommerce_gateway_title', 'custom_cod_payment_button_text', 10, 2 );
// Register Insurance Taxonomy for Doctors (and Services if needed)
function register_insurance_taxonomy() {
$labels = array(
'name' => 'Insurances',
'singular_name' => 'Insurance',
'search_items' => 'Search Insurances',
'all_items' => 'All Insurances',
'parent_item' => 'Parent Insurance',
'parent_item_colon' => 'Parent Insurance:',
'edit_item' => 'Edit Insurance',
'update_item' => 'Update Insurance',
'add_new_item' => 'Add New Insurance',
'new_item_name' => 'New Insurance Name',
'menu_name' => 'Insurances',
);
register_taxonomy(
'insurance',
array( 'doctors' ), // attach to doctors & services
array(
'hierarchical' => false,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'show_in_rest' => true,
'rewrite' => array( 'slug' => 'insurance' ),
)
);
}
add_action( 'init', 'register_insurance_taxonomy' );
// Edit fields
// Add custom fields when creating Insurance
function insurance_add_meta_fields() { ?>
<div class="form-field">
<label for="insurance_logo">Logo</label>
<input type="hidden" name="insurance_logo" id="insurance_logo" value="" />
<div id="insurance-logo-preview"></div>
<button type="button" class="button insurance-upload-logo">Upload Logo</button>
</div>
<div class="form-field">
<label for="insurance_status">Status</label>
<select name="insurance_status" id="insurance_status">
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div>
<div class="form-field">
<label for="insurance_desc">Description</label>
<textarea name="insurance_desc" id="insurance_desc" rows="3"></textarea>
</div>
<?php }
add_action( 'insurance_add_form_fields', 'insurance_add_meta_fields' );
// Edit fields for Insurance
function insurance_edit_meta_fields( $term ) {
$logo = get_term_meta( $term->term_id, 'insurance_logo', true );
$status = get_term_meta( $term->term_id, 'insurance_status', true );
$desc = get_term_meta( $term->term_id, 'insurance_desc', true );
?>
<tr class="form-field">
<th scope="row"><label for="insurance_logo">Logo</label></th>
<td>
<input type="hidden" name="insurance_logo" id="insurance_logo" value="<?php echo esc_attr( $logo ); ?>" />
<div id="insurance-logo-preview">
<?php if ( $logo ) : ?>
<img src="<?php echo esc_url( wp_get_attachment_url( $logo ) ); ?>" style="max-width:80px;height:auto;" />
<?php endif; ?>
</div>
<button type="button" class="button insurance-upload-logo">Upload Logo</button>
</td>
</tr>
<tr class="form-field">
<th scope="row"><label for="insurance_desc">Description</label></th>
<td>
<textarea name="insurance_desc" id="insurance_desc" rows="3"><?php echo esc_textarea( $desc ); ?></textarea>
</td>
</tr>
<?php }
add_action( 'insurance_edit_form_fields', 'insurance_edit_meta_fields' );
// Save fields
function insurance_save_meta_fields( $term_id ) {
if ( isset( $_POST['insurance_logo'] ) ) {
update_term_meta( $term_id, 'insurance_logo', intval( $_POST['insurance_logo'] ) ); // store as attachment ID
}
if ( isset( $_POST['insurance_desc'] ) ) {
update_term_meta( $term_id, 'insurance_desc', sanitize_textarea_field( $_POST['insurance_desc'] ) );
}
clean_term_cache( $term_id );
}
add_action( 'created_insurance', 'insurance_save_meta_fields' );
add_action( 'edited_insurance', 'insurance_save_meta_fields' );
// Enqueue media uploader for Insurance taxonomy add/edit screens
function insurance_admin_enqueue_media( $hook ) {
// Only load on taxonomy pages
if ( $hook !== 'edit-tags.php' && $hook !== 'term.php' ) {
return;
}
$screen = get_current_screen();
if ( empty( $screen->taxonomy ) || $screen->taxonomy !== 'insurance' ) {
return;
}
wp_enqueue_media();
wp_add_inline_script(
'jquery',
"jQuery(document).ready(function($){\n\tvar frame;\n\tfunction bindUploader(button){\n\t\t$(button).on('click', function(e){\n\t\t\te.preventDefault();\n\t\t\tif(frame){ frame.open(); return; }\n\t\t\tframe = wp.media({ title: 'Select or Upload Logo', button: { text: 'Use this logo' }, multiple: false });\n\t\t\tframe.on('select', function(){\n\t\t\t\tvar attachment = frame.state().get('selection').first().toJSON();\n\t\t\t\t$('#insurance_logo').val(attachment.id);\n\t\t\t\tvar url = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;\n\t\t\t\t$('#insurance-logo-preview').html(\"<img src='\"+url+\"' style='max-width:80px;height:auto;' />\");\n\t\t\t});\n\t\t\tframe.open();\n\t\t});\n\t}\n\tbindUploader('.insurance-upload-logo');\n});"
);
}
add_action( 'admin_enqueue_scripts', 'insurance_admin_enqueue_media' );
// Add Logo column to Insurance terms list
function insurance_columns( $columns ) {
$cols = array();
// Keep checkbox if present
if ( isset( $columns['cb'] ) ) {
$cols['cb'] = $columns['cb'];
unset( $columns['cb'] );
}
$cols['logo'] = 'Logo';
return $cols + $columns; // preserve remaining columns order
}
add_filter( 'manage_edit-insurance_columns', 'insurance_columns' );
function insurance_custom_column( $content, $column_name, $term_id ) {
if ( $column_name === 'logo' ) {
$logo_id = get_term_meta( $term_id, 'insurance_logo', true );
if ( $logo_id ) {
$url = wp_get_attachment_image_url( $logo_id, 'thumbnail' );
if ( $url ) {
$content = '<img src="' . esc_url( $url ) . '" style="width:40px;height:auto;" />';
}
}
}
return $content;
}
add_filter( 'manage_insurance_custom_column', 'insurance_custom_column', 10, 3 );
// Save or update insurance pricing
add_action('wp_ajax_save_insurance_pricing', 'save_insurance_pricing');
function save_insurance_pricing() {
// Verify nonce
check_ajax_referer('insurance_nonce', 'security');
$user_id = intval($_POST['user_id']);
$insurance = isset($_POST['insurance']) ? (array) $_POST['insurance'] : [];
if (!$user_id || empty($insurance)) {
wp_send_json_error(['message' => 'Invalid request.']);
}
// Filter out empty entries & prevent duplicates
$unique = [];
$final = [];
foreach ($insurance as $item) {
$company_id = intval($item['company_id']);
$type = sanitize_text_field($item['type']);
$amount = floatval($item['amount']);
if (!$company_id || isset($unique[$company_id])) {
continue; // Skip duplicates
}
$unique[$company_id] = true;
$final[] = [
'company_id' => $company_id,
'type' => $type,
'amount' => $amount,
];
}
update_user_meta($user_id, '_insurance_pricing', $final);
wp_send_json_success(['message' => 'Insurance pricing saved successfully!']);
}// Display insurance options at checkout
// add_action('woocommerce_before_order_notes', 'doccure_display_insurance_options_at_checkout');
function doccure_display_insurance_options_at_checkout($checkout) {
// Get current user ID
$user_id = get_current_user_id();
// print_r(WC()->cart->get_cart());
// Get doctor ID from cart items (you might need to adjust this based on your product setup)
$doctor_id = $user_id;
foreach (WC()->cart->get_cart() as $cart_item) {
if (isset($cart_item['doctor_id'])) {
$doctor_id = $cart_item['doctor_id'];
break;
}
}
// If no doctor ID found, try to get it from session or other method
if (!$doctor_id) {
// You might need to set this elsewhere in your booking process
$doctor_id = WC()->session->get('booking_doctor_id');
}
// Get doctor's user ID
$doctor_user_id = get_post_field('post_author', $doctor_id);
// Get insurance data
$insurance_data = get_user_meta($doctor_user_id, '_insurance_pricing', true);
if (!empty($insurance_data) && is_array($insurance_data)) {
echo '<div id="doccure_insurance_options"><h3>' . __('Insurance Options', 'doccure') . '</h3>';
$insurance_options = array('' => __('Select Insurance', 'doccure'));
foreach ($insurance_data as $index => $insurance) {
$insurance_term = get_term($insurance['company_id'], 'insurance');
if (!is_wp_error($insurance_term) && $insurance_term) {
$insurance_name = $insurance_term->name;
$insurance_type = $insurance['type'];
$insurance_amount = $insurance['amount'];
$display_text = $insurance_name . ' - ';
if ($insurance_type === 'percentage') {
$display_text .= $insurance_amount . '% ' . __('Discount', 'doccure');
} else {
$display_text .= doccure_price_format($insurance_amount, 'return') . ' ' . __('Discount', 'doccure');
}
$insurance_options[$index] = $display_text;
}
}
woocommerce_form_field('selected_insurance', array(
'type' => 'select',
'class' => array('form-row-wide'),
'label' => __('Select Insurance', 'doccure'),
'options' => $insurance_options,
), $checkout->get_value('selected_insurance'));
echo '</div>';
// Add JavaScript to handle insurance selection
wc_enqueue_js("
jQuery('select#selected_insurance').change(function(){
jQuery('body').trigger('update_checkout');
});
");
}
}
// Calculate insurance discount
// add_action('woocommerce_cart_calculate_fees', 'doccure_apply_insurance_discount');
function doccure_apply_insurance_discount() {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
// Check if insurance is selected
if (!empty($_POST['post_data'])) {
parse_str($_POST['post_data'], $post_data);
$selected_insurance = isset($post_data['selected_insurance']) ? $post_data['selected_insurance'] : '';
} else {
$selected_insurance = isset($_POST['selected_insurance']) ? $_POST['selected_insurance'] : '';
}
if (empty($selected_insurance)) {
return;
}
// Get doctor ID
$doctor_id = 0;
foreach (WC()->cart->get_cart() as $cart_item) {
if (isset($cart_item['doctor_id'])) {
$doctor_id = $cart_item['doctor_id'];
break;
}
}
if (!$doctor_id) {
$doctor_id = WC()->session->get('booking_doctor_id');
}
// Get doctor's user ID
$doctor_user_id = get_post_field('post_author', $doctor_id);
// Get insurance data
$insurance_data = get_user_meta($doctor_user_id, '_insurance_pricing', true);
if (!empty($insurance_data[$selected_insurance])) {
$insurance = $insurance_data[$selected_insurance];
$insurance_term = get_term($insurance['company_id'], 'insurance');
if (!is_wp_error($insurance_term) && $insurance_term) {
$insurance_name = $insurance_term->name;
$insurance_type = $insurance['type'];
$insurance_amount = $insurance['amount'];
// Calculate discount amount
$cart_total = WC()->cart->get_cart_contents_total();
$discount_amount = 0;
if ($insurance_type === 'percentage') {
$discount_amount = ($cart_total * $insurance_amount) / 100;
} else {
$discount_amount = min($insurance_amount, $cart_total);
}
if ($discount_amount > 0) {
// Apply discount as fee (negative fee)
WC()->cart->add_fee(sprintf(__('Insurance Discount (%s)', 'doccure'), $insurance_name), -$discount_amount);
}
}
}
}
// Get insurance options AJAX handler
add_action('wp_ajax_doccure_get_insurance_options', 'doccure_get_insurance_options');
add_action('wp_ajax_nopriv_doccure_get_insurance_options', 'doccure_get_insurance_options');
function doccure_get_insurance_options() {
check_ajax_referer('doccure_insurance_nonce', 'security');
$doctor_id = !empty($_POST['doctor_id']) ? intval($_POST['doctor_id']) : 0;
$clinic_id = !empty($_POST['clinic_id']) ? intval($_POST['clinic_id']) : 0;
if (!$doctor_id) {
wp_send_json_error(__('Invalid doctor ID', 'doccure'));
}
// Get doctor's user ID
$doctor_user_id = get_post_field('post_author', $doctor_id);
// Get insurance data
$insurance_data = get_user_meta($doctor_user_id, '_insurance_pricing', true);
$insurance_data = !empty($insurance_data) ? $insurance_data : array();
if (empty($insurance_data)) {
wp_send_json_error(__('No insurance options available', 'doccure'));
}
ob_start();
?>
<div class="insurance-options">
<div class="mb-3">
<label class="form-label"><?php esc_html_e('Select Insurance', 'doccure'); ?></label>
</div>
<div class="insurance-list">
<div class="form-check mb-2">
<input class="form-check-input" type="radio" name="selected_insurance"
id="insurance_none" value="none" checked>
<label class="form-check-label" for="insurance_none">
<?php esc_html_e('No Insurance', 'doccure'); ?>
</label>
</div>
<?php foreach ($insurance_data as $index => $insurance) :
$insurance_term = get_term($insurance['company_id'], 'insurance');
if (is_wp_error($insurance_term) || !$insurance_term) continue;
$insurance_name = $insurance_term->name;
$insurance_type = $insurance['type'];
$insurance_amount = $insurance['amount'];
$display_text = $insurance_name . ' - ';
if ($insurance_type === 'percentage') {
$display_text .= $insurance_amount . '% ' . __('Discount', 'doccure');
} else {
$display_text .= wc_price($insurance_amount) . ' ' . __('Discount', 'doccure');
}
?>
<div class="form-check mb-2">
<input class="form-check-input" type="radio" name="selected_insurance"
id="insurance_<?php echo esc_attr($index); ?>"
value="<?php echo esc_attr($index); ?>"
data-type="<?php echo esc_attr($insurance_type); ?>"
data-amount="<?php echo esc_attr($insurance_amount); ?>"
data-name="<?php echo esc_attr($insurance_name); ?>">
<label class="form-check-label" for="insurance_<?php echo esc_attr($index); ?>">
<?php echo esc_html($display_text); ?>
</label>
</div>
<?php endforeach; ?>
</div>
</div>
<?php
$html = ob_get_clean();
wp_send_json_success($html);
}
// Set selected insurance AJAX handler
add_action('wp_ajax_doccure_set_selected_insurance', 'doccure_set_selected_insurance');
add_action('wp_ajax_nopriv_doccure_set_selected_insurance', 'doccure_set_selected_insurance');
function doccure_set_selected_insurance() {
check_ajax_referer('doccure_insurance_nonce', 'security');
$insurance_data = array(
'id' => !empty($_POST['insurance_id']) ? sanitize_text_field($_POST['insurance_id']) : '',
'type' => !empty($_POST['insurance_type']) ? sanitize_text_field($_POST['insurance_type']) : '',
'amount' => !empty($_POST['insurance_amount']) ? floatval($_POST['insurance_amount']) : 0,
'name' => !empty($_POST['insurance_name']) ? sanitize_text_field($_POST['insurance_name']) : ''
);
// Store in session
WC()->session->set('selected_insurance', $insurance_data);
wp_send_json_success();
}
// Adjust cart item price based on insurance discount
// add_action('woocommerce_before_calculate_totals', 'doccure_adjust_cart_item_price', 20, 1);
function doccure_adjust_cart_item_price($cart) {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
foreach ($cart->get_cart() as $cart_item) {
if (isset($cart_item['insurance_discount']) && $cart_item['insurance_discount'] > 0) {
$original_price = $cart_item['data']->get_price();
$discounted_price = $original_price - $cart_item['insurance_discount'];
// Ensure price doesn't go below 0
$discounted_price = max(0, $discounted_price);
$cart_item['data']->set_price($discounted_price);
}
}
}
// Display insurance discount in cart and checkout
add_filter('woocommerce_get_item_data', 'doccure_display_insurance_discount_in_cart', 10, 2);
function doccure_display_insurance_discount_in_cart($item_data, $cart_item) {
if (isset($cart_item['insurance_discount']) && $cart_item['insurance_discount'] > 0) {
$item_data[] = array(
'key' => __('Insurance Discount', 'doccure'),
'value' => '-' . wc_price($cart_item['insurance_discount']),
'display' => ''
);
}
return $item_data;
}
// Add insurance discount as a negative fee
add_action('woocommerce_cart_calculate_fees', 'doccure_add_insurance_discount_fee');
function doccure_add_insurance_discount_fee() {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
foreach (WC()->cart->get_cart() as $cart_item) {
if (isset($cart_item['insurance_discount']) && $cart_item['insurance_discount'] > 0) {
$discount = floatval($cart_item['insurance_discount']);
$insurance_name = isset($cart_item['insurance_details']['company_name'])
? $cart_item['insurance_details']['company_name']
: __('Insurance Discount', 'doccure');
// Add as negative fee (discount)
WC()->cart->add_fee(
sprintf(__('Insurance Discount (%s)', 'doccure'), $insurance_name),
-$discount,
false // Not taxable
);
// Only process one item since discount is applied to entire cart
break;
}
}
}
// Display insurance information in cart item meta
add_filter('woocommerce_get_item_data', 'doccure_display_insurance_info_in_cart', 10, 2);
function doccure_display_insurance_info_in_cart($item_data, $cart_item) {
if (isset($cart_item['insurance_details']) && !empty($cart_item['insurance_details'])) {
$insurance = $cart_item['insurance_details'];
$item_data[] = array(
'key' => __('Insurance', 'doccure'),
'value' => $insurance['company_name'],
'display' => ''
);
$discount_type = ($insurance['type'] === 'percentage')
? $insurance['amount'] . '%'
: wc_price($insurance['amount']);
$item_data[] = array(
'key' => __('Discount', 'doccure'),
'value' => $discount_type,
'display' => ''
);
}
return $item_data;
}
// Display insurance discount in checkout review
add_action('woocommerce_review_order_before_order_total', 'doccure_display_insurance_discount_checkout');
function doccure_display_insurance_discount_checkout() {
foreach (WC()->cart->get_cart() as $cart_item) {
if (isset($cart_item['insurance_discount']) && $cart_item['insurance_discount'] > 0) {
$discount = floatval($cart_item['insurance_discount']);
$insurance_name = isset($cart_item['insurance_details']['company_name'])
? $cart_item['insurance_details']['company_name']
: __('Insurance', 'doccure');
$insurance_type = isset($cart_item['insurance_details']['type'])
? $cart_item['insurance_details']['type']
: '';
$insurance_amount = isset($cart_item['insurance_details']['amount'])
? $cart_item['insurance_details']['amount']
: '';
$discount_text = $insurance_name;
if ($insurance_type === 'percentage') {
$discount_text .= ' (' . $insurance_amount . '%)';
}
?>
<tr class="insurance-discount">
<th><?php echo esc_html($discount_text); ?></th>
<td>-<?php echo wc_price($discount); ?></td>
</tr>
<?php
break;
}
}
}
// Adjust the cart item price to include insurance discount
add_action('woocommerce_before_calculate_totals', 'doccure_adjust_cart_item_price_with_insurance', 20, 1);
function doccure_adjust_cart_item_price_with_insurance($cart) {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
if (isset($cart_item['insurance_discount']) && $cart_item['insurance_discount'] > 0) {
$original_price = $cart_item['data']->get_price();
$discount = floatval($cart_item['insurance_discount']);
// Set the discounted price
$cart_item['data']->set_price($original_price - $discount);
}
}
}
/**
* Checkout: Verify Insurance toggle and conditional discount application
*/
// Capture the posted checkbox during checkout updates and store in WC session
// add_action( 'woocommerce_checkout_update_order_review', function( $post_data ) {
// parse_str( $post_data, $parsed );
// $use_insurance = isset( $parsed['dc_use_insurance'] ) && $parsed['dc_use_insurance'] === 'yes' ? 'yes' : 'no';
// WC()->session->set( 'dc_use_insurance', $use_insurance );
// });
// Apply the insurance discount as a negative fee when enabled
// Dynamically adjust the product price based on insurance selection
add_action( 'woocommerce_before_calculate_totals', function( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
// Note: Avoid early return based on did_action count to ensure recalculations/logging occur reliably
// Initialize insurance session if not set
if ( ! WC()->session->get( 'dc_use_insurance' ) ) {
WC()->session->set( 'dc_use_insurance', 'no' );
}
$use_insurance = WC()->session->get( 'dc_use_insurance', 'no' );
// WC Logger setup
if ( function_exists( 'wc_get_logger' ) ) {
$logger = wc_get_logger();
$context = array( 'source' => 'doccure-insurance' );
$logger->info( 'before_calculate_totals hook running. use_insurance=' . $use_insurance . ' | cart_items=' . count( $cart->get_cart() ), $context );
}
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( isset( $logger ) ) {
$logger->info( 'Inspecting cart item ' . $cart_item_key, $context );
}
if ( isset( $cart_item['cart_data']['original_price'] ) && isset( $cart_item['cart_data']['insurance_discount'] ) ) {
// Preferred: nested under cart_data
$original_price = floatval( $cart_item['cart_data']['original_price'] );
$insurance_discount = floatval( $cart_item['cart_data']['insurance_discount'] );
if ( isset( $logger ) ) {
$logger->info( 'Using nested cart_data for pricing.', $context );
}
} elseif ( isset( $cart_item['original_price'] ) && isset( $cart_item['insurance_discount'] ) ) {
// Fallback: some setups may merge custom data at root level
$original_price = floatval( $cart_item['original_price'] );
$insurance_discount = floatval( $cart_item['insurance_discount'] );
if ( isset( $logger ) ) {
$logger->info( 'Using root-level cart item data for pricing.', $context );
}
}
if ( isset( $original_price ) && isset( $insurance_discount ) ) {
// Debug info via WooCommerce logger (visible in WooCommerce > Status > Logs)
if ( isset( $logger ) ) {
$logger->info( 'Cart item ' . $cart_item_key . ' | use_insurance=' . $use_insurance . ' | original_price=' . $original_price . ' | insurance_discount=' . $insurance_discount, $context );
}
if ( 'no' === $use_insurance ) {
// When insurance is NOT checked - use FULL original price
$cart_item['data']->set_price( $original_price );
} else {
// When insurance IS checked - use discounted price
$discounted_price = $original_price - $insurance_discount;
$cart_item['data']->set_price( max( 0, $discounted_price ) );
}
} else {
// Missing meta keys
if ( isset( $logger ) ) {
$present_keys = isset( $cart_item['cart_data'] ) ? implode( ',', array_keys( (array) $cart_item['cart_data'] ) ) : 'no cart_data';
$logger->warning( 'Cart item ' . $cart_item_key . ' missing required keys. Present cart_data keys: ' . $present_keys, $context );
}
}
}
if ( isset( $logger ) ) {
$logger->info( 'before_calculate_totals hook completed.', $context );
}
}, 9999 );
// Log cart item meta when adding to cart to verify insurance data is present
// add_filter( 'woocommerce_add_cart_item_data', function( $cart_item_data, $product_id, $variation_id ) {
// if ( function_exists( 'wc_get_logger' ) ) {
// $logger = wc_get_logger();
// $context = array( 'source' => 'doccure-insurance' );
// $logger->info( 'woocommerce_add_cart_item_data for product ' . $product_id . ' | keys=' . implode( ',', array_keys( (array) $cart_item_data ) ), $context );
// if ( isset( $cart_item_data['cart_data'] ) ) {
// $logger->info( 'cart_data keys: ' . implode( ',', array_keys( (array) $cart_item_data['cart_data'] ) ), $context );
// }
// }
// return $cart_item_data;
// }, 10, 3 );
// // Remove the fee-based approach since we're modifying the base price directly
// add_action( 'woocommerce_cart_calculate_fees', function ( WC_Cart $cart ) {
// // We're not using fees anymore - price is adjusted directly
// return;
// }, 20, 1 );
// Persist the choice on the order for reference
add_action( 'woocommerce_checkout_create_order', function( $order, $data ) {
$use_insurance = WC()->session->get( 'dc_use_insurance', 'no' );
if ( $use_insurance === 'yes' ) {
$order->update_meta_data( '_dc_use_insurance', 'yes' );
}
}, 10, 2 );
// Ensure line item unit price displays the insurance-adjusted price during checkout/cart fragments
add_filter( 'woocommerce_cart_item_price', function( $price_html, $cart_item, $cart_item_key ) {
$use_insurance = WC()->session ? WC()->session->get( 'dc_use_insurance', 'no' ) : 'no';
$orig = isset( $cart_item['cart_data']['original_price'] ) ? floatval( $cart_item['cart_data']['original_price'] ) : null;
$disc = isset( $cart_item['cart_data']['insurance_discount'] ) ? floatval( $cart_item['cart_data']['insurance_discount'] ) : null;
if ( $orig !== null && $disc !== null ) {
$final = ( 'yes' === $use_insurance ) ? max( 0, $orig - $disc ) : $orig;
$price_html = wc_price( $final );
}
return $price_html;
}, 9999, 3 );
// Ensure line item subtotal displays the insurance-adjusted subtotal during checkout/cart fragments
add_filter( 'woocommerce_cart_item_subtotal', function( $subtotal_html, $cart_item, $cart_item_key ) {
$use_insurance = WC()->session ? WC()->session->get( 'dc_use_insurance', 'no' ) : 'no';
$orig = isset( $cart_item['cart_data']['original_price'] ) ? floatval( $cart_item['cart_data']['original_price'] ) : null;
$disc = isset( $cart_item['cart_data']['insurance_discount'] ) ? floatval( $cart_item['cart_data']['insurance_discount'] ) : null;
$qty = isset( $cart_item['quantity'] ) ? max( 1, intval( $cart_item['quantity'] ) ) : 1;
if ( $orig !== null && $disc !== null ) {
$unit = ( 'yes' === $use_insurance ) ? max( 0, $orig - $disc ) : $orig;
$subtotal_html = wc_price( $unit * $qty );
}
return $subtotal_html;
}, 9999, 3 );
// Add insurance number field to checkout
// add_filter('woocommerce_checkout_fields', 'doccure_add_insurance_number_field');
function doccure_add_insurance_number_field($fields) {
// Check if cart has insurance data
$has_insurance = false;
foreach (WC()->cart->get_cart() as $cart_item) {
if ( ! empty( $cart_item['cart_data']['has_insurance'] ) && $cart_item['cart_data']['has_insurance'] == 1 ) {
$has_insurance = true;
break;
}
}
if ($has_insurance) {
$fields['billing']['insurance_number'] = array(
'label' => __('Insurance Number', 'doccure'),
'placeholder' => _x('Enter your insurance number', 'placeholder', 'doccure'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
'priority' => 25
);
}
return $fields;
}
add_filter('woocommerce_checkout_fields', 'doccure_add_reason_for_visit_field');
function doccure_add_reason_for_visit_field($fields) {
// Check if cart has insurance data
$fields['billing']['reason_for_visit'] = array(
'label' => __('Reason for Visit', 'doccure'),
'placeholder' => _x('Enter your reason for visit', 'placeholder', 'doccure'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
'priority' => 25
);
return $fields;
}
add_action('woocommerce_checkout_update_order_meta', 'doccure_save_reason_for_visit_to_order');
function doccure_save_reason_for_visit_to_order($order_id) {
if (!empty($_POST['reason_for_visit'])) {
update_post_meta($order_id, '_reason_for_visit', sanitize_text_field($_POST['reason_for_visit']));
}
}
//Display insurance number in admin order details
add_action('woocommerce_admin_order_data_after_billing_address', 'doccure_display_reason_for_visit_admin');
function doccure_display_reason_for_visit_admin($order) {
$reason_for_visit = get_post_meta($order->get_id(), '_reason_for_visit', true);
if (!empty($reason_for_visit)) {
echo '<p><strong>' . __('Reason for Visit:') . '</strong> ' . $reason_for_visit . '</p>';
}
}
// Display insurance number in order emails
add_action('woocommerce_email_order_meta', 'doccure_display_reason_for_visit_emails', 20, 4);
function doccure_display_reason_for_visit_emails($order, $sent_to_admin, $plain_text, $email) {
$reason_for_visit = get_post_meta($order->get_id(), '_reason_for_visit', true);
if (!empty($reason_for_visit)) {
if ($plain_text) {
echo "\n" . __('Reason for Visit:') . ' ' . $reason_for_visit . "\n";
} else {
echo '<p><strong>' . __('Reason for Visit:') . '</strong> ' . $reason_for_visit . '</p>';
}
}
}
// Validate insurance number field
// add_action('woocommerce_checkout_process', 'doccure_validate_insurance_number_field');
// function doccure_validate_insurance_number_field() {
// // Check if cart has insurance data
// $has_insurance = false;
// foreach (WC()->cart->get_cart() as $cart_item) {
// if ( ! empty( $cart_item['cart_data']['has_insurance'] ) && $cart_item['cart_data']['has_insurance'] == 1 ) {
// $has_insurance = true;
// break;
// }
// }
// if ($has_insurance && empty($_POST['insurance_number'])) {
// wc_add_notice(__('Please enter your insurance number.', 'doccure'), 'error');
// }
// }
// Save insurance number to order meta
// add_action('woocommerce_checkout_update_order_meta', 'doccure_save_insurance_number_to_order');
// function doccure_save_insurance_number_to_order($order_id) {
// if (!empty($_POST['insurance_number'])) {
// update_post_meta($order_id, '_insurance_number', sanitize_text_field($_POST['insurance_number']));
// }
// }
// Display insurance number in admin order details
// add_action('woocommerce_admin_order_data_after_billing_address', 'doccure_display_insurance_number_admin');
// function doccure_display_insurance_number_admin($order) {
// $insurance_number = get_post_meta($order->get_id(), '_insurance_number', true);
// if (!empty($insurance_number)) {
// echo '<p><strong>' . __('Insurance Number:') . '</strong> ' . $insurance_number . '</p>';
// }
// }
// // Display insurance number in order emails
// add_action('woocommerce_email_order_meta', 'doccure_display_insurance_number_emails', 20, 4);
// function doccure_display_insurance_number_emails($order, $sent_to_admin, $plain_text, $email) {
// $insurance_number = get_post_meta($order->get_id(), '_insurance_number', true);
// if (!empty($insurance_number)) {
// if ($plain_text) {
// echo "\n" . __('Insurance Number:') . ' ' . $insurance_number . "\n";
// } else {
// echo '<p><strong>' . __('Insurance Number:') . '</strong> ' . $insurance_number . '</p>';
// }
// }
// }
// Display insurance details in order items table
add_filter('woocommerce_get_item_data', 'doccure_display_insurance_details_in_items', 10, 2);
function doccure_display_insurance_details_in_items($item_data, $cart_item) {
if (isset($cart_item['cart_data']['has_insurance']) && $cart_item['cart_data']['has_insurance']) {
$insurance_details = $cart_item['cart_data']['insurance_details'];
$insurance_discount = $cart_item['cart_data']['insurance_discount'];
if (!empty($insurance_details)) {
$item_data[] = array(
'name' => __('Insurance', 'doccure'),
'value' => $insurance_details['type'] === 'percentage'
? $insurance_details['amount'] . '% amount (Unverified)'
: wc_price($insurance_details['amount']) . ' amount (Unverified)' // Mark as unverified by default
);
}
$item_data[] = array(
'name' => __('Insurance Discount', 'doccure'),
'value' => '-' . wc_price($insurance_discount)
);
}
return $item_data;
}
// When order is completed, save insurance details to booking post
add_action('woocommerce_order_status_completed', 'doccure_save_insurance_to_booking');
function doccure_save_insurance_to_booking($order_id) {
$order = wc_get_order($order_id);
// Get booking ID from order meta (you might need to adjust this based on how you link orders to bookings)
$booking_id = get_post_meta($order_id, '_booking_id', true);
if (!$booking_id) {
// Alternative: check if order contains booking product and extract booking ID
foreach ($order->get_items() as $item_id => $item) {
$booking_id = $item->get_meta('_booking_id');
if ($booking_id) break;
}
}
if ($booking_id && get_post_type($booking_id) === 'booking') {
$has_insurance = get_post_meta($order_id, '_has_insurance', true);
if ($has_insurance === 'yes') {
update_post_meta($booking_id, '_insurance_discount', get_post_meta($order_id, '_insurance_discount', true));
update_post_meta($booking_id, '_insurance_details', get_post_meta($order_id, '_insurance_details', true));
update_post_meta($booking_id, '_insurance_status', get_post_meta($order_id, '_insurance_status', true));
update_post_meta($booking_id, '_insurance_number', get_post_meta($order_id, '_insurance_number', true));
}
}
}
// Save insurance details to order meta when order is placed
add_action('woocommerce_checkout_update_order_meta', 'doccure_save_insurance_details_to_order');
function doccure_save_insurance_details_to_order($order_id) {
// Get the order
$order = wc_get_order($order_id);
// Loop through order items to find insurance data
foreach ($order->get_items() as $item_id => $item) {
$cart_data = $item->get_meta('cart_data');
if (!empty($cart_data) && isset($cart_data['has_insurance']) && $cart_data['has_insurance']) {
// Save insurance details to order meta
update_post_meta($order_id, '_has_insurance', 'yes');
update_post_meta($order_id, '_insurance_discount', $cart_data['insurance_discount']);
update_post_meta($order_id, '_original_price', $cart_data['original_price']);
update_post_meta($order_id, '_insurance_status', $cart_data['insurance_status']);
// Save insurance details as serialized array
if (!empty($cart_data['insurance_details'])) {
update_post_meta($order_id, '_insurance_details', $cart_data['insurance_details']);
}
// Save insurance number if provided
if (!empty($_POST['insurance_number'])) {
update_post_meta($order_id, '_insurance_number', sanitize_text_field($_POST['insurance_number']));
}
// Also save to item meta for easy access
$item->update_meta_data('_has_insurance', 'yes');
$item->update_meta_data('_insurance_discount', $cart_data['insurance_discount']);
$item->update_meta_data('_original_price', $cart_data['original_price']);
$item->update_meta_data('_insurance_status', $cart_data['insurance_status']);
$item->update_meta_data('_insurance_details', $cart_data['insurance_details']);
$item->save();
break;
}
}
}
add_action('wp_ajax_doccure_update_insurance_status', 'doccure_update_insurance_status');
function doccure_update_insurance_status() {
// Security check
if (!wp_verify_nonce($_POST['security'], 'ajax_nonce')) {
wp_send_json_error('Security check failed');
}
// Check permissions
// if (!current_user_can('manage_options') && !doccure_is_doctor(get_current_user_id())) {
// wp_send_json_error('Insufficient permissions');
// }
$booking_id = intval($_POST['booking_id']);
$new_status = sanitize_text_field($_POST['status']);
$notes = isset($_POST['notes']) ? wp_kses_post($_POST['notes']) : '';
$insurance_number = isset($_POST['insurance_number']) ? sanitize_text_field($_POST['insurance_number']) : '';
// Validate status
$allowed_statuses = array('unverified', 'verified', 'rejected');
if (!in_array($new_status, $allowed_statuses)) {
wp_send_json_error('Invalid status');
}
// Update insurance status
update_post_meta($booking_id, '_insurance_status', $new_status);
if ($notes !== '') {
update_post_meta($booking_id, '_insurance_notes', $notes);
}
if ($insurance_number !== '') {
update_post_meta($booking_id, '_insurance_number', $insurance_number);
}
// If status is verified, update the price in WooCommerce order if exists
$order_id = get_post_meta($booking_id, '_order_id', true);
if ($order_id) {
// persist notes on order if provided
if ($notes !== '') {
update_post_meta($order_id, '_insurance_notes', $notes);
}
// persist insurance number on order if provided
if ($insurance_number !== '') {
update_post_meta($order_id, '_insurance_number', $insurance_number);
}
if ($new_status === 'verified') {
$insurance_discount = get_post_meta($booking_id, '_insurance_discount', true);
$original_price = get_post_meta($booking_id, '_original_price', true);
if ($insurance_discount > 0 && $original_price > 0) {
$final_price = max(0, $original_price - $insurance_discount);
// Update order total
$order = wc_get_order($order_id);
if ($order) {
// Update order items price
foreach ($order->get_items() as $item_id => $item) {
$item->set_total($final_price);
$item->set_subtotal($final_price);
$item->save();
}
// Recalculate order totals
$order->calculate_totals();
$order->save();
}
}
}
}
wp_send_json_success(array(
'message' => __('Insurance details updated successfully', 'doccure_core'),
'status' => $new_status,
'notes_saved' => $notes !== '',
'insurance_number_saved' => $insurance_number !== ''
));
}
// Security codes
// Remove WordPress version number
remove_action('wp_head', 'wp_generator');
// Disable XML-RPC
add_filter('xmlrpc_enabled', '__return_false');
function add_security_headers() {
header( 'X-Frame-Options: SAMEORIGIN' );
header( 'X-Content-Type-Options: nosniff' );
header( 'X-XSS-Protection: 1; mode=block' );
header( 'Referrer-Policy: strict-origin-when-cross-origin' );
}
add_action( 'send_headers', 'add_security_headers' );