Clean Up the Playground WordPress Plugin

I looked around for a WordPress plugin that would delete content every X hours and didn’t find anything. It may be this is a strange desire or I could be bad at searching but in any case I built something to do that.

The idea I had was that people in a multisite environment could try out sites and get a good feel for how the plugin/theme would work but without the barrier of adding it to their site or creating an entirely new site.

The plugin also creates a page that has the shortcode on it which will trigger the cleansing manually.


I assume we’re going to delete all the content that wasn’t created by the admin. That lets us leave some directions and some demo content if needed that will persist after the site is purged of content.

I figured we’d auto-add people using the Join My Multisite plugin and setting the user to editor or lower. It might make more sense to create a custom role and/or restrict the ability to maliciously or accidentally change the author of content.

I used wp_schedule_event and set the refresh at every 24hrs.

I am only deleting pages, posts, and media. I haven’t gotten around to finding/deleting custom post types.

Plugin Name: Playground Cleaner - 24hr deleter of non-admin users and content
Plugin URI:
Description: delete non-admin users and content every 24 hours, use in conjunction with join my multisite or other way to add users
Version:     1.0
Author:      Tom Woodward
Author URI:
License:     GPL2
License URI:
Domain Path: /languages
Text Domain: my-toolset

defined( 'ABSPATH' ) or die( 'No script kiddies please!' );

function get_users_and_destroy_them(){
	$blog_id = get_current_blog_id();
	$args = array(
	'role__not_in' => array('Administrator'),	//leave the admins alone
	$users = get_users( $args );
	foreach ($users as $key => $user) {
		echo $user->ID;
		$posts = new WP_Query( array( 'author' => $user->ID ) );
		remove_user_from_blog($user->ID, $blog_id, NULL);

function get_content_and_destroy_it($user_id){
	$args = array(
		'author' => $user_id,
		'post_type' => array('post','page','attachment'),// add foreach ( get_post_types( '', 'names' ) as $post_type  to deal w custom post types - also attachments
    	'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash'),    
		'posts_per_page' => -1,

	$the_query = new WP_Query( $args );
	// The Loop
	if ( $the_query->have_posts() ) :
		while ( $the_query->have_posts() ) : $the_query->the_post();
			if (get_post_type() === 'post' || get_post_type() === 'page'){
			  wp_delete_post( get_the_id(), TRUE );
			if (get_post_type() === 'attachment'){
			  wp_delete_attachment( get_the_id(), TRUE );

	// Reset Post Data


add_shortcode( 'destroy', 'get_users_and_destroy_them' );

//only show your own posts/pages in admin land
function posts_for_current_author($query) {
    global $pagenow;
    if( 'edit.php' != $pagenow || !$query->is_admin )
        return $query;
    if( !current_user_can( 'activate_plugins' ) ) {
        global $user_ID;
        $query->set('author', $user_ID );
    return $query;
add_filter('pre_get_posts', 'posts_for_current_author');

//make a page that allows you to manually delete by visiting the page and stores the hours for the cron job

function make_destroy_page(){
	} else {
		$my_post = array(
		  'post_title'    => 'destroy',
		  'post_content'  => '[destroy]',
		  'post_status'   => 'publish',
		  'post_author'   => 1,
		  'post_type'	=> 'page',	
		// Insert the post into the database
		$post_id = wp_insert_post( $my_post );
		update_post_meta($post_id, 'destroy_content_pattern','48');

register_activation_hook( __FILE__, 'make_destroy_page' );

//make it run every 24 hrs & deactivate if plugin deactivated
register_activation_hook(__FILE__, 'scheduled_purge');

function scheduled_purge() {
    if (! wp_next_scheduled ( 'my_scheduled_purge' )) {
	wp_schedule_event(time(), 'daily', 'my_scheduled_purge'); //change back to daily 

add_action('my_scheduled_purge', 'get_users_and_destroy_them');

//turn off purge if plugin deactivated
register_deactivation_hook(__FILE__, 'purge_deactivation');
function purge_deactivation() {

1 Acknowledged laziness.

Privacy Statement