Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

A group that I joined created a wordpress site before I joined. they did not set up permalinks for the site. So when I took over maintaining the site, I been optimizing the site both for SEO and speed. So I am getting to the posts task, which contain links to other posts on the same site, but because permalinks were off they look like http://THE_SITE/index.php?post_id=432 within every post. I already enabled the %postname% permalink, so google is already updating its urls because of the 301's, but the problem is the posts still have the old default links.

So the question is: What is the best way to update the old links to the new permalinks

share|improve this question
2  
What you're asking is not an insignificant amount of work, and if you ask me, it's really not worth doing. The 301 redirects and canonical meta tags mean that no search engine will index the old URLs, they'll index the correct ones. There's only one real reason to do what you're asking: reduce load on your server (each link will result in two requests due to the redirect). If you still feel the need to move forward with it, I personally think it qualifies as a question "that require[s] professional hands-on involvement" as detailed in the FAQ –  Matthew Boynes May 29 '13 at 1:17

1 Answer 1

up vote 1 down vote accepted

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|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.
}

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.

share|improve this answer
    
This actually works perfectly. Very useful if someone starts a WordPress and never turns on permalinks in the beginning. Thanks a lot! –  joebl86 May 30 '13 at 4:38
1  
I just had to change the query name so it catches both ?p and ?post_id –  joebl86 May 30 '13 at 5:04
    
@joebl86 Thanks for the heads up, answer updated. –  TheDeadMedic May 31 '13 at 6:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.