简体   繁体   中英

How to add multiple variable products to the cart via the add-to-cart query string

I want to add two variable product into my cart when i clicking a link on my site. i added below code in my function.php this code is only working with the simple product its not working with the variable product.

function woocommerce_maybe_add_multiple_products_to_cart( $url = false ) {
    // Make sure WC is installed, and add-to-cart qauery arg exists, and contains at least one comma.
    if ( ! class_exists( 'WC_Form_Handler' ) || empty( $_REQUEST['add-to-cart'] ) || false === strpos( $_REQUEST['add-to-cart'], ',' ) ) {
        return;
    }

    // Remove WooCommerce's hook, as it's useless (doesn't handle multiple products).
    remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );

    $product_ids = explode( ',', $_REQUEST['add-to-cart'] );
    $count       = count( $product_ids );
    $number      = 0;

    foreach ( $product_ids as $id_and_quantity ) {
        // Check for quantities defined in curie notation (<product_id>:<product_quantity>)
        // https://dsgnwrks.pro/snippets/woocommerce-allow-adding-multiple-products-to-the-cart-via-the-add-to-cart-query-string/#comment-12236
        $id_and_quantity = explode( ':', $id_and_quantity );
        $product_id = $id_and_quantity[0];

        $_REQUEST['quantity'] = ! empty( $id_and_quantity[1] ) ? absint( $id_and_quantity[1] ) : 1;

        if ( ++$number === $count ) {
            // Ok, final item, let's send it back to woocommerce's add_to_cart_action method for handling.
            $_REQUEST['add-to-cart'] = $product_id;

            return WC_Form_Handler::add_to_cart_action( $url );
        }

        $product_id        = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $product_id ) );
        $was_added_to_cart = false;
        $adding_to_cart    = wc_get_product( $product_id );

        if ( ! $adding_to_cart ) {
            continue;
        }

        $add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $adding_to_cart->get_type(), $adding_to_cart );

        // Variable product handling
        if ( 'variable' === $add_to_cart_handler ) {
            woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_variable', $product_id );

        // Grouped Products
        } elseif ( 'grouped' === $add_to_cart_handler ) {
            woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_grouped', $product_id );

        // Custom Handler
        } elseif ( has_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler ) ){
            do_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler, $url );

        // Simple Products
        } else {
            woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_simple', $product_id );
        }
    }
}

// Fire before the WC_Form_Handler::add_to_cart_action callback.
add_action( 'wp_loaded', 'woocommerce_maybe_add_multiple_products_to_cart', 15 );


/**
 * Invoke class private method
 *
 * @since   0.1.0
 *
 * @param   string $class_name
 * @param   string $methodName
 *
 * @return  mixed
 */
function woo_hack_invoke_private_method( $class_name, $methodName ) {
    if ( version_compare( phpversion(), '5.3', '<' ) ) {
        throw new Exception( 'PHP version does not support ReflectionClass::setAccessible()', __LINE__ );
    }

    $args = func_get_args();
    unset( $args[0], $args[1] );
    $reflection = new ReflectionClass( $class_name );
    $method = $reflection->getMethod( $methodName );
    $method->setAccessible( true );

    $args = array_merge( array( $class_name ), $args );
    return call_user_func_array( array( $method, 'invoke' ), $args );
}

Also i want to run this code only one time. If the two product already added in cart then not added the product again into the cart.

Here is the function to add multiple variable products to WooCommerce cart.

function woocommerce_add_multiple_products_to_cart() {

    if ( empty( $_REQUEST['add-to-cart-manual'] ) ) {
        return;
    }

    global $woocommerce;

    //'add-to-cart' should be in this format - product_id1|variation_id1|variation_attribute1|variation_value1,product_id2|variation_id2|variation_attribute2|variation_value2 ...
    $product_var_ids = explode( ',', $_REQUEST['add-to-cart-manual'] ); //product with variation ids that needs to be added

    foreach ( $product_var_ids as $product_var_id ) {
        $pdt_var_temp = explode( '|', $product_var_id );
        $product_id = $pdt_var_temp[0];
        $variation_id = $pdt_var_temp[1];
        $variation_attribute = $pdt_var_temp[2];
        $variation_attribute_value = $pdt_var_temp[3];

        $pdt_in_cart = false;

        foreach ( $woocommerce->cart->cart_contents as $key => $values ) {      
            if( in_array( $values['variation_id'], $variation_id ) ) {  
                $pdt_in_cart = true;                
            }
        }

         if ( !$pdt_in_cart ) {   
            $quantity     = 1;
            $variation    = array( $variation_attribute  => $variation_attribute_value );

            $woocommerce->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation );
        }
    }
}

add_action( 'init', 'woocommerce_add_multiple_products_to_cart', 15 );

Please note the format you need to pass - http://example.com/?add-to-cart-manual=44|45|color|green,44|46|color|red and this is the format - product_id1|variation_id1|variation_attribute1|variation_value1,product_id2|variation_id2|variation_attribute2|variation_value2 and so on.

Based on product id you can check if product is added in the cart or not. Here is a code example

add_action( 'woocommerce_before_cart', 'bbloomer_find_product_in_cart' );

function bbloomer_find_product_in_cart() {

    $product_id = 282;

    $product_cart_id = WC()->cart->generate_cart_id( $product_id );
    $in_cart = WC()->cart->find_product_in_cart( $product_cart_id );

    if ( $in_cart ) {

        $notice = 'Product ID ' . $product_id . ' is in the Cart!';
        wc_print_notice( $notice, 'notice' );

    }

}

I hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM