User schedule a post?

Here’s one possible solution from many..

  • If user makes a post, he/she saves it as draft
  • User selects a datetime when he/she wants to publish it
  • It’s saved as post metadata, my_post_schedule_time in my example

Disclaimer: this is just an example. It should work perfectly but it will probably require some tweaking, tuning, customization and maybe even some optimization.

I guess I don’t have to tell you that impact on server depends how many posts you have.

This code would go to a new single .php file and you should put it to mu-plugins or plugins folder.


/*
 * Plugin Name: Your Scheduler
 * Plugin URI: http://www.your-site.com
 * Description: Schedules posts for users
 * Author: You
 * Author URI: http://www.your-site.com
*/ 



add_action( 'wp_ajax_nopriv_postSchedule', function() {  

    // Get current time
    $now = date( 'Y-m-d H:i:s' );

    // Get posts that has status "draft" and are "over time limit"
    $unpublished_posts = new WP_Query( array(

        'posts_per_page'    => -1,
        'post_type'         => 'post',   // Your post type
        'post_status'       => 'draft',  // Post status

        // Im pretty sure that it doesn't get posts without that meta value
        'meta_query' => array(
            array(
                'key'     => 'my_post_schedule_time',
                'value'   => $now,
                'type'    => 'DATETIME',
                'compare' => '<=',
            )
        )
    ));

    // Loop through all scheduled posts
    while( $unpublished_posts->have_posts() ) {

        $unpublished_posts->the_post();

        // Get schedule meta data
        $post_publish_time = get_post_meta( get_the_ID(), 'my_post_schedule_time', true );

        // Format it - might not need it, it depends how you save your metadata
        $format_post_publish_time = date( 'Y-m-d H:i:s', strtotime( $post_publish_time ) );

        // Check if we have schedule time, just in case
        if( ! empty( $format_post_publish_time ) ) { 

            // Check if that times has passed a.k.a smaller than current time
            if( $format_post_publish_time < $now ) {

                // Publish post
                wp_update_post( array( 'ID' => get_the_ID(), 'post_status' => 'publish' ) );
            }
        }
    }

    wp_reset_postdata();
});

Now you would need to set server cron job from your host cPanel that calls that function in your set interval (e.g in every 1 hour, in every 2 hours, once per day etc). More often == more precise.