Updated: added support of params

/* maybe redirect with permalinks change */
add_action( 'template_redirect', 'maybe_redirect_404_old_permalink' );
/**
 * Attempts to forward old permalinks to the new permalink structure
 *
 * @author Ben Lobaugh
https://ben.lobaugh.net/blog/202980/wordpress-add-category-to-permalink-and-redirect-old-permalinks
 */
function maybe_redirect_404_old_permalink() {
	// Only run this function if we are on a 404
	if( ! is_404() ) {
		return;
	}

	// "trick" to get the full URL
	$url = add_query_arg( '', '' );
    $regex = "#\?(.*?)$#smi";
    $params = "";
    if(preg_match($regex, $url, $match)) {
        $params = $match[1];
        $url = preg_replace($regex, '', $url);
    }
	/*
	 * Pull the URL path apart to find a slug (post_name)
	 * The final segment should be the slug
	 */
	$parts = explode( '/', $url );
	$parts = array_filter( $parts );
	$size = count( $parts );
	$maybe_slug = $parts[ $size ]; // We use size here because the filter turned 1 based

	// Attempt to locate corresponding post in the database
	$args = array(
			'name'        => $maybe_slug,
			'post_type'   => 'post',
			'post_status' => 'publish',
			'numberposts' => 1,
	);

	$posts = get_posts( $args );

	// Identify a found post
	if( $posts && ! empty( $posts[0]->ID ) ) {
		$post_id = $posts[0]->ID;

		$post_url = get_permalink( $post_id );

		// Attempt to forward to the new post permalink
		if( $post_url ) {
            if(!empty($params)) {
                $post_url .= "?" . $params;
            }
			wp_safe_redirect( $post_url, 301 ); // Permanent redirect
		}
	}

	/*
	 * If we made it down here then we could not find a matching post in
	 * the database. No biggie, simply do nothing and display the 404 page
	 * as normal
	 */
}

Leave a Reply

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