简体   繁体   中英

WooCommerce Conditional Custom Fields if Product Category in Cart

OK, I'm stumped. I've searched and read several posts including the related post Checking products in cart based on category name woocommerce? from where I derived much of this code, and Woocommerce - Add filter to display (or hide) custom checkout field if product ID == # which is specific to Product IDs, not Category IDs.

I want to display the sdc_custom_checkout_field if, and only if, the target category ID (237 in this case) is in the cart.

I tried commenting out the sdc_custom_checkout_field function and using a simple test shown below, but kept getting "Nope!", so I assume the query is incorrect.

add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );

function sdc_custom_checkout_field( $checkout ) {

 //Check if Product in Cart
 //$product_in_cart = check_product_in_cart();

 //Product is in cart so show additional fields
 if ( $product_in_cart === true ) {
 echo '<div id="my_custom_checkout_field"><h3>' . __( 'Duplicate Card Information' . '</h3><br>');

 woocommerce_form_field( 'dupecard_location', array(
 'type'  => 'text',
 'class' => array( 'dupecard-location form-row-wide' ),
 'label' => __( 'Course Location' ),
 ), $checkout->get_value( 'dupecard_location' ) );

 woocommerce_form_field( 'dupecard_instructor', array(
 'type'  => 'text',
 'class' => array( 'dupecard-instructor form-row-wide' ),
 'label' => __( 'Instructor Name' ),
 ), $checkout->get_value( 'dupecard_instructor' ) );

 woocommerce_form_field( 'dupecard_requestor_name', array(
 'type'  => 'text',
 'class' => array( 'dupecard-requestor-name form-row-wide' ),
 'label' => __( 'Requestor Name' ),
 ), $checkout->get_value( 'dupecard_requestor_name' ) );

 woocommerce_form_field( 'dupecard_requestor_email', array(
 'type'  => 'text',
 'class' => array( 'dupecard-requestor-email form-row-wide' ),
 'label' => __( 'Requestor Email' ),
 ), $checkout->get_value( 'dupecard_requestor_email' ) );

  woocommerce_form_field( 'dupecard_requestor_phone', array(
 'type'  => 'text',
 'class' => array( 'dupecard-requestor-phone form-row-wide' ),
 'label' => __( 'Requestor Phone' ),
 ), $checkout->get_value( 'dupecard_requestor_phone' ) );

 echo '</div>';
 }
}

function check_product_in_cart() {
//Check to see if user has product in cart
global $woocommerce;

//assign default negative value 
$product_in_cart = false;

// start cart items fetch loop

foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
    $_product = $values['data'];
    $terms = get_the_terms( $_product->id, 'product_cat' );

    // second level loop search, in case some items have several categories

    $cat_ids = array();

    foreach ($terms as $term) {
        $cat_ids[] = $term->term_id;
    }

    if(in_array(237, (array)$cat_ids)) {

      //category is in cart!
       $product_in_cart = true;
    }
}

return $product_in_cart;
}

Here's the test snippet:

if ($item_in_cart === true) {echo 'YES';}
else {echo 'Nope!';}

I also replaced

$item_in_cart

with

$product_in_cart

but it made no difference.

********** EDIT RESPONSE TO @PRAFULLA **********

@Prafulla - thanks for your input. I appreciate it. I modified my snippet as follows, incorporating yours, but was unable to get it to work. I'm a PHP newbie, so, no surprise. Do you have additional advice?

 add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );

 function sdc_custom_checkout_field( $checkout ) {

 //Check if Product in Cart
 $your_product_category = is_category_in_cart();

 //Product is in cart so show additional fields
 if ( $your_product_category === true ) {
 echo '<div id="my_custom_checkout_field"><h3>' . __( 'Duplicate Card Information' . '</h3><br>');

 woocommerce_form_field( 'dupecard_location', array(
 'type'  => 'text',
 'class' => array( 'dupecard-location form-row-wide' ),
 'label' => __( 'Course Location' ),
 ), $checkout->get_value( 'dupecard_location' ) );

 woocommerce_form_field( 'dupecard_instructor', array(
 'type'  => 'text',
 'class' => array( 'dupecard-instructor form-row-wide' ),
 'label' => __( 'Instructor Name' ),
 ), $checkout->get_value( 'dupecard_instructor' ) );

 woocommerce_form_field( 'dupecard_requestor_name', array(
 'type'  => 'text',
 'class' => array( 'dupecard-requestor-name form-row-wide' ),
 'label' => __( 'Requestor Name' ),
 ), $checkout->get_value( 'dupecard_requestor_name' ) );

 woocommerce_form_field( 'dupecard_requestor_email', array(
 'type'  => 'text',
 'class' => array( 'dupecard-requestor-email form-row-wide' ),
 'label' => __( 'Requestor Email' ),
 ), $checkout->get_value( 'dupecard_requestor_email' ) );

  woocommerce_form_field( 'dupecard_requestor_phone', array(
 'type'  => 'text',
 'class' => array( 'dupecard-requestor-phone form-row-wide' ),
 'label' => __( 'Requestor Phone' ),
 ), $checkout->get_value( 'dupecard_requestor_phone' ) );

 echo '</div>';
 }
}

