2
votes

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;
}
2

2 Answers

5
votes

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'] ) );
    }
}
0
votes

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;
    }
}