!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: Apache. PHP/7.3.33 

uname -a: Linux acloudg.aryanict.com 4.18.0-513.9.1.lve.el8.x86_64 #1 SMP Mon Dec 4 15:01:22 UTC
2023 x86_64
 

uid=1095(katebhospital) gid=1098(katebhospital) groups=1098(katebhospital) 

Safe-mode: OFF (not secure)

/var/softaculous/sitepad/editor/site-data/plugins/kkart-pro/includes/   drwxr-xr-x
Free 289.05 GB of 429.69 GB (67.27%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     class-kkart-ajax.php (125.64 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**
 * Kkart KKART_AJAX. AJAX Event Handlers.
 *
 * @class   KKART_AJAX
 * @package Kkart\Classes
 */

use Automattic\Jetpack\Constants;
use 
Automattic\Kkart\Utilities\NumberUtil;

defined'ABSPATH' ) || exit;

/**
 * KKART_Ajax class.
 */
class KKART_AJAX {

    
/**
     * Hook in ajax handlers.
     */
    
public static function init() {
        
add_action'init', array( __CLASS__'define_ajax' ), );
        
add_action'template_redirect', array( __CLASS__'do_kkart_ajax' ), );
        
self::add_ajax_events();
    }

    
/**
     * Get KKART Ajax Endpoint.
     *
     * @param string $request Optional.
     *
     * @return string
     */
    
public static function get_endpoint$request '' ) {
        return 
esc_url_rawapply_filters'kkart_ajax_get_endpoint'add_query_arg'kkart-ajax'$requestremove_query_arg( array( 'remove_item''add-to-cart''added-to-cart''order_again''_wpnonce' ), home_url'/''relative' ) ) ), $request ) );
    }

    
/**
     * Set KKART AJAX constant and headers.
     */
    
public static function define_ajax() {
        
// phpcs:disable
        
if ( ! empty( $_GET['kkart-ajax'] ) ) {
            
kkart_maybe_define_constant'DOING_AJAX'true );
            
kkart_maybe_define_constant'KKART_DOING_AJAX'true );
            if ( ! 
WP_DEBUG || ( WP_DEBUG && ! WP_DEBUG_DISPLAY ) ) {
                @
ini_set'display_errors'); // Turn off display_errors during AJAX events to prevent malformed JSON.
            
}
            
$GLOBALS['wpdb']->hide_errors();
        }
        
// phpcs:enable
    
}

    
/**
     * Send headers for KKART Ajax Requests.
     *
     * @since 2.5.0
     */
    
private static function kkart_ajax_headers() {
        if ( ! 
headers_sent() ) {
            
send_origin_headers();
            
send_nosniff_header();
            
kkart_nocache_headers();
            
header'Content-Type: text/html; charset=' get_option'blog_charset' ) );
            
header'X-Robots-Tag: noindex' );
            
status_header200 );
        } elseif ( 
Constants::is_true'WP_DEBUG' ) ) {
            
headers_sent$file$line );
            
trigger_error"kkart_ajax_headers cannot set headers - headers already sent by {$file} on line {$line}"E_USER_NOTICE ); // @codingStandardsIgnoreLine
        
}
    }

    
/**
     * Check for KKART Ajax request and fire action.
     */
    
public static function do_kkart_ajax() {
        global 
$wp_query;

        
// phpcs:disable WordPress.Security.NonceVerification.Recommended
        
if ( ! empty( $_GET['kkart-ajax'] ) ) {
            
$wp_query->set'kkart-ajax'sanitize_text_fieldwp_unslash$_GET['kkart-ajax'] ) ) );
        }

        
$action $wp_query->get'kkart-ajax' );

        if ( 
$action ) {
            
self::kkart_ajax_headers();
            
$action sanitize_text_field$action );
            
do_action'kkart_ajax_' $action );
            
wp_die();
        }
        
// phpcs:enable
    
}

    
/**
     * Hook in methods - uses WordPress ajax handlers (admin-ajax).
     */
    
public static function add_ajax_events() {
        
$ajax_events_nopriv = array(
            
'get_refreshed_fragments',
            
'apply_coupon',
            
'remove_coupon',
            
'update_shipping_method',
            
'get_cart_totals',
            
'update_order_review',
            
'add_to_cart',
            
'remove_from_cart',
            
'checkout',
            
'get_variation',
            
'get_customer_location',
            
'get_cart_items',
            
'set_cart_quantity',
            
'get_cart_data',
            
'cart_update_quantity'
        
);

        foreach ( 
$ajax_events_nopriv as $ajax_event ) {
            
add_action'wp_ajax_kkart_' $ajax_event, array( __CLASS__$ajax_event ) );
            
add_action'wp_ajax_nopriv_kkart_' $ajax_event, array( __CLASS__$ajax_event ) );

            
// KKART AJAX can be used for frontend ajax requests.
            
add_action'kkart_ajax_' $ajax_event, array( __CLASS__$ajax_event ) );
        }

        
$ajax_events = array(
            
'feature_product',
            
'mark_order_status',
            
'get_order_details',
            
'add_attribute',
            
'add_new_attribute',
            
'remove_variation',
            
'remove_variations',
            
'save_attributes',
            
'add_variation',
            
'link_all_variations',
            
'revoke_access_to_download',
            
'grant_access_to_download',
            
'get_customer_details',
            
'add_order_item',
            
'add_order_fee',
            
'add_order_shipping',
            
'add_order_tax',
            
'add_coupon_discount',
            
'remove_order_coupon',
            
'remove_order_item',
            
'remove_order_tax',
            
'reduce_order_item_stock',
            
'increase_order_item_stock',
            
'add_order_item_meta',
            
'remove_order_item_meta',
            
'calc_line_taxes',
            
'save_order_items',
            
'load_order_items',
            
'add_order_note',
            
'delete_order_note',
            
'json_search_products',
            
'json_search_products_and_variations',
            
'json_search_downloadable_products_and_variations',
            
'json_search_customers',
            
'json_search_categories',
            
'term_ordering',
            
'product_ordering',
            
'refund_line_items',
            
'delete_refund',
            
'rated',
            
'update_api_key',
            
'load_variations',
            
'save_variations',
            
'bulk_edit_variations',
            
'tax_rates_save_changes',
            
'shipping_zones_save_changes',
            
'shipping_zone_add_method',
            
'shipping_zone_methods_save_changes',
            
'shipping_zone_methods_save_settings',
            
'shipping_classes_save_changes',
            
'toggle_gateway_enabled',
            
'product_archives',
            
'cart_update_price_details',
            
'get_states',
            
'user_auth',
            
'get_product_variants',
            
'create_variable_product',
            
'save_billing_address',
            
'delete_address',
            
'get_address_details',
            
'set_billing_address',
            
'checkout_tabs_procceed',
            
'account_order_details',
            
'get_order_lists',
            
'get_order_downloads',
            
'set_variant_data',
            
'delete_all_variations',
            
'delete_variant',
            
'reload_cart_tab',
            
'check_postcode',
            
'get_country_locale',
        );

        foreach ( 
$ajax_events as $ajax_event ) {
            
add_action'wp_ajax_kkart_' $ajax_event, array( __CLASS__$ajax_event ) );
        }
    }

    
/**
     * Get a refreshed cart fragment, including the mini cart HTML.
     */
    
public static function get_refreshed_fragments() {
        
ob_start();

        
kkart_mini_cart();

        
$mini_cart ob_get_clean();

        
$data = array(
            
'fragments' => apply_filters(
                
'kkart_add_to_cart_fragments',
                array(
                    
'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' $mini_cart '</div>',
                )
            ),
            
'cart_hash' => KKART()->cart->get_cart_hash(),
        );

        
wp_send_json$data );
    }

    
/**
     * AJAX apply coupon on checkout page.
     */
    
public static function apply_coupon() {

        
check_ajax_referer'kkart_ajax''security' );

        if ( ! empty( 
$_POST['coupon_code'] ) ) {
            
KKART()->cart->add_discountkkart_format_coupon_codewp_unslash$_POST['coupon_code'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        
} else {
            
kkart_add_noticeKKART_Coupon::get_generic_coupon_errorKKART_Coupon::E_KKART_COUPON_PLEASE_ENTER ), 'error' );
        }

        
kkart_print_notices();
        
wp_die();
    }

    
/**
     * AJAX remove coupon on cart and checkout page.
     */
    
public static function remove_coupon() {
        
check_ajax_referer'kkart_ajax''security' );

        
$coupon = isset( $_POST['coupon'] ) ? kkart_format_coupon_codewp_unslash$_POST['coupon'] ) ) : false// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        
if ( empty( $coupon ) ) {
            
kkart_add_notice__'Sorry there was a problem removing this coupon.''kkart' ), 'error' );
        } else {
            
KKART()->cart->remove_coupon$coupon );
            
kkart_add_notice__'Coupon has been removed.''kkart' ) );
        }

        
kkart_print_notices();
        
wp_die();
    }

    
/**
     * AJAX update shipping method on cart page.
     */
    
public static function update_shipping_method() {
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
kkart_maybe_define_constant'KKART_CART'true );
        
        
$chosen_shipping_methods KKART()->session->get'chosen_shipping_methods' );
        
$posted_shipping_methods = isset( $_POST['shipping_method'] ) ? (array) kkart_cleanwp_unslash$_POST['shipping_method'] ) ) : array();

        if ( 
is_array$posted_shipping_methods ) ) {
            foreach ( 
$posted_shipping_methods as $i => $value ) {
                
$chosen_shipping_methods$i ] = $value;
            }
        }

        
KKART()->session->set'chosen_shipping_methods'$chosen_shipping_methods );

        
KKART()->cart->calculate_shipping();
        
KKART()->cart->calculate_totals();
        
        
$cart_details = ($_REQUEST['cart'] == '1') ? true false;
        
$data self::cart_update_price_details($cart_details);
                    
        
wp_send_json$data);
    }

    
/**
     * AJAX receive updated cart_totals div.
     */
    
public static function get_cart_totals() {
        
kkart_maybe_define_constant'KKART_CART'true );
        
KKART()->cart->calculate_totals();
        
kkart_cart_totals();
        
wp_die();
    }

    
/**
     * Session has expired.
     */
    
private static function update_order_review_expired() {
        
wp_send_json(
            array(
                
'fragments' => apply_filters(
                    
'kkart_update_order_review_fragments',
                    array(
                        
'form.kkart-checkout' => '<div class="kkart-error">' __'Sorry, your session has expired.''kkart' ) . ' <a href="' esc_urlkkart_get_page_permalink'shop' ) ) . '" class="kkart-backward">' __'Return to shop''kkart' ) . '</a></div>',
                    )
                ),
            )
        );
    }

    
/**
     * AJAX update order review on checkout.
     */
    
public static function update_order_review() {
        
check_ajax_referer'update-order-review''security' );

        
kkart_maybe_define_constant'KKART_CHECKOUT'true );

        if ( 
KKART()->cart->is_empty() && ! is_customize_preview() && apply_filters'kkart_checkout_update_order_review_expired'true ) ) {
            
self::update_order_review_expired();
        }

        
do_action'kkart_checkout_update_order_review', isset( $_POST['post_data'] ) ? wp_unslash$_POST['post_data'] ) : '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        
$chosen_shipping_methods KKART()->session->get'chosen_shipping_methods' );
        
$posted_shipping_methods = isset( $_POST['shipping_method'] ) ? kkart_cleanwp_unslash$_POST['shipping_method'] ) ) : array();

        if ( 
is_array$posted_shipping_methods ) ) {
            foreach ( 
$posted_shipping_methods as $i => $value ) {
                
$chosen_shipping_methods$i ] = $value;
            }
        }

        
KKART()->session->set'chosen_shipping_methods'$chosen_shipping_methods );
        
KKART()->session->set'chosen_payment_method', empty( $_POST['payment_method'] ) ? '' kkart_cleanwp_unslash$_POST['payment_method'] ) ) );
        
KKART()->customer->set_props(
            array(
                
'billing_country'   => isset( $_POST['country'] ) ? kkart_cleanwp_unslash$_POST['country'] ) ) : null,
                
'billing_state'     => isset( $_POST['state'] ) ? kkart_cleanwp_unslash$_POST['state'] ) ) : null,
                
'billing_postcode'  => isset( $_POST['postcode'] ) ? kkart_cleanwp_unslash$_POST['postcode'] ) ) : null,
                
'billing_city'      => isset( $_POST['city'] ) ? kkart_cleanwp_unslash$_POST['city'] ) ) : null,
                
'billing_address_1' => isset( $_POST['address'] ) ? kkart_cleanwp_unslash$_POST['address'] ) ) : null,
                
'billing_address_2' => isset( $_POST['address_2'] ) ? kkart_cleanwp_unslash$_POST['address_2'] ) ) : null,
            )
        );

        if ( 
kkart_ship_to_billing_address_only() ) {
            
KKART()->customer->set_props(
                array(
                    
'shipping_country'   => isset( $_POST['country'] ) ? kkart_cleanwp_unslash$_POST['country'] ) ) : null,
                    
'shipping_state'     => isset( $_POST['state'] ) ? kkart_cleanwp_unslash$_POST['state'] ) ) : null,
                    
'shipping_postcode'  => isset( $_POST['postcode'] ) ? kkart_cleanwp_unslash$_POST['postcode'] ) ) : null,
                    
'shipping_city'      => isset( $_POST['city'] ) ? kkart_cleanwp_unslash$_POST['city'] ) ) : null,
                    
'shipping_address_1' => isset( $_POST['address'] ) ? kkart_cleanwp_unslash$_POST['address'] ) ) : null,
                    
'shipping_address_2' => isset( $_POST['address_2'] ) ? kkart_cleanwp_unslash$_POST['address_2'] ) ) : null,
                )
            );
        } else {
            
KKART()->customer->set_props(
                array(
                    
'shipping_country'   => isset( $_POST['s_country'] ) ? kkart_cleanwp_unslash$_POST['s_country'] ) ) : null,
                    
'shipping_state'     => isset( $_POST['s_state'] ) ? kkart_cleanwp_unslash$_POST['s_state'] ) ) : null,
                    
'shipping_postcode'  => isset( $_POST['s_postcode'] ) ? kkart_cleanwp_unslash$_POST['s_postcode'] ) ) : null,
                    
'shipping_city'      => isset( $_POST['s_city'] ) ? kkart_cleanwp_unslash$_POST['s_city'] ) ) : null,
                    
'shipping_address_1' => isset( $_POST['s_address'] ) ? kkart_cleanwp_unslash$_POST['s_address'] ) ) : null,
                    
'shipping_address_2' => isset( $_POST['s_address_2'] ) ? kkart_cleanwp_unslash$_POST['s_address_2'] ) ) : null,
                )
            );
        }

        if ( isset( 
$_POST['has_full_address'] ) && kkart_string_to_boolkkart_cleanwp_unslash$_POST['has_full_address'] ) ) ) ) {
            
KKART()->customer->set_calculated_shippingtrue );
        } else {
            
KKART()->customer->set_calculated_shippingfalse );
        }

        
KKART()->customer->save();

        
// Calculate shipping before totals. This will ensure any shipping methods that affect things like taxes are chosen prior to final totals being calculated. Ref: #22708.
        
KKART()->cart->calculate_shipping();
        
KKART()->cart->calculate_totals();

        
// Get order review fragment.
        
ob_start();
        
kkart_order_review();
        
$kkart_order_review ob_get_clean();

        
// Get checkout payment fragment.
        
ob_start();
        
kkart_checkout_payment();
        
$kkart_checkout_payment ob_get_clean();

        
// Get messages if reload checkout is not true.
        
$reload_checkout = isset( KKART()->session->reload_checkout ) ? true false;
        if ( ! 
$reload_checkout ) {
            
$messages kkart_print_noticestrue );
        } else {
            
$messages '';
        }

        unset( 
KKART()->session->refresh_totalsKKART()->session->reload_checkout );

        
wp_send_json(
            array(
                
'result'    => empty( $messages ) ? 'success' 'failure',
                
'messages'  => $messages,
                
'reload'    => $reload_checkout,
                
'fragments' => apply_filters(
                    
'kkart_update_order_review_fragments',
                    array(
                        
'.kkart-checkout-review-order-table' => $kkart_order_review,
                        
'.kkart-checkout-payment' => $kkart_checkout_payment,
                    )
                ),
            )
        );
    }

    
