phpwordpresswoocommercecartdokan

Sort WooCommerce cart items by vendor when using Dokan plugin


We are working on a solution to sort the products in cart and checkout by the vendors store names. We found this here: Woocommerce sort cart products by product category but we have to extend this code for our case. Every product has a vendor. So we do not have to check if a product has no vendor.

I'm not sure how I can output the array in the right way. Can I do it like this?

add_action( 'woocommerce_cart_loaded_from_session', function() {

    global $woocommerce;
    
    // Build product array
    $products_in_cart = array();

    // Loop through cart items
    foreach ( $woocommerce->cart->cart_contents as $key => $item ) {
        
         // Get product object
        $product = $item->get_product();
        
        // Author id
        $author_id = $product->post->post_author;
        
        // Shopname
        $vendor = dokan()->vendor->get( $author_id );
        $shop_name = $vendor->get_shop_name();
        
        $products_in_cart[ $key ] = $shop_name[0]->name;
    
    }

    ksort( $products_in_cart );
    
    // Build cart array
    $cart_contents = array();
        
    foreach ( $products_in_cart as $cart_key => $Vendor_store ) {
        $cart_contents[ $cart_key ] = $woocommerce->cart->cart_contents[ $cart_key ];
    }
    
    // Output sorted cart
    $woocommerce->cart->cart_contents = $cart_contents;

}, 100 );

Solution

  • Updated: Try the following simplified and revisited code:

    add_action( 'woocommerce_cart_loaded_from_session', 'sort_cart_items_by_vendor', 100 );
    function sort_cart_items_by_vendor() {
        $items_to_sort = $cart_contents = array(); // Initializing
    
        // Loop through cart items
        foreach ( WC()->cart->cart_contents as $item_key => $cart_item ) {
            $vendor_id  = get_post_field( 'post_author', $cart_item['product_id']);
            $store_info = dokan_get_store_info( $vendor_id );
            $items_to_sort[ $item_key ] = $store_info['store_name'];
        }
    
        ksort( $items_to_sort );
        
        // Loop through sorted items key
        foreach ( $items_to_sort as $cart_item_key => $store_name ) {
            $cart_contents[ $cart_item_key ] = WC()->cart->cart_contents[ $cart_item_key ];
        }
        
        // Set sorted items as cart contents
        WC()->cart->cart_contents = $cart_contents;
    }
    

    Code goes in functions.php file of the active child theme (or active theme). It should work.

    Related: