Skip to main content
added 12 characters in body
Source Link
TheDeadMedic
  • 36.6k
  • 9
  • 68
  • 102
require 'wp-load.php'; // Only needed if *not* a plugin.

function out_with_the_old( $match ) {
    global $links;
    
    if ( ! isset( $links[ $match[1] ] ) ) { // Cache to save subsequent hits. 
        $links[ $match[1] ] = get_permalink( $match[1] );
        clean_post_cache( $match[1] );
    }
    
    return $links[ $match[1] ] ? $links[ $match[1] ] : $match[0]; // Just fallback to original URL if new permalink void (for whatever reason).
}

$links = array();
$posts = get_posts(
    array(
        'posts_per_page' => -1,
        'post_status'    => 'any',
        'post_type'      => 'any',
        'fields'         => 'ids', // Getting *everything* will most likely hit the memory limit.
    )
);

// Loop over each post & replace all old instances of the permalink with the new one.
foreach ( $posts as $post_id ) {
    $save = array();
    $post = get_post( $post_id );
    
    foreach ( array( 'post_content', 'post_excerpt' ) as $field ) {
        // Replace "domain\.com" with your domain name, minus "www." (escape dots with a backslash).
        // The regex accommodates for various forms of the same URL, including SSL, no "www" & no index.php.
        $text = preg_replace_callback( "|https"!https?://(?:www\.)?domain\.com/(?:index\.php)?\?p=(?:p|post_id)=([0-9]+)|"!", 'out_with_the_old', $post->$field );
        
        if ( $text !== $post->$field )
            $save[ $field ] = $text;
    }
    
    if ( $save )
        $wpdb->update(
            $wpdb->posts,
            $save,
            array(
                'ID' => $post_id,
            ),
            '%s',
            '%d'
        );
    
    clean_post_cache( $post ); // Otherwise we might soon hit a memory limit.
}
require 'wp-load.php'; // Only needed if *not* a plugin.

function out_with_the_old( $match ) {
    global $links;
    
    if ( ! isset( $links[ $match[1] ] ) ) { // Cache to save subsequent hits. 
        $links[ $match[1] ] = get_permalink( $match[1] );
        clean_post_cache( $match[1] );
    }
    
    return $links[ $match[1] ] ? $links[ $match[1] ] : $match[0]; // Just fallback to original URL if new permalink void (for whatever reason).
}

$links = array();
$posts = get_posts(
    array(
        'posts_per_page' => -1,
        'post_status'    => 'any',
        'post_type'      => 'any',
        'fields'         => 'ids', // Getting *everything* will most likely hit the memory limit.
    )
);

// Loop over each post & replace all old instances of the permalink with the new one.
foreach ( $posts as $post_id ) {
    $save = array();
    $post = get_post( $post_id );
    
    foreach ( array( 'post_content', 'post_excerpt' ) as $field ) {
        // Replace "domain\.com" with your domain name, minus "www." (escape dots with a backslash).
        // The regex accommodates for various forms of the same URL, including SSL, no "www" & no index.php.
        $text = preg_replace_callback( "|https?://(?:www\.)?domain\.com/(?:index\.php)?\?p=([0-9]+)|", 'out_with_the_old', $post->$field );
        
        if ( $text !== $post->$field )
            $save[ $field ] = $text;
    }
    
    if ( $save )
        $wpdb->update(
            $wpdb->posts,
            $save,
            array(
                'ID' => $post_id,
            ),
            '%s',
            '%d'
        );
    
    clean_post_cache( $post ); // Otherwise we might soon hit a memory limit.
}
require 'wp-load.php'; // Only needed if *not* a plugin.

function out_with_the_old( $match ) {
    global $links;
    
    if ( ! isset( $links[ $match[1] ] ) ) { // Cache to save subsequent hits. 
        $links[ $match[1] ] = get_permalink( $match[1] );
        clean_post_cache( $match[1] );
    }
    
    return $links[ $match[1] ] ? $links[ $match[1] ] : $match[0]; // Just fallback to original URL if new permalink void (for whatever reason).
}

$links = array();
$posts = get_posts(
    array(
        'posts_per_page' => -1,
        'post_status'    => 'any',
        'post_type'      => 'any',
        'fields'         => 'ids', // Getting *everything* will most likely hit the memory limit.
    )
);

// Loop over each post & replace all old instances of the permalink with the new one.
foreach ( $posts as $post_id ) {
    $save = array();
    $post = get_post( $post_id );
    
    foreach ( array( 'post_content', 'post_excerpt' ) as $field ) {
        // Replace "domain\.com" with your domain name, minus "www." (escape dots with a backslash).
        // The regex accommodates for various forms of the same URL, including SSL, no "www" & no index.php.
        $text = preg_replace_callback( "!https?://(?:www\.)?domain\.com/(?:index\.php)?\?(?:p|post_id)=([0-9]+)!", 'out_with_the_old', $post->$field );
        
        if ( $text !== $post->$field )
            $save[ $field ] = $text;
    }
    
    if ( $save )
        $wpdb->update(
            $wpdb->posts,
            $save,
            array(
                'ID' => $post_id,
            ),
            '%s',
            '%d'
        );
    
    clean_post_cache( $post ); // Otherwise we might soon hit a memory limit.
}
Source Link
TheDeadMedic
  • 36.6k
  • 9
  • 68
  • 102

Question interested me, so I took a shot. Not tested, so recommend backing up the wp_posts table before running (though you should do so regardless!)

As mentioned in the comments, don't forget to replace "domain.com" in the regular expression with your own.

require 'wp-load.php'; // Only needed if *not* a plugin.

function out_with_the_old( $match ) {
    global $links;
    
    if ( ! isset( $links[ $match[1] ] ) ) { // Cache to save subsequent hits. 
        $links[ $match[1] ] = get_permalink( $match[1] );
        clean_post_cache( $match[1] );
    }
    
    return $links[ $match[1] ] ? $links[ $match[1] ] : $match[0]; // Just fallback to original URL if new permalink void (for whatever reason).
}

$links = array();
$posts = get_posts(
    array(
        'posts_per_page' => -1,
        'post_status'    => 'any',
        'post_type'      => 'any',
        'fields'         => 'ids', // Getting *everything* will most likely hit the memory limit.
    )
);

// Loop over each post & replace all old instances of the permalink with the new one.
foreach ( $posts as $post_id ) {
    $save = array();
    $post = get_post( $post_id );
    
    foreach ( array( 'post_content', 'post_excerpt' ) as $field ) {
        // Replace "domain\.com" with your domain name, minus "www." (escape dots with a backslash).
        // The regex accommodates for various forms of the same URL, including SSL, no "www" & no index.php.
        $text = preg_replace_callback( "|https?://(?:www\.)?domain\.com/(?:index\.php)?\?p=([0-9]+)|", 'out_with_the_old', $post->$field );
        
        if ( $text !== $post->$field )
            $save[ $field ] = $text;
    }
    
    if ( $save )
        $wpdb->update(
            $wpdb->posts,
            $save,
            array(
                'ID' => $post_id,
            ),
            '%s',
            '%d'
        );
    
    clean_post_cache( $post ); // Otherwise we might soon hit a memory limit.
}

You could turn this into a plugin, but the cheap-n-easy way would be to dump into a script, FTP to the same directory as WordPress, then run in a browser.