/**
     * AJAX add to cart.
     */
    
public static function add_to_cart() {
        
ob_start();

        
// phpcs:disable WordPress.Security.NonceVerification.Missing
        
if ( ! isset( $_POST['product_id'] ) ) {
            return;
        }

        
$product_id        apply_filters'kkart_add_to_cart_product_id'absint$_POST['product_id'] ) );
        
$product           kkart_get_product$product_id );
        
$quantity          = empty( $_POST['quantity'] ) ? kkart_stock_amountwp_unslash$_POST['quantity'] ) );
        
$passed_validation apply_filters'kkart_add_to_cart_validation'true$product_id$quantity );
        
$product_status    get_post_status$product_id );
        
$variation_id      0;
        
$variation         = array();

        if ( 
$product && 'variation' === $product->get_type() ) {
            
$variation_id $product_id;
            
$product_id   $product->get_parent_id();
            
$variation    $product->get_variation_attributes();
        }

        if ( 
$passed_validation && false !== KKART()->cart->add_to_cart$product_id$quantity$variation_id$variation ) && 'publish' === $product_status ) {

            
do_action'kkart_ajax_added_to_cart'$product_id );

            if ( 
'yes' === get_option'kkart_cart_redirect_after_add' ) ) {
                
kkart_add_to_cart_message( array( $product_id => $quantity ), true );
            }

            
self::get_refreshed_fragments();

        } else {

            
// If there was an error adding to the cart, redirect to the product page to show any errors.
            
$data = array(
                
'error'       => true,
                
'product_url' => apply_filters'kkart_cart_redirect_after_error'get_permalink$product_id ), $product_id ),
            );

            
wp_send_json$data );
        }
        
// phpcs:enable
    
}
    
    
// TODO check for security start
    
public static function cart_update_price_details($cart false){
        
$cart_ob KKART()->cart;    
        
        
ob_start();
        
kkart_cart_totals_order_total_html();
        
$grand_total ob_get_clean();    
        
        
$data = array(
            
'grand_total' => $grand_total,
            
'sub_total' => $cart_ob->get_cart_subtotal(),
            
'all_items_total' => $cart_ob->get_cart_total(),
        );
        
        if( 
kkart_tax_enabled() && ! KKART()->cart->display_prices_including_tax() ){
            
$data['tax'] = kkart_tax_amount_html();
        }
        if( 
'yes' == get_option'kkart_enable_coupons' ) ) {
            
$data['discount'] = kkart_coupon_price_html();
        } 
        if( ! 
$cart || 'yes' == get_option'kkart_enable_shipping_calc' ) ) {
            
$data['grand_total'] = $grand_total;
        }
        if( ! 
$cart ) {
            
$data['delivery_charges'] = $cart_ob->get_cart_shipping_total();
        }
        
        return 
$data;
    }

    public static function 
cart_update_quantity(){
        
        
$cart_item_key kkart_clean( isset($_POST['cart_item_key']) ) ? wp_unslash$_POST['cart_item_key'] ) : '';
        
$quantity kkart_clean( isset($_POST['quantity']) ) ? wp_unslash$_POST['quantity'] ) : '';
        
        
$cart_item KKART()->cart->get_cart();
        
        
$product kkart_get_product($cart_item[$cart_item_key]['data']);
        
        
$max_value $product->get_max_purchase_quantity();
        
        if( 
$max_value && $quantity $max_value){
            
$quantity $max_value;
        }
        
        
KKART()->cart->set_quantity($cart_item_key$quantity);
        
        
$subtotal KKART()->cart->get_product_subtotal($product$quantity);
        
$data self::cart_update_price_details();
        
$data['product_subtotal'] = $subtotal;
        
        
wp_send_json($data);
    }    
    
    
/**
     * AJAX get state data
     */
    
public static function get_states(){
        
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$selected_country kkart_clean(isset($_POST['country_name']) ? wp_unslash($_POST['country_name']) : '');
        
$states KKART()->countries->get_states$selected_country );
        
wp_send_json($states);
    }
    
    
/**
     * AJAX get state data
     */   
    
public static function get_country_locale(){
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
$locale =  KKART()->countries->get_country_locale();
        
wp_send_json($locale);
    }

    
/**
     * AJAX get state data
     */
    
public static function check_postcode(){
        
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$country kkart_clean(isset($_POST['selected_country']) ? wp_unslash($_POST['selected_country']) : '');
        
$postcode kkart_clean(isset($_POST['post_code']) ?  wp_unslash($_POST['post_code']) : '');

        
$postcode_res KKART_Validation::is_postcode$postcode$country);
        
wp_send_json($postcode_res);
    }
    
    
/**
     * AJAX confirm USER login
     */
    
public static function user_auth(){
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$user_data get_userdata(get_current_user_id());

        
$data = array(
            
'isLoggedIn' => is_user_logged_in(),
            
'display_name' => $user_data->data->display_name,
            
'user_email' => $user_data->data->user_email
        
);
        
        
wp_send_json($data);
        
    }
    
    
/**
     * AJAX get product variants data and shipping classes
     */
    
public static function get_product_variants(){
        
check_ajax_referer'kkart_editor_nonce''kkart_nonce' );
        
        
$attribute_tax self::get_attribute_taxonomy();
        
        
$shipping_classes get_terms( array('taxonomy' => 'product_shipping_class''hide_empty' => false ) );
        
$product_id kkart_clean(isset($_POST['product_id']) ? wp_unslash($_POST['product_id']) : '');
        
$product kkart_get_product$product_id );
        
$product->has_child() ? $variations $product->get_available_variations() : $variations '';
        
        
$variation_data =[];
        
$product_id     absint$product_id );
        
$post           get_post$product_id ); // phpcs:ignore
        
$product_object kkart_get_product$product_id );
        
$product_children   kkart_get_products(
            array(
                
'status'  => array( 'private''publish''draft' ),
                
'type'    => 'variation',
                
'parent'  => $product_id,
                
'limit' => 50,
                
'orderby' => array(
                    
'menu_order' => 'ASC',
                    
'ID'         => 'DESC',
                ),
                
'return'  => 'objects',
            )
        );

        
        if ( !empty(
$product_children) ) {
        
            foreach ( 
$product_children as $child_product ) {
                
$variation_object kkart_get_product($child_product);
                
$variation_id   $variation_object->get_id();
                
$variation      get_post$variation_id );        
                
$variation_object_data = array(
                    
'attributes' => kkart_get_product_variation_attributes$variation_id ),
                    
'variation_id' => $variation_id,
                    
'status' => $variation_object->get_status(),
                    
'description' => $variation_object->get_description(),
                    
'sku' => $variation_object->get_sku(),
                    
'price' => $variation_object->get_price(),
                    
'regular_price' => $variation_object->get_regular_price(),
                    
'sale_price' => $variation_object->get_sale_price(),
                    
'date_on_sale_from' => $variation_object->get_date_on_sale_from(),
                    
'date_on_sale_to' => $variation_object->get_date_on_sale_to(),
                    
'manage_stock' => $variation_object->get_manage_stock(),
                    
'stock_quantity' => $variation_object->get_stock_quantity(),
                    
'stock_status' => $variation_object->get_stock_status(),
                    
'backorders' => $variation_object->get_backorders(),
                    
'weight' => $variation_object->get_weight(),
                    
'length' => $variation_object->get_length(),
                    
'width' => $variation_object->get_width(),
                    
'height' => $variation_object->get_height(),
                    
'virtual' => $variation_object->get_virtual(),
                    
'downloadable' => $variation_object->get_downloadable(),
                    
'downloads' => $variation_object->get_downloads(),
                    
'shipping_class_id' => $variation_object->get_shipping_class_id(),
                    
'shipping_class' => $variation_object->get_shipping_class(),
                    
'image_id' => $variation_object->get_image_id(),
                    
'image' => wp_get_attachment_url($variation_object->get_image_id()),
                    
'download_limit' => $variation_object->get_download_limit(),
                    
'download_expiry' => $variation_object->get_download_expiry(),
                    
'attribute_summary' => $variation_object->get_attribute_summary()
                );
                
                
array_push($variation_data$variation_object_data);
                
            }
        }
        
        
        
$data = array(
            
'variation' => $variation_data,
            
'attribute_tax' => $attribute_tax,
            
'shipping_classes' => $shipping_classes,
            
'message' => 'Success'
        
);
        
        if( empty(
$variation_data) ){
            
$data['message'] = 'No Variant found';
        }
        
        
wp_send_json($data);
        
    }
    
    
/**
     * AJAX to create variable poroduct
     **/
    
public static function create_variable_product(){
        
check_ajax_referer'kkart_editor_nonce''kkart_nonce' );
        
        
$attribute_data kkart_clean(isset($_POST['attribute_data']) ? wp_unslash($_POST['attribute_data']) : '');
        
$product_id kkart_clean(isset($_POST['product_id']) ? wp_unslash($_POST['product_id']) : '');
        
$variant_data kkart_clean(isset($_POST['variant_data']) ? wp_unslash($_POST['variant_data']) : '');
        
        
$attribute_data json_decode($attribute_data,true);
        
$variant_data json_decode($variant_data,true);
        
        
$product kkart_get_product($product_id);

        if( 
is_a($product'KKART_Product') && !$product->is_type('variable') && !$product->has_child() ){
            
$product = new KKART_Product_Variable($product_id);
        }
        
        if(empty(
$attribute_data)){
            
$product_children   kkart_get_products(
                array(
                    
'status'  => array( 'private''publish''draft' ),
                    
'type'    => 'variation',
                    
'parent'  => $product->get_id(),
                    
'orderby' => array(
                        
'menu_order' => 'ASC',
                        
'ID'         => 'DESC',
                    ),
                    
'return'  => 'objects',
                )
            );
            
            if(!empty(
$product_children)){
                foreach(
$product_children as $children){
                    
$children->delete();
                }
            }
        }
        
        
$attribute self::create_product_attribute($product,$attribute_data);
    
        if(
count($attribute) > 0){
            
$variant self::create_product_variants($attribute[0],$product$variant_data);
        }
        
        
wp_send_json($attribute);

    }
    
    
//matches the input variant types to already defined attribute taxonomy terms
    
public static function matchTerms($attribute,$input_attributes){
        
$term_id = [];
        (
gettype($attribute) == 'array') ? $options = (array) $attribute $options = (array) $attribute->get_options();
        
        foreach(
$options as $option){
        
            foreach(
$input_attributes['types'] as $type){
                
                if(
term_exists($type$input_attributes['name'])){
                    
array_push($term_id,(gettype($attribute) == 'array') ? $option->term_id $option);
                }
            
            }
            
        }
        return 
$term_id;
    }
    
    
//Creates product attribute
    
public static function create_product_attribute($product$attribute_data){
        
        
        
$id = [];
        foreach(
$attribute_data as $input_attribute){
            
$attributes = (array) $product->get_attributes();
            
            if(
array_key_exists$input_attribute['name'], $attributes ) && taxonomy_exists($input_attribute['name'])){
                
                    foreach(
$attributes as $key => $attribute){
            
                        if(
$key == $input_attribute['name'] && taxonomy_exists($input_attribute['name'])){
                            
$term_id self::matchTerms($attribute,$input_attribute);
                            
$attribute->set_options($term_id);
                            
$attributes[$key] = $attribute;
                        }        
                    }
                    
$product->set_attributes($attributes);
                    
array_push($id,$product->save());
                    continue;
            }
            
            
$attribute = new KKART_Product_Attribute();
            
$attribute->set_name($input_attribute['name']);
            
            if(
taxonomy_exists($input_attribute['name'])){
                
                
$terms get_terms([
                    
'taxonomy' => $input_attribute['name'],
                    
'hide_empty' => false,
                ]);
                
                
$term_id self::matchTerms($terms,$input_attribute);
                
                
// $terms = [];
                // foreach($term_id as $term){
                    // array_push($terms,get_term($term)->name); //getting term name from id
                // }
            
}
            
            (!empty(
$term_id)) ? $options $term_id $options $input_attribute['types'];
            
            
$attribute->set_options($options);
            
$term_id = []; //cleaning
            
$attribute->set_position);
            
$attribute->set_visible);
            
$attribute->set_variation);
            
$attributes[$attribute->get_name()] = $attribute;
            
            
$product->set_attributes($attributes);
            
            
array_push($id,$product->save());
            
            
//linking the attribute taxonomy terms to the product attribute types
            
if(!empty($term)){
                
                foreach(
$terms as $term_name){

                    if( ! 
has_term$term_name$input_attribute['name'], $product->get_id() ) && taxonomy_exists($input_attribute['name'])){
                        
wp_set_object_terms($product->get_id(), sanitize_title($term_name), $input_attribute['name'], true );
                    }
                }
            }
        }
        
        return 
$id;
    }
    
    
//creates variants
    
public static function create_product_variants($id$product$variants){
        
            
$product_children   kkart_get_products(
                array(
                    
'status'  => array( 'private''publish''draft' ),
                    
'type'    => 'variation',
                    
'parent'  => $product->get_id(),
                    
'orderby' => array(
                        
'menu_order' => 'ASC',
                        
'ID'         => 'DESC',
                    ),
                    
'return'  => 'objects',
                )
            );
            if(!empty(
$product_children)){
                foreach(
$product_children as $children){
                    
$children->delete();
                }
            }
        foreach(
$variants as $variant){
            
            
//if(isset($variant['attribute_name']) && isset($variant['variant']) && empty($variant['variation_id'])){
                
                
$variation = new KKART_Product_Variation();
                
$variation->set_parent_id($id);
                
                
self::set_variant($variation,$variant);
                
                
$variation_id $variation->save(); 
                
            
//}elseif(!empty($variant['variation_id'])){
                
                //self::update_product_variants($variant);
            
            //}
        
}
    }
    
    public static function 
edit_attribute_taxonomy(){
        
//print_r();
    
}
    
    
//sets the variant
    
public static function set_variant($variation$variant){
        
        
$attributes      = array(); // Initializing
        
$attribute_names = (array) $variant['attribute_name'];
        
$attribute_terms = (array) $variant['variant']; 
    
        
// Formatting attributes data array
        
foreach( $attribute_names as $key => $attribute_name ){
            
$attributes[sanitize_title($attribute_name)] = $attribute_terms[$key];
        }
        
        
$variation->set_attributes($attributes); 
    }
    
    
// public static function update_product_variants($variant){
        
        // $variation = kkart_get_product($variant['variation_id']);
        // self::set_variant($variation,$variant);
        // $variation_id = $variation->save(); 
    // }
    
    
    /**
     * AJAX to sets all the variants details
     **/
    
public static function set_variant_data(){
        
check_ajax_referer'kkart_editor_nonce''kkart_nonce' );

        
$variation_id kkart_clean( isset($_POST['variation_id'])) ? wp_unslash$_POST['variation_id'] ) : '';
        
$form_data kkart_clean( isset($_POST['form_data'])) ? wp_unslash$_POST['form_data'] ) : '';
        
$variation kkart_get_product($variation_id);
        
        
        foreach(
$form_data as $field){
            
            switch(
$field['name']){
            
                case 
'image_id' :
                    
$variation->set_image_id($field['value']);
                    break;
            
                case 
'sku' 
                    
$variation->set_sku($field['value']);
                    break;
                    
                case 
'enabled' :
                    
$variation->set_status($field['value'] == 'on' 'publish' 'private');
                    break;
                    
                case 
'virtual' 
                    
$variation->set_virtual(($field['value'] == 'on') ? 0);
                    break;
                    
                case 
'downloadable' 
                    
$variation->set_downloadable(($field['value'] == 'on') ? 0);
                    break;

                case 
'manage_stock' 
                    
$variation->set_manage_stock(($field['value'] == 'on') ? 0);    
                    break;
                
                case 
'regular_price' 
                    
$variation->set_regular_price(abs($field['value']) != abs($field['value']) : '');
                    break;
                
                case 
'sale_price' 
                    
$variation->set_sale_price(abs($field['value']) != abs($field['value']) : '');
                    break;

                case 
'sale_start_date' :
                    
$variation->set_date_on_sale_from($field['value']);
                    break;
                
                case 
'sale_end_date' 
                    
$variation->set_date_on_sale_to($field['value']);
                    break;
                    
                case 
'stock_status' 
                    
$variation->set_stock_status($field['value']);
                    break;
                    
                case 
'stock_quantity' 
                    
$variation->set_stock_quantity(absint($field['value']));
                    break;
                
                case 
'weight' 
                    
$variation->set_weight(abs($field['value']));
                    break;
                    
                case 
'length' 
                    
$variation->set_length(abs($field['value']));
                    break;
                    
                case 
'width' 
                    
$variation->set_width(abs($field['value']));
                    break;
                    
                case 
'height' 
                    
$variation->set_height(abs($field['value']));
                    break;
                    
                case 
'shipping_class' 
                    
$variation->set_shipping_class_id(absint($field['value']));
                    break;
                    
                case 
'description' 
                    
$variation->set_description($field['value']);
                    break;
                    
                case 
'download_file_data' 
                    
$variation->set_downloads($field['value']);
            }
        }
        
$variation->save();
        
        
wp_send_json('Success');
    
    }
    
// check for security end
    
    
public static function get_attribute_taxonomy(){
        
        
$attribute_tax kkart_get_attribute_taxonomies();
        
$attribute_tax_name  array_values(kkart_get_attribute_taxonomy_labels());
        
$terms self::get_attribute_terms($attribute_tax_name);
        
        
$attribute_data = array(
            
'attribute_tax_name' => $attribute_tax_name,
            
'attribute_terms' => $terms
        
);
        
        return 
$attribute_data;
    }
    
    
//fetches attribute taxonmy terms
    
public static function get_attribute_terms($attribute_tax_name){
        
        
$terms = [];
        
        foreach(
$attribute_tax_name as $attribute_name){
            
$attribute_name 'pa_'.strtolower($attribute_name);

            
array_push($termsget_terms(array(
                
'taxonomy' => $attribute_name,
                
'hide_empty' => false
            
)));
        }
        
        return 
$terms;
    }
    
    
/**
     * AJAX to delete a single variant at a time
     **/
    
public static function delete_variant(){
        
check_ajax_referer'kkart_editor_nonce''kkart_nonce' );
    
        
$variant_id kkart_clean( isset($_POST['variant_id']) ) ? wp_unslash$_POST['variant_id'] ) : false;
        
        
$variation kkart_get_product($variant_id);
        
$variation->delete();
    }
    
    
/**
     * AJAX to delete all variants at a time
     **/
    
public static function variation_bulk_action_delete_all_variations($variation_ids$data){
        
        foreach(
$variation_ids as $variation_id){
            
$variation kkart_get_product($variation_id);
            
$product_id $variation->get_parent_id();
            
$variation->delete();
        }
        
delete_post_meta($product_id,'_product_attributes');
    }
    
    
/**
     * AJAX remove from cart.
     */
    
public static function remove_from_cart() {
        
ob_start();

        
// phpcs:ignore WordPress.Security.NonceVerification.Missing
        
$cart_item_key kkart_clean( isset( $_POST['cart_item_key'] ) ? wp_unslash$_POST['cart_item_key'] ) : '' );

        if ( 
$cart_item_key && false !== KKART()->cart->remove_cart_item$cart_item_key ) ) {
            
wp_send_json(self::cart_update_price_details());
        } else {
            
wp_send_json_error();
        }
    }
    
    
// Save checkout address handler
    
public static function save_billing_address(){
        
        
// Some AJAX security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$done = array();
        
$data $_REQUEST;
        
$address_id '';
        
        if(! 
is_user_logged_in()){
            
$done['error'] = __('Please login and try again!');
            
wp_send_json($done);
        }
        
        if(!empty(
$_REQUEST['address_id']) ){
            
$address_id $_REQUEST['address_id'];
        }else{
            
$address_id 'addr_'.rand(10009999);
        }
        
        
// Update user Address
        
$ret kkart_update_user_address($address_id$data);
        
        if(
$ret['error']){
            
$done['postal_error'] = $ret['error'];
            echo 
json_encode($done);
            
wp_die();
        }
        
        if(empty(
$ret)){
            
$done['error'] = 'The updated data not fond, Some thing wrong';
            echo 
json_encode($done);
            
wp_die();
        }
        
        
$done['success'] = 'true';
        
$done['address_id'] = $address_id;
        
$done['address_data'] = $ret;
        
$done['address_data']['address_id'] = $address_id;
        echo 
json_encode($done);
        
wp_die();
    }
    
    
// Delete checkout address handler
    
public static function delete_address(){
        
        
// Some AJAX security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$done = array();
        
        if(! 
is_user_logged_in()){
            
$done['error'] = __('Please login and try again!');
            
wp_send_json($done);
        }
        
        if(empty(
$_REQUEST['address_id'])){
            
$done['error'] = __('Address ID not found');
            
wp_send_json($done);
        }
        
        
$ret kkart_delete_user_address($_REQUEST['address_id']);
        
        if(empty(
$ret)){
            
$done['error'] = 'Unable to delete address for some reason! Please contact to Shop author!';
            echo 
json_encode($done);
            
wp_die();
        }
        
        
$done['success'] = 'true';
        
$done['address_id'] = $address_id;
        echo 
json_encode($done);
        
wp_die();
    }
    
    
// Get checkout address handler
    
public static function get_address_details(){
        
        
// Some AJAX security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$done = array();
        
        if(! 
is_user_logged_in()){
            
$done['error'] = __('Please login and try again!');
            
wp_send_json($done);
        }
        
        
$user_id get_current_user_id();
        
$ret kkart_get_user_address();
        
        if(empty(
$ret)){
            
$done['error'] = 'Unable to get address for some reason! Please contact to Shop author!';
            echo 
json_encode($done);
            
wp_die();
        }
        
        
$done['address_data'] = $ret;

        if(!empty(
$_REQUEST['address_id'])){
            if(!isset(
$ret[$_REQUEST['address_id']])){
                
$done['error'] = __('Address ID not found');
                echo 
json_encode($done);
                
wp_die();
            }
            
            
$ret $ret[$_REQUEST['address_id']];
        }
        
        
$prefix 'billing_';
        
        if(isset(
$_REQUEST['is_shipping']) && $_REQUEST['is_shipping'] == 'true'){
            
$prefix 'shipping_';
        }
        
        
// Update user address ID
        
$active_id get_user_meta$user_id$prefix.'address_id'true);
        
        
$done['success'] = 'true';
        
$done['address_data'] = $ret;
        
$done['active_addr_id'] = $active_id;
        echo 
json_encode($done);
        
wp_die();
    }
    
    
// Set billing address handler
    
public static function set_billing_address(){
        
        
// Some AJAX security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$done = array();
        
        if(! 
is_user_logged_in()){
            
$done['error'] = __('Please login and try again!');
            
wp_send_json($done);
        }
        
        if(empty(
$_REQUEST['address_id'])){
            
$done['error'] = __('Address ID not found');
            
wp_send_json($done);
        }
        
        
$user_id get_current_user_id();
        
$ret kkart_get_user_address($_REQUEST['address_id']);
        
$prefix 'billing_';
        
        if(empty(
$ret)){
            
$done['error'] = 'Unable to Set address for some reason! Please contact to Shop author!';
            echo 
json_encode($done);
            
wp_die();
        }
        
        if(
$_REQUEST['is_shipping'] == 'true'){
            
$prefix 'shipping_';
        }
        
        foreach(
$ret as $key => $value){
            
$key substr($key8);
            
update_user_meta$user_id$prefix.$key$value);
        }
        
        
// Update user address ID
        
update_user_meta$user_id$prefix.'address_id'$_REQUEST['address_id']);
        
        
$done['success'] = 'true';
        
$done['address_data'] = $ret;
        echo 
json_encode($done);
        
wp_die();
    }
    
    public static function 
reload_cart_tab() {
        
        
// Some AJAX Security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
KKART()->cart->calculate_totals();
        
$cart_tab_html kkart_checkout_cart();
        
wp_send_json$cart_tab_html );
    }
    
    
// Checkout procceed handler
    
public static function checkout_tabs_procceed(){
        
        
// Some AJAX security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$done = array();
        
$tab_type = @$_REQUEST['tab_type'];
        
        if(empty(
$tab_type)){
            
$done['error'] = __('Please provide valid tab type!');
            echo 
json_encode($done);
            
wp_die();
        }
        
        switch(
$tab_type){
            case 
'login':
            
                if(!
is_user_logged_in()){
                    
$done['logged_out'] = __('Please login and try again!');
                }
                
                if(
is_user_logged_in()){
                    
$user_data get_userdata(get_current_user_id());

                    
$done['login_auth'] = array(
                        
'isLoggedIn' => is_user_logged_in(),
                        
'display_name' => $user_data->data->display_name,
                        
'user_email' => $user_data->data->user_email
                    
);
                }
        
                break;
            case 
'billing':
            
                
$addresses kkart_get_user_address();    
                
$user_id get_current_user_id();
                
$active_addr_id get_user_meta($user_id'billing_address_id'true);
                
                if(!
is_user_logged_in()){
                    
$done['logged_out'] = __('Please login and try again!');
                }
                
                if(!
array_key_exists($active_addr_id$addresses)){
                    
$done['error'] = __('Please Set the valid address for the billing!');
                }
                
                break;
            case 
'shipping':
            
                
$addresses kkart_get_user_address();    
                
$user_id get_current_user_id();
                
$active_addr_id get_user_meta($user_id'shipping_address_id'true);

                if(!
is_user_logged_in()){
                    
$done['logged_out'] = __('Pleaselease login and try again!');
                }
                
                
// Skip error if not set differrent address
                
if(!array_key_exists($active_addr_id$addresses) && empty($_REQUEST['ship_to_billing_address'])){
                    
$done['error'] = __('Please Set the valid address for the shipping!');
                }
                
                break;
            case 
'cart':
                
// TODO: if any cart related validations
                
if(!is_user_logged_in()){
                    
$done['logged_out'] = __('Pleaselease login and try again!');
                }
                
                if ( 
KKART()->cart->is_empty() ) {
                    
$done['error'] = __('Unable to procceed Due to empty cart!');
                }
                
                break;
            case 
'payment':
            
                if(!
is_user_logged_in()){
                    
$done['logged_out'] = __('Please login and try again!');
                    break;
                }
                
                
kkart_maybe_define_constant'KKART_CHECKOUT'true );
                
KKART()->checkout()->process_checkout();
                break;
        }
        
        echo 
json_encode($done);
        
wp_die();
    }
    
    
/**
     * Process ajax checkout form.
     */
    
public static function checkout() {
        
kkart_maybe_define_constant'KKART_CHECKOUT'true );
        
KKART()->checkout()->process_checkout();
        
wp_die);
    }

    
/**
     * Get a matching variation based on posted attributes.
     */
    
public static function get_variation() {
        
ob_start();

        
// phpcs:disable WordPress.Security.NonceVerification.Missing
        
if ( empty( $_POST['product_id'] ) ) {
            
wp_die();
        }

        
$variable_product kkart_get_productabsint$_POST['product_id'] ) );

        if ( ! 
$variable_product ) {
            
wp_die();
        }

        
$data_store   KKART_Data_Store::load'product' );
        
$variation_id $data_store->find_matching_product_variation$variable_productwp_unslash$_POST ) );
        
$variation    $variation_id $variable_product->get_available_variation$variation_id ) : false;
        
wp_send_json$variation );
        
// phpcs:enable
    
}

    
/**
     * Locate user via AJAX.
     */
    
public static function get_customer_location() {
        
$location_hash KKART_Cache_Helper::geolocation_ajax_get_location_hash();
        
wp_send_json_success( array( 'hash' => $location_hash ) );
    }

    
/**
     * Toggle Featured status of a product from admin.
     */
    
public static function feature_product() {
        if ( 
current_user_can'edit_products' ) && check_admin_referer'kkart-feature-product' ) && isset( $_GET['product_id'] ) ) {
            
$product kkart_get_productabsint$_GET['product_id'] ) );

            if ( 
$product ) {
                
$product->set_featured( ! $product->get_featured() );
                
$product->save();
            }
        }

        
wp_safe_redirectwp_get_referer() ? remove_query_arg( array( 'trashed''untrashed''deleted''ids' ), wp_get_referer() ) : admin_url'edit.php?post_type=product' ) );
        exit;
    }

    
/**
     * Mark an order with a status.
     */
    
public static function mark_order_status() {
        if ( 
current_user_can'edit_shop_orders' ) && check_admin_referer'kkart-mark-order-status' ) && isset( $_GET['status'], $_GET['order_id'] ) ) {
            
$status sanitize_text_fieldwp_unslash$_GET['status'] ) );
            
$order  kkart_get_orderabsintwp_unslash$_GET['order_id'] ) ) );

            if ( 
kkart_is_order_status'kkart-' $status ) && $order ) {
                
// Initialize payment gateways in case order has hooked status transition actions.
                
KKART()->payment_gateways();

                
$order->update_status$status''true );
                
do_action'kkart_order_edit_status'$order->get_id(), $status );
            }
        }

        
wp_safe_redirectwp_get_referer() ? wp_get_referer() : admin_url'edit.php?post_type=shop_order' ) );
        exit;
    }

    
/**
     * Get order details.
     */
    
public static function get_order_details() {
        
check_admin_referer'kkart-preview-order''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_GET['order_id'] ) ) {
            
wp_die( -);
        }

        
$order kkart_get_orderabsint$_GET['order_id'] ) );

        if ( 
$order ) {
            include_once 
__DIR__ '/admin/list-tables/class-kkart-admin-list-table-orders.php';

            
wp_send_json_successKKART_Admin_List_Table_Orders::order_preview_get_order_details$order ) );
        }
        
wp_die();
    }

    
/**
     * Add an attribute row.
     */
    
public static function add_attribute() {
        
ob_start();

        
check_ajax_referer'add-attribute''security' );

        if ( ! 
current_user_can'edit_products' ) || ! isset( $_POST['taxonomy'], $_POST['i'] ) ) {
            
wp_die( -);
        }

        
$i             absint$_POST['i'] );
        
$metabox_class = array();
        
$attribute     = new KKART_Product_Attribute();

        
$attribute->set_idkkart_attribute_taxonomy_id_by_namesanitize_text_fieldwp_unslash$_POST['taxonomy'] ) ) ) );
        
$attribute->set_namesanitize_text_fieldwp_unslash$_POST['taxonomy'] ) ) );
        
$attribute->set_visibleapply_filters'kkart_attribute_default_visibility') );
        
$attribute->set_variationapply_filters'kkart_attribute_default_is_variation') );

        if ( 
$attribute->is_taxonomy() ) {
            
$metabox_class[] = 'taxonomy';
            
$metabox_class[] = $attribute->get_name();
        }

        include 
__DIR__ '/admin/meta-boxes/views/html-product-attribute.php';
        
wp_die();
    }

    
/**
     * Add a new attribute via ajax function.
     */
    
public static function add_new_attribute() {
        
check_ajax_referer'add-attribute''security' );

        if ( 
current_user_can'manage_product_terms' ) && isset( $_POST['taxonomy'], $_POST['term'] ) ) {
            
$taxonomy esc_attrwp_unslash$_POST['taxonomy'] ) ); // phpcs:ignore
            
$term     kkart_cleanwp_unslash$_POST['term'] ) );

            if ( 
taxonomy_exists$taxonomy ) ) {

                
$result wp_insert_term$term$taxonomy );

                if ( 
is_wp_error$result ) ) {
                    
wp_send_json(
                        array(
                            
'error' => $result->get_error_message(),
                        )
                    );
                } else {
                    
$term get_term_by'id'$result['term_id'], $taxonomy );
                    
wp_send_json(
                        array(
                            
'term_id' => $term->term_id,
                            
'name'    => $term->name,
                            
'slug'    => $term->slug,
                        )
                    );
                }
            }
        }
        
wp_die( -);
    }

    
/**
     * Delete variations via ajax function.
     */
    
public static function remove_variations() {
        
check_ajax_referer'delete-variations''security' );

        if ( 
current_user_can'edit_products' ) && isset( $_POST['variation_ids'] ) ) {
            
$variation_ids array_map'absint', (array) wp_unslash$_POST['variation_ids'] ) );

            foreach ( 
$variation_ids as $variation_id ) {
                if ( 
'product_variation' === get_post_type$variation_id ) ) {
                    
$variation kkart_get_product$variation_id );
                    
