Skip to content

Instantly share code, notes, and snippets.

@pixeldevsio
Last active February 22, 2020 01:31
Show Gist options
  • Save pixeldevsio/44670f6e1c66842243c6a6c37f51d06f to your computer and use it in GitHub Desktop.
Save pixeldevsio/44670f6e1c66842243c6a6c37f51d06f to your computer and use it in GitHub Desktop.
<?php
/**
* Add Phone field to Shipping on checkout page
* Validation automatically happens since we set it via WooCommerce Hook
*/
add_filter( 'woocommerce_checkout_fields', 'custom_override_default_address_fields' );
function custom_override_default_address_fields($fields){
// Get access to WooCommerce and grab the current billing and shipping countries on page load.
global $woocommerce;
$billingCountryCode = $woocommerce->customer->get_billing_country();
$shippingCountryCode = $woocommerce->customer->get_shipping_country();
// add our shipping phone
$fields['shipping']['shipping_phone'] = array(
'label' => 'Phone',
'required' => false,
'class' => array( 'form-row-wide', 'shipping-phone' ),
'priority' => 90,
);
// check countries on page load to determine if phone should be required or not
if($billingCountryCode !== 'US' || $shippingCountryCode !== 'US'){
$fields['shipping']['shipping_phone']['required'] = true;
}
return $fields;
}
/**
* Add javascript to require shipping phone field if country is not US
*/
add_action( 'woocommerce_after_checkout_form', 'pd_show_notice_shipping' );
function pd_show_notice_shipping(){
?>
<script>
jQuery(document).ready(function($){
var countryCode = 'US';
// Set up Shipping function
function setShippingPhoneBasedOnShippingCountry(shippingCountry, countryCode){
if( shippingCountry != countryCode ){
// .shipping-phone is the entire wrapper
if(!$('.shipping-phone label .required').length){
$('.shipping-phone').addClass('validate-required');
$('.shipping-phone label .optional').remove();
$('.shipping-phone label').append('<abbr class="required" title="required">*</abbr>');
}
// #shipping_phone is the input field
$('#shipping_phone').prop('required',true);
}
// if selected country is US
else {
// .shipping-phone is the entire wrapper
if(!$('.shipping-phone label .optional').length){
$('.shipping-phone').removeClass('validate-required');
$('.shipping-phone label .required').remove();
$('.shipping-phone label').append('<span class="optional">(optional)</span>');
}
// #shipping_phone is the input field
$('#shipping_phone').prop('required',false);
}
}
// Set up Billing function
function setShippingPhoneBasedOnBillingCountry(shippingCountry, countryCode){
if( shippingCountry != countryCode ){
// .shipping-phone is the entire wrapper
if(!$('.shipping-phone label .required').length){
$('.shipping-phone').addClass('validate-required');
$('.shipping-phone label .optional').remove();
$('.shipping-phone label').append('<abbr class="required" title="required">*</abbr>');
}
// #shipping_phone is the input field
$('#shipping_phone').prop('required',true);
}
// if selected country is US
else {
// .shipping-phone is the entire wrapper
if(!$('.shipping-phone label .optional').length){
$('.shipping-phone').removeClass('validate-required');
$('.shipping-phone label .required').remove();
$('.shipping-phone label').append('<span class="optional">(optional)</span>');
}
// #shipping_phone is the input field
$('#shipping_phone').prop('required',false);
}
}
// Set the country code to US for validation
// Trigger off of document change due to being able to hide / show shipping fields when "Ship to a different address?" is selected
$(document).on('change', '.country_select', function(){
// no var or let needed as it's local to this function
billingCountry = $('#billing_country').val();
shippingCountry = $('#shipping_country').val();
shippingDifferent = $('#ship-to-different-address-checkbox');
// if shipping is different? is selected
if($(shippingDifferent).is(':checked')){
// if selected shipping country is not US
setShippingPhoneBasedOnShippingCountry(shippingCountry, countryCode);
} else {
// Even though shipping fields are hidden at this point, we still need to require phone field to be required. WooCommerce just hides the fields, doesnt remove them from the DOM. Tricky, I know.
setShippingPhoneBasedOnBillingCountry(billingCountry, countryCode);
}
});
// revert the shipping phone requirement based on the billing if the "shipping to different?" checkbox is unchecked. Else, use shipping country
$(document).on('click', '#ship-to-different-address-checkbox', function(){
billingCountry = $('#billing_country').val();
shippingCountry = $('#shipping_country').val();
if(!$(this).is(':checked')){
setShippingPhoneBasedOnBillingCountry(billingCountry, countryCode);
} else {
setShippingPhoneBasedOnShippingCountry(shippingCountry, countryCode);
}
});
});
</script>
<?php
}
/**
* Display phone field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'pd_custom_checkout_field_display_admin_order_meta', 10, 1 );
function pd_custom_checkout_field_display_admin_order_meta($order){
echo '<p class="form-field"><strong>'.__('Shipping Phone').':</strong> ' . get_post_meta( $order->get_id(), '_shipping_phone', true ) . '</p>';
}
/**
* Display phone field in emails
*/
add_filter('woocommerce_email_order_meta_keys', 'pd_custom_order_meta_keys');
function pd_custom_order_meta_keys( $keys ) {
$keys[] = 'Shipping Phone'; // This will look for a custom field called 'Shipping Phone' and add it to emails
return $keys;
}
/**
* Display phone field on user profile
*/
add_filter( 'woocommerce_customer_meta_fields', 'filter_add_customer_meta_fields', 10, 1 );
function filter_add_customer_meta_fields( $args ) {
$args['shipping']['fields']['shipping_phone'] = array(
'label' => __( 'Shipping Phone', 'woocommerce' ),
'description' => '',
);
return $args;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment