In Share on Social Plugin, we use WordPress Ajax to save and view the share statistics. In this chapter, we use WordPress Ajax to send share details from client to server and save it as WordPress options and then add a menu page to display the statistics in Google Charts.

9.1. WordPress Ajax

When user shares a blog, functions in js/share.js use Social Network API to share and on success, send the share details to the server.

WordPress centralizes and routes Ajax calls to its file wp-admin/admin-ajax.php. To initiate Ajax, JavaScript require URL of this file and we use wp_localize_script() function, explained in Pass Data to JavaScript to pass URL and other data from the server to client.

share-on-social/frontend/class-frontend.php

    function add_sos_scripts () {
        ....          
        wp_localize_script( 'sos_script', 'sos_data', 
                array(
                        'ajax_url' => admin_url( 'admin-ajax.php' ),
                        'nonce' => wp_create_nonce( 'sos-save-stat' ),
                        'gplus_client_id' => $gplus_client_id ) );
    }

WordPress function admin_url() returns the URL of admin-ajax.php. WordPress function wp_create_nonce() creates one time security token called nonce that can be only used for sos-save-stat request. The screenshot shows passed data in the browsers’ View Source screen.

WordPress Ajax - ajax URL.

When a share is completed, JavaScript calls handleResponse() with the response received from the Social Network and in the function, we use JQuery Ajax to communicate with the server.

share-on-social/js/share.js

function handleResponse(type, shareName, response) {

    jQuery.ajax({
        type : 'POST',
        url : sos_data.ajax_url,
        data : {
            action : 'save-stats',
            type : type,
            share_name : shareName,
            share_stats : JSON.stringify(response),
            _ajax_nonce : sos_data.nonce,
        },
        success : function(data, textStatus, XMLHttpRequest) {
            console.log(data);
            openLocker(shareName);
        },
        error : function(MLHttpRequest, textStatus, errorThrown) {
            console.log(errorThrown);
        }
    });
}

In jQuery.ajax(), we use POST method to pass the data. The Ajax URL passed by the WordPress is retrieved with sos_data.ajax_url and assigned to url parameter. The data parameter passes the share details, nonce, share name, share type and the JSON string of the response received from the social network.

WordPress jQuery

jQuery library included with WordPress is set to noConflict mode and in that mode, we are allowed to use jQuery(#somefunction) and not the shorthand $(#somefunction). For more information refer jQuery noConflict Wrappers

JQuery.ajax() call with type: POST and url : http://example.org/wp-admin/admin-ajax.php invokes the WordPress Ajax script wp-admin/admin-ajax.php.

But, how admin-ajax.php is able to determine the actual Ajax handler method for a specific request. In data parameter we also provide another bit of information to the server in action: 'save-stats', which tells admin-ajax.php that it has to invoke method or function attached to the action hooks wp_ajax_save-stats or wp_ajax_nopriv_save-stats.

 
 

So, we have to add action method to these two hooks and that is done in plugins’ Ajax file- admin/class-ajax.php.

share-on-social/admin/class-ajax.php

class Sos_Ajax {

    public function setup () {

        add_action( 'wp_ajax_nopriv_save-stats', array( $this,'save_stats' ) );
        add_action( 'wp_ajax_save-stats', array( $this,'save_stats' ) );

    }

In Sos_Ajax::setup() method. we add Sos_Ajax::save_stats() as action method to hooks wp_ajax_save-stats and wp_ajax_nopriv_save-stats.

When client js/share.js makes the Ajax call, WordPress receives the request and passes it on to wp-admin/admin-ajax.php, which do the action wp_ajax_save-stats and invokes the Sos_Ajax::save_stats(). The Ajax handler method processes the request and returns the response back to client.

Ajax - Admin and Regular Users

The only difference between action hooks wp_ajax_ and wp_ajax_nopriv_ is that wp_ajax triggers when user is logged in as admin and wp_ajax_nopriv triggers for regular user. In other words, wp_ajax_save-stats invokes save_stats() method only admins but not for regular users. The second one, wp_ajax_nopriv_save-stats invokes the method when regular user shares.

Let’s see what goes on in the Ajax method Sos_Ajax::save_stats().

share-on-social/admin/class-ajax.php

    public function save_stats () {
        $valid_req = check_ajax_referer( 'sos-save-stat', false, false );
        if ( false == $valid_req ) {
            wp_die( '-1' );
        }
        
        if ( ! isset( $_POST<a href="http://codex.wordpress.org/Function_Reference/check_ajax_referer" target="_blank"> 'type' ] ) || ! isset( $_POST[ 'share_name' ] ) ) {
            wp_die( '-1' );
        }
        $share_on = $_POST[ 'type' ];
        $share_name = $_POST[ 'share_name' ];
        
        $this->update_sos_stats( $share_on, $share_name );
        $this->update_sos_stats_summary( $share_on, $share_name );
        
        wp_die( '1' );
    }

The method, first do a security check and ascertains whether it is a valid Ajax request originated from indented page with the help of WordPress function [check_ajax_referer() which uses _ajax_nonce sent by jQuery.ajax() call. If security check fails, then wp_die() function gracefully terminate the Ajax call and return -1 to client.

Next, verify whether required data - type and share_name are set in $_POST and if not, terminate the Ajax call with wp_die().

After those checks, call Sos_Ajax::update_sos_stats() and Sos_Ajax::update_sos_stats_summary() methods to save the stats in the database.

Finally, terminate the Ajax call again with wp_die(), but return 1 which indicates successful call.

Ajax Termination

In both cases, success or failure, we use wp_die() to terminate the Ajax call and based on the return value, 1 or -1, client determines the status - success or failure.

We will explain the importance of wp_die() in a later chapter on Ajax Unit Testing.

Let’s see how data is saved to WordPress database by the Sos_Ajax::update_sos_stats() method.

share-on-social/admin/class-ajax.php

    public function update_sos_stats ( $share_on, $share_name ) {

        $stats = get_option( 'sos_stats' );
        if ( null == $stats ) {
            $stats = array();
        }

        $stat = array(
                'date' => strtotime( 'now UTC' ), // UTC timestamp
                'type' => $share_on,
                'share_name' => $share_name
        );
        
        $stats[] = $stat;
        update_option( 'sos_stats', $stats );
    }

It uses get_option() function to check whether option sos_stats exists in the database else creates a new one. Next, it creates an array from the data sent by the client and update it as WordPress Option sos_stats using update_option() function.

 
 

In the next two sections, we revisit some the topics covered so far in the tutorial such as WordPress Menu, Enqueue Scripts and WordPress Ajax to create a new sub menu and display the Share Statistics in Google Charts.