$variation->deletetrue );
                }
            }
        }

        
wp_die( -);
    }

    
/**
     * Save attributes via ajax.
     */
    
public static function save_attributes() {
        
check_ajax_referer'save-attributes''security' );

        if ( ! 
current_user_can'edit_products' ) || ! isset( $_POST['data'], $_POST['post_id'] ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            
parse_strwp_unslash$_POST['data'] ), $data ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

            
$attributes   KKART_Meta_Box_Product_Data::prepare_attributes$data );
            
$product_id   absintwp_unslash$_POST['post_id'] ) );
            
$product_type = ! empty( $_POST['product_type'] ) ? kkart_cleanwp_unslash$_POST['product_type'] ) ) : 'simple';
            
$classname    KKART_Product_Factory::get_product_classname$product_id$product_type );
            
$product      = new $classname$product_id );

            
$product->set_attributes$attributes );
            
$product->save();

            
ob_start();
            
$attributes $product->get_attributes'edit' );
            
$i          = -1;
            if ( ! empty( 
$data['attribute_names'] ) ) {
                foreach ( 
$data['attribute_names'] as $attribute_name ) {
                    
$attribute = isset( $attributessanitize_title$attribute_name ) ] ) ? $attributessanitize_title$attribute_name ) ] : false;
                    if ( ! 
$attribute ) {
                        continue;
                    }
                    
$i++;
                    
$metabox_class = array();

                    if ( 
$attribute->is_taxonomy() ) {
                        
$metabox_class[] = 'taxonomy';
                        
$metabox_class[] = $attribute->get_name();
                    }

                    include 
__DIR__ '/admin/meta-boxes/views/html-product-attribute.php';
                }
            }

            
$response['html'] = ob_get_clean();
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Add variation via ajax function.
     */
    
public static function add_variation() {
        
check_ajax_referer'add-variation''security' );

        if ( ! 
current_user_can'edit_products' ) || ! isset( $_POST['post_id'], $_POST['loop'] ) ) {
            
wp_die( -);
        }

        global 
$post// Set $post global so its available, like within the admin screens.

        
$product_id       intval$_POST['post_id'] );
        
$post             get_post$product_id ); // phpcs:ignore
        
$loop             intval$_POST['loop'] );
        
$product_object   kkart_get_product_object'variable'$product_id ); // Forces type to variable in case product is unsaved.
        
$variation_object kkart_get_product_object'variation' );
        
$variation_object->set_parent_id$product_id );
        
$variation_object->set_attributesarray_fill_keysarray_map'sanitize_title'array_keys$product_object->get_variation_attributes() ) ), '' ) );
        
$variation_id   $variation_object->save();
        
$variation      get_post$variation_id );
        
$variation_data array_mergeget_post_custom$variation_id ), kkart_get_product_variation_attributes$variation_id ) ); // kept for BW compatibility.
        
include __DIR__ '/admin/meta-boxes/views/html-variation-admin.php';
        
wp_die();
    }

    
/**
     * Link all variations via ajax function.
     */
    
public static function link_all_variations() {
        
check_ajax_referer'link-variations''security' );

        if ( ! 
current_user_can'edit_products' ) ) {
            
wp_die( -);
        }

        
kkart_maybe_define_constant'KKART_MAX_LINKED_VARIATIONS'50 );
        
kkart_set_time_limit);

        
$post_id = isset( $_POST['post_id'] ) ? intval$_POST['post_id'] ) : 0;

        if ( ! 
$post_id ) {
            
wp_die();
        }

        
$product    kkart_get_product$post_id );
        
$data_store $product->get_data_store();

        if ( ! 
is_callable( array( $data_store'create_all_product_variations' ) ) ) {
            
wp_die();
        }

        echo 
esc_html$data_store->create_all_product_variations$productConstants::get_constant'KKART_MAX_LINKED_VARIATIONS' ) ) );

        
$data_store->sort_all_product_variations$product->get_id() );
        
wp_die();
    }

    
/**
     * Delete download permissions via ajax function.
     */
    
public static function revoke_access_to_download() {
        
check_ajax_referer'revoke-access''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['download_id'], $_POST['product_id'], $_POST['order_id'], $_POST['permission_id'] ) ) {
            
wp_die( -);
        }
        
$download_id   kkart_cleanwp_unslash$_POST['download_id'] ) );
        
$product_id    intval$_POST['product_id'] );
        
$order_id      intval$_POST['order_id'] );
        
$permission_id absint$_POST['permission_id'] );
        
$data_store    KKART_Data_Store::load'customer-download' );
        
$data_store->delete_by_id$permission_id );

        
do_action'kkart_ajax_revoke_access_to_product_download'$download_id$product_id$order_id$permission_id );

        
wp_die();
    }

    
/**
     * Grant download permissions via ajax function.
     */
    
public static function grant_access_to_download() {

        
check_ajax_referer'grant-access''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['loop'], $_POST['order_id'], $_POST['product_ids'] ) ) {
            
wp_die( -);
        }

        global 
$wpdb;

        
$wpdb->hide_errors();

        
$order_id     intval$_POST['order_id'] );
        
$product_ids  array_filterarray_map'absint', (array) wp_unslash$_POST['product_ids'] ) ) );
        
$loop         intval$_POST['loop'] );
        
$file_counter 0;
        
$order        kkart_get_order$order_id );

        foreach ( 
$product_ids as $product_id ) {
            
$product kkart_get_product$product_id );
            
$files   $product->get_downloads();

            if ( ! 
$order->get_billing_email() ) {
                
wp_die();
            }

            if ( ! empty( 
$files ) ) {
                foreach ( 
$files as $download_id => $file ) {
                    
$inserted_id kkart_downloadable_file_permission$download_id$product_id$order );
                    if ( 
$inserted_id ) {
                        
$download = new KKART_Customer_Download$inserted_id );
                        
$loop ++;
                        
$file_counter ++;

                        if ( 
$file->get_name() ) {
                            
$file_count $file->get_name();
                        } else {
                            
/* translators: %d file count */
                            
$file_count sprintf__'File %d''kkart' ), $file_counter );
                        }
                        include 
__DIR__ '/admin/meta-boxes/views/html-order-download-permission.php';
                    }
                }
            }
        }
        
wp_die();
    }

    
/**
     * Get customer details via ajax.
     */
    
public static function get_customer_details() {
        
check_ajax_referer'get-customer-details''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['user_id'] ) ) {
            
wp_die( -);
        }

        
$user_id  absint$_POST['user_id'] );
        
$customer = new KKART_Customer$user_id );

        if ( 
has_filter'kkart_found_customer_details' ) ) {
            
kkart_deprecated_function'The kkart_found_customer_details filter''3.0''kkart_ajax_get_customer_details' );
        }

        
$data                  $customer->get_data();
        
$data['date_created']  = $data['date_created'] ? $data['date_created']->getTimestamp() : null;
        
$data['date_modified'] = $data['date_modified'] ? $data['date_modified']->getTimestamp() : null;

        
$customer_data apply_filters'kkart_ajax_get_customer_details'$data$customer$user_id );
        
wp_send_json$customer_data );
    }

    
/**
     * Add order item via ajax. Used on the edit order screen in WP Admin.
     *
     * @throws Exception If order is invalid.
     */
    
public static function add_order_item() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) ) {
            
wp_die( -);
        }

        if ( ! isset( 
$_POST['order_id'] ) ) {
            throw new 
Exception__'Invalid order''kkart' ) );
        }
        
$order_id absintwp_unslash$_POST['order_id'] ) );

        
// If we passed through items it means we need to save first before adding a new one.
        
$items = ( ! empty( $_POST['items'] ) ) ? wp_unslash$_POST['items'] ) : ''// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        
$items_to_add = isset( $_POST['data'] ) ? array_filterwp_unslash( (array) $_POST['data'] ) ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        
try {
            
$response self::maybe_add_order_item$order_id$items$items_to_add );
            
wp_send_json_success$response );
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }
    }

    
/**
     * Add order item via AJAX. This is refactored for better unit testing.
     *
     * @param int          $order_id     ID of order to add items to.
     * @param string|array $items        Existing items in order. Empty string if no items to add.
     * @param array        $items_to_add Array of items to add.
     *
     * @return array     Fragments to render and notes HTML.
     * @throws Exception When unable to add item.
     */
    
private static function maybe_add_order_item$order_id$items$items_to_add ) {
        try {
            
$order kkart_get_order$order_id );

            if ( ! 
$order ) {
                throw new 
Exception__'Invalid order''kkart' ) );
            }

            if ( ! empty( 
$items ) ) {
                
$save_items = array();
                
parse_str$items$save_items );
                
kkart_save_order_items$order->get_id(), $save_items );
            }

            
// Add items to order.
            
$order_notes = array();

            foreach ( 
$items_to_add as $item ) {
                if ( ! isset( 
$item['id'], $item['qty'] ) || empty( $item['id'] ) ) {
                    continue;
                }
                
$product_id absint$item['id'] );
                
$qty        kkart_stock_amount$item['qty'] );
                
$product    kkart_get_product$product_id );

                if ( ! 
$product ) {
                    throw new 
Exception__'Invalid product ID''kkart' ) . ' ' $product_id );
                }
                if ( 
'variable' === $product->get_type() ) {
                    
/* translators: %s product name */
                    
throw new Exceptionsprintf__'%s is a variable product parent and cannot be added.''kkart' ), $product->get_name() ) );
                }
                
$validation_error = new WP_Error();
                
$validation_error apply_filters'kkart_ajax_add_order_item_validation'$validation_error$product$order$qty );

                if ( 
$validation_error->get_error_code() ) {
                    
/* translators: %s: error message */
                    
throw new Exceptionsprintf__'Error: %s''kkart' ), $validation_error->get_error_message() ) );
                }
                
$item_id                 $order->add_product$product$qty );
                
$item                    apply_filters'kkart_ajax_order_item'$order->get_item$item_id ), $item_id$order$product );
                
$added_items$item_id ] = $item;
                
$order_notes$item_id ] = $product->get_formatted_name();

                
// We do not perform any stock operations here because they will be handled when order is moved to a status where stock operations are applied (like processing, completed etc).

                
do_action'kkart_ajax_add_order_item_meta'$item_id$item$order );
            }

            
/* translators: %s item name. */
            
$order->add_order_notesprintf__'Added line items: %s''kkart' ), implode', '$order_notes ) ), falsetrue );

            
do_action'kkart_ajax_order_items_added'$added_items$order );

            
$data get_post_meta$order_id );

            
// Get HTML to return.
            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
            
$items_html ob_get_clean();

            
ob_start();
            
$notes kkart_get_order_notes( array( 'order_id' => $order_id ) );
            include 
__DIR__ '/admin/meta-boxes/views/html-order-notes.php';
            
$notes_html ob_get_clean();

            return array(
                
'html'       => $items_html,
                
'notes_html' => $notes_html,
            );
        } catch ( 
Exception $e ) {
            throw 
$e// Forward exception to caller.
        
}
    }

    
/**
     * Add order fee via ajax.
     *
     * @throws Exception If order is invalid.
     */
    
public static function add_order_fee() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            
$order_id = isset( $_POST['order_id'] ) ? absint$_POST['order_id'] ) : 0;
            
$order    kkart_get_order$order_id );

            if ( ! 
$order ) {
                throw new 
Exception__'Invalid order''kkart' ) );
            }

            
$amount = isset( $_POST['amount'] ) ? kkart_cleanwp_unslash$_POST['amount'] ) ) : 0;

            
$calculate_tax_args = array(
                
'country'  => isset( $_POST['country'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['country'] ) ) ) : '',
                
'state'    => isset( $_POST['state'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['state'] ) ) ) : '',
                
'postcode' => isset( $_POST['postcode'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['postcode'] ) ) ) : '',
                
'city'     => isset( $_POST['city'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['city'] ) ) ) : '',
            );

            if ( 
strstr$amount'%' ) ) {
                
$formatted_amount $amount;
                
$percent          floatvaltrim$amount'%' ) );
                
$amount           $order->get_total() * ( $percent 100 );
            } else {
                
$amount           floatval$amount );
                
$formatted_amount kkart_price$amount, array( 'currency' => $order->get_currency() ) );
            }

            
$fee = new KKART_Order_Item_Fee();
            
$fee->set_amount$amount );
            
$fee->set_total$amount );
            
/* translators: %s fee amount */
            
$fee->set_namesprintf__'%s fee''kkart' ), kkart_clean$formatted_amount ) ) );

            
$order->add_item$fee );
            
$order->calculate_taxes$calculate_tax_args );
            
$order->calculate_totalsfalse );
            
$order->save();

            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
            
$response['html'] = ob_get_clean();
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Add order shipping cost via ajax.
     *
     * @throws Exception If order is invalid.
     */
    
public static function add_order_shipping() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            
$order_id = isset( $_POST['order_id'] ) ? absint$_POST['order_id'] ) : 0;
            
$order    kkart_get_order$order_id );

            if ( ! 
$order ) {
                throw new 
Exception__'Invalid order''kkart' ) );
            }

            
$order_taxes      $order->get_taxes();
            
$shipping_methods KKART()->shipping() ? KKART()->shipping()->load_shipping_methods() : array();

            
// Add new shipping.
            
$item = new KKART_Order_Item_Shipping();
            
$item->set_shipping_rate( new KKART_Shipping_Rate() );
            
$item->set_order_id$order_id );
            
$item_id $item->save();

            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-shipping.php';
            
$response['html'] = ob_get_clean();
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Add order tax column via ajax.
     *
     * @throws Exception If order or tax rate is invalid.
     */
    
public static function add_order_tax() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            
$order_id = isset( $_POST['order_id'] ) ? absint$_POST['order_id'] ) : 0;
            
$order    kkart_get_order$order_id );

            if ( ! 
$order ) {
                throw new 
Exception__'Invalid order''kkart' ) );
            }

            
$rate_id = isset( $_POST['rate_id'] ) ? absint$_POST['rate_id'] ) : '';

            if ( ! 
$rate_id ) {
                throw new 
Exception__'Invalid rate''kkart' ) );
            }

            
$data get_post_meta$order_id );

            
// Add new tax.
            
$item = new KKART_Order_Item_Tax();
            
$item->set_rate$rate_id );
            
$item->set_order_id$order_id );
            
$item->save();

            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
            
$response['html'] = ob_get_clean();
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Add order discount via ajax.
     *
     * @throws Exception If order or coupon is invalid.
     */
    
public static function add_coupon_discount() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            
$order_id           = isset( $_POST['order_id'] ) ? absint$_POST['order_id'] ) : 0;
            
$order              kkart_get_order$order_id );
            
$calculate_tax_args = array(
                
'country'  => isset( $_POST['country'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['country'] ) ) ) : '',
                
'state'    => isset( $_POST['state'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['state'] ) ) ) : '',
                
'postcode' => isset( $_POST['postcode'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['postcode'] ) ) ) : '',
                
'city'     => isset( $_POST['city'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['city'] ) ) ) : '',
            );

            if ( ! 
$order ) {
                throw new 
Exception__'Invalid order''kkart' ) );
            }

            if ( empty( 
$_POST['coupon'] ) ) {
                throw new 
Exception__'Invalid coupon''kkart' ) );
            }

            
// Add user ID and/or email so validation for coupon limits works.
            
$user_id_arg    = isset( $_POST['user_id'] ) ? absint$_POST['user_id'] ) : 0;
            
$user_email_arg = isset( $_POST['user_email'] ) ? sanitize_emailwp_unslash$_POST['user_email'] ) ) : '';

            if ( 
$user_id_arg ) {
                
$order->set_customer_id$user_id_arg );
            }
            if ( 
$user_email_arg ) {
                
$order->set_billing_email$user_email_arg );
            }

            
$result $order->apply_couponkkart_format_coupon_codewp_unslash$_POST['coupon'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

            
if ( is_wp_error$result ) ) {
                throw new 
Exceptionhtml_entity_decodewp_strip_all_tags$result->get_error_message() ) ) );
            }

            
$order->calculate_taxes$calculate_tax_args );
            
$order->calculate_totalsfalse );

            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
            
