WooCommerce add to cart validation: prevent add to cart

33.3k views Asked by At

I have a probleme with woocommerce that im trying to fix for few days.

I am creating a website for a guy and he wanted me to add a custom input on the product page, I couldn't do it myself so I used a freelancer online for it.

On the product page I have an add-to-cart button, quantity input and date input.

The "date input" is the freelancer did.

The thing is that when the $_REQUEST['thedate'] is empty the custom error popup but the product still added to the cart.

the code:(functions.php)

function add_the_date_validation() { 
  if ( empty( $_REQUEST['thedate'] )) {
    wc_add_notice( __( 'Please enter a date.', 'woocommerce' ), 'error' );
    return false;
  }
  return true;
}
add_action( 'woocommerce_add_to_cart_validation', 'add_the_date_validation', 10, 5 );    

the view: https://i.stack.imgur.com/a75P6.png

  • How can i prevent the product to add itslef to the cart?

other codes the freelancer did:

function save_add_the_date_field( $cart_item_key, $product_id = null, $quantity= null, $variation_id= null, $variation= null ) {
  if( isset( $_REQUEST['thedate'] ) ) {
    WC()->session->set( $cart_item_key.'_the_date', $_REQUEST['thedate'] );
  }
}

add_action( 'woocommerce_add_to_cart', 'save_add_the_date_field', 1, 5 );

function render_meta_on_checkout_order_review_item( $quantity = null, $cart_item = null, $cart_item_key = null ) {
  if( $cart_item_key && WC()->session->__isset( $cart_item_key.'_the_date' ) ) {
    echo $quantity. '<dl class="">
                      <dt class="">Date: </dt>
                      <dd class=""><p>'. WC()->session->get( $cart_item_key.'_the_date') .'</p></dd>
                    </dl>';
  }
}

add_filter( 'woocommerce_checkout_cart_item_quantity', 'render_meta_on_checkout_order_review_item', 1, 3 );

function the_date_order_meta_handler( $item_id, $values, $cart_item_key ) {
  if( WC()->session->__isset( $cart_item_key.'_the_date' ) ) {
    wc_add_order_item_meta( $item_id, "the_date", WC()->session->get( $cart_item_key.'_the_date') );
  }
}

add_action( 'woocommerce_add_order_item_meta', 'the_date_order_meta_handler', 1, 3 );

function the_date_force_individual_cart_items($cart_item_data, $product_id) {
  $unique_cart_item_key = md5( microtime().rand() );
  $cart_item_data['unique_key'] = $unique_cart_item_key;

  return $cart_item_data;
}

add_filter( 'woocommerce_add_cart_item_data','the_date_force_individual_cart_items', 10, 2 );
4

There are 4 answers

8
helgatheviking On BEST ANSWER

I would have said that you should use Product Add-Ons but it doesn't seem to have a date picker. Anyway, I would try modifying your validation function as follows:

function add_the_date_validation( $passed ) { 
if ( empty( $_REQUEST['thedate'] )) {
    wc_add_notice( __( 'Please enter a date.', 'woocommerce' ), 'error' );
    $passed = false;
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'add_the_date_validation', 10, 5 );  

Instead of returning TRUE you want to return the current status of the $passed variable. I can't promise that will work, because I am not going to set up the rest of the code required to test it, but this is similar to what I have done many times.

On another note, unless you mean to apply this validation to every product in your store, you need to limit this function with some additional conditional logic.

0
Branksy On

I had this issue and after much trial and error the fix was to adjust the $priority parameter (10 is default) in :

add_filter( 'woocommerce_add_to_cart_validation', 'add_the_date_validation', 10, 5 );

As per usual, I tried everything else first...changed this to 15 and bingo..! I guess it was running ahead of code ranked lower priority, which then let items into cart.

2
Safuan Dinar On

Yes, sorry i'am new in this forum. However i have found a solution, i have edit directly class-wc-cart.php at line 900, and i have copy the function before the if:

if($passed!=false)
{
    do_action( 'woocommerce_add_to_cart', $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data );
}

Now for me it works, i know that isn't the most correct solution but for the moment it works, i have only to be careful when i will update woocommerce

0
Maulik patel On
// Allow only pre-defined quantity from specific per category in the cart
add_filter( 'woocommerce_add_to_cart_validation', 'allowed_quantity_per_category_in_the_cart', 10, 2 );
function allowed_quantity_per_category_in_the_cart( $passed, $product_id) {

  $running_qty = 0;
  $restricted_product_cats = $restricted_product_cat_slugs = array();

    //Specify the category/categories by category slug and the quantity limit
    $restricted_product_cats[] = array('cat_slug'=> 'skip-bins', 'max_num_products' => 1); // change here
    //$restricted_product_cats[] = array('cat_slug'=> 'caliper-paint-kit', 'max_num_products' => 4); //change here
    foreach($restricted_product_cats as $restricted_prod_cat) $restricted_product_cat_slugs[]= $restricted_prod_cat['cat_slug'];

    // Getting the current product category slugs in an array
    $product_cats_object = get_the_terms( $product_id, 'product_cat' );
    foreach($product_cats_object as $obj_prod_cat) $current_product_cats[]=$obj_prod_cat->slug;

    // Iterating through each cart item
    foreach (WC()->cart->get_cart() as $cart_item_key=>$cart_item ){


        // Check if restricted category/categories found
      if( array_intersect($restricted_product_cat_slugs, $current_product_cats) ) {

        foreach($restricted_product_cats as $restricted_product_cat){
          if( in_array($restricted_product_cat['cat_slug'], $current_product_cats) && has_term( $current_product_cats, 'product_cat', $cart_item['product_id'] )) {

                    // count(selected category) quantity
            $running_qty += (int) $cart_item['quantity'];

                    // Check if More than allowed products in the cart
            if( $running_qty >= $restricted_product_cat['max_num_products'] ) {

                        //limit to maximum allowed
                        //WC()->cart->set_quantity( $cart_item_key, $restricted_product_cat['max_num_products'] ); // Change quantity

                        // Get the category information
              $catinfo = get_term_by('slug', $restricted_product_cat['cat_slug'], 'product_cat');

              wc_add_notice( sprintf( 'Maximum of  %s '.($restricted_product_cat['max_num_products']>1?'skip bin ('.$catinfo->name.') are':'skip bin').' allowed in the cart. Please remove the existing Skip Bin from the cart to add the new Skip Bin',  $restricted_product_cat['max_num_products'] ), 'error' );
                         ///WC()->cart->empty_cart();
                        $passed = false; // don't add the new product to the cart
                        // We stop the loop
                        break;
                      }
                    }
                  }
                }
              }
              return $passed;
}