WordPressでパーマリンクのカスタム構造を変更した時、404を回避するリダイレクト処理をfunctions.phpへ書く

設定>パーマリンク設定でカスタム構造を/%postname%/から/news/%category%/%postname%/に変更した時に投稿ページが404になるので、下記をfunctions.phpに記述。slugの値を探してリダイレクトしてる。

固定ページもリダイレクトされないようにするのが地味に大変だった。ついでにカテゴリーページにつく/category/を削除する記述も追記してる。

カテゴリーページの下層に、そのカテゴリーの投稿ページを置くことで、カテゴリーページのSEOを強くするのが目的。

/*
redirect single post
*/
add_action( 'template_redirect', 'redirect_single_post_url' );
function redirect_single_post_url() {
  if( is_404() ){
	
	global $wp;
	//x $url = get_permalink();	// 空文字列だ
	$url = home_url( $wp->request );
	$url_arr = explode('/', $url);
	// delete empty array values
	$url_arr=array_filter($url_arr, function($value) { return !is_null($value) && $value !== ''; });
	//slug set last array value
    $post_slug = array_pop($url_arr);
    $args = array(
      'name'        => $post_slug,
      'post_type'   => 'post',
      'post_status' => 'publish',
      'numberposts' => 1
    );
    $my_posts = get_posts($args);
    if( $my_posts ) {
        $post_id = $my_posts[0]->ID;
        echo $url_new = get_permalink($post_id);
    		wp_safe_redirect( $url_new, 301 );
    }else{
    		wp_safe_redirect( home_url( '/' ), 301 );
        
    }
    exit();
  }
}
/*
 no category setting (don't work wpml and yoast not category setting)
*/
function remcat_function($link) {
return str_replace("/category/", "/", $link);
}
add_filter('user_trailingslashit', 'remcat_function');
function remcat_flush_rules() {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
add_action('init', 'remcat_flush_rules');
function remcat_rewrite($wp_rewrite) {
$new_rules = array('(.+)/page/(.+)/?' => 'index.php?category_name='.$wp_rewrite->preg_index(1).'&paged='.$wp_rewrite->preg_index(2));
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_filter('generate_rewrite_rules', 'remcat_rewrite');