$response['html'] = ob_get_clean();
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Remove coupon from an order via ajax.
     *
     * @throws Exception If order or coupon is invalid.
     */
    
public static function remove_order_coupon() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            
$order_id           = isset( $_POST['order_id'] ) ? absint$_POST['order_id'] ) : 0;
            
$order              kkart_get_order$order_id );
            
$calculate_tax_args = array(
                
'country'  => isset( $_POST['country'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['country'] ) ) ) : '',
                
'state'    => isset( $_POST['state'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['state'] ) ) ) : '',
                
'postcode' => isset( $_POST['postcode'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['postcode'] ) ) ) : '',
                
'city'     => isset( $_POST['city'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['city'] ) ) ) : '',
            );

            if ( ! 
$order ) {
                throw new 
Exception__'Invalid order''kkart' ) );
            }

            if ( empty( 
$_POST['coupon'] ) ) {
                throw new 
Exception__'Invalid coupon''kkart' ) );
            }

            
$order->remove_couponkkart_format_coupon_codewp_unslash$_POST['coupon'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
$order->calculate_taxes$calculate_tax_args );
            
$order->calculate_totalsfalse );

            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
            
$response['html'] = ob_get_clean();
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Remove an order item.
     *
     * @throws Exception If order is invalid.
     */
    
public static function remove_order_item() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['order_id'], $_POST['order_item_ids'] ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            
$order_id absint$_POST['order_id'] );
            
$order    kkart_get_order$order_id );

            if ( ! 
$order ) {
                throw new 
Exception__'Invalid order''kkart' ) );
            }

            if ( ! isset( 
$_POST['order_item_ids'] ) ) {
                throw new 
Exception__'Invalid items''kkart' ) );
            }

            
$order_item_ids     wp_unslash$_POST['order_item_ids'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
$items              = ( ! empty( $_POST['items'] ) ) ? wp_unslash$_POST['items'] ) : ''// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
$calculate_tax_args = array(
                
'country'  => isset( $_POST['country'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['country'] ) ) ) : '',
                
'state'    => isset( $_POST['state'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['state'] ) ) ) : '',
                
'postcode' => isset( $_POST['postcode'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['postcode'] ) ) ) : '',
                
'city'     => isset( $_POST['city'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['city'] ) ) ) : '',
            );

            if ( ! 
is_array$order_item_ids ) && is_numeric$order_item_ids ) ) {
                
$order_item_ids = array( $order_item_ids );
            }

            
// If we passed through items it means we need to save first before deleting.
            
if ( ! empty( $items ) ) {
                
$save_items = array();
                
parse_str$items$save_items );
                
kkart_save_order_items$order->get_id(), $save_items );
            }

            if ( ! empty( 
$order_item_ids ) ) {
                
$order_notes = array();

                foreach ( 
$order_item_ids as $item_id ) {
                    
$item_id absint$item_id );
                    
$item    $order->get_item$item_id );

                    
// Before deleting the item, adjust any stock values already reduced.
                    
if ( $item->is_type'line_item' ) ) {
                        
$changed_stock kkart_maybe_adjust_line_item_product_stock$item);

                        if ( 
$changed_stock && ! is_wp_error$changed_stock ) ) {
                            
/* translators: %1$s: item name %2$s: stock change */
                            
$order->add_order_notesprintf__'Deleted %1$s and adjusted stock (%2$s)''kkart' ), $item->get_name(), $changed_stock['from'] . '&rarr;' $changed_stock['to'] ), falsetrue );
                        } else {
                            
/* translators: %s item name. */
                            
$order->add_order_notesprintf__'Deleted %s''kkart' ), $item->get_name() ), falsetrue );
                        }
                    }

                    
kkart_delete_order_item$item_id );
                }
            }

            
$order kkart_get_order$order_id );
            
$order->calculate_taxes$calculate_tax_args );
            
$order->calculate_totalsfalse );

            
// Get HTML to return.
            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
            
$items_html ob_get_clean();

            
ob_start();
            
$notes kkart_get_order_notes( array( 'order_id' => $order_id ) );
            include 
__DIR__ '/admin/meta-boxes/views/html-order-notes.php';
            
$notes_html ob_get_clean();

            
wp_send_json_success(
                array(
                    
'html'       => $items_html,
                    
'notes_html' => $notes_html,
                )
            );
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Remove an order tax.
     *
     * @throws Exception If there is an error whilst deleting the rate.
     */
    
public static function remove_order_tax() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['order_id'], $_POST['rate_id'] ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            
$order_id absint$_POST['order_id'] );
            
$rate_id  absint$_POST['rate_id'] );

            
$order kkart_get_order$order_id );
            if ( ! 
$order->is_editable() ) {
                throw new 
Exception__'Order not editable''kkart' ) );
            }

            
kkart_delete_order_item$rate_id );

            
// Need to load order again after deleting to have latest items before calculating.
            
$order kkart_get_order$order_id );
            
$order->calculate_totalsfalse );

            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
            
$response['html'] = ob_get_clean();
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Calc line tax.
     */
    
public static function calc_line_taxes() {
        
check_ajax_referer'calc-totals''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['order_id'], $_POST['items'] ) ) {
            
wp_die( -);
        }

        
$order_id           absint$_POST['order_id'] );
        
$calculate_tax_args = array(
            
'country'  => isset( $_POST['country'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['country'] ) ) ) : '',
            
'state'    => isset( $_POST['state'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['state'] ) ) ) : '',
            
'postcode' => isset( $_POST['postcode'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['postcode'] ) ) ) : '',
            
'city'     => isset( $_POST['city'] ) ? kkart_strtoupperkkart_cleanwp_unslash$_POST['city'] ) ) ) : '',
        );

        
// Parse the jQuery serialized items.
        
$items = array();
        
parse_strwp_unslash$_POST['items'] ), $items ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        // Save order items first.
        
kkart_save_order_items$order_id$items );

        
// Grab the order and recalculate taxes.
        
$order kkart_get_order$order_id );
        
$order->calculate_taxes$calculate_tax_args );
        
$order->calculate_totalsfalse );
        include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
        
wp_die();
    }

    
/**
     * Save order items via ajax.
     */
    
public static function save_order_items() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['order_id'], $_POST['items'] ) ) {
            
wp_die( -);
        }

        if ( isset( 
$_POST['order_id'], $_POST['items'] ) ) {
            
$order_id absint$_POST['order_id'] );

            
// Parse the jQuery serialized items.
            
$items = array();
            
parse_strwp_unslash$_POST['items'] ), $items ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

            // Save order items.
            
kkart_save_order_items$order_id$items );

            
// Return HTML items.
            
$order kkart_get_order$order_id );

            
// Get HTML to return.
            
ob_start();
            include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
            
$items_html ob_get_clean();

            
ob_start();
            
$notes kkart_get_order_notes( array( 'order_id' => $order_id ) );
            include 
__DIR__ '/admin/meta-boxes/views/html-order-notes.php';
            
$notes_html ob_get_clean();

            
wp_send_json_success(
                array(
                    
'html'       => $items_html,
                    
'notes_html' => $notes_html,
                )
            );
        }
        
wp_die();
    }

    
/**
     * Load order items via ajax.
     */
    
public static function load_order_items() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['order_id'] ) ) {
            
wp_die( -);
        }

        
// Return HTML items.
        
$order_id absint$_POST['order_id'] );
        
$order    kkart_get_order$order_id );
        include 
__DIR__ '/admin/meta-boxes/views/html-order-items.php';
        
wp_die();
    }

    
/**
     * Add order note via ajax.
     */
    
public static function add_order_note() {
        
check_ajax_referer'add-order-note''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['post_id'], $_POST['note'], $_POST['note_type'] ) ) {
            
wp_die( -);
        }

        
$post_id   absint$_POST['post_id'] );
        
$note      wp_kses_posttrimwp_unslash$_POST['note'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        
$note_type kkart_cleanwp_unslash$_POST['note_type'] ) );

        
$is_customer_note = ( 'customer' === $note_type ) ? 0;

        if ( 
$post_id ) {
            
$order      kkart_get_order$post_id );
            
$comment_id $order->add_order_note$note$is_customer_notetrue );
            
$note       kkart_get_order_note$comment_id );

            
$note_classes   = array( 'note' );
            
$note_classes[] = $is_customer_note 'customer-note' '';
            
$note_classes   apply_filters'kkart_order_note_class'array_filter$note_classes ), $note );
            
?>
            <li rel="<?php echo absint$note->id ); ?>" class="<?php echo esc_attrimplode' '$note_classes ) ); ?>">
                <div class="note_content">
                    <?php echo wp_kses_postwpautopwptexturizemake_clickable$note->content ) ) ) ); ?>
                </div>
                <p class="meta">
                    <abbr class="exact-date" title="<?php echo esc_attr$note->date_created->date'y-m-d h:i:s' ) ); ?>">
                        <?php
                        
/* translators: $1: Date created, $2 Time created */
                        
printfesc_html__'added on %1$s at %2$s''kkart' ), esc_html$note->date_created->date_i18nkkart_date_format() ) ), esc_html$note->date_created->date_i18nkkart_time_format() ) ) );
                        
?>
                    </abbr>
                    <?php
                    
if ( 'system' !== $note->added_by ) :
                        
/* translators: %s: note author */
                        
printf' ' esc_html__'by %s''kkart' ), esc_html$note->added_by ) );
                    endif;
                    
?>
                    <a href="#" class="delete_note" role="button"><?php esc_html_e'Delete note''kkart' ); ?></a>
                </p>
            </li>
            <?php
        
}
        
wp_die();
    }

    
/**
     * Delete order note via ajax.
     */
    
public static function delete_order_note() {
        
check_ajax_referer'delete-order-note''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['note_id'] ) ) {
            
wp_die( -);
        }

        
$note_id = (int) $_POST['note_id'];

        if ( 
$note_id ) {
            
kkart_delete_order_note$note_id );
        }
        
wp_die();
    }

    
/**
     * Search for products and echo json.
     *
     * @param string $term (default: '') Term to search for.
     * @param bool   $include_variations in search or not.
     */
    
public static function json_search_products$term ''$include_variations false ) {
        
check_ajax_referer'search-products''security' );

        if ( empty( 
$term ) && isset( $_GET['term'] ) ) {
            
$term = (string) kkart_cleanwp_unslash$_GET['term'] ) );
        }

        if ( empty( 
$term ) ) {
            
wp_die();
        }

        if ( ! empty( 
$_GET['limit'] ) ) {
            
$limit absint$_GET['limit'] );
        } else {
            
$limit absintapply_filters'kkart_json_search_limit'30 ) );
        }

        
$include_ids = ! empty( $_GET['include'] ) ? array_map'absint', (array) wp_unslash$_GET['include'] ) ) : array();
        
$exclude_ids = ! empty( $_GET['exclude'] ) ? array_map'absint', (array) wp_unslash$_GET['exclude'] ) ) : array();

        
$exclude_types = array();
        if ( ! empty( 
$_GET['exclude_type'] ) ) {
            
// Support both comma-delimited and array format inputs.
            
$exclude_types wp_unslash$_GET['exclude_type'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
if ( ! is_array$exclude_types ) ) {
                
$exclude_types explode','$exclude_types );
            }

            
// Sanitize the excluded types against valid product types.
            
foreach ( $exclude_types as &$exclude_type ) {
                
$exclude_type strtolowertrim$exclude_type ) );
            }
            
$exclude_types array_intersect(
                
array_merge( array( 'variation' ), array_keyskkart_get_product_types() ) ),
                
$exclude_types
            
);
        }

        
$data_store KKART_Data_Store::load'product' );
        
$ids        $data_store->search_products$term'', (bool) $include_variationsfalse$limit$include_ids$exclude_ids );

        
$products = array();

        foreach ( 
$ids as $id ) {
            
$product_object kkart_get_product$id );

            if ( ! 
kkart_products_array_filter_readable$product_object ) ) {
                continue;
            }

            
$formatted_name $product_object->get_formatted_name();
            
$managing_stock $product_object->managing_stock();

            if ( 
in_array$product_object->get_type(), $exclude_typestrue ) ) {
                continue;
            }

            if ( 
$managing_stock && ! empty( $_GET['display_stock'] ) ) {
                
$stock_amount $product_object->get_stock_quantity();
                
/* Translators: %d stock amount */
                
$formatted_name .= ' &ndash; ' sprintf__'Stock: %d''kkart' ), kkart_format_stock_quantity_for_display$stock_amount$product_object ) );
            }

            
$products$product_object->get_id() ] = rawurldecodewp_strip_all_tags($formatted_name) );
        }

        
wp_send_jsonapply_filters'kkart_json_search_found_products'$products ) );
    }

    
/**
     * Search for product variations and return json.
     *
     * @see KKART_AJAX::json_search_products()
     */
    
public static function json_search_products_and_variations() {
        
self::json_search_products''true );
    }

    
/**
     * Search for downloadable product variations and return json.
     *
     * @see KKART_AJAX::json_search_products()
     */
    
public static function json_search_downloadable_products_and_variations() {
        
check_ajax_referer'search-products''security' );

        if ( ! empty( 
$_GET['limit'] ) ) {
            
$limit absint$_GET['limit'] );
        } else {
            
$limit absintapply_filters'kkart_json_search_limit'30 ) );
        }

        
$include_ids = ! empty( $_GET['include'] ) ? array_map'absint', (array) wp_unslash$_GET['include'] ) ) : array();
        
$exclude_ids = ! empty( $_GET['exclude'] ) ? array_map'absint', (array) wp_unslash$_GET['exclude'] ) ) : array();

        
$term       = isset( $_GET['term'] ) ? (string) kkart_cleanwp_unslash$_GET['term'] ) ) : '';
        
$data_store KKART_Data_Store::load'product' );
        
$ids        $data_store->search_products$term'downloadable'truefalse$limit );

        
$product_objects array_filterarray_map'kkart_get_product'$ids ), 'kkart_products_array_filter_readable' );
        
$products        = array();

        foreach ( 
$product_objects as $product_object ) {
            
$products$product_object->get_id() ] = rawurldecode$product_object->get_formatted_name() );
        }

        
wp_send_json$products );
    }

    
/**
     * Search for customers and return json.
     */
    
public static function json_search_customers() {
        
ob_start();

        
check_ajax_referer'search-customers''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) ) {
            
wp_die( -);
        }

        
$term  = isset( $_GET['term'] ) ? (string) kkart_cleanwp_unslash$_GET['term'] ) ) : '';
        
$limit 0;

        if ( empty( 
$term ) ) {
            
wp_die();
        }

        
$ids = array();
        
// Search by ID.
        
if ( is_numeric$term ) ) {
            
$customer = new KKART_Customerintval$term ) );

            
// Customer does not exists.
            
if ( !== $customer->get_id() ) {
                
$ids = array( $customer->get_id() );
            }
        }

        
// Usernames can be numeric so we first check that no users was found by ID before searching for numeric username, this prevents performance issues with ID lookups.
        
if ( empty( $ids ) ) {
            
$data_store KKART_Data_Store::load'customer' );

            
// If search is smaller than 3 characters, limit result set to avoid
            // too many rows being returned.
            
if ( strlen$term ) ) {
                
$limit 20;
            }
            
$ids $data_store->search_customers$term$limit );
        }

        
$found_customers = array();

        if ( ! empty( 
$_GET['exclude'] ) ) {
            
$ids array_diff$idsarray_map'absint', (array) wp_unslash$_GET['exclude'] ) ) );
        }

        foreach ( 
$ids as $id ) {
            
$customer = new KKART_Customer$id );
            
/* translators: 1: user display name 2: user ID 3: user email */
            
$found_customers$id ] = sprintf(
                
/* translators: $1: customer name, $2 customer id, $3: customer email */
                
esc_html__'%1$s (#%2$s &ndash; %3$s)''kkart' ),
                
$customer->get_first_name() . ' ' $customer->get_last_name(),
                
$customer->get_id(),
                
$customer->get_email()
            );
        }

        
wp_send_jsonapply_filters'kkart_json_search_found_customers'$found_customers ) );
    }

    
/**
     * Search for categories and return json.
     */
    
public static function json_search_categories() {
        
ob_start();

        
check_ajax_referer'search-categories''security' );

        if ( ! 
current_user_can'edit_products' ) ) {
            
wp_die( -);
        }

        
