wp cli, save-permalink

This custom wp cli script saves the original permalink as post meta for comparisons later after changing permalink structure.

To run, type wp save-permalink. It will go through all posts and add a meta_key of be_original_permalink with the current permalink as the value.

While this specific functionality might not be useful to most, you can use this as a guide to creating your own custom wp cli scripts.

Any time I need to update a large number of posts, I use wp cli because it’s fast and won’t time out. It also lets me ensure the code only executes once.

<?php
//Check to make sure WP_CLI is running. This way our code isn't loaded on normal site visits.
if ( defined('WP_CLI') && WP_CLI ) {

	class BE_Save_Permalink extends WP_CLI_Command {

		public $step = 1;
		public $per_step = 100;
		public $post_count = 0;
		public $max_num_pages = 0;
		private $complete = false;

		public function __invoke( $args, $assoc_args ) {

			$args = array(
				'posts_per_page' => - 1,
				'post_type'      => 'post',
				'fields'         => 'ids',
			);
			$post_ids = new WP_Query( $args );
			$this->post_count = count( $post_ids->posts );

			// always round up.
			// 80 total posts / 100 posts per step = .8 -> round this up to one page
			// 120 total posts / 100 posts per step = 1.2 -> round this up to two pages
			$this->max_num_pages = ceil( $this->post_count / $this->per_step );

			wp_reset_postdata();
			WP_CLI::line( 'Found ' . $this->post_count . ' posts' );


			while( false === $this->complete ){
				$this->process_step();
			} // end while

		} // end function

		private function process_step(){

			// check to see if we've exceeded the pages
			if( $this->max_num_pages < $this->step ){
				$this->complete = true;
				WP_CLI::line( 'We have exceeded the number of pages. Ending.' );
				return;
			} // end if

			$args = array(
				'posts_per_page' => $this->per_step,
				'paged' => $this->step,
				'post_type' => 'post',
				'no_found_rows' => true,
				'update_post_term_cache' => false
			);
			$my_query = new WP_Query( $args );

			if( $my_query->have_posts() ):

				while ( $my_query->have_posts() ) : $my_query->the_post();
					update_post_meta( get_the_ID(), 'be_original_permalink', get_permalink() );


					// Leave this off if dealing with thousands of posts
					// WP_CLI::line( 'Updated post with ID  ' . get_the_ID() );

				endwhile;

				// increment our step
				WP_CLI::line( 'Completed Step #' . $this->step);
				$this->step++;

			else:
				WP_CLI::line( 'ERROR! Query returned no posts!' );
			endif;

			wp_reset_postdata();
		} // end function
	} // end class

	WP_CLI::add_command( 'save-permalink', 'BE_Save_Permalink', [
		'shortdesc'	=> 'Saves the original permalink as post meta for comparisons later after changing permalink structure',
	] );

}// end if
Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk