Set post to draft after set period based on post_modified date


I have a custom post type for the user profile page. My client wants all users to update their profile at least once a month, so we want their profile (custom post) to be automatically set to draft after 30 days. They will then receive an email asking them to update the post. The post needs to be set to draft again 30 days after the last modified date and another reminder sent out, etc.

So far I have this code to expire the posts after 30 days of the published date, which doesn’t seem to work. I assume I am missing something regarding the cron scheduling:

if ( ! wp_next_scheduled( 'run_post_expiration' ) ) {
    wp_schedule_event( time(), 'hourly', 'run_post_expiration' );
add_action( 'run_post_expiration', 'expire_posts' );

function expire_posts() {
    global $wpdb;
    $daystogo = "30";
    $sql = "UPDATE wp_posts 
        SET `post_status` = 'draft' 
        WHERE `post_type` = 'profile' 
        AND DATEDIFF(NOW(), `the_date`) > '$daystogo')";
add_action('init', 'expire_posts');

I have this code to set the post_date to the post_modified date, therefore enabling the code above to still work every 30 days:

function reset_post_date_wpse_121565($data,$postarr) {
    $data['post_date'] = $data['post_modified'];
    $data['post_date_gmt'] = $data['post_modified_gmt'];      
    global $post;
    if ($post->post_type == 'profile'){
        return $data;

The above code to modify the post_date does actually work, but it is also causing some problems with other post types which I wasn’t expecting, so I think there may be an error somewhere.

Can anybody help me to get this to work? Or am I even going about this in the right way? Perhaps there is a better solution. I have tried the “Post Expirator” plugin, but this only works with the post_date; once someone has updated their profile once, it no longer works.


I edited the original code to set the posts to draft to this (based on some code I found elsewhere):

add_action( 'my_trash_hook', 'my_trash_hook_function' );
if (!wp_next_scheduled('my_trash_hook')) {
    wp_schedule_event( time(), 'hourly', 'my_trash_hook' );

function my_trash_hook_function() {
    global $wpdb;
    $daystogo = "1";
    $sql = "UPDATE {$wpdb->posts}
        SET 'post_status' = 'draft'
        WHERE 'post_type' = 'tests'
        AND DATEDIFF(NOW(), 'the_date') > '$daystogo')";

I have another function set up to send me an email when the post is set to draft and another to send me an email when the post is published again.

What is happening is that when I log in to the site I am sent an email saying the post has been published, but not one saying the post was set to draft. Not sure if the two pieces of code are conflicting with each other or just plain wrong.

user36987 4 months 0 Answers 14 views 0

Leave an answer