admin管理员组文章数量:1291037
I'm writing a post approval utility for the front end, because we don't want our editor to be able to access the admin dashboard. There are questions on Stack nearly identical to what I'm trying to accomplish, but that guy's problem has to do with the infinite loop issue. Otherwise, he claims his code works:
How to change post status from publish to draft using hook in wordpress?
I'm writing a plugin to do this (in my case I want to change 'draft' to 'publish'). I don't want to have to edit the functions.php in the child theme, because I want the plugin to be standalone, for any WordPress site. So all code is in my plugin's main php file.
- I can get all posts with status of 'draft'.
- I can use an html checkbox, javascript, and WP's ajax functions to select the post I want to change by ID.
The "change status" code looks like this (in the plugin main php file):
/* This function should toggle a post status from 'draft' to 'publish' */
add_action( 'wp_ajax_approvepost', 'approvepost_callback' );
add_action( 'wp_ajax_nopriv_approvepost', 'approvepost_callback' );
function approvepost_callback(){
$post = array(
'ID' => $_POST['postid'], // e.g., 28
'post_status' => 'publish',
'edit_date' => true
);
$result = wp_update_post($post,true); // (there, you like that better?)
echo $result; // I get a result of "1". The post ID is 28. wp_update_post failed?
wp_die();
}
... wp_update_post
returns a 1, so I take that to mean there were no errors. But when I refresh the front-end page, the post shows up again, meaning it is still in draft mode, and when I inspect the post in the WP admin dashboard, sure enough, it's still in draft. What am I doing wrong or missing?
UPDATE: If I execute the function from my child theme functions.php, the code works, but not by using AJAX. I have to call the function directly, like by refreshing the page, and the function returns the post ID, and the post status will change to 'publish'. As soon as I invoke the function using AJAX, the post status does not change, and the function returns a 1.
UPDATE I removed the AJAX action altogether, and defaulted to an old timey standard form submit, which refreshes the form page. Under these conditions, wp_update_post works as expected. Something about wp_update_post doesn't like to be called by AJAX. My suspicion is it has something to do with security, but whatever it is, I can't find any reference to it in the documentation.
ADDITIONAL JAVASCRIPT Some have asked to see the javascript, especially the ajax code:
jQuery(document).ready(function($){
// AJAX url
var ajax_url = approve_posts_ajax_object.ajax_url;
var data = {
'action': 'approvepost',
};
$('button#submit-approval').on("click",function(){
var checkboxes = $("input[name='post_id']");
data.postid = [];
// loop over them all
for (var i=0; i<checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
data.postid[i] = $(checkboxes[i]).val();
}
else{
data.postid[i] = "";
}
}
$.ajax({
url: ajax_url,
type: 'post',
data: data,
dataType: 'json',
success: function(response){
// Add new rows to table
approvePost(response);
}
});
});
});
function approvePost(data){
jQuery("#diag").html(data); //just want to output the callback response for now.
}
SOLUTION (so that others can see what works):
Javascript, with AJAX call:
jQuery(document).ready(function($){
// AJAX url
var ajax_url = approve_posts_ajax_object.ajax_url;
var data = {
'action': 'approvepost',
};
$('button#approval_submit').on("click",function(){
var checkboxes = $("input[name='post_id']");
data.postid = [];
// loop over them all
for (var i=0; i<checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
data.postid[i] = $(checkboxes[i]).val();
}
}
$.ajax({
url: ajax_url,
type: 'post',
data: data,
dataType: 'json',
success: function(response){
approvePost(response);
}
});
});
});
function approvePost(data){
jQuery("#diag").html("");
var string = "\n";
jQuery.each(data,function(k,v){
string += k + " = " + v + "<br>";
});
jQuery("#diag").append(string);
}
PHP (with ajax callback function, in main plugin file):
/* This is the function that toggles a post status from draft to published */
add_action( 'wp_ajax_approvepost', 'approvepost_callback' );
add_action( 'wp_ajax_nopriv_approvepost', 'approvepost_callback' );
function approvepost_callback(){
$update = array();
for($i=0;$i<count($_POST['postid']);$i++){
$post = array(
'ID' => $_POST['postid'][$i],
'post_status' => 'publish'
);
$update[$i] = wp_update_post($post);
}
echo json_encode($update);
wp_die();
}
I'm writing a post approval utility for the front end, because we don't want our editor to be able to access the admin dashboard. There are questions on Stack nearly identical to what I'm trying to accomplish, but that guy's problem has to do with the infinite loop issue. Otherwise, he claims his code works:
How to change post status from publish to draft using hook in wordpress?
I'm writing a plugin to do this (in my case I want to change 'draft' to 'publish'). I don't want to have to edit the functions.php in the child theme, because I want the plugin to be standalone, for any WordPress site. So all code is in my plugin's main php file.
- I can get all posts with status of 'draft'.
- I can use an html checkbox, javascript, and WP's ajax functions to select the post I want to change by ID.
The "change status" code looks like this (in the plugin main php file):
/* This function should toggle a post status from 'draft' to 'publish' */
add_action( 'wp_ajax_approvepost', 'approvepost_callback' );
add_action( 'wp_ajax_nopriv_approvepost', 'approvepost_callback' );
function approvepost_callback(){
$post = array(
'ID' => $_POST['postid'], // e.g., 28
'post_status' => 'publish',
'edit_date' => true
);
$result = wp_update_post($post,true); // (there, you like that better?)
echo $result; // I get a result of "1". The post ID is 28. wp_update_post failed?
wp_die();
}
... wp_update_post
returns a 1, so I take that to mean there were no errors. But when I refresh the front-end page, the post shows up again, meaning it is still in draft mode, and when I inspect the post in the WP admin dashboard, sure enough, it's still in draft. What am I doing wrong or missing?
UPDATE: If I execute the function from my child theme functions.php, the code works, but not by using AJAX. I have to call the function directly, like by refreshing the page, and the function returns the post ID, and the post status will change to 'publish'. As soon as I invoke the function using AJAX, the post status does not change, and the function returns a 1.
UPDATE I removed the AJAX action altogether, and defaulted to an old timey standard form submit, which refreshes the form page. Under these conditions, wp_update_post works as expected. Something about wp_update_post doesn't like to be called by AJAX. My suspicion is it has something to do with security, but whatever it is, I can't find any reference to it in the documentation.
ADDITIONAL JAVASCRIPT Some have asked to see the javascript, especially the ajax code:
jQuery(document).ready(function($){
// AJAX url
var ajax_url = approve_posts_ajax_object.ajax_url;
var data = {
'action': 'approvepost',
};
$('button#submit-approval').on("click",function(){
var checkboxes = $("input[name='post_id']");
data.postid = [];
// loop over them all
for (var i=0; i<checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
data.postid[i] = $(checkboxes[i]).val();
}
else{
data.postid[i] = "";
}
}
$.ajax({
url: ajax_url,
type: 'post',
data: data,
dataType: 'json',
success: function(response){
// Add new rows to table
approvePost(response);
}
});
});
});
function approvePost(data){
jQuery("#diag").html(data); //just want to output the callback response for now.
}
SOLUTION (so that others can see what works):
Javascript, with AJAX call:
jQuery(document).ready(function($){
// AJAX url
var ajax_url = approve_posts_ajax_object.ajax_url;
var data = {
'action': 'approvepost',
};
$('button#approval_submit').on("click",function(){
var checkboxes = $("input[name='post_id']");
data.postid = [];
// loop over them all
for (var i=0; i<checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
data.postid[i] = $(checkboxes[i]).val();
}
}
$.ajax({
url: ajax_url,
type: 'post',
data: data,
dataType: 'json',
success: function(response){
approvePost(response);
}
});
});
});
function approvePost(data){
jQuery("#diag").html("");
var string = "\n";
jQuery.each(data,function(k,v){
string += k + " = " + v + "<br>";
});
jQuery("#diag").append(string);
}
PHP (with ajax callback function, in main plugin file):
/* This is the function that toggles a post status from draft to published */
add_action( 'wp_ajax_approvepost', 'approvepost_callback' );
add_action( 'wp_ajax_nopriv_approvepost', 'approvepost_callback' );
function approvepost_callback(){
$update = array();
for($i=0;$i<count($_POST['postid']);$i++){
$post = array(
'ID' => $_POST['postid'][$i],
'post_status' => 'publish'
);
$update[$i] = wp_update_post($post);
}
echo json_encode($update);
wp_die();
}
Share
Improve this question
edited Jun 4, 2021 at 15:37
TARKUS
asked Jun 2, 2021 at 21:31
TARKUSTARKUS
13710 bronze badges
8
|
Show 3 more comments
2 Answers
Reset to default 1Something about wp_update_post doesn't like to be called by AJAX.
No, there is no such thing. :)
My suspicion is it has something to do with security
And I believed that also wasn't the case, hence I asked for your JS code.
And the actual problem is that the POST parameter postid
(i.e. $_POST['postid']
) is actually an array of post IDs, so you can't simply do 'ID' => $_POST['postid']
. And regarding this: "wp_update_post returns a 1", it's because the function calls get_post()
and it's actually the one which returned 1
. So that also means, the post that was updated is the one with that ID, i.e. 1
(which is the "Hello world!" post in a default WordPress install).
So you need to do a foreach
then call wp_update_post()
to update each of the posts. Example based on your code:
function approvepost_callback() {
$data = array();
foreach ( (array) $_POST['postid'] as $post_id ) {
if ( empty( $post_id ) || ! is_numeric( $post_id ) ) {
continue;
}
$post = array(
'ID' => $post_id,
'post_status' => 'publish',
'edit_date' => true // what is edit_date?
);
$result = wp_update_post( $post, true );
if ( $result && ! is_wp_error( $result ) ) {
$data[] = $post_id;
}
}
// In your JS, you set dataType to 'json', so make sure to send a valid JSON response.
wp_send_json( $data ); // this function will call wp_die()
}
Some JavaScript Notes
You don't need the following
else
because it will add empty items to the array (data.postid
):else{ data.postid[i] = ""; }
I would ensure the above array is not empty before proceeding with the AJAX (
$.ajax()
) call:if ( data.postid.length < 1 ) { console.log( 'no selections' ); return; } $.ajax( ... your code here. );
And last but not least... you should consider using the REST API instead to update your posts (see the Update a Post endpoint), because among other good things, the REST API has a better error handling and for example if you specified an invalid/non-existent post ID, the response would look like so which tells what exactly went wrong: {code: "rest_post_invalid_id", message: "Invalid post ID.", data: {status: 404}}
— better than simply 0
or 1
, right? :)
This may be a weird answer since I think it has nothing to do with the ajax.... try clearing the cache memory or install 1 and purge the cache also 1s more save the permalink with post name selected
本文标签: pluginswpupdatepost does not change post status from draft to publishreturns 1
版权声明:本文标题:plugins - wp_update_post does not change post status from draft to publish, returns 1 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741522206a2383254.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
wp_update_post
returns the post ID on success, so unless your ID is 1, then something is awry there. Try checking for awp_error
. – vancoder Commented Jun 2, 2021 at 22:17$_POST
is unusual and likely to cause fatal errors on newer versions of PHP. It also means everything passed into the AJAX endpoint also gets returned which could lead to security issues. Was there a reason not to use the Posts endpoint of the REST API for your AJAX? This code would allow any post to be published bypassing capability security checks – Tom J Nowell ♦ Commented Jun 2, 2021 at 22:25echo $result
withvar_dump( $result )
and try again making your AJAX call, then see what the dump outputted. And I also agreed with @HowdyMcGee, so can we see your AJAX/JS script? Did you try checking the console for any errors? – Sally CJ Commented Jun 4, 2021 at 1:35