I am using woocommerce for a site for a nonprofit that sells tickets to classes and tickets to events. When someone is signing up for a class then need to list their emergency contact information and agree to a liability release. When they are buying a ticket to an event the nonprofit doesn't need the emergency contact info or the liability release. So... they want those fields to appear on the woocommerce checkout only on the condition that the person is checking out with a ticket for a class. Make sense?
I figured out how to add the custom fields and the custom liability releases a few months ago when they first added the classes to the website. I created a "class" product category in woocommerce and a function to test for any products in the shopping cart that are in that category, so I can conditionally show the fields.
All of these functions are in my functions.php file and I right now I am running the conditional statement to check for the "class" category in each of the functions. I need help learning how to check for the "class" category once, then run the functions that display the fields, validated the fields, add the data to the database and generate the new order emails. Make sense?
Here's what I have currently:
// Add fields for Emergency Contact & Medical Information to the checkout page
add_action('woocommerce_after_order_notes', 'customise_checkout_field');
function customise_checkout_field($checkout)
{
// Check to see if there is a class in the cart
// function is at the end
$class_in_cart = is_conditional_product_in_cart( 'class' );
// There is a class in the cart so show additional fields
if ( $class_in_cart === true ) {
echo '<div id="customise_checkout_field"><h3>' . __('Emergency Contact & Medical Information') . '</h3>';
woocommerce_form_field('emergency_contact', array(
'type' => 'text',
'class' => array(
'emergency-contact form-row-wide'
) ,
'label' => __('Emergency Contact') ,
'placeholder' => __('Please enter first & last name') ,
'required' => true,
) , $checkout->get_value('emergency_contact'));
woocommerce_form_field('emergency_contact_relationship', array(
'type' => 'text',
'class' => array(
'emergency-contact-relationship form-row-wide'
) ,
'label' => __('What is your relationship with this person?') ,
'placeholder' => __('Example: Mother') ,
'required' => true,
) , $checkout->get_value('emergency_contact_relationship'));
woocommerce_form_field('emergency_contact_phone', array(
'type' => 'text',
'class' => array(
'emergency-contact-phone form-row-wide'
) ,
'label' => __('What is their phone number?') ,
'placeholder' => __('(555) 555-5555') ,
'required' => true,
) , $checkout->get_value('emergency_contact_phone'));
woocommerce_form_field('medical_medicine', array(
'type' => 'textarea',
'class' => array(
'medical-medicine form-row-wide'
) ,
'label' => __('Do you have any medical conditions and are you taking any medications we need to be aware of?') ,
'placeholder' => __('If not please write in "none"') ,
'required' => true,
) , $checkout->get_value('medical_medicine'));
echo '</div>';
}
}
// Process emergency contact fields
add_action('woocommerce_checkout_process', 'custom_checkout_fields_process');
function custom_checkout_fields_process() {
// Check to see if there is a class in the cart
$class_in_cart = is_conditional_product_in_cart( 'class' );
// There is a class in the cart so show additional fields
if ( $class_in_cart === true ) {
// if the field is set, if not then show an error message.
if (!$_POST['emergency_contact']) wc_add_notice(__('Please list an emergency contact.') , 'error');
if (!$_POST['emergency_contact_relationship']) wc_add_notice(__('Please indicate your relationship with your emergency contact.') , 'error');
if (!$_POST['emergency_contact_phone']) wc_add_notice(__('Please list a phone number for your emergency contact.') , 'error');
if (!$_POST['medical_medicine']) wc_add_notice(__('Please list any medications or write in "none".') , 'error');
}
}
// Add emergency contact information to the database
add_action('woocommerce_checkout_update_order_meta', 'custom_checkout_fields_update_order_meta');
function custom_checkout_fields_update_order_meta($order_id) {
// Check to see if there is a class in the cart
$class_in_cart = is_conditional_product_in_cart( 'class' );
// There is a class in the cart so show additional fields
if ( $class_in_cart === true ) {
if (!empty($_POST['emergency_contact'])) {
update_post_meta($order_id, 'emergency_contact', sanitize_text_field($_POST['emergency_contact']));
}
if (!empty($_POST['emergency_contact_relationship'])) {
update_post_meta($order_id, 'emergency_contact_relationship', sanitize_text_field($_POST['emergency_contact_relationship']));
}
if (!empty($_POST['emergency_contact_phone'])) {
update_post_meta($order_id, 'emergency_contact_phone', sanitize_text_field($_POST['emergency_contact_phone']));
}
if (!empty($_POST['medical_medicine'])) {
update_post_meta($order_id, 'medical_medicine', sanitize_text_field($_POST['medical_medicine']));
}
}
}
// Add the emergency contact fields to order email
add_filter( 'woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys' );
function my_custom_checkout_field_order_meta_keys( $keys ) {
// Check to see if there is a class in the cart
$class_in_cart = is_conditional_product_in_cart( 'class' );
// There is a class in the cart so show additional fields
if ( $class_in_cart === true ) {
echo '<h2>Emergency Contact & Medical Information:</h2>';
$keys['Emergency Contact'] = 'emergency_contact';
$keys['Emergency Contact Relationship'] = 'emergency_contact_relationship';
$keys['Emergency Contact Phone'] = 'emergency_contact_phone';
$keys['Medical Conditions & Medications'] = 'medical_medicine';
return $keys;
} // end class in cart condition
}
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
// Add custom checkboxes to woocommerce checkout page for Photo Release, Mailing List & Release of Liability
// add_action( 'woocommerce_after_order_notes', 'custom_checkout_fields' );
add_action( 'woocommerce_review_order_before_submit', 'custom_checkout_fields' );
function custom_checkout_fields() {
echo '<div id="custom_checkout_fields">
<h3>Mailing Lists</h3>
<p>Mailing List boilerplate';
woocommerce_form_field( 'mailing_consent', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('Please add me to Nonprofit\'s electronic and paper mailing lists.'),
'required' => false,
'clear' => true,
'default' => 1 //This will pre-select the checkbox
), WC()->checkout->get_value( 'mailing_consent' ) );
// Check to see if there is a class in the cart
$class_in_cart = is_conditional_product_in_cart( 'class' );
// There is a class in the cart so show additional fields
if ( $class_in_cart === true ) {
echo '<h3>Photo Release</h3>
<p>Photo Release Boilerplate</p>';
woocommerce_form_field( 'photo_consent', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('I agree to the Photo Release as outlined above.'),
'required' => false,
'clear' => true,
'default' => 1 //This will pre-select the checkbox
), WC()->checkout->get_value( 'photo_consent' ) );
echo '<h3>Release of Liability</h3>
<p>Release of Liability Boilerplate</p>';
woocommerce_form_field( 'liability_release', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('I agree to the Photo Release as outlined above.'),
'required' => true,
'clear' => true,
'default' => 1 //This will pre-select the checkbox
), WC()->checkout->get_value( 'liability_release' ) );
} // end class in cart condition
echo '</div>';
}
// Show notice if customer doesn't check the Release of Liability checkbox
add_action( 'woocommerce_checkout_process', 'liability_release_not_given' );
function liability_release_not_given() {
// Check to see if there is a class in the cart
$class_in_cart = is_conditional_product_in_cart( 'class' );
// There is a class in the cart so show additional fields
if ( $class_in_cart === true ) {
if ( ! (int) isset( $_POST['liability_release'] ) ) {
wc_add_notice( __( 'You must agree to the Release of Liability to register for this class. Please contact us with any questions.' ), 'error' );
}
} // end class in cart condition
}
// Save the custom checkout field in the order meta, when checkbox has been checked
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta', 10, 1 );
function custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['mailing_consent'] ) )
update_post_meta( $order_id, 'mailing_consent', $_POST['mailing_consent'] );
if ( ! empty( $_POST['photo_consent'] ) )
update_post_meta( $order_id, 'photo_consent', $_POST['photo_consent'] );
if ( ! empty( $_POST['liability_release'] ) )
update_post_meta( $order_id, 'liability_release', $_POST['liability_release'] );
}
/*-----------------------------------------------------------------------------------------------------------------------------------------------*/
// Display custom field results on the order edit page (backend)
// for various liability fields
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_field_on_order_edit_pages', 10, 1 );
function display_custom_field_on_order_edit_pages( $order ){
$mailing_consent = get_post_meta( $order->get_id(), 'mailing_consent', true );
if( $mailing_consent == 1 )
echo '<p>' . $order->billing_first_name . ' ' . $order->billing_last_name . ' agreed to the be added to Nonprofit\'s mailing lists.</p>';
$photo_consent = get_post_meta( $order->get_id(), 'photo_consent', true );
if( $photo_consent == 1 )
echo '<p>' . $order->billing_first_name . ' ' . $order->billing_last_name . ' agreed to the Photo Release.</p>';
$liability_release = get_post_meta( $order->get_id(), 'liability_release', true );
if( $liability_release == 1 )
echo '<p>' . $order->billing_first_name . ' ' . $order->billing_last_name . ' agreed to the Release of Liability.</p>';
}
/**
* Check if Class is In cart
*
* https://wordimpress.com/create-conditional-checkout-fields-woocommerce/
* https://businessbloomer.com/woocommerce-check-product-category-cart/
*
* @param $product_id
*
* @return bool
*/
function is_conditional_product_in_cart( $category_name ) {
//Check to see if user has a class in their cart
global $woocommerce;
//flag no class in cart
$class_in_cart = false;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
// if ( $_product->cat === $category_id ) {
// //class is in cart!
//$class_in_cart = true;
if (has_term ( $category_name, 'product_cat', $_product->get_id() ) ) {
//class is in cart!
$class_in_cart = true;
}
}
return $class_in_cart;
}
As you can probably tell I pieced this together from various sources on the web and I realize it is a bit of a mess. Currently the conditional statement:
// Check to see if there is a class in the cart
$class_in_cart = is_conditional_product_in_cart( 'class' );
// There is a class in the cart so show additional fields
if ( $class_in_cart === true ) {
Is repeated for each function. I know this isn't efficient but I'm not sure how to fix it. What I would like to do is this:
- Test for products that are in the "class" category
- If "class" then run all the functions to display and process emergency contact fields and photo release and release of liability fields
- Display "join mailing list" agreement regardless of whether or not there is a "class" in the cart and process that field no matter what.
I tried just wrapping everything in another function but that broke the code. Maybe it would be best to move this into a plugin?
Thanks for any ideas and help you can give.