Update Old Links To Pretty Permalinks Custom Post Type

You can cycle your posts, extract urls and then look at the query vars in them to create the proper link, an finally replace old links with new in post_content.

This kind of work should be runned once, so I suggest to create a plugin and run this function on deactivation.

I also created an helper function to extract urls from post content. WP 3.7 comes with a core function wp_extract_urls, however this function return url without query vars, so is useless for our scope.

<?php
/**
 * Plugin Name: Url Replacer
 * Author: G.M.
 */

register_deactivation_hook( __FILE__, 'gm_replace_my_old_urls' );

function my_extract_urls( $content ) {
  preg_match_all("#<a.*?href=[\"\'](http[s]*://[^>\"]*?)[\"\'][^>]*?>(.*?)</a>#si", $content, $urls);  
  $urls = array_unique( array_map( 'html_entity_decode', $urls[1] ) );
  return array_values( $urls );
}

function gm_replace_my_old_urls() {
  $query = new WP_Query( array('posts_per_page' => -1) );
  if ( empty($query->posts) ) return;
  foreach ( $query->posts as $post ) {
    $urls = my_extract_urls($post->post_content); 
    if ( empty($urls) ) continue;
    $new = array();
    $old = array();
    foreach ( $urls as $url ) {
      if ( ! substr_count( $url, home_url() ) ) continue; // external url
      $url_array = explode( '?', $url );
      $qs = array();
      if ( count($url_array) == 2 ) parse_str( $url_array[1], $qs );
      if ( ! isset($qs['p']) && ! isset($qs['page_id']) ) continue;
      $id = isset($qs['p']) ? $qs['p'] : $qs['page_id'];
      $link = get_permalink($id);
      if ( ! $link ) continue;
      $old[] = $url;
      $new[] = $link;
    }
    if ( ! empty($new) ) {
      $post = (array)$post;
      $post['post_content'] = str_replace($old, $new, $post['post_content']);
      wp_update_post($post);
    }
  }
}

Save this code in a file and save in plugin folder. After that go in your dashboard and activate it. Nothing should happen. Now disable the plugin. It should take some seconds when plugin is deactivated go to check your posts…

Leave a Comment