Here is an idea but before we go into details, here are VERY VERY IMPORTANT notes
NOTE: READ THIS FIRST
-
Take a database back up before running this code. It is advisable to run this on a local install first for testing purposes.
-
Note on
wp_trash_post()
, from the codexIf trash is disabled, the post or page is permanently deleted.
-
I have tested the code, and it works. You can however make changes to it to suite your needs. As it stands, the code should only delete posts when a new post is published
WORKSFLOW
What we need to do is
-
Run a custom function to delete posts when ever a new post is published. For this, we will use the
transition_post_status
hook. Just one note, this hook fires when a post is published, trashed, updated and untrashed. We will need to restrict our custom function to only run when a post is published. This line,if ( $new_status == 'publish' && $old_status != 'publish' )
will take care of that -
Use
get_posts()
to get all the published posts. You can adjust this to suite your needs. We only need the post ids, so this is what we will get. It makes the query really fast and does not eat up resources -
The returned array of posts from
get_posts()
needs to be counted, and if there are more than a 1000 posts, we need to get the post ids after the first thousand posts. we will usearray_slice
here -
We need to run
wp_trash_post
if we have more than 1000 posts to trash these posts. If you need to delete everything attached to the post as well, you can usewp_delete_post
here instead ofwp_trash_post
. You can just uncomment this line,wp_delete_post( $trash_post );
in the code and comment this line outwp_trash_post( $trash_post );
. Do not run both at the same time
PUTTING IT INTO CODE
The code is well commented as well, so it will be easy to follow. Just one note, you will need a minimum of PHP5.4+ installed on your server due to the use of new array syntax. Also note, closures needs a minimum of PHP5.3
add_action( 'transition_post_status', function ( $new_status, $old_status, $post )
{
// Run this only when a new post is publish to save on unnecessary waste of resources
if ( $new_status == 'publish' && $old_status != 'publish' ) {
/*
* Use get_posts() to count all the posts published, get only post ids to improve performance
* This array of post ids will also be used to get the post ids of posts to be trashed
*/
$total_posts = get_posts( ['posts_per_page' => -1, 'fields' => 'ids'] );
// Count the amount of posts in the returned array from get_posts
$count = count( $total_posts );
// Run the following only if we have more than a thousand posts
if ( $count > 1000 ) {
// Get all post id after the first 1000 posts
$set_to_trash = array_slice( $total_posts, 1000 );
foreach ( $set_to_trash as $trash_post ) {
// Use wp_trash_post to trash the posts
wp_trash_post( $trash_post );
// You can also use wp_delete_post here to delete everything attached to the post
//wp_delete_post( $trash_post );
}
// Unset $trash_post for safety
unset( $trash_post );
}
}
}, 10, 3 );
TO CONCLUDE
You can set your installation to permanently delete trashed posts by adding the following line to wp-config.php
define('EMPTY_TRASH_DAYS', 0 );
Just note, this will permanently delete posts and they cannot be recovered