I registered a custom post type "job" to create job board site. Without a plugin, how can I make the posts auto change status to pending after 90 days? I am new in WordPress & PHP. I tried some solutions found on the internet, but not working.

Sorry that I don't really good in PHP, I can't write code myself. For testing, do these solutions need to wait for 1 days if I change the code expired 1 day? Cos I paste the code in my functions.php and nothing happened.

Tried Solutions: Code to auto expire posts after 30 days Automatically move pending posts after 30 days and, update the post date, when users update the posts Set post to draft after set period based on post_modified date Posts to expire (deleted) after a date

2 Answers 2


This is one of those questions that seem easy enough, but are actually quite complicated. If you don't want to use an existing plugin, you'll have to write your own (and hence learn more php as this is not a please-write-my-code-for-free-site). Here's an outline.

First you will need to select all the posts of type job which are older than 90 days and which have status "published". Like this:

$args = array(
  'post_type' => 'job',
  'date_query' => 'XXX',
  'post_status' => 'published',
  'nopaging' => true );
$wpse251989_query = wp_query ($args);

At XXX you will need to write a query selecting the date 90 days ago (you cannot just subtract 90 from today, because that will get you a negative day if it is not yet april).

Now, you must loop through all posts you retrieve and change the status.

if ( $wpse251989_query->have_posts() ) {
  while ( $wpse251989_query->have_posts() ) {
    wp_update_post(array ('post_status' => 'pending'));

If you dump this code in you functions.php it will be executed on every page load. You could get away with that if you have a powerful server. You could also put it behind a condition like is_admin, making sure it is only executed when an administrator is logged in. The safest way to make sure this is executed only once daily is using a cron job, which brings you into advanced php territory.

  • Thank you cjbj. You expain all steps very clearly. But sound like it is a bit difficult to a beginner. I still don't understand what is a cron job even if I google and found the answer. I also don't get why I can't directly put the 90 to replace XXX. If I decided to put those code in functions.php, what should I do next step? Sorry that I am still beginner to code, there are still many things I don't understand
    – Bryan
    Nov 6, 2019 at 13:24
  • The problem is that this is not a beginner's task. In practical terms the best you can do is find a plugin that will do this for you. date_query is a variable that lets you specify a range of dates. "90" is not a range of dates, just a number.
    – cjbj
    Nov 6, 2019 at 15:54
  • Even without knowing how to program it in PHP you should gather that if today is "27-03-2019" it takes some logic to figure out what 90 days earlier is.
    – cjbj
    Nov 6, 2019 at 15:58
  • 1
    I got that cjbj. I think the best solution for me now is using a plugin. Anyway, Thank you so much for your help
    – Bryan
    Nov 6, 2019 at 16:34

Try Below code in your functions.php

function expire_posts() {
  global $wpdb;
  $daystogo = "30";
  $sql = "UPDATE wp_posts SET `post_status` = 'draft' WHERE `post_type` = 'post' AND DATEDIFF(NOW(), `post_date`) > '$daystogo')";
  $wpdb->query( $sql );

add_action ('init' ,'expire_posts')
  • replace wp_with your db prefix Nov 6, 2019 at 9:48
  • 1
    This will check all posts older than 30 days every time a page is loaded. As the database grows this function will eat more and more processing power. Remember: reading from the database is cheap, but writing expensive in terms of processing time.
    – cjbj
    Nov 6, 2019 at 10:48
  • Pratikb.Simform Thank you for your suggestion.
    – Bryan
    Nov 6, 2019 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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