$search_text = isset( $_GET['term'] ) ? kkart_cleanwp_unslash$_GET['term'] ) ) : '';

        if ( ! 
$search_text ) {
            
wp_die();
        }

        
$found_categories = array();
        
$args             = array(
            
'taxonomy'   => array( 'product_cat' ),
            
'orderby'    => 'id',
            
'order'      => 'ASC',
            
'hide_empty' => true,
            
'fields'     => 'all',
            
'name__like' => $search_text,
        );

        
$terms get_terms$args );

        if ( 
$terms ) {
            foreach ( 
$terms as $term ) {
                
$term->formatted_name '';

                if ( 
$term->parent ) {
                    
$ancestors array_reverseget_ancestors$term->term_id'product_cat' ) );
                    foreach ( 
$ancestors as $ancestor ) {
                        
$ancestor_term get_term$ancestor'product_cat' );
                        if ( 
$ancestor_term ) {
                            
$term->formatted_name .= $ancestor_term->name ' > ';
                        }
                    }
                }

                
$term->formatted_name              .= $term->name ' (' $term->count ')';
                
$found_categories$term->term_id ] = $term;
            }
        }

        
wp_send_jsonapply_filters'kkart_json_search_found_categories'$found_categories ) );
    }

    
/**
     * Ajax request handling for categories ordering.
     */
    
public static function term_ordering() {
        
// phpcs:disable WordPress.Security.NonceVerification.Missing
        
if ( ! current_user_can'edit_products' ) || empty( $_POST['id'] ) ) {
            
wp_die( -);
        }

        
$id       = (int) $_POST['id'];
        
$next_id  = isset( $_POST['nextid'] ) && (int) $_POST['nextid'] ? (int) $_POST['nextid'] : null;
        
$taxonomy = isset( $_POST['thetaxonomy'] ) ? esc_attrwp_unslash$_POST['thetaxonomy'] ) ) : null// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        
$term     get_term_by'id'$id$taxonomy );

        if ( ! 
$id || ! $term || ! $taxonomy ) {
            
wp_die);
        }

        
kkart_reorder_terms$term$next_id$taxonomy );

        
$children get_terms$taxonomy"child_of=$id&menu_order=ASC&hide_empty=0" );

        if ( 
$term && count$children ) ) {
            echo 
'children';
            
wp_die();
        }
        
// phpcs:enable
    
}

    
/**
     * Ajax request handling for product ordering.
     *
     * Based on Simple Page Ordering by 10up (https://wordpress.org/plugins/simple-page-ordering/).
     */
    
public static function product_ordering() {
        global 
$wpdb;

        
// phpcs:disable WordPress.Security.NonceVerification.Missing
        
if ( ! current_user_can'edit_products' ) || empty( $_POST['id'] ) ) {
            
wp_die( -);
        }

        
$sorting_id  absint$_POST['id'] );
        
$previd      absint( isset( $_POST['previd'] ) ? $_POST['previd'] : );
        
$nextid      absint( isset( $_POST['nextid'] ) ? $_POST['nextid'] : );
        
$menu_orders wp_list_pluck$wpdb->get_results"SELECT ID, menu_order FROM {$wpdb->posts} WHERE post_type = 'product' ORDER BY menu_order ASC, post_title ASC" ), 'menu_order''ID' );
        
$index       0;

        foreach ( 
$menu_orders as $id => $menu_order ) {
            
$id absint$id );

            if ( 
$sorting_id === $id ) {
                continue;
            }
            if ( 
$nextid === $id ) {
                
$index ++;
            }
            
$index ++;
            
$menu_orders$id ] = $index;
            
$wpdb->update$wpdb->posts, array( 'menu_order' => $index ), array( 'ID' => $id ) );

            
/**
             * When a single product has gotten it's ordering updated.
             * $id The product ID
             * $index The new menu order
            */
            
do_action'kkart_after_single_product_ordering'$id$index );
        }

        if ( isset( 
$menu_orders$previd ] ) ) {
            
$menu_orders$sorting_id ] = $menu_orders$previd ] + 1;
        } elseif ( isset( 
$menu_orders$nextid ] ) ) {
            
$menu_orders$sorting_id ] = $menu_orders$nextid ] - 1;
        } else {
            
$menu_orders$sorting_id ] = 0;
        }

        
$wpdb->update$wpdb->posts, array( 'menu_order' => $menu_orders$sorting_id ] ), array( 'ID' => $sorting_id ) );

        
KKART_Post_Data::delete_product_query_transients();

        
do_action'kkart_after_product_ordering'$sorting_id$menu_orders );
        
wp_send_json$menu_orders );
        
// phpcs:enable
    
}

    
/**
     * Handle a refund via the edit order screen.
     *
     * @throws Exception To return errors.
     */
    
public static function refund_line_items() {
        
ob_start();

        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) ) {
            
wp_die( -);
        }

        
$order_id               = isset( $_POST['order_id'] ) ? absint$_POST['order_id'] ) : 0;
        
$refund_amount          = isset( $_POST['refund_amount'] ) ? kkart_format_decimalsanitize_text_fieldwp_unslash$_POST['refund_amount'] ) ), kkart_get_price_decimals() ) : 0;
        
$refunded_amount        = isset( $_POST['refunded_amount'] ) ? kkart_format_decimalsanitize_text_fieldwp_unslash$_POST['refunded_amount'] ) ), kkart_get_price_decimals() ) : 0;
        
$refund_reason          = isset( $_POST['refund_reason'] ) ? sanitize_text_fieldwp_unslash$_POST['refund_reason'] ) ) : '';
        
$line_item_qtys         = isset( $_POST['line_item_qtys'] ) ? json_decodesanitize_text_fieldwp_unslash$_POST['line_item_qtys'] ) ), true ) : array();
        
$line_item_totals       = isset( $_POST['line_item_totals'] ) ? json_decodesanitize_text_fieldwp_unslash$_POST['line_item_totals'] ) ), true ) : array();
        
$line_item_tax_totals   = isset( $_POST['line_item_tax_totals'] ) ? json_decodesanitize_text_fieldwp_unslash$_POST['line_item_tax_totals'] ) ), true ) : array();
        
$api_refund             = isset( $_POST['api_refund'] ) && 'true' === $_POST['api_refund'];
        
$restock_refunded_items = isset( $_POST['restock_refunded_items'] ) && 'true' === $_POST['restock_refunded_items'];
        
$refund                 false;
        
$response               = array();

        try {
            
$order      kkart_get_order$order_id );
            
$max_refund kkart_format_decimal$order->get_total() - $order->get_total_refunded(), kkart_get_price_decimals() );

            if ( ! 
$refund_amount || $max_refund $refund_amount || $refund_amount ) {
                throw new 
Exception__'Invalid refund amount''kkart' ) );
            }

            if ( 
kkart_format_decimal$order->get_total_refunded(), kkart_get_price_decimals() ) !== $refunded_amount ) {
                throw new 
Exception__'Error processing refund. Please try again.''kkart' ) );
            }

            
// Prepare line items which we are refunding.
            
$line_items = array();
            
$item_ids   array_uniquearray_mergearray_keys$line_item_qtys ), array_keys$line_item_totals ) ) );

            foreach ( 
$item_ids as $item_id ) {
                
$line_items$item_id ] = array(
                    
'qty'          => 0,
                    
'refund_total' => 0,
                    
'refund_tax'   => array(),
                );
            }
            foreach ( 
$line_item_qtys as $item_id => $qty ) {
                
$line_items$item_id ]['qty'] = max$qty);
            }
            foreach ( 
$line_item_totals as $item_id => $total ) {
                
$line_items$item_id ]['refund_total'] = kkart_format_decimal$total );
            }
            foreach ( 
$line_item_tax_totals as $item_id => $tax_totals ) {
                
$line_items$item_id ]['refund_tax'] = array_filterarray_map'kkart_format_decimal'$tax_totals ) );
            }

            
// Create the refund object.
            
$refund kkart_create_refund(
                array(
                    
'amount'         => $refund_amount,
                    
'reason'         => $refund_reason,
                    
'order_id'       => $order_id,
                    
'line_items'     => $line_items,
                    
'refund_payment' => $api_refund,
                    
'restock_items'  => $restock_refunded_items,
                )
            );

            if ( 
is_wp_error$refund ) ) {
                throw new 
Exception$refund->get_error_message() );
            }

            if ( 
did_action'kkart_order_fully_refunded' ) ) {
                
$response['status'] = 'fully_refunded';
            }
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'error' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Delete a refund.
     */
    
public static function delete_refund() {
        
check_ajax_referer'order-item''security' );

        if ( ! 
current_user_can'edit_shop_orders' ) || ! isset( $_POST['refund_id'] ) ) {
            
wp_die( -);
        }

        
$refund_ids array_map'absint'is_array$_POST['refund_id'] ) ? wp_unslash$_POST['refund_id'] ) : array( wp_unslash$_POST['refund_id'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        
foreach ( $refund_ids as $refund_id ) {
            if ( 
$refund_id && 'shop_order_refund' === get_post_type$refund_id ) ) {
                
$refund   kkart_get_order$refund_id );
                
$order_id $refund->get_parent_id();
                
$refund->deletetrue );
                
do_action'kkart_refund_deleted'$refund_id$order_id );
            }
        }
        
wp_die();
    }

    
/**
     * Triggered when clicking the rating footer.
     */
    
public static function rated() {
        if ( ! 
current_user_can'manage_kkart' ) ) {
            
wp_die( -);
        }
        
update_option'kkart_admin_footer_text_rated');
        
wp_die();
    }

    
/**
     * Create/Update API key.
     *
     * @throws Exception On invalid or empty description, user, or permissions.
     */
    
public static function update_api_key() {
        
ob_start();

        global 
$wpdb;

        
check_ajax_referer'update-api-key''security' );

        if ( ! 
current_user_can'manage_kkart' ) ) {
            
wp_die( -);
        }

        
$response = array();

        try {
            if ( empty( 
$_POST['description'] ) ) {
                throw new 
Exception__'Description is missing.''kkart' ) );
            }
            if ( empty( 
$_POST['user'] ) ) {
                throw new 
Exception__'User is missing.''kkart' ) );
            }
            if ( empty( 
$_POST['permissions'] ) ) {
                throw new 
Exception__'Permissions is missing.''kkart' ) );
            }

            
$key_id      = isset( $_POST['key_id'] ) ? absint$_POST['key_id'] ) : 0;
            
$description sanitize_text_fieldwp_unslash$_POST['description'] ) );
            
$permissions = ( in_arraywp_unslash$_POST['permissions'] ), array( 'read''write''read_write' ), true ) ) ? sanitize_text_fieldwp_unslash$_POST['permissions'] ) ) : 'read';
            
$user_id     absint$_POST['user'] );

            
// Check if current user can edit other users.
            
if ( $user_id && ! current_user_can'edit_user'$user_id ) ) {
                if ( 
get_current_user_id() !== $user_id ) {
                    throw new 
Exception__'You do not have permission to assign API Keys to the selected user.''kkart' ) );
                }
            }

            if ( 
$key_id ) {
                
$data = array(
                    
'user_id'     => $user_id,
                    
'description' => $description,
                    
'permissions' => $permissions,
                );

                
$wpdb->update(
                    
$wpdb->prefix 'kkart_api_keys',
                    
$data,
                    array( 
'key_id' => $key_id ),
                    array(
                        
'%d',
                        
'%s',
                        
'%s',
                    ),
                    array( 
'%d' )
                );

                
$response                    $data;
                
$response['consumer_key']    = '';
                
$response['consumer_secret'] = '';
                
$response['message']         = __'API Key updated successfully.''kkart' );
            } else {
                
$consumer_key    'ck_' kkart_rand_hash();
                
$consumer_secret 'cs_' kkart_rand_hash();

                
$data = array(
                    
'user_id'         => $user_id,
                    
'description'     => $description,
                    
'permissions'     => $permissions,
                    
'consumer_key'    => kkart_api_hash$consumer_key ),
                    
'consumer_secret' => $consumer_secret,
                    
'truncated_key'   => substr$consumer_key, -),
                );

                
$wpdb->insert(
                    
$wpdb->prefix 'kkart_api_keys',
                    
$data,
                    array(
                        
'%d',
                        
'%s',
                        
'%s',
                        
'%s',
                        
'%s',
                        
'%s',
                    )
                );

                
$key_id                      $wpdb->insert_id;
                
$response                    $data;
                
$response['consumer_key']    = $consumer_key;
                
$response['consumer_secret'] = $consumer_secret;
                
$response['message']         = __'API Key generated successfully. Make sure to copy your new keys now as the secret key will be hidden once you leave this page.''kkart' );
                
$response['revoke_url']      = '<a style="color: #a00; text-decoration: none;" href="' esc_urlwp_nonce_urladd_query_arg( array( 'revoke-key' => $key_id ), admin_url'admin.php?page=kkart-settings&tab=advanced&section=keys' ) ), 'revoke' ) ) . '">' __'Revoke key''kkart' ) . '</a>';
            }
        } catch ( 
Exception $e ) {
            
wp_send_json_error( array( 'message' => $e->getMessage() ) );
        }

        
// wp_send_json_success must be outside the try block not to break phpunit tests.
        
wp_send_json_success$response );
    }

    
/**
     * Load variations via AJAX.
     */
    
public static function load_variations() {
        
ob_start();

        
check_ajax_referer'load-variations''security' );

        if ( ! 
current_user_can'edit_products' ) || empty( $_POST['product_id'] ) ) {
            
wp_die( -);
        }

        
// Set $post global so its available, like within the admin screens.
        
global $post;

        
$loop           0;
        
$product_id     absint$_POST['product_id'] );
        
$post           get_post$product_id ); // phpcs:ignore
        
$product_object kkart_get_product$product_id );
        
$per_page       = ! empty( $_POST['per_page'] ) ? absint$_POST['per_page'] ) : 10;
        
$page           = ! empty( $_POST['page'] ) ? absint$_POST['page'] ) : 1;
        
$variations     kkart_get_products(
            array(
                
'status'  => array( 'private''publish' ),
                
'type'    => 'variation',
                
'parent'  => $product_id,
                
'limit'   => $per_page,
                
'page'    => $page,
                
'orderby' => array(
                    
'menu_order' => 'ASC',
                    
'ID'         => 'DESC',
                ),
                
'return'  => 'objects',
            )
        );

        if ( 
$variations ) {
            
kkart_render_invalid_variation_notice$product_object );

            foreach ( 
$variations as $variation_object ) {
                
$variation_id   $variation_object->get_id();
                
$variation      get_post$variation_id );
                
$variation_data array_mergeget_post_custom$variation_id ), kkart_get_product_variation_attributes$variation_id ) ); // kept for BW compatibility.
                
include __DIR__ '/admin/meta-boxes/views/html-variation-admin.php';
                
$loop++;
            }
        }
        
wp_die();
    }

    
/**
     * Save variations via AJAX.
     */
    
public static function save_variations() {
        
ob_start();

        
check_ajax_referer'save-variations''security' );

        
// Check permissions again and make sure we have what we need.
        
if ( ! current_user_can'edit_products' ) || empty( $_POST ) || empty( $_POST['product_id'] ) ) {
            
wp_die( -);
        }

        
$product_id                           absint$_POST['product_id'] );
        
KKART_Admin_Meta_Boxes::$meta_box_errors = array();
        
KKART_Meta_Box_Product_Data::save_variations$product_idget_post$product_id ) );

        
do_action'kkart_ajax_save_product_variations'$product_id );

        
$errors KKART_Admin_Meta_Boxes::$meta_box_errors;

        if ( 
$errors ) {
            echo 
'<div class="error notice is-dismissible">';

            foreach ( 
$errors as $error ) {
                echo 
'<p>' wp_kses_post$error ) . '</p>';
            }

            echo 
'<button type="button" class="notice-dismiss"><span class="screen-reader-text">' esc_html__'Dismiss this notice.''kkart' ) . '</span></button>';
            echo 
'</div>';

            
delete_option'kkart_meta_box_errors' );
        }

        
wp_die();
    }

    
