wordpressvalidationwoocommerceproductvendor

Only allow products in cart of the same vendor in WooCommerce


I have written a function in my functions.php file of my child theme in my WoocCmmerce store.

The validation on the add to cart button checks if all products in the cart come from only 1 vendor.

This function does not work correctly as the notice only displays when i manually refresh the page. It should display the notice immediately. Can anyone help me?

Here's my code below:

add_action( 'wp_enqueue_scripts', 'martfury_child_enqueue_scripts', 20 );
function martfury_child_enqueue_scripts() {
    wp_enqueue_style( 'martfury-child-style', get_stylesheet_uri() );
    if ( is_rtl() ) {
        wp_enqueue_style( 'martfury-rtl', get_template_directory_uri() . '/rtl.css', array(), '20180105' );
    }
}

add_action( 'woocommerce_add_to_cart_validation', function( $is_allow, $product_id, $quantity ) {
    $product = get_post( $product_id );
    $product_author = $product->post_author;

    //Iterating through each cart item
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $cart_product_id = $cart_item['product_id'];
        $cart_product = get_post( $cart_product_id );
        $cart_product_author = $cart_product->post_author;
        if( $cart_product_author != $product_author ) {
            $is_allow = false;
            break;
        }
    }

    if( !$is_allow ){
        // We display an error message
    wc_add_notice( __( "Well, you already have some item in your cart. First checkout with those and then purchase other items!", "wcfm-ecogear" ), 'error' );
        
    return wp_redirect($woocommerce->cart->get_cart_url());
    }
    return $is_allow;
    
}, 50, 3 );

Solution

  • It seems that some of the steps you apply are unnecessary, this should suffice

    function filter_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {       
        // Cart NOT empty
        if ( ! WC()->cart->is_empty() ) {
            // Retrieves post data given a post ID or post object.
            $product = get_post( $product_id );
        
            // Post author
            $product_author = $product->post_author;
        
            // Flag, by default false
            $flag = false;
    
            // Loop trough cart
            foreach( WC()->cart->get_cart() as $cart_item ) {
                // Get product ID
                $cart_product_id = $cart_item['data']->get_id();
    
                // Get post
                $cart_product = get_post( $cart_product_id );
                
                // Post author
                $cart_product_author = $cart_product->post_author;
                
                // Condition NOT equal
                if( $cart_product_author != $product_author ) {
                    $flag = true;
    
                    // Break loop
                    break;
                }
            }
            
            // True
            if ( $flag ) {
                // Add notice    
                wc_add_notice( __( 'Products in the cart have to come from only 1 vendor', 'woocommerce' ), 'error' );
    
                // NOT passed
                $passed = false;
            }
        }
        
        return $passed;
    }
    add_filter( 'woocommerce_add_to_cart_validation', 'filter_woocommerce_add_to_cart_validation', 10, 5 );