Plugin: AJAX query external API to sync to tables

Sketch/Concept

To make requests to remote/external APIs, use the WP HTTP API. More in depth examples/details can be found in some of my answers here.

Then simply add an admin page with add_submenu_page() or add_menu_page() or the related functions.

Finally add a script via wp_register/enqueue_script() on the admin_enqueue_scripts-hook. There you fire an (search archives) call and update your tables.

Use in plugins

It’s pretty simple. Here’s a quick mockup. It shows everything that is needed to do every possible AJAX call. I splitted up the registration and the queuing of the script so you can enqueue the script when and where ever you need.

Nonces

Nonces and referrer checks are already implemented for security. It uses a constant naming scheme so it gets less confusing (especially with the nonce checks).

OOP construct with a shared name

The PHP:

class WPSEexampleAJAX
{
    public $name="wpse";

    public function __construct()
    {
        add_action( 'wp_loaded', array( $this, 'scriptsRegister' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'scriptsEnqueue' ) );

        // Logged in users - everybody in Admin
        add_action( "wp_ajax_{$this->name}_action", array( $this, 'ajaxCb' ) );
        // Guests/not logged in
        add_action( "wp_ajax_nopriv_{$this->name}_action", array( $this, 'ajaxCb' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'scriptsLocalize' ) );
    }

    public function scriptsRegister( $page )
    {
        $file="WPSEexample.js";
        wp_register_script(
            $this->name,
            plugins_url( "assets/scripts/{$file}", __FILE__ ),
            array(
                'jquery',
                // 'add other possible dependencies in here',
            ),
            filemtime( plugin_dir_path( __FILE__ )."assets/scripts/{$file}" ),
            true
        );
    }

    public function scriptsEnqueue( $page )
    {
        wp_enqueue_script( $this->name );
    }

    public function scriptsLocalize( $page )
    {
        wp_localize_script( $this->name, "{$this->name}Object", array(
            'ajaxurl'          => admin_url( 'admin-ajax.php' ),
            '_ajax_nonce'      => wp_create_nonce( "{$this->name}_action" ),
            'action'           => "{$this->name}_action",
            'post_type'        => get_current_screen()->post_type,
            // 'foo'              => 'bar',
        ) );
    }

    public function ajaxCb()
    {
        $data = array_map( 'esc_attr', $_GET );

        check_ajax_referer( $data['action'] );

        // DO STUFF IN HERE

        wp_send_json_success( array(
            // 'foo' => 'bar',
        ) );
    }
}

The JavaScript an actual AJAX send/catch

Inside your registered JavaScript file, you just fire the ajax call and retrieve the result. Nowadays you got different points where you can intercept or catch the result. The script isn’t really doing anything, but just logging into the console. The wpseObject that was localized has an alias in the function call, so you can simply use plugin instead. I like doing it that way, so I can easily identify the localized object later on (also shorter to write). It’s just my personal naming convention.

( function( $, plugin ) {
    "use strict";

        $.ajax( {
            url  : plugin.ajaxurl,
            data : {
                action      : plugin.action,
                _ajax_nonce : plugin._ajax_nonce,
                foo         : plugin.foo,
            },
            beforeSend : function( d ) {
                console.log( 'AJAX Before send', d );
            }
        } )
            .done( function( response, textStatus, jqXHR ) {
                // console.log( 'AJAX done', data, textStatus, jqXHR, jqXHR.getAllResponseHeaders() );
            } )
            .fail( function( jqXHR, textStatus, errorThrown ) {
                console.log( 'AJAX failed', jqXHR.getAllResponseHeaders(), textStatus, errorThrown );
            } )
            .then( function( jqXHR, textStatus, errorThrown ) {
                console.log( 'AJAX after', jqXHR, textStatus, errorThrown );
            } );
} )( jQuery || {}, wpseObject || {} );

More info on the different parts for the $.ajax() call in the official jQuery documentation.

Hint: Make sure you always use jQuery from WordPress core and no CDN version. Else you’ll likely hit a wall with conflicts or outdated versions in case a user updates core, but not your plugin.