Ask your WordPress questions! Pay money and get answers fast! (more info)

WooCommerce Conditional Custom Fields if Product Category in Cart WordPress

  • SOLVED

I need to display Custom Fields above the Order Notes (woocommerce_before_order_notes) if, and only if, the target category(ies) is/are in the cart.

I've tried this two ways. The first method I did myself, the second is based on the single feedback I received on [[LINK href="http://stackoverflow.com/questions/33226691/woocommerce-conditional-custom-fields-if-product-category-in-cart/33229123?noredirect=1#comment54293542_33229123"]]SO[[/LINK]]. Neither is working.

<strong>METHOD ONE:</strong>
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;
}


<strong>METHOD TWO:</strong>
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;
}

Answers (2)

2015-10-23

Kyle answers:

Try this:

[UPDATED]
add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );
function sdc_custom_checkout_field( $checkout ) {

if( check_order_for_cat() ){

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_order_for_cat(){

$pass = false;

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 ) ){

$pass = true;

}

}

return $pass_1;

}


function is_category_in_cart( $product_id ){

return has_term( 237,'product_cat', get_post( $product_id ) );

}


killerdesigner comments:

Hey Kyle. Thanks for the rapid response. I tried that, did not work.

I added <?php var_dump( $product_types_in_cart[0] ); ?> to both cart.php and form-checkout.php, which both returned NULL.

~KillerDesigner


Kyle comments:

That is not in my code...


killerdesigner comments:

Kyle... have to award Rempty (since his answer worked). I'm new to WPQ. Is there a way for me to reward you too?

~KD


Kyle comments:

Rempty just copy and pasted my code, I had a typo... oh well


killerdesigner comments:

Kyle, just saw your response. I know the var_dump wasn't in your code, but yours didn't work, I added that to test. As it turns out, it didn't work for Rempty's either, even though his code worked.

~KD


Kyle comments:

You can award different prize amounts per answer. For the record rempty changed 1 line of my 71 lines of code. My code works the same if you change "return $pass_1;" to "return $pass;"


killerdesigner comments:

Seriously, a typo? That sucks. OK, since I'm brand new to WPQ, I'm not sure how to award the prize, and the instructional link returns 500 http://blog.tailormadeanswers.com/2011/04/22/voting-assign-prize-money/

Any idea?


Kyle comments:

He posted the correct answer, so not much I can do about it. Up to you. Here is the code chunk for your form fields with 'required' added

add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );
function sdc_custom_checkout_field( $checkout ) {

if( check_order_for_cat() ){

echo '<div id="my_custom_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_order_for_cat( $order_id ){

$pass = false;

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 ) ){

$pass = true;

}

}

return $pass;

}


function is_category_in_cart( $product_id ){

return has_term( 237,'product_cat', get_post( $product_id ) );

}


Kyle comments:

Don't worry too much about it. Just glad you got the answer haha


killerdesigner comments:

Here's a solution. If I can figure how to award Rempty, I'll do that. I'll then open another request for $25 on how to make my fields required, and add them to the notification email. As soon as I am ready to post it, I'll ping you. Fair enough?


killerdesigner comments:

Kyle, please see my response to Rempty below (if you can).

2015-10-23

Rempty answers:

Try this, i made some modifications on Kyle code.

add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );

function sdc_custom_checkout_field( $checkout ) {
if( check_product_category() ){
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_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 ) );
}


killerdesigner comments:

Rempty,

Worked like a charm, thanks! How do I make the fields required?

~KD


Rempty comments:

I no have problem with the reward, you can vote for Kyle.
I dont take any credit for the code, as i said " i made some modifications on Kyle code."
I just wanted to help

About validation and plus save values


/*Validate*/

add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

function my_custom_checkout_field_process() {

if( check_product_category() ){
if ( !$_POST['dupecard_location'] )
wc_add_notice( __( '<b>Course Location</b> is required.' ), 'error' );

if ( ! $_POST['dupecard_instructor'] )
wc_add_notice( __( '<b>Instructor Name</b> is required.' ), 'error' );

if ( ! $_POST['dupecard_requestor_name'] )
wc_add_notice( __( '<b>Requestor Name</b> is required.' ), 'error' );

if ( ! $_POST['dupecard_requestor_email'] )
wc_add_notice( __( '<b>Requestor Email</b> is required.' ), 'error' );

if ( ! $_POST['dupecard_requestor_phone'] )
wc_add_notice( __( '<b>Requestor Phone</b> is required.' ), 'error' );
}

}


/*Save*/
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'] ) );
}

}


killerdesigner comments:

Wow! You guys are AWESOME! Thanks for the additional code assist. You R O C K!!

I just messaged Lawrence (website owner/creator) asking if there's a way to award both of you. As I stated in response to Kyle, the instructions on how to award return 500 Internal Server error http://blog.tailormadeanswers.com/2011/04/22/voting-assign-prize-money/

I guess I just upvote, eh?

If you email me at s t e v e - a t - (my username) dot com, I'll award Kyle, then send you a gift by PayPal for your assistance.

Fair enough?


killerdesigner comments:

Rempty, it came to my attention that compensation outside of this website is against Terms and Conditions. I discovered that I could split the prize by up voting, which is what I did. I hope you understand.

Sorry all, I am new to the website - didn't mean to violate T & C's.

I sincerely appreciate your assistance, and will come back for more!