function is_category_in_cart( $your_product_category = 237 ){
global $woocommerce;
$products_in_cart = $woocommerce->cart->get_cart();
$product_types_in_cart = array_column( $products_in_cart, 'data' );
//if (  $product_types_in_cart[0]->product_type == 'subscription' ) { this is what I have tested 
if (  $product_types_in_cart[0]->product_cat == $your_product_category ) {
    return true;
}
return $your_product_category;
}

After much work, research, and the assistance of some paid help on another website, this is the working result:

// Add the field to the checkout

add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );

function sdc_custom_checkout_field( $checkout ) {
    if( check_product_category() ){
        echo '<div id="sdc_checkout_field"><h3>' . __( 'Duplicate Card Information' . '</h3><br>');

        woocommerce_form_field( 'dupecard_location', array(
            'type'  => 'text',
            'required'  => true,
            'class' => array( 'dupecard-location form-row-wide' ),
            'label' => __( 'Course Location' ),
        ), $checkout->get_value( 'dupecard_location' ) );

        woocommerce_form_field( 'dupecard_instructor', array(
            'type'  => 'text',
            'required'  => true,
            'class' => array( 'dupecard-instructor form-row-wide' ),
            'label' => __( 'Instructor Name' ),
        ), $checkout->get_value( 'dupecard_instructor' ) );

        woocommerce_form_field( 'dupecard_requestor_name', array(
            'type'  => 'text',
            'required'  => true,
            'class' => array( 'dupecard-requestor-name form-row-wide' ),
            'label' => __( 'Requestor Name' ),
        ), $checkout->get_value( 'dupecard_requestor_name' ) );

        woocommerce_form_field( 'dupecard_requestor_email', array(
            'type'  => 'text',
            'required'  => true,
            'class' => array( 'dupecard-requestor-email form-row-wide' ),
            'label' => __( 'Requestor Email' ),
        ), $checkout->get_value( 'dupecard_requestor_email' ) );

        woocommerce_form_field( 'dupecard_requestor_phone', array(
            'type'  => 'text',
            'required'  => true,
            'class' => array( 'dupecard-requestor-phone form-row-wide' ),
            'label' => __( 'Requestor Phone' ),
        ), $checkout->get_value( 'dupecard_requestor_phone' ) );
        echo '</div>';
    }
}

function check_product_category(){
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $product_id   = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );  
        if( is_category_in_cart( $product_id ) ){
            return  true;       
        }
    }
    return false;
}

function is_category_in_cart( $product_id ){
    return has_term( 237,'product_cat', get_post( $product_id ) );
}

/*Save to DB as post meta*/
add_action( 'woocommerce_checkout_update_order_meta',                  'my_custom_checkout_field_update_order_meta' );

function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['dupecard_location'] ) ) {
    update_post_meta( $order_id, 'dupecard_location', sanitize_text_field( $_POST['dupecard_location'] ) );
    }
    if ( ! empty( $_POST['dupecard_instructor'] ) ) {
    update_post_meta( $order_id, 'dupecard_instructor', sanitize_text_field( $_POST['dupecard_instructor'] ) );
    }
    if ( ! empty( $_POST['dupecard_requestor_name'] ) ) {
    update_post_meta( $order_id, 'dupecard_requestor_name', sanitize_text_field( $_POST['dupecard_requestor_name'] ) );
    }
    if ( ! empty( $_POST['dupecard_requestor_email'] ) ) {
    update_post_meta( $order_id, 'dupecard_requestor_email', sanitize_text_field( $_POST['dupecard_requestor_email'] ) );
    }
    if ( ! empty( $_POST['dupecard_requestor_phone'] ) ) {
    update_post_meta( $order_id, 'dupecard_requestor_phone', sanitize_text_field( $_POST['dupecard_requestor_phone'] ) );
    }
}

This is how I get the job done in my case , please try it and note where you need to give your input on this code as It is not written for direct use.

function is_category_in_cart( $your_product_category = null ){
    global $woocommerce;
    $products_in_cart = $woocommerce->cart->get_cart();
    $product_types_in_cart = array_column( $products_in_cart, 'data' );
    //if (  $product_types_in_cart[0]->product_type == 'subscription' ) { this is what I have tested 
    if (  $product_types_in_cart[0]->product_cat == $your_product_category ) {
        return true;
    }
}

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