Woocommerce Replace Product in Cart Upon Place Ord

2019-07-06 22:46发布

I have been searching on the web, reading docs & stuff but I can't figure out on replacing product in Checkout Page.

For your information, my main product page is in the Home Page and each product that have been selected, will redirected to Checkout Page. Now here, there is a problem. Let me explain....

You see, I have a carousel slider in Checkout Page which user can change/replace their product (which already been added into their cart) before they pay.

form-checkout.php

global $woocommerce;
global $product;
$items = $woocommerce->cart->get_cart();
foreach ($items as &$item){
     $id = $item['product_id'];
}
echo $id;

<div id="carousel-example-generic" class="carousel slide" data-ride="carousel" data-interval="false">
     <div class="carousel-inner" role="listbox">
     <?php
          // Querying of product information retrieval
          $args = array( 'post_type' => 'product', 'posts_per_page' => 4, 'orderby' =>'menu_order', 'order' =>'ASC');
          $loop = new WP_Query( $args );

          // Display each retrieved product
               while ( $loop->have_posts() ) : 
               $loop->the_post();
               // WooCommerce global product variable. Refer: https://docs.woothemes.com/document/class-reference/
               global $product;
               global $woocommerce;
     ?>
<div class="item <?php if ($product->id == $id) { ?> active <?php } ?>">
     <div class="p-big" id="p-custom-color">
          <strong><?php the_title(); ?></strong>
     </div>
     <div class="p-light-black">CANDIDATES</div>
     <input type="hidden" id="product" name="productid" value="<?php echo $product->id; ?>">
</div>
     <?php
               endwhile;
               wp_reset_query(); // After the loop ended, quit the custom loop and reset back the main loop
     ?>
     </div>
</div>


<!-- Upon form submission -->
if (isset($_POST['woocommerce_checkout_place_order'])){

     global $woocommerce;
     $woocommerce->cart->empty_cart(); // Empty the cart

     $selectedproduct = $_POST['selectedproductid']; // Get the selected product
     do_shortcode('[add_to_cart id="' . $selectedproduct . '"]'); // Insert the selected product in the the cart
     return esc_url( wc_get_checkout_url() ); // Redirect to Payment Gateway Page
}

<form name="checkout" method="post" class="checkout woocommerce-checkout" action="" enctype="multipart/form-data">

     <?php if ( sizeof( $checkout->checkout_fields ) > 0 ) : ?>

     <?php do_action( 'woocommerce_checkout_before_customer_details' ); ?>

     <?php do_action( 'woocommerce_checkout_billing' ); ?>

     <?php do_action( 'woocommerce_checkout_after_customer_details' ); ?>

     <?php endif; ?>


          <h3 id="order_review_heading"><?php _e( 'Your order', 'woocommerce' ); ?></h3>

     <?php do_action( 'woocommerce_checkout_before_order_review' ); ?>

          <div id="order_review" class="woocommerce-checkout-review-order">
               <!-- Checkout Review -->
               <input type="hidden" id="selectedproduct" name="selectedproductid" value="">
               <?php do_action( 'woocommerce_checkout_order_review' ); ?>
          </div>

     <?php do_action( 'woocommerce_checkout_after_order_review' ); ?>

</form>

As you can see, in the carousel, I have included <input type="hidden" id="product" name="productid" value="<?php echo $product->id; ?>"> to get each product ID and with my jQuery (I didn't show here), I took any product ID that the product is currently on the active slide and fill it in the <input type="hidden" id="selectedproduct" name="selectedproductid" value=""> in the form.

By that, I can replace the product that have been added to cart with the selected/chosen product based on the active slide with these code (Located above the form):-

<!-- Upon form submission -->
if (isset($_POST['woocommerce_checkout_place_order'])){

     global $woocommerce;
     $woocommerce->cart->empty_cart(); // Empty the cart

     $selectedproduct = $_POST['selectedproductid']; // Get the selected product
     do_shortcode('[add_to_cart id="' . $selectedproduct . '"]'); // Insert the selected product in the the cart
     return esc_url( wc_get_checkout_url() ); // Redirect to Payment Gateway Page
}

The problem here is, it failed to replace the old product with the current chosen product and it just redirect to the payment gateway page with the old product.

I want it to replace the product with the new selected ones upon placing order. Is it possible? I hope it is, because I have been playing with WooCommerce for weeks now and I don't want my effort to be futile. Help me guys.....

1条回答
该账号已被封号
2楼-- · 2019-07-06 23:05

After few days of figuring this out, with 30+ Chrome tabs, 50+ of purchases test & 10 gallons of coffee, finally I found the answer...

add_action('woocommerce_checkout_process', 'change_product_upon_submission');
function change_product_upon_submission() {
     if ( !empty( $_POST['_wpnonce'] ) && !empty($_POST['selectedproductid']) ) {
     $selectedproduct = $_POST['selectedproductid']; // Get the selected product
     WC()->cart->empty_cart(); //Empty the cart
     WC()->cart->add_to_cart( $selectedproduct ); // Insert the selected product in the cart
     }
}

The hook required to trigger this function is within the WC_Checkout process_checkout() class in includes/class-wc-checkout.php. This woocommerce_checkout_process doesn't exist WooCommerce template files, we're gonna be thorough. So to do whatever custom stuff before sending data to the payment gateway upon place order submission, we're gonna need to manipulate the woocommerce_checkout_process hook as process_checkout() function processes the checkout after the confirm order button is pressed.

Hope this save someone's lives as I don't have any because I need to sleep after few days of burning midnight oil figuring this abomination.

查看更多
登录 后发表回答