Update status, meta while inside a post using AJAX button
-
15-04-2021 - |
Domanda
So I am trying to click a custom button I made in a meta box the fire off AJAX. All works except getting the ID of the post and the refreshing of the page. I have tried using global $post; $post_id = $post->ID
or $post_id = $_POST['post_id'];
or $post_id = get_the_ID();
, none of these work.
What I was trying to accomplish eventually is: after clicking the button, a popup happens with "are you sure?"Yes/No. If I click Yes, to change Status function fires and refreshes the post page with status changed.
I am using an Ajax Get with the URL of behind my button: /wp-admin/admin-ajax.php?action=ew_change_status
Reference: Trying to load content of a post via AJAX
This is my functions.php code:
add_action( 'wp_ajax_change_status', 'ew_change_status' );
function ew_change_status() {
//$post_id = $_POST['post_id'];
//$post_id = get_the_ID();
global $post;
global $user_ID;
$post_id = $post->ID;
var_dump($post_id);
remove_filter( current_filter(), __FUNCTION__ );
//Show popup
// ...
// Update Status
$my_post = array(
'ID' => $post_id,
'post_status' => 'status-pending',
);
// Update custom field with User Id
update_post_meta($post_id, 'post_key', $user_ID);
//echo "Updated";
// Update the post into the database
wp_update_post( $my_post );
//wp_redirect(); //Same Page?
//exit;
}
Soluzione
First things first
In a wp_ajax_{action}
or wp_ajax_nopriv_{action}
callback, the global $post
variable is by default a null
because WordPress has not yet set it up. You can confirm it using a simple callback like so:
add_action( 'wp_ajax_test', function(){
global $post;
var_dump( $post );
wp_die();
} );
Visit /wp-admin/admin-ajax.php?action=test
and you should see NULL
displayed on the page. If you don't see a NULL
, then it's possible that a plugin or custom code has made a query which changed the $post
variable.
Now a solution
Since you're making the AJAX request via a button click and the button is inside a meta box which I suppose is on the post edit screen (wp-admin/edit.php
), then an easy way to fix the issue of the $post
being still a NULL
in your wp_ajax_change_status
callback, is to send the post ID from your AJAX script (JavaScript).
On the post edit screen, the post ID is stored in a hidden input
field named post_ID
which looks like this and stores the ID of the post that's currently being edited:
<input type='hidden' id='post_ID' name='post_ID' value='123' />
So you can use the value and send it to your AJAX callback. E.g.:
jQuery.ajax({
url: '/wp-admin/admin-ajax.php',
data: {
action: 'change_status',
post_id: jQuery( '#post_ID' ).val() // send the post ID
},
type: 'post'
});
Then in your AJAX callback (i.e. the ew_change_status()
function), you can retrieve the submitted post ID like so:
$post_id = filter_input( INPUT_POST, 'post_id' );
Additional Notes
In your AJAX callback, make sure to check whether the current user can edit the post. E.g.:
if ( ! current_user_can( 'edit_post', $post_id ) ) { wp_die(); }
Use a nonce (because you are editing a post). For example,
a) In your meta box, create a hidden
input
for storing the nonce:// Creates an <input> with the `id` and `name` "my_security". <?php wp_nonce_field( 'change-post-status', 'my_security' ); ?>
b) Include the nonce in the AJAX request:
jQuery.ajax({ url: '/wp-admin/admin-ajax.php', data: { action: 'change_status', post_id: jQuery( '#post_ID' ).val(), security: jQuery( '#my_security' ).val() }, type: 'post' });
c) In your AJAX callback, verify the nonce:
check_ajax_referer( 'change-post-status', 'security' );
So your ew_change_status()
may look like:
function ew_change_status() {
check_ajax_referer( 'change-post-status', 'security' );
$post_id = filter_input( INPUT_POST, 'post_id' );
if ( ! $post_id || ! ( $post = get_post( $post_id ) ) ) {
wp_die( 'No such post, or invalid ID.' );
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
wp_die( 'You can not edit this post.' );
}
... your code here ...
wp_die();
}