Tag Archives: WP Cron

Prevent WordPress from automatically purging trash from custom post type

Preface

WordPress has a constant called EMPTY_TRASH_DAYS that it automatically sets to 30. What that means is that WordPress will automatically delete all posts, pages, custom post types, etc, that have been in the trash for 30 or more days.

1
2
3
4
5
6
7
8
// wp-includes/default-constants.php
 
function wp_functionality_constants( ) {
    ...
    if ( !defined( 'EMPTY_TRASH_DAYS' ) )
        define( 'EMPTY_TRASH_DAYS', 30 );
    ...
}
// wp-includes/default-constants.php

function wp_functionality_constants( ) {
	...
	if ( !defined( 'EMPTY_TRASH_DAYS' ) )
		define( 'EMPTY_TRASH_DAYS', 30 );
	...
}

Whenever you trash a post, WordPress creates a meta field called _wp_trash_meta_time containing the time it was trashed.

1
2
3
4
5
6
7
// wp-includes/post.php
 
function wp_trash_post($post_id = 0) {
    ...
    add_post_meta($post_id,'_wp_trash_meta_time', time());
    ...
}
// wp-includes/post.php

function wp_trash_post($post_id = 0) {
	...
	add_post_meta($post_id,'_wp_trash_meta_time', time());
	...
}

WordPress has a daily event scheduled…

1
2
3
4
// wp-admin/admin.php
 
if ( !wp_next_scheduled('wp_scheduled_delete') && !defined('WP_INSTALLING') )
    wp_schedule_event(time(), 'daily', 'wp_scheduled_delete');
// wp-admin/admin.php

if ( !wp_next_scheduled('wp_scheduled_delete') && !defined('WP_INSTALLING') )
	wp_schedule_event(time(), 'daily', 'wp_scheduled_delete');

…that will run a function called wp_scheduled_delete to permanently delete all expired posts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// wp-includes/functions.php
 
function wp_scheduled_delete() {
    global $wpdb;
 
    $delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
 
    $posts_to_delete = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);
 
    foreach ( (array) $posts_to_delete as $post ) {
        $post_id = (int) $post['post_id'];
        if ( !$post_id )
            continue;
 
        $del_post = get_post($post_id);
 
        if ( !$del_post || 'trash' != $del_post->post_status ) {
            delete_post_meta($post_id, '_wp_trash_meta_status');
            delete_post_meta($post_id, '_wp_trash_meta_time');
        } else {
            wp_delete_post($post_id);
        }
    }
    ...
}
// wp-includes/functions.php

function wp_scheduled_delete() {
	global $wpdb;

	$delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );

	$posts_to_delete = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);

	foreach ( (array) $posts_to_delete as $post ) {
		$post_id = (int) $post['post_id'];
		if ( !$post_id )
			continue;

		$del_post = get_post($post_id);

		if ( !$del_post || 'trash' != $del_post->post_status ) {
			delete_post_meta($post_id, '_wp_trash_meta_status');
			delete_post_meta($post_id, '_wp_trash_meta_time');
		} else {
			wp_delete_post($post_id);
		}
	}
	...
}

Continue reading