/**
     * Bulk action - Toggle Enabled.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_toggle_enabled$variations$data ) {
        foreach ( 
$variations as $variation_id ) {
            
$variation kkart_get_product$variation_id );
            
$variation->set_status'private' === $variation->get_status'edit' ) ? 'publish' 'private' );
            
$variation->save();
        }
    }

    
/**
     * Bulk action - Toggle Downloadable Checkbox.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_toggle_downloadable$variations$data ) {
        
self::variation_bulk_toggle$variations'downloadable' );
    }

    
/**
     * Bulk action - Toggle Virtual Checkbox.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_toggle_virtual$variations$data ) {
        
self::variation_bulk_toggle$variations'virtual' );
    }

    
/**
     * Bulk action - Toggle Manage Stock Checkbox.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_toggle_manage_stock$variations$data ) {
        
self::variation_bulk_toggle$variations'manage_stock' );
    }

    
/**
     * Bulk action - Set Regular Prices.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_regular_price$variations$data ) {
        
self::variation_bulk_set$variations'regular_price'$data['value'] );
    }

    
/**
     * Bulk action - Set Sale Prices.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_sale_price$variations$data ) {
        
self::variation_bulk_set$variations'sale_price'$data['value'] );
    }

    
/**
     * Bulk action - Set Stock Status as In Stock.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_stock_status_instock$variations$data ) {
        
self::variation_bulk_set$variations'stock_status''instock' );
    }

    
/**
     * Bulk action - Set Stock Status as Out of Stock.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_stock_status_outofstock$variations$data ) {
        
self::variation_bulk_set$variations'stock_status''outofstock' );
    }

    
/**
     * Bulk action - Set Stock Status as On Backorder.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_stock_status_onbackorder$variations$data ) {
        
self::variation_bulk_set$variations'stock_status''onbackorder' );
    }

    
/**
     * Bulk action - Set Stock.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_stock$variations$data ) {
        if ( ! isset( 
$data['value'] ) ) {
            return;
        }

        
$quantity kkart_stock_amountkkart_clean$data['value'] ) );

        foreach ( 
$variations as $variation_id ) {
            
$variation kkart_get_product$variation_id );
            if ( 
$variation->managing_stock() ) {
                
$variation->set_stock_quantity$quantity );
            } else {
                
$variation->set_stock_quantitynull );
            }
            
$variation->save();
        }
    }

    
/**
     * Bulk action - Set Weight.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_weight$variations$data ) {
        
self::variation_bulk_set$variations'weight'$data['value'] );
    }

    
/**
     * Bulk action - Set Length.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_length$variations$data ) {
        
self::variation_bulk_set$variations'length'$data['value'] );
    }

    
/**
     * Bulk action - Set Width.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_width$variations$data ) {
        
self::variation_bulk_set$variations'width'$data['value'] );
    }

    
/**
     * Bulk action - Set Height.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_height$variations$data ) {
        
self::variation_bulk_set$variations'height'$data['value'] );
    }

    
/**
     * Bulk action - Set Download Limit.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_download_limit$variations$data ) {
        
self::variation_bulk_set$variations'download_limit'$data['value'] );
    }

    
/**
     * Bulk action - Set Download Expiry.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_download_expiry$variations$data ) {
        
self::variation_bulk_set$variations'download_expiry'$data['value'] );
    }

    
/**
     * Bulk action - Delete all.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_delete_all$variations$data ) {
        if ( isset( 
$data['allowed'] ) && 'true' === $data['allowed'] ) {
            foreach ( 
$variations as $variation_id ) {
                
$variation kkart_get_product$variation_id );
                
$variation->deletetrue );
            }
        }
    }

    
/**
     * Bulk action - Sale Schedule.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_sale_schedule$variations$data ) {
        if ( ! isset( 
$data['date_from'] ) && ! isset( $data['date_to'] ) ) {
            return;
        }

        foreach ( 
$variations as $variation_id ) {
            
$variation kkart_get_product$variation_id );

            if ( 
'false' !== $data['date_from'] ) {
                
$variation->set_date_on_sale_fromkkart_clean$data['date_from'] ) );
            }

            if ( 
'false' !== $data['date_to'] ) {
                
$variation->set_date_on_sale_tokkart_clean$data['date_to'] ) );
            }

            
$variation->save();
        }
    }

    
/**
     * Bulk action - Increase Regular Prices.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_regular_price_increase$variations$data ) {
        
self::variation_bulk_adjust_price$variations'regular_price''+'kkart_clean$data['value'] ) );
    }

    
/**
     * Bulk action - Decrease Regular Prices.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_regular_price_decrease$variations$data ) {
        
self::variation_bulk_adjust_price$variations'regular_price''-'kkart_clean$data['value'] ) );
    }

    
/**
     * Bulk action - Increase Sale Prices.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_sale_price_increase$variations$data ) {
        
self::variation_bulk_adjust_price$variations'sale_price''+'kkart_clean$data['value'] ) );
    }

    
/**
     * Bulk action - Decrease Sale Prices.
     *
     * @param array $variations List of variations.
     * @param array $data Data to set.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_action_variable_sale_price_decrease$variations$data ) {
        
self::variation_bulk_adjust_price$variations'sale_price''-'kkart_clean$data['value'] ) );
    }

    
/**
     * Bulk action - Set Price.
     *
     * @param array  $variations List of variations.
     * @param string $field price being adjusted _regular_price or _sale_price.
     * @param string $operator + or -.
     * @param string $value Price or Percent.
     *
     * @used-by bulk_edit_variations
     */
    
private static function variation_bulk_adjust_price$variations$field$operator$value ) {
        foreach ( 
$variations as $variation_id ) {
            
$variation   kkart_get_product$variation_id );
            
$field_value $variation->{"get_$field"}( 'edit' );

            if ( 
'%' === substr$value, -) ) {
                
$percent      kkart_format_decimalsubstr$value0, -) );
                
$field_value += NumberUtil::round( ( $field_value 100 ) * $percentkkart_get_price_decimals() ) * "{$operator}1";
            } else {
                
$field_value += $value "{$operator}1";
            }

            
$variation->{"set_$field"}( $field_value );
            
$variation->save();
        }
    }

    
/**
     * Bulk set convenience function.
     *
     * @param array  $variations List of variations.
     * @param string $field Field to set.
     * @param string $value to set.
     */
    
private static function variation_bulk_set$variations$field$value ) {
        foreach ( 
$variations as $variation_id ) {
            
$variation kkart_get_product$variation_id );
            
$variation->{ "set_$field}( kkart_clean$value ) );
            
$variation->save();
        }
    }

    
/**
     * Bulk toggle convenience function.
     *
     * @param array  $variations List of variations.
     * @param string $field Field to toggle.
     */
    
private static function variation_bulk_toggle$variations$field ) {
        foreach ( 
$variations as $variation_id ) {
            
$variation  kkart_get_product$variation_id );
            
$prev_value $variation->{ "get_$field}( 'edit' );
            
$variation->{ "set_$field}( ! $prev_value );
            
$variation->save();
        }
    }

    
/**
     * Bulk edit variations via AJAX.
     *
     * @uses KKART_AJAX::variation_bulk_set()
     * @uses KKART_AJAX::variation_bulk_adjust_price()
     * @uses KKART_AJAX::variation_bulk_action_variable_sale_price_decrease()
     * @uses KKART_AJAX::variation_bulk_action_variable_sale_price_increase()
     * @uses KKART_AJAX::variation_bulk_action_variable_regular_price_decrease()
     * @uses KKART_AJAX::variation_bulk_action_variable_regular_price_increase()
     * @uses KKART_AJAX::variation_bulk_action_variable_sale_schedule()
     * @uses KKART_AJAX::variation_bulk_action_delete_all()
     * @uses KKART_AJAX::variation_bulk_action_variable_download_expiry()
     * @uses KKART_AJAX::variation_bulk_action_variable_download_limit()
     * @uses KKART_AJAX::variation_bulk_action_variable_height()
     * @uses KKART_AJAX::variation_bulk_action_variable_width()
     * @uses KKART_AJAX::variation_bulk_action_variable_length()
     * @uses KKART_AJAX::variation_bulk_action_variable_weight()
     * @uses KKART_AJAX::variation_bulk_action_variable_stock()
     * @uses KKART_AJAX::variation_bulk_action_variable_sale_price()
     * @uses KKART_AJAX::variation_bulk_action_variable_regular_price()
     * @uses KKART_AJAX::variation_bulk_action_toggle_manage_stock()
     * @uses KKART_AJAX::variation_bulk_action_toggle_virtual()
     * @uses KKART_AJAX::variation_bulk_action_toggle_downloadable()
     * @uses KKART_AJAX::variation_bulk_action_toggle_enabled
     */
    
public static function bulk_edit_variations() {
        
ob_start();

        
check_ajax_referer'kkart_editor_nonce''kkart_nonce' );
        
//check_ajax_referer( 'bulk_edit_variations', 'security' );


        // Check permissions again and make sure we have what we need.
        
if ( ! current_user_can'edit_products' ) || empty( $_POST['product_id'] ) || empty( $_POST['bulk_action'] ) ) {
            
wp_die( -);
        }
        
        
$product_id  absint$_POST['product_id'] );
        
$bulk_action kkart_cleanwp_unslash$_POST['bulk_action'] ) );
        
$data        = ! empty( $_POST['data'] ) ? kkart_cleanwp_unslash$_POST['data'] ) ) : array();
        
$variations  = array();

        if ( 
apply_filters'kkart_bulk_edit_variations_need_children'true ) ) {
            
$variations get_posts(
                array(
                    
'post_parent'    => $product_id,
                    
'posts_per_page' => -1,
                    
'post_type'      => 'product_variation',
                    
'fields'         => 'ids',
                    
'post_status'    => array( 'publish''private' ),
                )
            );
        }

        if ( 
method_exists__CLASS__"variation_bulk_action_$bulk_action) ) {
            
call_user_func( array( __CLASS__"variation_bulk_action_$bulk_action), $variations$data );
        } else {
            
do_action'kkart_bulk_edit_variations_default'$bulk_action$data$product_id$variations );
        }

        
do_action'kkart_bulk_edit_variations'$bulk_action$data$product_id$variations );
        
KKART_Product_Variable::sync$product_id );
        
kkart_delete_product_transients$product_id );
        
wp_die();
    }
    public static function 
bulk_edit_variation() {
    
        
check_ajax_referer'kkart_editor_nonce''kkart-nounce' );

        
// Check permissions again and make sure we have what we need.
        // if ( empty( $_POST['product_id'] ) || empty( $_POST['bulk_action'] ) ) {
            // wp_die( -1 );
        // }

        
$product_id  absint$_POST['product_id'] );
        
$bulk_action kkart_cleanwp_unslash$_POST['bulk_action'] ) );
        
$data        = ! empty( $_POST['data'] ) ? kkart_cleanwp_unslash$_POST['data'] ) ) : array();
        
$variations  = array();

        if ( 
apply_filters'kkart_bulk_edit_variations_need_children'true ) ) {
            
$variations get_posts(
                array(
                    
'post_parent'    => $product_id,
                    
'posts_per_page' => -1,
                    
'post_type'      => 'product_variation',
                    
'fields'         => 'ids',
                    
'post_status'    => array( 'publish''private' ),
                )
            );
        }

        if ( 
method_exists__CLASS__"variation_bulk_action_$bulk_action) ) {
            
call_user_func( array( __CLASS__"variation_bulk_action_$bulk_action), $variations$data );
        } else {
            
do_action'kkart_bulk_edit_variations_default'$bulk_action$data$product_id$variations );
        }

        
do_action'kkart_bulk_edit_variations'$bulk_action$data$product_id$variations );
        
KKART_Product_Variable::sync$product_id );
        
kkart_delete_product_transients$product_id );
        
wp_die();
    }


    
/**
     * Handle submissions from assets/js/settings-views-html-settings-tax.js Backbone model.
     */
    
public static function tax_rates_save_changes() {
        
// phpcs:disable WordPress.Security.NonceVerification.Missing
        
if ( ! isset( $_POST['kkart_tax_nonce'], $_POST['changes'] ) ) {
            
wp_send_json_error'missing_fields' );
            
wp_die();
        }

        
$current_class = ! empty( $_POST['current_class'] ) ? wp_unslash$_POST['current_class'] ) : ''// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        
if ( ! wp_verify_noncewp_unslash$_POST['kkart_tax_nonce'] ), 'kkart_tax_nonce-class:' $current_class ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
wp_send_json_error'bad_nonce' );
            
wp_die();
        }

        
$current_class KKART_Tax::format_tax_rate_class$current_class );

        
// Check User Caps.
        
if ( ! current_user_can'manage_kkart' ) ) {
            
wp_send_json_error'missing_capabilities' );
            
wp_die();
        }

        
$changes wp_unslash$_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        
foreach ( $changes as $tax_rate_id => $data ) {
            if ( isset( 
$data['deleted'] ) ) {
                if ( isset( 
$data['newRow'] ) ) {
                    
// So the user added and deleted a new row.
                    // That's fine, it's not in the database anyways. NEXT!
                    
continue;
                }
                
KKART_Tax::_delete_tax_rate$tax_rate_id );
            }

            
$tax_rate array_intersect_key(
                
$data,
                array(
                    
'tax_rate_country'  => 1,
                    
'tax_rate_state'    => 1,
                    
'tax_rate'          => 1,
                    
'tax_rate_name'     => 1,
                    
'tax_rate_priority' => 1,
                    
'tax_rate_compound' => 1,
                    
'tax_rate_shipping' => 1,
                    
'tax_rate_order'    => 1,
                )
            );

            if ( isset( 
$tax_rate['tax_rate'] ) ) {
                
$tax_rate['tax_rate'] = kkart_format_decimal$tax_rate['tax_rate'] );
            }

            if ( isset( 
$data['newRow'] ) ) {
                
$tax_rate['tax_rate_class'] = $current_class;
                
$tax_rate_id                KKART_Tax::_insert_tax_rate$tax_rate );
            } elseif ( ! empty( 
$tax_rate ) ) {
                
KKART_Tax::_update_tax_rate$tax_rate_id$tax_rate );
            }

            if ( isset( 
$data['postcode'] ) ) {
                
$postcode array_map'kkart_clean'$data['postcode'] );
                
$postcode array_map'kkart_normalize_postcode'$postcode );
                
KKART_Tax::_update_tax_rate_postcodes$tax_rate_id$postcode );
            }
            if ( isset( 
$data['city'] ) ) {
                
KKART_Tax::_update_tax_rate_cities$tax_rate_idarray_map'kkart_clean'array_map'wp_unslash'$data['city'] ) ) );
            }
        }

        
KKART_Cache_Helper::invalidate_cache_group'taxes' );
        
KKART_Cache_Helper::get_transient_version'shipping'true );

        
wp_send_json_success(
            array(
                
'rates' => KKART_Tax::get_rates_for_tax_class$current_class ),
            )
        );
        
// phpcs:enable
    
}

    
/**
     * Handle submissions from assets/js/kkart-shipping-zones.js Backbone model.
     */
    
public static function shipping_zones_save_changes() {
        if ( ! isset( 
$_POST['kkart_shipping_zones_nonce'], $_POST['changes'] ) ) {
            
wp_send_json_error'missing_fields' );
            
wp_die();
        }

        if ( ! 
wp_verify_noncewp_unslash$_POST['kkart_shipping_zones_nonce'] ), 'kkart_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
wp_send_json_error'bad_nonce' );
            
wp_die();
        }

        
// Check User Caps.
        
if ( ! current_user_can'manage_kkart' ) ) {
            
wp_send_json_error'missing_capabilities' );
            
wp_die();
        }

        
$changes wp_unslash$_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        
foreach ( $changes as $zone_id => $data ) {
            if ( isset( 
$data['deleted'] ) ) {
                if ( isset( 
$data['newRow'] ) ) {
                    
// So the user added and deleted a new row.
                    // That's fine, it's not in the database anyways. NEXT!
                    
continue;
                }
                
KKART_Shipping_Zones::delete_zone$zone_id );
                continue;
            }

            
$zone_data array_intersect_key(
                
$data,
                array(
                    
'zone_id'    => 1,
                    
'zone_order' => 1,
                )
            );

            if ( isset( 
$zone_data['zone_id'] ) ) {
                
$zone = new KKART_Shipping_Zone$zone_data['zone_id'] );

                if ( isset( 
$zone_data['zone_order'] ) ) {
                    
$zone->set_zone_order$zone_data['zone_order'] );
                }

                
$zone->save();
            }
        }

        
wp_send_json_success(
            array(
                
'zones' => KKART_Shipping_Zones::get_zones'json' ),
            )
        );
    }

    
/**
     * Handle submissions from assets/js/kkart-shipping-zone-methods.js Backbone model.
     */
    
public static function shipping_zone_add_method() {
        if ( ! isset( 
$_POST['kkart_shipping_zones_nonce'], $_POST['zone_id'], $_POST['method_id'] ) ) {
            
wp_send_json_error'missing_fields' );
            
wp_die();
        }

        if ( ! 
wp_verify_noncewp_unslash$_POST['kkart_shipping_zones_nonce'] ), 'kkart_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
wp_send_json_error'bad_nonce' );
            
wp_die();
        }

        
// Check User Caps.
        
if ( ! current_user_can'manage_kkart' ) ) {
            
wp_send_json_error'missing_capabilities' );
            
wp_die();
        }

        
$zone_id     kkart_cleanwp_unslash$_POST['zone_id'] ) );
        
$zone        = new KKART_Shipping_Zone$zone_id );
        
$instance_id $zone->add_shipping_methodkkart_cleanwp_unslash$_POST['method_id'] ) ) );

        
wp_send_json_success(
            array(
                
'instance_id' => $instance_id,
                
'zone_id'     => $zone->get_id(),
                
'zone_name'   => $zone->get_zone_name(),
                
'methods'     => $zone->get_shipping_methodsfalse'json' ),
            )
        );
    }

    
/**
     * Handle submissions from assets/js/kkart-shipping-zone-methods.js Backbone model.
     */
    
public static function shipping_zone_methods_save_changes() {
        if ( ! isset( 
$_POST['kkart_shipping_zones_nonce'], $_POST['zone_id'], $_POST['changes'] ) ) {
            
wp_send_json_error'missing_fields' );
            
wp_die();
        }

        if ( ! 
wp_verify_noncewp_unslash$_POST['kkart_shipping_zones_nonce'] ), 'kkart_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
wp_send_json_error'bad_nonce' );
            
wp_die();
        }

        if ( ! 
current_user_can'manage_kkart' ) ) {
            
wp_send_json_error'missing_capabilities' );
            
wp_die();
        }

        global 
$wpdb;

        
$zone_id kkart_cleanwp_unslash$_POST['zone_id'] ) );
        
$zone    = new KKART_Shipping_Zone$zone_id );
        
$changes wp_unslash$_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        
if ( isset( $changes['zone_name'] ) ) {
            
$zone->set_zone_namekkart_clean$changes['zone_name'] ) );
        }

        if ( isset( 
$changes['zone_locations'] ) ) {
            
$zone->clear_locations( array( 'state''country''continent' ) );
            
$locations array_filterarray_map'kkart_clean', (array) $changes['zone_locations'] ) );
            foreach ( 
$locations as $location ) {
                
// Each posted location will be in the format type:code.
                
$location_parts explode':'$location );
                switch ( 
$location_parts[0] ) {
                    case 
'state':
                        
$zone->add_location$location_parts[1] . ':' $location_parts[2], 'state' );
                        break;
                    case 
'country':
                        
$zone->add_location$location_parts[1], 'country' );
                        break;
                    case 
'continent':
                        
$zone->add_location$location_parts[1], 'continent' );
                        break;
                }
            }
        }

        if ( isset( 
$changes['zone_postcodes'] ) ) {
            
$zone->clear_locations'postcode' );
            
$postcodes array_filterarray_map'strtoupper'array_map'kkart_clean'explode"\n"$changes['zone_postcodes'] ) ) ) );
            foreach ( 
$postcodes as $postcode ) {
                
$zone->add_location$postcode'postcode' );
            }
        }

        if ( isset( 
$changes['methods'] ) ) {
            foreach ( 
$changes['methods'] as $instance_id => $data ) {
                
$method_id $wpdb->get_var$wpdb->prepare"SELECT method_id FROM {$wpdb->prefix}kkart_shipping_zone_methods WHERE instance_id = %d"$instance_id ) );

                if ( isset( 
$data['deleted'] ) ) {
                    
$shipping_method KKART_Shipping_Zones::get_shipping_method$instance_id );
                    
$option_key      $shipping_method->get_instance_option_key();
                    if ( 
$wpdb->delete"{$wpdb->prefix}kkart_shipping_zone_methods", array( 'instance_id' => $instance_id ) ) ) {
                        
delete_option$option_key );
                        
do_action'kkart_shipping_zone_method_deleted'$instance_id$method_id$zone_id );
                    }
                    continue;
                }

                
$method_data array_intersect_key(
                    
$data,
                    array(
                        
'method_order' => 1,
                        
'enabled'      => 1,
                    )
                );

                if ( isset( 
$method_data['method_order'] ) ) {
                    
$wpdb->update"{$wpdb->prefix}kkart_shipping_zone_methods", array( 'method_order' => absint$method_data['method_order'] ) ), array( 'instance_id' => absint$instance_id ) ) );
                }

                if ( isset( 
$method_data['enabled'] ) ) {
                    
$is_enabled absint'yes' === $method_data['enabled'] );
                    if ( 
$wpdb->update"{$wpdb->prefix}kkart_shipping_zone_methods", array( 'is_enabled' => $is_enabled ), array( 'instance_id' => absint$instance_id ) ) ) ) {
                        
do_action'kkart_shipping_zone_method_status_toggled'$instance_id$method_id$zone_id$is_enabled );
                    }
                }
            }
        }

        
$zone->save();

        
wp_send_json_success(
            array(
                
'zone_id'   => $zone->get_id(),
                
'zone_name' => $zone->get_zone_name(),
                
'methods'   => $zone->get_shipping_methodsfalse'json' ),
            )
        );
    }

    
/**
     * Save method settings
     */
    
public static function shipping_zone_methods_save_settings() {
        if ( ! isset( 
$_POST['kkart_shipping_zones_nonce'], $_POST['instance_id'], $_POST['data'] ) ) {
            
wp_send_json_error'missing_fields' );
            
wp_die();
        }

        if ( ! 
wp_verify_noncewp_unslash$_POST['kkart_shipping_zones_nonce'] ), 'kkart_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
wp_send_json_error'bad_nonce' );
            
wp_die();
        }

        if ( ! 
current_user_can'manage_kkart' ) ) {
            
wp_send_json_error'missing_capabilities' );
            
wp_die();
        }

        
$instance_id     absint$_POST['instance_id'] );
        
$zone            KKART_Shipping_Zones::get_zone_by'instance_id'$instance_id );
        
$shipping_method KKART_Shipping_Zones::get_shipping_method$instance_id );
        
$shipping_method->set_post_datawp_unslash$_POST['data'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        
$shipping_method->process_admin_options();

        
KKART_Cache_Helper::get_transient_version'shipping'true );

        
wp_send_json_success(
            array(
                
'zone_id'   => $zone->get_id(),
                
'zone_name' => $zone->get_zone_name(),
                
'methods'   => $zone->get_shipping_methodsfalse'json' ),
                
'errors'    => $shipping_method->get_errors(),
            )
        );
    }

    
/**
     * Handle submissions from assets/js/kkart-shipping-classes.js Backbone model.
     */
    
public static function shipping_classes_save_changes() {
        if ( ! isset( 
$_POST['kkart_shipping_classes_nonce'], $_POST['changes'] ) ) {
            
wp_send_json_error'missing_fields' );
            
wp_die();
        }

        if ( ! 
wp_verify_noncewp_unslash$_POST['kkart_shipping_classes_nonce'] ), 'kkart_shipping_classes_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            
wp_send_json_error'bad_nonce' );
            
wp_die();
        }

        if ( ! 
current_user_can'manage_kkart' ) ) {
            
wp_send_json_error'missing_capabilities' );
            
wp_die();
        }

        
$changes wp_unslash$_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        
foreach ( $changes as $term_id => $data ) {
            
$term_id absint$term_id );

            if ( isset( 
$data['deleted'] ) ) {
                if ( isset( 
$data['newRow'] ) ) {
                    
// So the user added and deleted a new row.
                    // That's fine, it's not in the database anyways. NEXT!
                    
continue;
                }
                
wp_delete_term$term_id'product_shipping_class' );
                continue;
            }

            
$update_args = array();

            if ( isset( 
$data['name'] ) ) {
                
$update_args['name'] = kkart_clean$data['name'] );
            }

            if ( isset( 
$data['slug'] ) ) {
                
$update_args['slug'] = kkart_clean$data['slug'] );
            }

            if ( isset( 
$data['description'] ) ) {
                
$update_args['description'] = kkart_clean$data['description'] );
            }

            if ( isset( 
$data['newRow'] ) ) {
                
$update_args array_filter$update_args );
                if ( empty( 
$update_args['name'] ) ) {
                    continue;
                }
                
$inserted_term wp_insert_term$update_args['name'], 'product_shipping_class'$update_args );
                
$term_id       is_wp_error$inserted_term ) ? $inserted_term['term_id'];
            } else {
                
wp_update_term$term_id'product_shipping_class'$update_args );
            }

            
do_action'kkart_shipping_classes_save_class'$term_id$data );
        }

        
$kkart_shipping KKART_Shipping::instance();

        
wp_send_json_success(
            array(
                
'shipping_classes' => $kkart_shipping->get_shipping_classes(),
            )
        );
    }

    
/**
     * Toggle payment gateway on or off via AJAX.
     *
     * @since 3.4.0
     */
    
public static function toggle_gateway_enabled() {
        if ( 
current_user_can'manage_kkart' ) && check_ajax_referer'kkart-toggle-payment-gateway-enabled''security' ) && isset( $_POST['gateway_id'] ) ) {
            
// Load gateways.
            
$payment_gateways KKART()->payment_gateways->payment_gateways();

            
// Get posted gateway.
            
$gateway_id kkart_cleanwp_unslash$_POST['gateway_id'] ) );

            foreach ( 
$payment_gateways as $gateway ) {
                if ( ! 
in_array$gateway_id, array( $gateway->idsanitize_titleget_class$gateway ) ) ), true ) ) {
                    continue;
                }
                
$enabled $gateway->get_option'enabled''no' );

                if ( ! 
kkart_string_to_bool$enabled ) ) {
                    if ( 
$gateway->needs_setup() ) {
                        
wp_send_json_error'needs_setup' );
                        
wp_die();
                    } else {
                        
$gateway->update_option'enabled''yes' );
                    }
                } else {
                    
// Disable the gateway.
                    
$gateway->update_option'enabled''no' );
                }

                
wp_send_json_success( ! kkart_string_to_bool$enabled ) );
                
wp_die();
            }
        }

        
wp_send_json_error'invalid_gateway_id' );
        
wp_die();
    }
    
    
//Products Categories Handler
    
function product_archives(){
        
        
// TODO: change
        // Some AJAX security
        
check_ajax_referer('pagelayer_ajax''pagelayer_nonce');
        
        
// Load Shortcodes
        
pagelayer_load_shortcodes();
        
        
// Call the function
        
kkart_sc_product_archives($_POST);

        echo 
$_POST['atts']['product_archives'];
        
        
wp_die();
    }
    
    public static function 
account_order_details(){
        
        
// Some AJAX security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        if ( ! isset( 
$_POST['order_id'] ) ) {
            
wp_die( -);
        }

        
$order_id =  $_POST['order_id'] ;
        
        
$result kkart_account_view_order($order_id);
        
        echo 
$result;
        
        
wp_die();
    }
    
    
//Customer Order List
    
function get_order_lists(){

        
// TODO: change
        // Some AJAX security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$sel_col $_POST['sel_col'];
        
        
//TODO: for valid user and logged in user
        
$current_user_id get_current_user_id();
        
        
$order_ids kkart_get_orders(
            array(
                
'limit'    => -1,
                
'customer' => $current_user_id,
                
'return'   => 'ids',
            )
        );
        
        if(!empty(
$order_ids)){
            
            foreach(
$order_ids as $ik => $iv){
                
                
$order kkart_get_orderabsint$iv ) );
                
$item_count $order->get_item_count();
                
                foreach(
$sel_col as $sk => $sv){
                    
                    if(
'order-number' == $sv){
                        
$order_data[$iv][$sk] = $order->get_order_number();
                    }
                    if(
'order-date' == $sv){
                        
$order_data[$iv][$sk] = kkart_format_datetime($order->get_date_created());
                    }
                    if(
'order-status' == $sv){
                        
$order_data[$iv][$sk] = $order->get_status();
                    }
                    if(
'order-total' == $sv){
                        
$order_data[$iv][$sk] = sprintf_n'%1$s for %2$s item''%1$s for %2$s items'$item_count'kkart' ), $order->get_formatted_order_total(), $item_count );
                    }
                    if(
'order-actions' == $sv){
                        
$order_data[$iv][$sk] = kkart_get_account_orders_actions($order);
                    }
                }
            }
        }
        
        
wp_send_json_success($order_data);
        
        
wp_die();
    }
    
    
//Customer Order Downloads
    
function get_order_downloads(){

        
// TODO: change
        // Some AJAX security
        
check_ajax_referer'kkart_ajax''kkart_nonce' );
        
        
$sel_col $_POST['sel_col'];
        
        
//TODO: for valid user and logged in user
        
$current_user_id get_current_user_id();
        
        
$downloads KKART()->customer->get_downloadable_products();
        
        if(!empty(
$downloads)){
            
            foreach(
$downloads as $dk => $dv){
                
                foreach(
$sel_col as $sk => $sv){
                    
                    if(
'download-product' == $sv){
                        if ( 
$dv['product_url'] ) {
                            
$download_data[$dk][$sk] = '<a href="' esc_url$dv['product_url'] ) . '">' esc_html$dv['product_name'] ) . '</a>';
                        } else {
                            
$download_data[$dk][$sk] = esc_html$dv['product_name'] );
                        }
                    }
                    if(
'download-file' == $sv){
                        
$download_data[$dk][$sk] = '<a href="' esc_url$dv['download_url'] ) . '" class="kkart-MyAccount-downloads-file button alt">' esc_html$dv['download_name'] ) . '</a>';
                    }
                    if(
'download-remaining' == $sv){
                        
$download_data[$dk][$sk] = is_numeric$dv['downloads_remaining'] ) ? esc_html$dv['downloads_remaining'] ) : esc_html__'&infin;''kkart' );
                    }
                    if(
'download-expires' == $sv){
                        if ( ! empty( 
$dv['access_expires'] ) ) {
                            
$download_data[$dk][$sk] = '<time datetime="' esc_attrdate'Y-m-d'strtotime$dv['access_expires'] ) ) ) . '" title="' esc_attrstrtotime$dv['access_expires'] ) ) . '">' esc_htmldate_i18nget_option'date_format' ), strtotime$dv['access_expires'] ) ) ) . '</time>';
                        } else {
                            
$download_data[$dk][$sk] = esc_html__'Never''kkart' );
                        }
                    }
                }
            }
        }
        
        
wp_send_json_success($download_data);
    }
    
    public static function 
get_cart_items(){
        
        
$items KKART()->cart->get_cart();
        
        if(!empty(
$items)){
            
wp_send_json_success($items);
        }else{
            
wp_send_json_error('error!!');
        }            
    }
    
    public static function 
set_cart_quantity(){
        
        
$cart_item_key $_POST['cart_item_key'];
        
$quantity $_POST['quantity'];

        
$return KKART()->cart->set_quantity($cart_item_key$quantity);
        
        
wp_send_json_success($return);
        
wp_die();
    }
    
    public static function 
get_cart_data(){
        
        
$quantity KKART()->cart->get_cart_contents_count();
        
        
// Get min cart
        
ob_start();
        
kkart_mini_cart();
        
$mini_cart ob_get_clean();
        
        
// Cart sub total
        
ob_start();
        
kkart_cart_totals_subtotal_html();
        
$cart_total ob_get_clean();
        
        
$response = array(
           
'fragments' =>  $mini_cart,
           
'quantity' => $quantity,
           
'price' => $cart_total
        
);
        
        
wp_send_json_success($response);
        
wp_die();
    }
}

KKART_AJAX::init();

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by KaizenLouie | C99Shell Github | Generation time: 0.1979 ]--