Fill a WordPress Site with Data (a Large Number of Posts) and Comments (for Testing)

It so happened that it was necessary to test something on WordPress and the blog needed to contain a lot of information, a large number of posts and comments, i.e. a large amount of content was required. I decided to quickly write a couple of functions to quickly fill the site with a huge number of demo posts. I think it will come in handy in the future. And since it may come in handy not only for me, I'm sharing the results.

To populate the site with test data to check the structure and layout, see this instruction.

Here's the code that can be placed in your favorite function.php:

$filler = new Fill_Database_Posts(
	$_GET['fill_db'] ?? 0,
	$_GET['fill_db_comments'] ?? 0,
	$_GET['cats'] ?? '',
	$_GET['tags'] ?? '',
);
$filler->init();

/**
 * ?fill_db=3000&cats=1|3&tags=tag1|tag2|tag3
 * ?fill_db_comments=3000
 */
class Fill_Database_Posts {

	private int $fill_limit;
	private int $fill_limit_comments;
	private string $cats;
	private string $tags;

	public function __construct( $fill_limit, $fill_limit_comments, $cats, $tags ) {
		$this->fill_limit = (int) $fill_limit ?: 50;
		$this->fill_limit_comments = (int) $fill_limit_comments ?: 50;
		$this->cats = sanitize_text_field( $cats );
		$this->tags = sanitize_text_field( $tags );
	}

	public function init() {
		add_filter( 'init', [ $this, '_fill_db' ] );
	}

	public function _fill_db() {
		wp_suspend_cache_addition( true ); // disable caching

		$this->fill_content();
		$this->fill_comments();
	}

	// ?fill_db=3000&cats=1|3&tags=tag1|tag2|tag3
	private function fill_content() {

		for( $i = 1; $i <= $this->fill_limit; $i++ ){
			$rand = rand( 1, 99999 );

			$content = '';
			for( $g = 0; $g < 30; $g++ ){
				$content .= "next post with random number: $rand . ";
			}

			$post_date = $this->get_random( '2020|2021|2022|2023' ) . '-0' . rand( 1, 9 ) . '-' . rand( 10, 30 ) . ' 23:25:59';

			$postid = wp_insert_post( wp_slash( [
				'comment_status' => $this->get_random( 'closed|open' ),
				'ping_status'    => $this->get_random( 'closed|open' ),
				'post_category'  => array_filter( [ (int) $this->get_random( $this->cats ?: '1' ) ] ),
				'tags_input'     => array_filter( [ (int) $this->get_random( $this->tags ?: '' ) ] ),
				'post_type'      => 'post',
				'post_title'     => "Post with a random number $rand",
				'post_content'   => $content,
				'post_date'      => $post_date,
				'post_status'    => 'publish',
			] ) );

			if( $postid ){
				$this->add_post_metadata( $postid );
			}

			flush();
		}
	}

	// ?fill_db_comments=3000
	private function fill_comments() {
		global $wpdb;

		$post_ids = $wpdb->get_col(
			"SELECT ID FROM $wpdb->posts WHERE post_status='publish' AND post_type='post' AND comment_status='open' ORDER BY rand() LIMIT 150"
		);

		for( $i = 1; $i <= $this->fill_limit_comments; $i++ ){
			$rand = rand( 1, 99999 );

			$content = '';
			for( $g = 0; $g < 5; $g++ ){
				$content .= "comment: $rand . ";
			}
			$post_date = $this->get_random( '2009|2011' ) . '-0' . rand( 1, 9 ) . '-' . rand( 10, 30 ) . ' 23:25:59';

			$postid = wp_insert_comment( [
				'comment_post_ID'      => (int) $post_ids[ array_rand( $post_ids ) ],
				'comment_author'       => 'commentator name',
				'comment_author_email' => '[email protected]',
				'comment_author_url'   => '',
				'comment_content'      => $content,
				'comment_author_IP'    => '127.0.0.1',
				'comment_agent'        => 'Opera 10.0',
				'comment_date'         => $post_date,
				'comment_approved'     => 1,
			] );

			flush();
		}

	}

	// Add a custom field "views" to the created posts
	private function add_post_metadata( $post_id ) {
		update_post_meta( $post_id, 'views', rand( 10, 9999999 ) );
	}

	private function get_random( $data = '' ) {
		$arg = explode( '|', $data );
		$rand_key = array_rand( $arg );

		return $arg[ $rand_key ];
	}
}

I won't explain in detail what and why. In a few words, here's how it works:

To fill the blog with posts

Append to the URL something like this:

?fill_db=3000&cats=1|3&tags=tag1|tag2|tag3

where 3000 - the number of posts to be added. cats=1|3 - posts will be randomly added to category 1 or 3. tags=tag1|tag2|tag3 - posts will be assigned one of the tags (using Cyrillic is not allowed, specify slugs).

The posts also get a custom field "views" filled with views. Edit the function fill_db_with_metadata_add_views() to change the addition of custom fields.

To fill with comments

Append to the URL something like this:

?fill_db_comments=3000

Comments will be "left" on random posts open for commenting. 3000 - the number of comments.

As for where this can be applied? Anywhere - fill the blog and test its speed; with 100k posts, obvious "issues" come out immediately. You can test templates, functions, individual database queries, or something else.