Making Custom Field Required WooCommerce - php

Please bear with me if I am not asking this question correctly. I am trying to modify a WooCommerce custom field to make it required.
The function is below:
public function delivery_checkout_field( $checkout )
{
echo '<div class="checkout-delivery" id="delivery_checkout_field">';
echo '<input class="js-picker-object" type="hidden" value="' . esc_attr( json_encode( $this->delivery_get_picker_object() ) ) . '" />';
echo '<h3 class="with-description">' . __( 'Delivery Schedule', 'gastro-core' ) . '</h3>';
echo '<p class="description">Enter your desired delivery time or leave blank, if you don\'t have one.</p>';
woocommerce_form_field( 'delivery_date', array(
'type' => 'text',
'class' => array( 'delivery-field form-row-first' ),
'label' => __( 'Delivery Date' ),
'placeholder' => __( 'Enter delivery date.' ),
), $checkout->get_value( 'delivery_date' ) );
woocommerce_form_field( 'delivery_time', array(
'type' => 'text',
'class' => array( 'delivery-field form-row-last' ),
'label' => __( 'Delivery Time' ),
'placeholder' => __( 'Enter delivery time.' ),
), $checkout->get_value( 'delivery_time' ) );
echo '</div>';
}
This section saves the fields.
// Save delivery data
public function delivery_checkout_field_update( $order_id )
{
if ( !empty( $_POST['delivery_date'] ) ) {
update_post_meta(
$order_id,
'Delivery Date',
sanitize_text_field( $_POST['delivery_date'] )
);
}
if ( !empty( $_POST['delivery_time'] ) ) {
update_post_meta(
$order_id,
'Delivery Time',
sanitize_text_field( $_POST['delivery_time'] )
);
}
}

For the required HTML5 attribute and other custom attributes woocommerce function has the custom_attributes option.
'custom_attributes' => array( 'required' => 'required' )

Related

Add and display multiple Custom Fields for Variations in WooCommerce

