How to Access custom database content with AJAX onClick refresh of div inside member-only WordPress page?

I’d use the default WP AJAX API so WP can handle all the authentication for you.

You’d add a function and an action to trigger it:

function wpse_314311_get_quote() {
    // get quote from db
    // print json to client
    exit;
}
add_action( 'wp_ajax_get_quote', 'wpse_314311_get_quote' );

That way, WP will make sure that only logged in users are allowed to access the API. If you wanted to allow anonymous users as well, you’d add

add_action( 'wp_ajax_nopriv_get_quote', 'wpse_314311_get_quote' );

On the server side, you’ll use WPDB to access your custom tables inside the WP database:

global $wpdb;
if($quote = $wpdb->get_row("SELECT * FROM my_quotes_table ORDER BY RAND() LIMIT 0, 1")) {
    print $quote->quote_body . " by " . $quote->quote_author;
}

Together this might look something like

function wpse_314311_get_quote() {
    global $wpdb;
    if($quote = $wpdb->get_row("SELECT * FROM my_quotes_table ORDER BY RAND() LIMIT 0, 1")) {
        print json_encode(array("success" => true, "message" => $quote->quote_body));
    }
    else {
        print json_encode(array("success" => false, "message" => "no quote found"));
    }
    // print json to client
    exit;
}
add_action( 'wp_ajax_get_quote', 'wpse_314311_get_quote' );

In the front end, you can then access it by passing action=get_quote to the API (usually /wp-admin/admin-ajax.php, but you might want to look into putting it into a variable with wp_localize_script):

jQuery(document).ready(function($) {
    $("#myButton").click( function() {
        jQuery.post("/wp-admin/admin-ajax.php", { "action": "get_quote"}, function(response) {
            console.log(response);
            $("#myDiv").text(response.message);
        });
    }
});

Put that in a script (for this example, I’m assuming inside your theme in a js folder in a file named quote-refresh.js and make WP load it with wp_enqueue_script. Be sure to let WP know your script requires jQuery to be loaded, e.g.

wp_enqueue_script( "quote-refresh", get_template_directory_uri() . "/js/quote-refresh.js", array("jquery") );

You can put everything in your theme’s function.php assuming you’re using a child theme and not Understrap directly (which you should if you ever want to customize anything in the theme and still be able to update the original theme), or create a very simple plugin to add it to WP.

As for controlling access: that’s hard depending on your paranoia. Protecting unauthorized access is easy, WP will make sure the requests are coming from logged in users. Making sure those users don’t use automation to suck out everything in your DB is much harder – you’d have to decide which pattern of behavior is a bored human hitting “refresh” every few seconds to read something else and which is a bot that just wants the content.

Please excuse typos and bugs in code, I don’t have any means to run it right now.

Leave a Comment