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:
- Everytime a post is published get the 51th post id (ordered by publish date)
- 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 );
}
}