Skip to content

Instantly share code, notes, and snippets.

@RichardNesbitt
Created December 29, 2019 05:36
Show Gist options
  • Save RichardNesbitt/82a90cdc859a765ca0c1882287281f84 to your computer and use it in GitHub Desktop.
Save RichardNesbitt/82a90cdc859a765ca0c1882287281f84 to your computer and use it in GitHub Desktop.
Example of some custom validation rules for woocommerce checkout page. Forcing names to match account holder, custom rules based on shipping classes and shipping locations.
<?php
## add this to /wp-content/[your-theme]/woocommerce/checkout ##
/**
* Checkout Form
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/form-checkout.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates
* @version 3.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
//get list of products in the cart
global $woocommerce;
$items = $woocommerce->cart->get_cart();
//get logged in user name
$current_user = wp_get_current_user();
?>
<script>
//set vars to hold user name
var user_fname = '<?php echo $current_user->first_name; ?>';
var user_lname = '<?php echo $current_user->last_name; ?>';
//push all shipping classes into an array
var shipping_classes = [];
<?php foreach( $items as $item) { ?>
shipping_classes.push("<?php echo $item['data']->get_shipping_class(); ?>");
<?php } ?>
</script>
<!-- container for custom error messages -->
<div id="customAlert" class="woocommerce-error alert alert_error" role="alert" style="display:none;">
<div class="alert_icon"><i class="icon-alert"></i></div>
<div class="alert_wrapper"></div>
</div>
<?php
do_action( 'woocommerce_before_checkout_form', $checkout );
// If checkout registration is disabled and not logged in, the user cannot checkout.
if ( ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in() ) {
echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'woocommerce' ) ) );
return;
}
?>
<form name="checkout" method="post" class="checkout woocommerce-checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
<?php if ( $checkout->get_checkout_fields() ) : ?>
<?php do_action( 'woocommerce_checkout_before_customer_details' ); ?>
<div class="col2-set" id="customer_details">
<div class="col-1">
<?php do_action( 'woocommerce_checkout_billing' ); ?>
</div>
<div class="col-2">
<?php do_action( 'woocommerce_checkout_shipping' ); ?>
</div>
</div>
<?php do_action( 'woocommerce_checkout_after_customer_details' ); ?>
<?php endif; ?>
<?php do_action( 'woocommerce_checkout_before_order_review_heading' ); ?>
<h3 id="order_review_heading"><?php esc_html_e( 'Your order', 'woocommerce' ); ?></h3>
<?php do_action( 'woocommerce_checkout_before_order_review' ); ?>
<div id="order_review" class="woocommerce-checkout-review-order">
<?php do_action( 'woocommerce_checkout_order_review' ); ?>
</div>
<?php do_action( 'woocommerce_checkout_after_order_review' ); ?>
</form>
<?php do_action( 'woocommerce_after_checkout_form', $checkout ); ?>
<script>
//create rules to match city or state, as well as the prohibited shipping class for that location
//add as many as you like. This currently only works for city/state vs shipping class
var rules = [
{'param':'State','value':'WA','Class':'shipping-class-slug'},
{'param':'City','value':'San Francisco','Class':'shipping-class-slug'}
];
//when any field changes
jQuery('input').blur( function(){
//reset variables
var passing = true;
var box_checked = false;
//is the shipping box checked?
if( jQuery('#ship-to-different-address-checkbox').prop("checked") ) {
box_checked = true;
}
//process each rule
rules.forEach( function(rule){
//location to check
var check1 = rule['value'];
//console.log(check1);
var check2 = '';
//get the entered location
if( rule['param'] == 'State' ) {
if( box_checked ) {
check2 = jQuery('#shipping_state').val();
console.log(check2);
} else {
check2 = jQuery('#billing_state').val();
console.log(check2);
}
} else if ( rule['param'] == 'City' ) {
if( box_checked ) {
check2 = jQuery('#shipping_city').val();
console.log(check2);
} else {
check2 = jQuery('#billing_city').val();
console.log(check2);
}
}
//fail if the rule is matched
if( check1 == check2 && shipping_classes.indexOf(rule['Class']) !== -1 ){
passing = false;
//console.log(rule['Class']);
}
});
if( !passing ){
//disable the shipping button if rule matched
jQuery('#place_order').prop('disabled', true);
//display an error message and scroll up to it.
jQuery('#customAlert').show();
jQuery('#customAlert .alert_wrapper').html('We are unable to ship one more items due to city/state laws where you are. Please review your purchase and try again.').focus();
jQuery([document.documentElement, document.body]).animate({
scrollTop: jQuery("#customAlert").offset().top - 200
}, 1000);
} else {
//turn the shipping button back on if no rules matched
jQuery('#place_order').prop('disabled', false);
//hide the error block
jQuery('#customAlert').hide();
}
});
//force billing & shipping names to match account holder name
jQuery(document).ready(function() {
jQuery('#billing_first_name').val(user_fname).attr('disabled', true);
jQuery('#shipping_first_name').val(user_fname).attr('disabled', true);
jQuery('#billing_last_name').val(user_lname).attr('disabled', true);
jQuery('#shipping_last_name').val(user_lname).attr('disabled', true);
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment