Cart page

<?php
/*
Plugin Name: HloMart Cart
Description: HloMart Cart
Version: 1.0
Author: Bishal Thapa
*/


































































// hide the star rating for no rating 
add_action('wp_head', function() {
    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => -1,
        'meta_query'     => array(
            array(
                'key'     => '_wc_review_count',
                'value'   => 0,
                'compare' => '='
            )
        )
    );

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        echo "<style>";
        while ($query->have_posts()) {
            $query->the_post();
            $product_id = get_the_ID();
            echo ".post-{$product_id} .star-rating { display: none !important; }";
        }
        echo "</style>";
    }

    wp_reset_postdata();
});



























// If stock is limited and cart quantity more

add_action('woocommerce_before_checkout_process', 'adjust_cart_quantity_before_checkout');

function adjust_cart_quantity_before_checkout() {
    // Get the cart object
    $cart = WC()->cart->get_cart();
    
    $updated = false; // Track if any changes were made

    foreach ($cart as $cart_item_key => $cart_item) {
        $product_id = $cart_item['product_id'];
        $product = wc_get_product($product_id);

        if ($product && $product->is_in_stock()) {
            $stock_quantity = $product->get_stock_quantity(); // Get available stock
            
            // If stock is limited and cart quantity exceeds stock
            if (!is_null($stock_quantity) && $cart_item['quantity'] > $stock_quantity) {
                WC()->cart->set_quantity($cart_item_key, $stock_quantity, true); // Set max available
                $updated = true; // Mark changes
            }
        }
    }

    // Redirect to checkout after fixing cart quantity
    if ($updated) {
        wp_safe_redirect(wc_get_checkout_url());
        exit;
    }
}













































































// Add "Buy Now" button to the product page
add_action('woocommerce_after_add_to_cart_button', 'add_buy_now_button');

function add_buy_now_button() {
    global $product;
    
    // Check if product is in stock
    if ( !$product->is_in_stock() ) {
        echo '<button type="button" disabled class="button alt buy-now-button out-of-stock">Out of Stock</button>';
        return;
    }
    
    // Add nonce for security
    wp_nonce_field('buy_now_action', 'buy_now_nonce');
    
    // Output the button markup
    if ( $product->is_type('variable') ) {
        echo '<button type="submit" name="buy_now" class="button alt buy-now-button">Buy Now</button>';
    } else {
        echo '<button type="submit" name="buy_now" value="1" class="button alt buy-now-button">Buy Now</button>';
    }
}

// Handle "Buy Now" action and apply logic
add_action('template_redirect', 'handle_buy_now_redirect');

function handle_buy_now_redirect() {
    if ( isset($_POST['buy_now']) && isset($_POST['add-to-cart']) ) {
        // Verify nonce
        if ( !isset($_POST['buy_now_nonce']) || !wp_verify_nonce($_POST['buy_now_nonce'], 'buy_now_action') ) {
            return;
        }

        $product_id = intval($_POST['add-to-cart']);
        $quantity   = !empty($_POST['quantity']) ? intval($_POST['quantity']) : 1;
        $cart       = WC()->cart;

        // Check if it's a variable product
        if ( isset($_POST['variation_id']) && !empty($_POST['variation_id']) ) {
            $variation_id = intval($_POST['variation_id']);
            $variations   = array();

            // Collect selected variation attributes
            foreach ( $_POST as $key => $value ) {
                if ( strpos($key, 'attribute_') !== false ) {
                    $variations[$key] = wc_clean($value);
                }
            }

            // Remove the exact same variation of the product from the cart
            foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
                if ( $cart_item['product_id'] == $product_id && $cart_item['variation_id'] == $variation_id ) {
                    $cart->remove_cart_item($cart_item_key);
                }
            }

            // Add the newly selected variation to the cart
            $cart->add_to_cart($product_id, $quantity, $variation_id, $variations);
        } else {
            // For simple products, remove only if the exact same product exists
            foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
                if ( $cart_item['product_id'] == $product_id ) {
                    $cart->remove_cart_item($cart_item_key);
                }
            }
            $cart->add_to_cart($product_id, $quantity);
        }

        // Redirect to cart page
        wp_safe_redirect( wc_get_cart_url() );
        exit;
    }
}

// For variable products, disable the Buy Now button if the selected variation is out of stock.
add_action('wp_footer', 'disable_buy_now_button_for_out_of_stock_variations');

