WooCommerce default to free shipping or legacy free shipping

Recent WooCommerce updates (starting with 2.6.0) introduced the concept of shipping zones.  You have the option to configure Shipping Zones, which will provide the standard selections like Flat Rate, Free Shipping and Local Pickup.  

In the meantime however, the existing shipping methods will be renamed with a legacy "legacy_" prefix and that can cause some of the shipping customizations to no longer work. One of those is the snippet provided by WooCommerce used to hide all other shipping methods when free shipping is available. The code relies on the shipping method using method_id of free_shipping and no longer works since the method_id has changed to legacy_free_shipping.

To support the legacy_free_shipping shipping method but also be ready for when your regions are configured you can use the following modified code (This needs to be added/replaced in functions.php).

function my_hide_shipping_when_free_is_available( $rates ) {
    $free = array();
    $legacyFree = array();
    foreach ( $rates as $rate_id => $rate ) {
        if ( 'free_shipping' === $rate->method_id ) {
            $free[ $rate_id ] = $rate;
        if ( 'legacy_free_shipping' === $rate->method_id ) {
            $legacyFree[ $rate_id ] = $rate;
    return ! empty( $free ) ? $free : (!empty($legacyFree) ? $legacyFree : $rates);
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_when_free_is_available', 100 );        

The original code is here:

Ajax calls in WordPress

Adding Ajax functionality to your theme or plugin code can be a bit challenging. I will distill the many articles, tips and forums i’ve read on how to do this and provide straightforward workflow you can use.

The consensus is that the safest way to handle ajax calls in wordpress is through the use of the built-in capability provided by admin-ajax.php and so that is how we will proceed.

The sequence of steps that have to occur are as follows.

1. Register, enqueue and localize a javascript file.

This one may seem confusing but localizing in this case is simply a way of injecting the info we will need on client side.  This .js file can be empty but has to exist.

wp_enqueue_script( 'my-ajax', get_stylesheet_directory_uri().'/assets/js/ajax.js');

wp_localize_script( 'my-ajax', 
                        'ajaxurl' => admin_url( 'admin-ajax.php' ),
                        'nonce' => wp_create_nonce( 'my-ajax-nonce' ),

In the example above MyAjaxObject is how you will get the ajaxurl and the nonce in your javascript code. For example:

alert(MyAjaxObject.ajaxurl); // Display ajaxurl value
alert(MyAjaxObject.nonce); // Display the nonce

2. Create a php class to hold data for all your ajax calls.

This is not absolutely necessary but will make it easier to maintain a common pattern across all of your ajax code.

Create a new php file to hold the class, for example my_ajax_response_class.php

class MyAjaxResponse {

public $message;
public $html;
public $exception;


You add any variables you feel you might need to use i prefer the above.

Note: you do not need a success indicator in this class, that will be automatically provided by wordpress’ wp_send_json_success and wp_send_json_error methods.

3. Create and register the php function to handle the call and respond.

Here you will create a function and register it either inside of functions.php file or any other php file you import in functions.php.

The function will accept any incoming parameters, perform some operations and return a JSON formatted response

    function monday_fail() {
        $resp = new MyAjaxResponse();

        if(!wp_verify_nonce($nonce, 'my-ajax-nonce')) {

        $monday = 1;
        $jdd = jddayofweek();
        switch($jdd) {
            case $monday:
                $resp->;message = 'It\'s a monday.';
                $resp->;html = 'It\'s not a monday.';                

To register this function you will need to use one of the following methods.  The first requires a logged-in user while the second does not and is more suited for front-end calls.

There are some additional notes on how exactly those two differ in here: http://codex.wordpress.org/AJAX_in_Plugins (go to the Ajax on the Viewer-Facing Side section)

  1. wp_ajax_{some_name}
  2. wp_ajax_nopriv_{some_name}

In my examples I use the wp_ajax_{some_name} action so the user does have to be logged in.

    if(is_admin()) {
        add_action('wp_ajax_monday-fail', 'monday_fail');        

A nonce (form of a security token) will be used for all calls to ensure the requests are coming from where we expect.

4. Make the call from javascript and handle the response.

In this final piece of the puzzle you will create the code that makes the calls and handles the response.  I always choose to use jQuery for this purpose so here it is.

    jQuery(document).ready(function ($) { 

        function create_directory(newName) {
                type       : "POST",
                data       : {
                              action: 'monday-fail', 
                              nonce : MyAjaxObject.nonce                              
                dataType   : "JSON",
                url        : MyAjaxObject.ajaxurl,
                success    : function(data){

                    if(data.success) {
                    } else {
                       alert(data.data.message); // display the returned message

                error     : function(jqXHR, textStatus, errorThrown) {
                    alert('Unable to check what day it is.');
                    console.log(jqXHR + " :: " + textStatus + " :: " + errorThrown);


A few notes on the above code:

The above code will typically go into the head section of the page, inside of a script tag.

The dataType is set to JSON since that’s how we will receive our response.

Url is set using the object we created by localizing our script in Step 1.

To refer to our MyAjaxResponse object from Step 2 we use data.data, that’s how the wordpress function embeds it.

As part of the data we send to the function is action, that has to match {some_name} name used when you registered the function in Step 3.

The other variable: nonce, is generated through localization in Step 1.


wp_send_json_succes and wp_send_json_error automatically handle the response portion of the logic but if you choose not to use them make sure to die(); after sending the response to the client otherwise a 0 or other junk will be appended to the response on the client side.