6

I'm using this bit to insert/update a custom post type from the front-end. The date is set from a custom jquery datepicker.

    if (strtotime($date) < strtotime('tomorrow')) {
            $newpostdata['post_status'] = 'publish';
    } elseif (strtotime($date) > strtotime('today')) {
            $newpostdata['post_status'] = 'future';
            $newpostdata['post_date'] = date('Y-m-d H:i:s', strtotime($date));
    }

    if ('insert' == $operation) {
        $err = wp_insert_post($newpostdata, true);
    } elseif ('edit' == $operation) {
        $newpostdata['ID'] = $post_id;
        $err = wp_update_post($newpostdata);
    }

This works when first publishing the post, setting it correctly as publish or future, with the correct date.

This doesn't work when editing the same post, neither from publish to future nor the other way around. Everything else is properly updated, except for the post status/future_date.

UPDATE Oct. 9th I'm starting to think this might be a bug, so i started a conversation at the wp-hackers mailing list, about this. There's some fresh install test results on the link.


OTHER FAILED ATTEMPTS:

i've tried leaving post_status decisions to wp_insert_post() using:

elseif ('edit' == $operation) {
        $newpostdata['post_status'] = '';
        $newpostdata['ID'] = $post_id;
        $err = wp_update_post($newpostdata);
    }

And this sets the post status to draft while maintaning the requested dates.

I've also tried calling wp_transition_post_status() again (it's called once inside wp_insert_post()):

elseif ('edit' == $operation) {
        $newpostdata['ID'] = $post_id;
        $err = wp_update_post($newpostdata);
        wp_transition_post_status($old_status, $status, $post_id);
    }

but that also didn't seem to work.

I'm running out of ideas here. Any clues?

9
  • I am confused, When editing the post, and setting it to future, the post date doesn't get updated? Oct 8 '12 at 2:03
  • post date gets updated, but post status doesn't. So if I publish a post today, and then set it to future with a date three days from today, the date gets changed, but post_status is still publish, instead of future
    – moraleida
    Oct 8 '12 at 2:26
  • Ok, this just in: if I strip out the post_status before updating the post, it then gets reverted to draft and still appears in the admin panel as scheduled. So it works, but that still doesn't answer why I can't revert it to future.
    – moraleida
    Oct 8 '12 at 2:33
  • Are you doing this as logged in user with sufficient capabilities? Data manipulation functions tend to check if user is actually allowed to perform it.
    – Rarst
    Oct 9 '12 at 1:03
  • 1
    I had a similar problem and the cause of it was that the post_status parameter was more than 20 characters long. codex.wordpress.org/Post_Status Hope it helps! May 18 '17 at 17:57
12

Answer couldn't be simpler.

As pointed out by Otto at the wp-hackers list, problem was me not setting post_date_gmt when using wp_update_post().

Final code looks like this:

if ( $post_date < strtotime( "tomorrow" ) ) {
        $status = 'publish';    
        $newpostdata['post_status'] = $status;
        $newpostdata['post_date'] = date( 'Y-m-d H:i:s',  $post_date );

        // Also pass 'post_date_gmt' so that WP plays nice with dates
        $newpostdata['post_date_gmt'] = gmdate( 'Y-m-d H:i:s', $post_date );

    } elseif ( $post_date > strtotime( 'today' ) ) {
        $status = 'future';    
        $newpostdata['post_status'] = $status;
        $newpostdata['post_date'] = date( 'Y-m-d H:i:s', $post_date );

        // Also pass 'post_date_gmt' so that WP plays nice with dates
        $newpostdata['post_date_gmt'] = gmdate( 'Y-m-d H:i:s', $post_date );
    }

    if ('insert' == $operation) {
        $err = wp_insert_post($newpostdata, true);
    } elseif ('edit' == $operation) {
        $newpostdata['ID'] = $post_id;
        $err = wp_update_post($newpostdata);
    }
0
3

I also tried the above code using wp_update_post() , but it doesn't work well with WordPress 3.9, it makes post_status empty and deleted all custom fields. I therefore created a custom query using the wpdb class. I hope this will work for all of you:

$wpdb->query( 
    $wpdb->prepare( 
        "UPDATE $wpdb->posts SET post_status = 'draft' WHERE ID = %d", 
        $post_id 
    )
);    

and this worked well on my localhost and hosting too.

1
  • 1
    Welcome to WordPress Development. I hope you don't mind the modifications. I fixed the prepare statement.
    – birgire
    Dec 10 '14 at 17:25
1

We update the post status all the time, here is an example of how we allow users (on the front end editor that was built) to "pause" ads by changing them to draft:

if ($action == 'pause') {
        $my_post = array();
        $my_post['ID'] = $aid;
        $my_post['post_status'] = 'draft';
        wp_update_post($my_post);
        $action_msg = __('Ad has been paused', 'mytheme');
}
1

$newpostdata['post_date'] = date( 'Y-m-d H:i:s', $post_date );

This will return fisrt intial date of php 1970, use strtotime to convert string to time

$newpostdata['post_date'] = date( 'Y-m-d H:i:s', strtotime($post_date) );

0

You need to add "edit_date" => true in wp_update_post array

0

Not the OP's issue, but as a notable point of reference for others finding their way here researching a similar issue where wp_update_post() doesn't update post_status ...

As @adrianthedev noted above in a comment on the OP, note that the maximum length of a custom post status is 20 chars.

https://developer.wordpress.org/reference/functions/register_post_status/#comment-3927

When 20 chars are exceeded, you are able to register the custom post status using register_post_status(), but currently unable to set a post as using it with wp_update_post(), at least as of WordPress v5.5.1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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