function disable_buy_now_button_for_out_of_stock_variations() {
    if ( is_product() ) { ?>
        <script defer>
        jQuery(document).ready(function($) {
            var buyNowButton = $('.buy-now-button');

            if ($('form.variations_form').length) {
                buyNowButton.prop('disabled', true);
            }

            $('form.variations_form').on('found_variation', function(event, variation) {
                buyNowButton.prop('disabled', !variation.is_in_stock);
            });

            $('form.variations_form').on('reset_data', function() {
                buyNowButton.prop('disabled', true);
            });
        });
        </script>
    <?php }
}












































/**
 * Custom Cart Page, Removal, and Restoration
 *
 * Place this code in your theme's functions.php file or in a custom plugin.
 */

/**
 * Enqueue inline CSS and JavaScript only on pages with the [custom_cart_page] shortcode.
 */
function custom_cart_page_enqueue_scripts() {
    global $post;

    if ( is_singular() && isset( $post->post_content ) && has_shortcode( $post->post_content, 'custom_cart_page' ) ) {

        // Enqueue Custom CSS
        wp_register_style( 'custom-cart-style', false );
        wp_enqueue_style( 'custom-cart-style' );
        $custom_css = "
            /* Minified Custom Cart Page Styles */
            .quantity-selector button{font-size:9px;padding:5px 10px;background-color:transparent;border:0px solid #cccc;}
            .quantity-selector .quantity-input{width:70px;text-align:center;font-size:11px;padding:5px;border:0px solid #ccc;}
            .remove-item{position:absolute;top:10%;left:5px;font-size:14px;color:red;background-color:#E8F2FF;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:10;}
            .custom_cart_item{display:flex;justify-content:space-between;padding:2px 0;border-bottom:1px solid #ddd;align-items:center;position:relative;}
            .product-info{display:flex;flex-direction:column;justify-content:center;width:100%;}
            .product-name{font-weight:bold;font-size:13px;color:#333;}
            .custom_cart_totals p{font-size:18px;font-weight:bold;margin-bottom:8px;color:red;text-align:center;}
            .custom_cart_totals{width:100%;margin:35px auto 0 auto;background-color:#ffffff;padding:5px 10px;border-bottom:5px solid #e0e0e0;box-shadow:0 1px 5px rgba(0,0,0,0.1);z-index:1000;text-align:center;font-family:'Arial',sans-serif;font-size:14px;color:#333;line-height:1;border-radius:15px;box-sizing:border-box;}
            .checkout-button.button.alt{display:inline-block;padding:15px 30px;font-size:16px;font-weight:600;text-transform:uppercase;text-align:center;color:#ffffff;background-color:#0073e6;border:none;border-radius:5px;box-shadow:0 4px 10px rgba(0,0,0,0.1);transition:all .3s ease;cursor:pointer;}
            @media (min-width: 1024px){.custom_cart_totals{width:50%;margin:35px auto 0 auto;}}
        ";
        wp_add_inline_style( 'custom-cart-style', $custom_css );

        // Enqueue Custom JavaScript
        wp_register_script( 'custom-cart-script', false, array( 'jquery' ), '1.0', true );
        wp_enqueue_script( 'custom-cart-script' );

        wp_localize_script( 'custom-cart-script', 'customCart', array(
            'ajax_url' => admin_url( 'admin-ajax.php' ),
            'nonce'    => wp_create_nonce( 'custom_cart_nonce' )
        ) );

        $custom_js = "
            jQuery(document).ready(function($) {
                var updateTimeout;
                function updateSelectedTotal() {
                    var selectedTotal = 0;
                    $('.product-select:checked').each(function() {
                        var cartItemKey = $(this).data('cart_item_key');
                        var quantity = $(this).closest('.custom_cart_item').find('.quantity-input').val();
                        var priceText = $(this).closest('.custom_cart_item').find('.price').text();
                        var price = parseFloat(priceText.replace(/[^\d.-]/g, ''));
                        selectedTotal += price * quantity;
                    });
                    $('#selected-products-total').text(selectedTotal.toFixed(2));
                }
                $('.quantity-increment').on('click', function() {
                    var input = $(this).prev('.quantity-input');
                    var value = parseInt(input.val()) || 0;
                    input.val(value + 1);
                    scheduleUpdate(input);
                });
                $('.quantity-decrement').on('click', function() {
                    var input = $(this).next('.quantity-input');
                    var value = parseInt(input.val()) || 0;
                    if (value > 1) {
                        input.val(value - 1);
                        scheduleUpdate(input);
                    }
                });
                $('.quantity-input').on('input', function() {
                    var input = $(this);
                    clearTimeout(updateTimeout);
                    scheduleUpdate(input);
                });
                function scheduleUpdate(input) {
                    clearTimeout(updateTimeout);
                    updateTimeout = setTimeout(function() {
                        updateCart(input);
                    }, 600);
                }
                function updateCart(input) {
                    var key = input.data('cart_item_key');
                    var newQuantity = input.val();
                    if (newQuantity <= 0 || isNaN(newQuantity)) {
                        return;
                    }
                    $.ajax({
                        url: customCart.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'update_cart_quantity',
                            cart_item_key: key,
                            quantity: newQuantity,
                            security: customCart.nonce
                        },
                        success: function(response) {
                            if (response.success) {
                                location.reload();
                            } else {
                                alert(response.data.message);
                            }
                        },
                        error: function() {
                            alert('Failed to update quantity. Please try again.');
                        }
                    });
                }
                $('#proceed-to-checkout').on('click', function(e) {
                    e.preventDefault();
                    var selectedItems = [];
                    $('.product-select:checked').each(function() {
                        selectedItems.push($(this).data('cart_item_key'));
                    });
                    if (selectedItems.length === 0) {
                        alert('Please select at least one item to proceed to checkout.');
                        return;
                    }
                    $.ajax({
                        url: customCart.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'proceed_to_checkout',
                            selected_items: selectedItems,
                            security: customCart.nonce
                        },
                        success: function(response) {
                            if (response.success) {
                                window.location.href = '" . esc_url( wc_get_checkout_url() ) . "';
                            } else {
                                alert(response.data.message);
                            }
                        },
                        error: function() {
                            alert('Failed to proceed to checkout. Please try again.');
                        }
                    });
                });
                $('.remove-item').on('click', function() {
                    var key = $(this).data('cart_item_key');
                    $.ajax({
                        url: customCart.ajax_url,
                        method: 'POST',
                        data: {
                            action: 'remove_cart_item',
                            cart_item_key: key,
                            security: customCart.nonce
                        },
                        success: function(response) {
                            if (response.success) {
                                location.reload();
                            } else {
                                alert(response.data.message);
                            }
                        },
                        error: function() {
                            alert('Failed to remove item. Please try again.');
                        }
                    });
                });
                $('.product-select').on('change', function() {
                    updateSelectedTotal();
                });
                $('#select-all').on('change', function() {
                    var isChecked = $(this).prop('checked');
                    $('.product-select').prop('checked', isChecked);
                    updateSelectedTotal();
                });
                $('.product-select').on('change', function() {
                    var allSelected = $('.product-select').length === $('.product-select:checked').length;
                    $('#select-all').prop('checked', allSelected);
                    updateSelectedTotal();
                });
                updateSelectedTotal();
            });
        ";
        wp_add_inline_script( 'custom-cart-script', $custom_js );
    }
}
add_action( 'wp_enqueue_scripts', 'custom_cart_page_enqueue_scripts' );
















/**
 * Custom Cart Page Shortcode with Optimized Image Loading
 */
function custom_cart_page_shortcode() {
    if ( ! class_exists( 'WooCommerce' ) ) {
        return '';
    }
    ob_start();
    echo '<h2 style="text-align: center; font-size: 30px; font-weight: bold; color: #2c3e50; margin-bottom: 20px;">🛒 My Cart</h2>';

    if ( WC()->cart->is_empty() ) {
        echo '<p style="text-align: center; font-size: 20px; font-weight: bold; color: #2c3e50; padding: 15px; border: 1px solid #ddd; border-radius: 5px; background-color: #f8f9fa; display: inline-block;">🛒 Your cart is currently empty. Start shopping now!</p>';
        echo '<div style="text-align: center; margin: 40px 0;">';
        echo '<a href="' . esc_url( wc_get_page_permalink( 'shop' ) ) . '" class="button">🛍️ Return to Shop</a>';
        echo '</div>';
        echo '<div style="margin-top: 40px;">' . do_shortcode('[products limit="20" orderby="popularity"]') . '</div>';
        echo '<div style="text-align: center; margin: 40px 0;">';
        echo '<a href="' . esc_url( wc_get_page_permalink( 'shop' ) ) . '" class="button">🛍️ Return to Shop</a>';
        echo '</div>';
    } else {
        echo '<label for="select-all">Select all</label>';
        echo '<input type="checkbox" id="select-all" />';
        echo '<form id="cart-selection-form">';
        echo '<ul class="custom_cart_list product_list_widget">';

        $selected_items = array();
        $current_time   = time();
        $last_24_hours  = $current_time - 86400;
        $cart_items     = array_reverse( WC()->cart->get_cart() );

        foreach ( $cart_items as $cart_item_key => $cart_item ) {
            $product      = $cart_item['data'];
            $product_name = sanitize_text_field( $product->get_name() );
            $product_image = wp_get_attachment_image_src( $product->get_image_id(), 'woocommerce_thumbnail' )[0]; // Optimized image size
            $price        = floatval( $product->get_price() );
            $quantity     = intval( $cart_item['quantity'] );

            if ( $product->get_stock_quantity() !== null && $quantity > $product->get_stock_quantity() ) {
                $quantity = $product->get_stock_quantity();
                WC()->cart->set_quantity( $cart_item_key, $quantity );
            }

            $total_price = $price * $quantity;
            $timestamp   = isset( $cart_item['timestamp'] ) ? $cart_item['timestamp'] : 0;
            if ( $timestamp >= $last_24_hours ) {
                $selected_items[] = $cart_item_key;
            }
            ?>
            <li class="custom_cart_item" data-cart_item_key="<?php echo esc_attr( $cart_item_key ); ?>">
                <span class="remove-item" data-cart_item_key="<?php echo esc_attr( $cart_item_key ); ?>">Remove</span>
                <div class="product-image-container">
                    <input type="checkbox" class="product-select" data-cart_item_key="<?php echo esc_attr( $cart_item_key ); ?>" <?php echo in_array( $cart_item_key, $selected_items ) ? 'checked' : ''; ?> /> Select
                    <a href="<?php echo esc_url( get_permalink( $product->get_id() ) ); ?>" class="product-link">
                        <img src="<?php echo esc_url( $product_image ); ?>" 
                             alt="<?php echo esc_attr( $product_name ); ?>" 
                             width="60" height="60" 
                             loading="lazy" 
                             style="width: 60px; height: 60px; object-fit: cover;" />
                    </a>
                </div>
                <div class="product-info">
                    <a href="<?php echo esc_url( get_permalink( $product->get_id() ) ); ?>" class="product-link">
                        <span class="product-name"><?php echo esc_html( $product_name ); ?></span>
                        <span class="stock-info" style="color: green; font-size: 12px;"> <?php echo esc_html( $product->get_stock_quantity() ); ?> In stock</span>
                    </a>
                    <div class="product-price" style="display: flex; align-items: center;">
                        <span class="price" style="color: red; margin-right: 20px;"><?php echo wc_price( $price ); ?></span>
                        <div class="quantity-selector" style="display: flex; align-items: left;">
                            <button type="button" class="quantity-decrement">➖</button>
                            <input type="text" class="quantity-input" data-cart_item_key="<?php echo esc_attr( $cart_item_key ); ?>" value="<?php echo esc_attr( $quantity ); ?>" />
                            <button type="button" class="quantity-increment">➕</button>
                        </div>
                    </div>
                    <div class="second-row" style="display: flex; align-items: center; margin-top: 10px;">
                        <span class="total-price" data-cart_item_key="<?php echo esc_attr( $cart_item_key ); ?>" style="color: red; font-weight: bold; font-size: 14px;">Total: <?php echo wc_price( $total_price ); ?></span>
                    </div>
                </div>
            </li>
            <?php
        }
        echo '</ul>';
        echo '<div class="custom_cart_totals">';
        echo '<p style="color: #f08905; font-size: 10px; font-weight: 600; margin-top: 0; margin-bottom: 0; text-align: right;"><strong>Cart Total:</strong> ' . WC()->cart->get_total() . '</p>';
        echo '<p><strong>Total:</strong> ' . get_woocommerce_currency_symbol() . '<span id="selected-products-total">0.00</span></p>';
        echo '<button type="button" id="proceed-to-checkout" class="checkout-button button alt" style="background: #ff6110; color: white;">Proceed to Checkout &#128666;</button>';
        echo '</div>';
    }
    return ob_get_clean();
}
add_shortcode( 'custom_cart_page', 'custom_cart_page_shortcode' );










/**
 * Adds a timestamp to cart item data when a product is added.
 */
function add_timestamp_to_cart_item( $cart_item_data, $product_id ) {
    $cart_item_data['timestamp'] = time();
    return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'add_timestamp_to_cart_item', 10, 2 );








/**
 * AJAX Endpoint: Remove Cart Item.
 */
function remove_cart_item() {
    check_ajax_referer( 'custom_cart_nonce', 'security' );
    if ( isset( $_POST['cart_item_key'] ) ) {
        $cart_item_key = sanitize_text_field( $_POST['cart_item_key'] );
        WC()->cart->remove_cart_item( $cart_item_key );
        wp_send_json_success( array( 'cart_total' => WC()->cart->get_total() ) );
    } else {
        wp_send_json_error( array( 'message' => 'Invalid item key.' ) );
    }
}
add_action( 'wp_ajax_remove_cart_item', 'remove_cart_item' );
add_action( 'wp_ajax_nopriv_remove_cart_item', 'remove_cart_item' );

/**
 * AJAX Endpoint: Update Cart Quantity.
 */
function update_cart_quantity() {
    check_ajax_referer( 'custom_cart_nonce', 'security' );
    if ( isset( $_POST['cart_item_key'], $_POST['quantity'] ) ) {
        $cart_item_key = sanitize_text_field( $_POST['cart_item_key'] );
        $quantity = intval( $_POST['quantity'] );
        if ( $quantity > 0 && WC()->cart->find_product_in_cart( $cart_item_key ) ) {
            WC()->cart->set_quantity( $cart_item_key, $quantity );
            wp_send_json_success( array( 'cart_total' => WC()->cart->get_total() ) );
        } else {
            wp_send_json_error( array( 'message' => 'Invalid quantity or cart item.' ) );
        }
    } else {
        wp_send_json_error( array( 'message' => 'Missing parameters.' ) );
    }
}
add_action( 'wp_ajax_update_cart_quantity', 'update_cart_quantity' );
add_action( 'wp_ajax_nopriv_update_cart_quantity', 'update_cart_quantity' );








/**
 * AJAX Endpoint: Proceed to Checkout.
 *
 * This endpoint removes unselected items and stores them in the session.
 */
function proceed_to_checkout() {
    check_ajax_referer( 'custom_cart_nonce', 'security' );
    if ( isset( $_POST['selected_items'] ) ) {
        $selected_items = array_map( 'sanitize_text_field', $_POST['selected_items'] );
        $removed_items = array();

        foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
            if ( ! in_array( $cart_item_key, $selected_items ) ) {
                $product = $cart_item['data'];
                // Save full product data including variation details.
                $removed_item = array(
                    'quantity'  => intval( $cart_item['quantity'] ),
                    'sku'       => $product->get_sku(),
                    'name'      => $product->get_name(),
                    'price'     => $product->get_price(),
                    'image'     => wp_get_attachment_image_src( $product->get_image_id(), 'thumbnail' )[0] ?: 'path/to/fallback-image.jpg',
                );
                if ( $product->is_type( 'variation' ) ) {
                    $removed_item['product_id']   = $product->get_parent_id();
                    $removed_item['variation_id'] = $product->get_id();
                    $removed_item['variation']    = isset( $cart_item['variation'] ) ? $cart_item['variation'] : array();
                } else {
                    $removed_item['product_id']   = $product->get_id();
                    $removed_item['variation_id'] = 0;
                    $removed_item['variation']    = array();
                }
                $removed_items[] = $removed_item;
                WC()->cart->remove_cart_item( $cart_item_key );
            }
        }
        WC()->session->set( 'removed_cart_items', $removed_items );
        wp_send_json_success();
    } else {
        wp_send_json_error( array( 'message' => 'No items selected.' ) );
    }
}
add_action( 'wp_ajax_proceed_to_checkout', 'proceed_to_checkout' );
add_action( 'wp_ajax_nopriv_proceed_to_checkout', 'proceed_to_checkout' );










/**
 * Restore removed cart items when the cart page is visited.
 */
function restore_removed_items_to_cart() {
    if ( is_cart() ) {
        $removed_items = WC()->session->get( 'removed_cart_items', array() );
        if ( ! empty( $removed_items ) ) {
            foreach ( $removed_items as $item ) {
                $product_id   = $item['product_id'];
                $quantity     = intval( $item['quantity'] );
                $variation_id = isset( $item['variation_id'] ) ? $item['variation_id'] : 0;
                $variation    = isset( $item['variation'] ) ? $item['variation'] : array();

                if ( $variation_id ) {
                    WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation );
                } else {
                    WC()->cart->add_to_cart( $product_id, $quantity );
                }
            }
            WC()->cart->calculate_totals();
            WC()->session->set( 'removed_cart_items', array() );
        }
    }
}
add_action( 'template_redirect', 'restore_removed_items_to_cart' );

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart
Scroll to Top