2

I have a plugin that prepends an upvote box to the_content of a single post, sends data via AJAX back to the main plugin PHP file and calls a function to update a database value on success.

Here is the PHP callback from the AJAX:

function update_parlay_points() {
    //Update Parlay Points field on database with points from Post request. 
    //global $post;
    //$post_id = $post->ID;     
    $post_id = get_the_ID();
    $points = $_POST['score'];      
    $update_points = "UPDATE wp_posts 
        SET parlay_points = '$points' 
        WHERE id = $post_id";   
    var_dump( $post_id );
    echo $update_points;           
    global $mysqli;
    $mysqli->query( $update_points ) or die( "Query failed" );
    wp_die();
}

In Chrome's Developer tools, this gives me:

bool(false) UPDATE wp_posts SET parlay_points = '26' WHERE id = Query failed

As you can see, I tried declaring the $post variable as global to account for failures due to being outside of the Loop. The content that triggers the AJAX request is prepended to the_content, so I am not sure if I need to "enter" the Loop again somehow. I tried if ( have_posts() ) and if ( is_single() ) before get_the_ID() with no success. The Loop, in general, really confuses me.

I have also tried accessing $post->ID from the action hook the_post. Strangely enough, I am able to successfully echo the current post's ID but cannot store it in a globally scoped variable.

$post_id = Null;
add_action( 'the_post', 'wp_store_post_info' );
function wp_store_post_info() {
    //Set current post as global variable. 
    global $post;
    global $post_id;
    $post_id = $post->ID;
    echo $post_id;
}
function update_parlay_points() {
    //...
    global $post_id;
    //Do stuff with the $post_id...
}

This does not work either:

$GLOBALS['post_id'] = $post->ID;

I am certain that the above function is being called, because the correct $post_id is being echoed. However, when I click the upvote button I get:

NULL UPDATE wp_posts SET parlay_points = '28' WHERE id = Failed Query

3 Answers 3

1

As you can see, I tried declaring the $post variable as global to account for failures due to being outside of the Loop.

The problem is not that the post is "outside of the loop", problem is that AJAX request is a completely separate HTTP request.

When you do an AJAX request, is just like you are opening a new window on browser and open the url in this separate window. It means that the script that handles the AJAX request knows nothing about the page that sent the request.

If you need to process a specific post in the AJAX request, you need to send the post ID to process as part of the AJAX request data.

2
  • This is probably the crucial bit of info I was missing. Thanks.
    – AlexFADev
    Commented Aug 10, 2015 at 3:06
  • Got it working! Simply echoed the id into a hidden div, then passed it back with the AJAX call.
    – AlexFADev
    Commented Aug 10, 2015 at 10:48
1

My suggesion is to use wp_localize_script() to pass the post id to your AJAX calls.
Something like this..

function my_script_enqueue() {
    global $post;

    $translations = array(
        'postID' => $post->ID
    );

    wp_enqueue_script( 'myscript', '/url/to/your/script.js', array('jquery') );
    wp_localize_script( 'myscript', 'MyAJAX', $translations );
}
add_action('wp_enqueue_scripts', 'my_script_enqueue')
0

What about sending the post id of the single post trough ajax as well? So if you create a hidden input that contains the id, something like this:

<input type="hidden" id="post_id" name="post_id" value="<?php echo $post->ID; ?>">

Then you can just pick the id and send it trough the ajax request, so your function will end up looking something like this:

function update_parlay_points() {

    //Update Parlay Points field on database with points from Post request.     
    $post_id = $_POST['post_id'];
    $points = $_POST['score'];      

    $update_points = "UPDATE wp_posts 
        SET parlay_points = '$points' 
        WHERE id = $post_id";   

    var_dump( $post_id );

    echo $update_points;           

    global $mysqli;
    $mysqli->query( $update_points ) or die( "Query failed" );

    wp_die();
}   

I would also check out the $wpdb Object, insted of using $mysqli to handle the DB quieres.

2
  • Tried echoing the $post_id into a hidden div in the prepended content, then passing that through the AJAX request. It isn't working right now, but it makes sense that it would. Unfortunately I have a final exam in 2 days, so will have to pick it back up after :(. Thanks.
    – AlexFADev
    Commented Aug 10, 2015 at 3:04
  • @AlexFADev There are multiple ways to get the post id, and it depends on how your prepended post is called. You might try get_the_ID instead, or call global $post in the prepended content. Also try to return the id in the ajax request to see if you got the right id. Good luck on your exams ;) Commented Aug 10, 2015 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.