A quick custom plugin to import redirections into Safe Redirect Manager

At Code for the People we’ve just imported a load of blogposts from Drupal into WordPress. One of the differences is that Drupal encodes fancy characters, like typographically nice “quote marks”, into the URL whereas WordPress mostly drops them. We ended up with about 80 URLs which had changed and the need for a redirections plugin… enter Safe Redirect Manager by Taylor Lovett at 10up. I didn’t want to manually type in 80 redirects though, I wanted to get them in automatically and to this end I wrote a quick custom plugin which hooked into Safe Redirect Manager in a couple of places.

The plugin does require a change to Safe Redirect Manager to make it possible to use the public methods in another plugin. I’ve submitted a pull request to Taylor, and hopefully he’ll consider the change. If you want to temporarily make a hack yourself, change the last line of the Safe Redirect Manager plugin from this:

new SRM_Safe_Redirect_Manager();

to this:

global $safe_redirect_manager;
$safe_redirect_manager = new SRM_Safe_Redirect_Manager();

To use the plugin below yourself, you will need to amend the $redirects array to contain the redirections you need with the key being the from URL and the value being the to URL.

<?php
/*
Plugin Name: Safe Redirect Manager - IMPORT
Plugin URI: http://www.codeforthepeople.com/?plugin=safe-redirects-manager-import

GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/

/**
 * @uses post_exists, wp_insert_post, update_post_meta, SRM_Safe_Redirect_Manager::sanitize_redirect_from, SRM_Safe_Redirect_Manager::sanitize_redirect_to
 * @return void
 */
function srm_import_init() {
	$redirects = array(
		'http://www.example.com/blog/%E2%80%99s-banker-bashing' => 'http://www.example.com/blog/banker-bashing/',
		'http://www.example.com/blog/your-peril%E2%80%A6' => 'http://www.example.com/blog/your-peril/',
	);
	
	foreach ( $redirects as $from => $to ) {
		// Using a hash of the redirect on the post title means
		// that is unique and we can use the importer (otherwise the
		// importer doesn't recognise the redirects created at the
		// same time as unique, and doesn't import them).
		$key = md5( $from . $to );
		if ( post_exists( $key ) )
			continue;
		$postdata = array(
			'post_type' => $GLOBALS[ 'safe_redirect_manager' ]->redirect_post_type,
			'post_status' => 'publish',
			'comment_status' => 'closed',
			'ping_status' => 'closed',
			'post_title' => $key,
		);
		$post_id = wp_insert_post( $postdata );
		update_post_meta( $post_id, $GLOBALS[ 'safe_redirect_manager' ]->meta_key_redirect_from, $GLOBALS[ 'safe_redirect_manager' ]->sanitize_redirect_from( $from ) );
		update_post_meta( $post_id, $GLOBALS[ 'safe_redirect_manager' ]->meta_key_redirect_to, $GLOBALS[ 'safe_redirect_manager' ]->sanitize_redirect_to( $to ) );
		update_post_meta( $post_id, $GLOBALS[ 'safe_redirect_manager' ]->meta_key_redirect_status_code, 301 );
	}
}
add_action( 'admin_init', 'srm_import_init' );

function srmi_admin_notices() {
	?>
<div class="updated fade"><p>The redirects have been imported and <strong>the Safe Redirect Manager - IMPORT plugin should now be uninstalled</strong>.</p></div>
	<?php
}
add_action( 'admin_notices', 'srmi_admin_notices' );

You’ll notice I’m setting the post_title to an MD5 hash of the from and to URLs, this allows me to use WordPress’ builtin post_exists to check if the post exists by looking up the title; note that the post_exists function is only available when in the admin area, but we’re doing the import on admin_init action so that’s OK. Making the titles unique like this also means I can use the WordPress export/import process to move the redirects to another site, otherwise the WordPress importer sees a number of posts with no title, no content and the same date, and it thinks they are all the same post (because it’s using the post_exists function only checks title, content and date).

For safety and to make it easier to see what was going on (and recover if I made an error), I ran this on my dev site, made sure the redirects were all working, then exported using the WordPress exporter and imported on the client’s production site.

As soon as the plugin has been activated, you can deactivate it… and it’ll keep bugging you with an admin notice until you do. Always good to keep the place tidy.

Join the Conversation

1 Comment

  1. This is awesome! Saved me a ton of manual labor. Because of my server situation, I was unable to just add my 1000+ redirects to an .htaccess file. This worked perfectly. I’d recommend doing in batches, as I got a 502 error after about 600 had processed.

    The pull request you made is part of the plugin now. Looks like an importer is coming at some point. Right now, there’s a built in way to do it, but only with WordPress-CLI: https://github.com/tlovett1/Safe-Redirect-Manager/issues/97

    There’s also a maximum limit on the redirects, which was set for “performance” reasons, but can be adjusted with a filter. Your plugin ignores the limit, but the message will be visible in the admin area. Filter code: https://twitter.com/tlovett12/status/562623027092160513

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.