Based on Enhanced WooCommerce Custom Fields for Variations answer code for adding a custom field to a product variation which works.
I have added additional custom fields, 6 at all. When I update the product, the data does not save and does not display on the front end either.
What have I done incorrectly when adding the additional custom fields?
My code:
// Add a custom field to variation settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
function variation_settings_fields( $loop, $variation_data, $variation ) {
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_model[' . $variation->ID . ']',
'label' => __( 'model', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_model', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_wattage[' . $variation->ID . ']',
'label' => __( 'wattage', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_wattage', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_lumen[' . $variation->ID . ']',
'label' => __( 'lumen', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_lumen', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_material[' . $variation->ID . ']',
'label' => __( 'material', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_material', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_dimension[' . $variation->ID . ']',
'label' => __( 'dimension', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_dimension', true )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_year[' . $variation->ID . ']',
'label' => __( 'year', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_year', true )
)
);
}
// Save custom field value from variation settings
add_action( 'woocommerce_admin_process_variation_object', 'save_variation_settings_fields', 10, 2 );
function save_variation_settings_fields( $variation, $loop ) {
if( isset($_POST['_model'][$loop]) ) {
$variation->update_meta_data( '_model', sanitize_text_field($_POST['_model'][$loop]) );
}
if( isset($_POST['_wattage'][$loop]) ) {
$variation->update_meta_data( '_wattage', sanitize_text_field($_POST['_wattage'][$loop]) );
}
if( isset($_POST['_lumen'][$loop]) ) {
$variation->update_meta_data( '_lumen', sanitize_text_field($_POST['_lumen'][$loop]) );
}
if( isset($_POST['_material'][$loop]) ) {
$variation->update_meta_data( '_material', sanitize_text_field($_POST['_material'][$loop]) );
}
if( isset($_POST['_dimension'][$loop]) ) {
$variation->update_meta_data( '_dimension', sanitize_text_field($_POST['_dimension'][$loop]) );
}
if( isset($_POST['_year'][$loop]) ) {
$variation->update_meta_data( '_year', sanitize_text_field($_POST['_year'][$loop]) );
}
}
// Add variation custom field to single variable product form
add_filter( 'woocommerce_available_variation', 'add_variation_custom_field_to_variable_form', 10, 3 );
function add_variation_custom_field_to_variable_form( $variation_data, $product, $variation ) {
$variation_data['model'] = $variation->get_meta('_model');
$variation_data['wattage'] = $variation->get_meta('_wattage');
$variation_data['lumen'] = $variation->get_meta('_lumen');
$variation_data['material'] = $variation->get_meta('_material');
$variation_data['dimension'] = $variation->get_meta('_dimension');
$variation_data['year'] = $variation->get_meta('_year');
return $variation_data;
}
add_action( 'woocommerce_product_additional_information', 'add_html_container_to_display_selected_variation_custom_field' );
function add_html_container_to_display_selected_variation_custom_field( $product ){
echo '<div class="custom_variation-text-field"></div>';
}
// Display selected variation custom field value to product the tab
add_action( 'woocommerce_after_variations_form', 'display_selected_variation_custom_field_js' );
function display_selected_variation_custom_field_js(){
?>
<script type="text/javascript">
(function($){
$('form.cart').on('show_variation', function(event, data) {
$('.custom_variation-text-field').text(data.text_field);
}).on('hide_variation', function(event) {
$('.custom_variation-text-field').text('');
});
})(jQuery);
</script>
<?php
}
To make it save the data, I have made some changes in the 1st function (2nd one stay unchanged):
// Add a custom field to variation settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
function variation_settings_fields( $loop, $variation_data, $variation ) {
woocommerce_wp_text_input( array(
'id' => '_model[' . $loop . ']',
'label' => __( 'model', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_model', true )
) );
woocommerce_wp_text_input(
array(
'id' => '_wattage[' . $loop . ']',
'label' => __( 'wattage', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_wattage', true )
) );
woocommerce_wp_text_input( array(
'id' => '_lumen[' . $loop . ']',
'label' => __( 'lumen', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_lumen', true )
) );
woocommerce_wp_text_input( array(
'id' => '_material[' . $loop . ']',
'label' => __( 'material', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_material', true )
) );
woocommerce_wp_text_input( array(
'id' => '_dimension[' . $loop . ']',
'label' => __( 'dimension', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'This is the description text...', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_dimension', true )
) );
woocommerce_wp_text_input( array(
'id' => '_year[' . $loop . ']',
'label' => __( 'year', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_year', true )
) );
}
// Save custom field value from variation settings
add_action( 'woocommerce_admin_process_variation_object', 'save_variation_settings_fields', 10, 2 );
function save_variation_settings_fields( $variation, $loop ) {
if( isset($_POST['_model'][$loop]) ) {
$variation->update_meta_data( '_model', sanitize_text_field($_POST['_model'][$loop]) );
}
if( isset($_POST['_wattage'][$loop]) ) {
$variation->update_meta_data( '_wattage', sanitize_text_field($_POST['_wattage'][$loop]) );
}
if( isset($_POST['_lumen'][$loop]) ) {
$variation->update_meta_data( '_lumen', sanitize_text_field($_POST['_lumen'][$loop]) );
}
if( isset($_POST['_material'][$loop]) ) {
$variation->update_meta_data( '_material', sanitize_text_field($_POST['_material'][$loop]) );
}
if( isset($_POST['_dimension'][$loop]) ) {
$variation->update_meta_data( '_dimension', sanitize_text_field($_POST['_dimension'][$loop]) );
}
if( isset($_POST['_year'][$loop]) ) {
$variation->update_meta_data( '_year', sanitize_text_field($_POST['_year'][$loop]) );
}
}
It should better work to custom fields data to database and display the saved values in admin.
Now the frontend display part is wrong (your last 2 functions).
You need first to think about how you want to display that multiple custom fields, how should be the html structure and the labels related to each custom field. So edit your question as I can't guess that for you.
Here is a working example with all your custom fields, to display the data in frontend single product pages, for the selected variation:
// Add variation custom field to single variable product form
add_filter( 'woocommerce_available_variation', 'add_variation_custom_field_to_variable_form', 10, 3 );
function add_variation_custom_field_to_variable_form( $variation_data, $product, $variation ) {
$variation_data['model'] = $variation->get_meta('_model');
$variation_data['wattage'] = $variation->get_meta('_wattage');
$variation_data['lumen'] = $variation->get_meta('_lumen');
$variation_data['material'] = $variation->get_meta('_material');
$variation_data['dimension'] = $variation->get_meta('_dimension');
$variation_data['year'] = $variation->get_meta('_year');
return $variation_data;
}
add_action( 'woocommerce_product_additional_information', 'add_html_container_to_display_selected_variation_custom_field' );
function add_html_container_to_display_selected_variation_custom_field( $product ){
echo '<div class="custom_variation-text-field">aaa</div>';
}
// Display selected variation custom field value to product the tab
add_action( 'woocommerce_after_variations_form', 'display_selected_variation_custom_field_js' );
function display_selected_variation_custom_field_js(){
?>
<script type="text/javascript">
(function($){
var a = '.custom_variation-text-field', b = $(a).html();
$('form.cart').on('show_variation', function(event, data) {
outputHtml = '';
if( data.model ) {
outputHtml += '<span><strong><?php _e("Model"); ?><strong>: '+data.model+'<span><br>';
}
if( data.wattage ) {
outputHtml += '<span><strong><?php _e("Wattage"); ?><strong>: '+data.wattage+'<span><br>';
}
if( data.lumen ) {
outputHtml += '<span><strong><?php _e("Lumen"); ?><strong>: '+data.lumen+'<span><br>';
}
if( data.material ) {
outputHtml += '<span><strong><?php _e("Material"); ?><strong>: '+data.material+'<span><br>';
}
if( data.dimension ) {
outputHtml += '<span><strong><?php _e("Dimension"); ?><strong>: '+data.dimension+'<span><br>';
}
if( data.year ) {
outputHtml += '<span><strong><?php _e("Year"); ?><strong>: '+data.year+'<span>';
}
if( outputHtml ) {
$(a).html(outputHtml);
}
}).on('hide_variation', function(event) {
$(a).html(b);
});
})(jQuery);
</script>
<?php
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

WooCommerce: Display custom checkout fields if specific product IDs are in cart

I am running an online-store selling grills. Only the grills are shipped via a specific carrier where additional informations are needed.
I managed to display a dropdown when a certain product_ID is in the cart. When a specific value is selected a text-area is displayed.
This should happen for about 10 products, not just one.
After reading a number of threads and searching the web, i cant figure out, how to add more than one product_ID.
add_action( 'woocommerce_after_order_notes', 'grills_versandauswahl_checkout_field' );
function grills_versandauswahl_checkout_field( $checkout ) {
$grill_in_cart = grills_is_conditional_product_in_cart ( 125 );
if ( $grill_in_cart === true ) {
echo '<div id="my_custom_checkout_field"><h3>' . __( 'Versandoptionen' ) . '</h3><p style="margin: 0 0 8px;">text</p>';
woocommerce_form_field( 'versandoption', array(
'type' => 'select',
'class' => array( 'wps-drop' ),
'label' => __( 'Versandoptionen' ),
'required' => true,
'options' => array(
'blank' => __( 'Auswählen', 'wps' ),
'fixtermin' => __( 'Fixtermin', 'wps' ),
'avis' => __( 'Telefonisches Avis', 'wps' ),
)
), $checkout->get_value( 'versandoption' ) );
woocommerce_form_field( 'inscription_textbox', array(
'type' => 'textarea',
'class' => array( 'inscription-text form-row-wide' ),
'label' => __( 'Wunschtermin / Ablageort' ),
), $checkout->get_value( 'inscription_textbox' ) );
echo '</div>';
}
}
function grills_is_conditional_product_in_cart( $product_id ) {
//Check to see if user has product in cart
global $woocommerce;
//flag no book in cart
$grill_in_cart = false;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id === $product_id ) {
//book is in cart!
$grill_in_cart = true;
}
}
return $grill_in_cart;
}
To make your conditional function work for many product Ids use the following:
// Custom conditional function
function grills_in_cart( $product_ids ) {
foreach ( WC()->cart->get_cart() as $item ) {
if ( array_intersect($product_ids, array( $item['product_id'], $item['variation_id']) ) ) {
return true;
}
}
return false;
}
// Conditionally display custom checkout fields for specific product IDS
add_action( 'woocommerce_after_order_notes', 'grills_versandauswahl_checkout_field' );
function grills_versandauswahl_checkout_field( $checkout ) {
// Here define the targeted product IDs in this array
$targeted_ids = array( 125, 132, 154 );
$text_domain = 'woocommerce';
if ( grills_in_cart( $targeted_ids ) ) {
echo '<div id="my_custom_checkout_field">
<h3>' . __( "Versandoptionen", $text_domain ) . '</h3>
<p style="margin: 0 0 8px;">' . __( "text", $text_domain ) . '</p>';
woocommerce_form_field( 'versandoption', array(
'type' => 'select',
'class' => array('wps-drop'),
'label' => __( "Versandoptionen", $text_domain ),
'required' => true,
'options' => array(
'blank' => __( "Auswählen", $text_domain ),
'fixtermin' => __( "Fixtermin", $text_domain ),
'avis' => __( "Telefonisches Avis", $text_domain ),
),
), $checkout->get_value( 'versandoption' ) );
woocommerce_form_field( 'inscription_textbox', array(
'type' => 'textarea',
'class' => array( 'inscription-text form-row-wide' ),
'label' => __( 'Wunschtermin / Ablageort', $text_domain ),
), $checkout->get_value( 'inscription_textbox' ) );
echo '</div>';
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Note: $global $woocommerce; + $woocommerce->cart has been replaced by WC()->cart

How to set up Custom Fields in the Product Variations interface for WooCommerce

The WordPress plugin WooCommerce supports Custom Fields.
Custom Fields can be toggled under Screen Options:
However, these Custom Fields do no get segregated for product variations. There is only one set of Custom Fields that applies to all product variations in the WooCommerce interface, and this is inappropriate because different product variations may have different product MPNs, for example, which is one of the Custom Fields I have set up for myself.
The closest off-site solution I found does not link up to custom fields. The code, shown below, shows how one can set up input fields in the Product Variations interface. How can I modify the solution below to link up the Product Variations interface the custom fields?
This question is distinct from questions concerned with Advanced Custom Fields, as I am not using that plugin. Furthermore, at least one other similar question on Stack Overflow but I'm not proficient with PHP and I don't comprehend it, nor do I know if it is relevant - but I will point out that solution has not been accepted by the OP and I don't want to necropost there.
/**
* Create new fields for variations
*
*/
function variation_settings_fields( $loop, $variation_data, $variation ) {
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_ean_code[' . $variation->ID . ']',
'label' => __( 'EAN-CODE', 'woocommerce' ),
'placeholder' => 'EAN-CODE',
'desc_tip' => 'true',
'description' => __( 'Enter your custom EAN code.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_ean_code', true )
)
);
woocommerce_wp_text_input(
array(
'id' => '_stock_amsterdam[' . $variation->ID . ']',
'label' => __( 'Nr. of Stock in Amsterdam', 'woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Enter nr. of Stock in Amsterdam', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_stock_amsterdam', true ),
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
woocommerce_wp_text_input(
array(
'id' => '_stock_den_bosch[' . $variation->ID . ']',
'label' => __( 'Nr. of Stock in Den Bosch', 'woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Enter nr. of Stock in Den Bosch', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_stock_den_bosch', true ),
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
woocommerce_wp_text_input(
array(
'id' => '_stock_alkmaar[' . $variation->ID . ']',
'label' => __( 'Nr. of Stock in Alkmaar', 'woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Enter nr. of Stock in Alkmaar', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_stock_alkmaar', true ),
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
}
/**
* Save new fields for variations
*
*/
function save_variation_settings_fields( $post_id ) {
// Text Field
$text_field = $_POST['_ean_code'][ $post_id ];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, '_ean_code', esc_attr( $text_field ) );
}
$number_field = $_POST['_stock_amsterdam'][ $post_id ];
if( ! empty( $number_field ) ) {
update_post_meta( $post_id, '_stock_amsterdam', esc_attr( $number_field ) );
}
$number_field = $_POST['_stock_den_bosch'][ $post_id ];
if( ! empty( $number_field ) ) {
update_post_meta( $post_id, '_stock_den_bosch', esc_attr( $number_field ) );
}
$number_field = $_POST['_stock_alkmaar'][ $post_id ];
if( ! empty( $number_field ) ) {
update_post_meta( $post_id, '_stock_alkmaar', esc_attr( $number_field ) );
}
}
// Save Variation Settings
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
// Add Variation Settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );

Hide Custom Checkout Fields on WooCommerce Based on User Role

I've created a user role of CSR and several custom checkout fields to appear on the Checkout page of WooCommerce, and I want to hide these checkout fields from any other user but those with the CSR role.
I've created the fields and the role, but something is off with my fields as they're still showing up for all users. I followed the tutorial here to hide the fields. Apologies if the formatting of the code is off. The editor didn't accept most of my formatting when I pulled it in from Atom.
ADD CUSTOM FIELDS
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div class="my_custom_checkout_field"><h2>' . __('CSR Information')
.'</h2>';
woocommerce_form_field( 'date_of_purchase', array(
'type' => 'text',
'label' => __('Date of Purchase', 'woocommerce'),
'placeholder' => _x('MM/DD/YYYY', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
), $checkout->get_value( 'date_of_purchase' ));
woocommerce_form_field( 'place_of_purchase', array(
'type' => 'select',
'label' => __('Place of Purchase', 'woocommerce'),
'placeholder' => _x('Select Option', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
'options' => array('option-1' => 'Option 1', 'option_2' => 'Option 2',
'option_3' => 'Option 3'),
), $checkout->get_value( 'place_of_purchase' ));
woocommerce_form_field( 'color_item', array(
'type' => 'select',
'label' => __('Product Color', 'woocommerce'),
'placeholder' => _x('Select Option', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
'options' => array('option-1' => 'Option 1', 'option_2' => 'Option 2',
'option_3' => 'Option 3'),
), $checkout->get_value( 'color_item' ));
woocommerce_form_field( 'product_model', array(
'type' => 'select',
'label' => __('Model', 'woocommerce'),
'placeholder' => _x('Select Option', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
'options' => array('option-1' => 'Option 1', 'option_2' => 'Option 2',
'option_3' => 'Option 3'),
), $checkout->get_value( 'product_model' ));
echo '<strong>' . __('Check All That Apply:') .'</strong>';
woocommerce_form_field( 'lightbulb_out', array(
'type' => 'checkbox',
'class' => array('checkbox_field'),
'label' => __('Lightbulb is Out'),
'required' => false,
), $checkout->get_value( 'lightbulb_out' ));
woocommerce_form_field( 'not_turn_on', array(
'type' => 'checkbox',
'class' => array('checkbox_field'),
'label' => __('Will Not Turn On'),
'required' => false,
), $checkout->get_value( 'not_turn_on' ));
woocommerce_form_field( 'fan_not_running', array(
'type' => 'checkbox',
'class' => array('checkbox_field'),
'label' => __('Fan Stopped Running'),
'required' => false,
), $checkout->get_value( 'fan_not_running' ));
woocommerce_form_field( 'strange_noise', array(
'type' => 'checkbox',
'class' => array('checkbox_field'),
'label' => __('Strange Noise'),
'required' => false,
), $checkout->get_value( 'strange_noise' ));
woocommerce_form_field( 'not_catching', array(
'type' => 'checkbox',
'class' => array('checkbox_field'),
'label' => __('Not Catching Insects'),
'required' => false,
), $checkout->get_value( 'not_catching' ));
woocommerce_form_field( 'csr_other', array(
'type' => 'checkbox',
'class' => array('checkbox_field'),
'label' => __('Other'),
'required' => false,
), $checkout->get_value( 'csr_other' ));
woocommerce_form_field( 'case_description', array(
'type' => 'textarea',
'label' => __('Description of Case', 'woocommerce'),
'placeholder' => _x('Please provide details', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
), $checkout->get_value( 'case_description' ));
echo '</div>';
}
ADD CSR ROLE
$result = add_role( 'csr', __('CSR' ),
array(
'read' => true, // true allows this capability
'edit_posts' => false, // Denies user to edit their own posts
'edit_pages' => false, // Denies user to edit pages
'edit_others_posts' => false, // Denies user to edit others posts not just
their own
'create_posts' => false, // Denies user to create new posts
'manage_categories' => false, // Denies user to manage post categories
'publish_posts' => false, // Denies the user to publish, otherwise posts stays
in draft mode
'edit_themes' => false, // false denies this capability. User can’t edit your
theme
'install_plugins' => false, // User cant add new plugins
'update_plugin' => false, // User can’t update any plugins
'update_core' => false // user cant perform core updates
)
);
HIDE CSR VALUES FOR ALL BUT CSR
function custom_override_checkout_fields( $fields ) {
if ( ! current_user_can( 'csr' ) && isset( $fields['date_of_purchase'] ) ) {
unset( $fields[['date_of_purchase']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['place_of_purchase'] ) ) {
unset( $fields[['place_of_purchase']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['color_item'] ) ) {
unset( $fields[['color_item']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['product_model'] ) ) {
unset( $fields[['product_model']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['lightbulb_out'] ) ) {
unset( $fields[['lightbulb_out']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['not_turn_on'] ) ) {
unset( $fields[['not_turn_on']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['fan_not_running'] ) ) {
unset( $fields[['fan_not_running']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['strange_noise'] ) ) {
unset( $fields[['strange_noise']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['not_catching'] ) ) {
unset( $fields[['not_catching']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['csr_other'] ) ) {
unset( $fields[['csr_other']] );
}
if ( ! current_user_can( 'csr' ) && isset( $fields['case_description'] ) ) {
unset( $fields[['case_description']] );
}
return $fields;
}
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields'
);
I've expanded on the code I posted in my tutorial on how to customize the WooCommerce Checkout.
First you need to register the new checkout fields. This is where I've added a current_user_can() to test if the current user has the appropriate capabilities to see these extra fields. You can probably use current_user_can( 'csr' ) or even better add something like a manage_csr capability to the csr role. I'm using the manage_options capability because it was easier for me to test.
// Add new checkout fields
function kia_filter_checkout_fields( $fields ){
if( current_user_can( 'manage_options' ) ) {
$fields['extra_fields'] = array(
'date_of_purchase' => array(
'type' => 'text',
'label' => __( 'Date of Purchase', 'your-plugin' ),
'placeholder' => _x ('MM/DD/YYYY', 'placeholder', 'your-plugin' ),
'required' => false,
'class' => array( 'form-row-wide' ),
'clear' => true
),
'place_of_purchase' => array(
'type' => 'select',
'label' => __( 'Place of Purchase', 'your-plugin' ),
'placeholder' => _x( 'Select Option', 'placeholder', 'your-plugin' ),
'required' => false,
'class' => array('form-row-wide' ),
'clear' => true,
'options' => array('option-1' => __( 'Option 1', 'your-plugin' ), 'option_2' => __( 'Option 2', 'your-plugin' ), 'option_3' => __( 'Option 3', 'your-plugin' ) )
),
'color_item' => array(
'type' => 'select',
'label' => __( 'Product Color', 'your-plugin' ),
'placeholder' => _x( 'Select Option', 'placeholder', 'your-plugin' ),
'required' => false,
'class' => array( 'form-row-wide' ),
'clear' => true,
'options' => array( 'option-1' => __( 'Option 1', 'your-plugin' ), 'option_2' => __( 'Option 2', 'your-plugin' ), 'option_3' => __( 'Option 3', 'your-plugin' ) )
),
'product_model' => array(
'type' => 'select',
'label' => __( 'Model', 'your-plugin' ),
'placeholder' => _x('Select Option', 'placeholder', 'your-plugin' ),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
'options' => array( 'option-1' => __( 'Option 1', 'your-plugin' ), 'option_2' => __( 'Option 2', 'your-plugin' ), 'option_3' => __( 'Option 3', 'your-plugin' ) )
),
'product_condition' => array(
'type' => 'multicheck',
'label' => __( 'Product Condition:', 'your-plugin' ),
'description' => __( 'Check All That Apply:', 'your-plugin' ),
'required' => false,
'clear' => true,
'options' => array( 'lightbulb_out' => __( 'Lightbulb is Out', 'your-plugin' ),
'not_turn_on' => __( 'Will Not Turn On', 'your-plugin' ),
'fan_not_running' => __( 'Fan Stopped Running', 'your-plugin' ),
'strange_noise' => __( 'Strange Noise', 'your-plugin' ),
'not_catching' => __( 'Not Catching Insectsn', 'your-plugin' ),
'csr_other' => __( 'Other', 'your-plugin' ),
),
),
'case_description' => array(
'type' => 'textarea',
'label' => __( 'Description of Case', 'your-plugin' ),
'placeholder' => _x( 'Please provide details', 'placeholder', 'your-plugin' ),
'required' => false,
'class' => array( 'form-row-wide' ),
'clear' => true,
),
);
}
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'kia_filter_checkout_fields' );
You will note that I've done something different with your "Fan Stopped", etc checkboxes. You don't have to do this, but I was curious and procrastinating. WooCommerce doesn't support a multi-check set of checkboxes, but it does support defining your own custom field types. So with the following we create a new type of form field:
function kia_multicheck_form_field( $field, $key, $args, $value ){
$field_html = '<fieldset>';
if( isset( $args['label'] ) ){
$field_html .= '<legend>' . $args['label'] . '</legend>';
}
if ( ! empty( $args['options'] ) ) {
foreach ( $args['options'] as $option_key => $option_text ) {
$field_html .= '<input type="checkbox" class="input-multicheck ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" value="' . esc_attr( $option_key ) . '" name="' . esc_attr( $key ) . '[]" id="' . esc_attr( $args['id'] ) . '_' . esc_attr( $option_key ) . '"' . checked( $value, $option_key, false ) . ' />';
$field_html .= '<label for="' . esc_attr( $args['id'] ) . '_' . esc_attr( $option_key ) . '" class="multicheck ' . implode( ' ', $args['label_class'] ) . '">' . $option_text . '</label>';
}
}
if ( $args['description'] ) {
$field_html .= '<span class="description">' . esc_html( $args['description'] ) . '</span>';
}
$field_html .= '</fieldset>';
$container_class = esc_attr( implode( ' ', $args['class'] ) );
$container_id = esc_attr( $args['id'] ) . '_field';
$after = ! empty( $args['clear'] ) ? '<div class="clear"></div>' : '';
$field_container = '<p class="form-row %1$s" id="%2$s" data-sort="' . esc_attr( $sort ) . '">%3$s</p>';
$field = sprintf( $field_container, $container_class, $container_id, $field_html ) . $after;
return $field;
}
add_filter( 'woocommerce_form_field_multicheck', 'kia_multicheck_form_field', 10, 4 );
Next we display the new fields on the checkout page.... but only if they exist, because harkening back to the first code block, they won't be in the checkout fields array if the user doesn't have the right permissions.
// display the extra field on the checkout form
function kia_extra_checkout_fields(){
$checkout = WC()->checkout();
if( isset( $checkout->checkout_fields['extra_fields'] ) ) { ?>
<div class="extra-fields">
<h3><?php _e( 'CSR Information' ); ?></h3>
<?php
// because of this foreach, everything added to the array in the previous function will display automagically
foreach ( $checkout->checkout_fields['extra_fields'] as $key => $field ) :
woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
endforeach; ?>
</div>
<?php }
}
add_action( 'woocommerce_checkout_after_customer_details' ,'kia_extra_checkout_fields' );
Now you'll probably need to add some CSS to make this look better, and you need a way to save the multicheck data. You can review my tutorial on how to save the rest, and perhaps figure out the multicheck on your own.

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

Categories