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.
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.