Auto delete WordPress images/thumbnails (all sizes) and featured after X days/hours, or similar?

I am looking for solution to auto delete images of old posts in WordPress site. I want to hold images of current 50 posts, others should be deleted automatically. It can be function to delete on time interval, or function to hold only images of last 50 posts. Does anyone know function or some plugin which can do this or similar things, to automatically delete older images? I believe that setting a cron job will be needed.

Someone posted this function in stackoverflow but I don’t see any mention of time.


function delete_post_media( $post_id ) {

    $attachments = get_posts( array(
        'post_type'      => 'attachment',
        'posts_per_page' => -1,
        'post_status'    => 'any',
        'post_parent'    => $post_id
    ) );

    foreach ( $attachments as $attachment ) {
        if ( false === wp_delete_attachment( $attachment->ID ) ) {
            // Log failure to delete attachment.
        }
    }
}

Related posts

1 comment

  1. If you need to retain only images for last 50 posts, I don’t think that a cron job or a WP cron is the best thing you can do, in WordPress you can know when a post is published, and you can run a routine everytime it happen, deleting images for the post pubblished 50 posts ago.

    That’s easy, better performing (you do nothing if you have nothing to do, a cron job runs regardless you have something to delete or not).

    The workflow is pretty easy:

    1. Everytime a post is published get the 51th post id (ordered by publish date)
    2. delete all images having that id as post parent

    the code:

    add_action( 'save_post', 'cleanup_old_post_images', 10, 3 );
    
    function cleanup_old_post_images( $post_ID, $post, $update ) {
      if ( $update ) return; // do nothing on update
      $postid51th = get51th_postid(); // see below
      if ( ! empty( $postid51th ) && is_numeric( $postid51th ) ) {
        delete_post_media( $postid51th ); // see below, function in OP
      }
    }
    
    function get51th_postid() {
      return $GLOBALS['wpdb']->get_var(
        "SELECT ID FROM " . $GLOBALS['wpdb']->posts .
        " WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC
        LIMIT 50, 1"
      ); 
    }
    
    function delete_post_media( $post_id ) {
      $attachments = get_posts( array(
        'post_type'      => 'attachment',
        'nopaging'       => TRUE,
        'post_parent'    => $post_id
      ) );
      if ( empty( $attachments ) ) return; // added this line to prevent errors
      foreach ( $attachments as $attachment ) {
        if ( false === wp_delete_attachment( $attachment->ID ) ) {
          // Log failure to delete attachment.
        }
      }
    }
    

    This works for posts published after you put the code in the site, but you can write a run-once function to delete images for older posts

    add_action( 'shutdown', 'delete_older_attachments' );
    
    function delete_older_attachments() {
    
      // run only on admin and use a transient to run once
      if ( ! is_admin() || get_transient('get_older_postids') ) return;     
    
      // the query to exclude last 50 posts
      $latest_query = "SELECT ID FROM " . $GLOBALS['wpdb']->posts .
        " WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC
        LIMIT 50"
      );
    
      // get older posts ids
      $older_ids = $GLOBALS['wpdb']->get_row(
        "SELECT ID FROM " . $GLOBALS['wpdb']->posts . 
        " WHERE post_type = 'post' AND post_status = 'publish'
        AND ID NOT IN (" . $latest_query . ")"
      );
    
      // get attachments for older posts
      if ( ! empty( $older_ids ) && is_array( $older_ids )  ) {
        $attachments = $GLOBALS['wpdb']->get_row(
          "SELECT ID FROM " . $GLOBALS['wpdb']->posts . 
          " WHERE post_type = 'attachments'
          AND post_parent IN (" . implode( ',', $older_ids ) . ")"
        );
      }
    
      if ( isset($attachments) && ! empty( $attachments ) && is_array( $attachments )  ) {
        foreach ( $attachments as $attachment ) {
          if ( false === wp_delete_attachment( $attachment ) ) {
            // Log failure to delete attachment.
          }
        }
        // set the transient to assure run once
        set_transient( 'get_older_postids', 1 );
      }
    }
    

Comments are closed.