WordPress.org

Make WordPress Core

Changeset 19778


Ignore:
Timestamp:
01/28/12 20:40:55 (4 years ago)
Author:
duck_
Message:

Redirect bare category URLs for permalink structures starting with %category%. Fixes #19876.

When using a structure like /%category%/%postname%/ it might be thought that /uncategorized/
(missing the "/category/" base) results in the category archive. Previously this worked due to
$walk_dirs = true for the post permalink structure, but canonical didn't redirect it. Now
there is no rewrite rule to match => 404. The fix is to use a canonical redirect.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/canonical.php

    r19712 r19778  
    9494 
    9595        if ( ! $redirect_url ) 
    96             $redirect_url = redirect_guess_404_permalink(); 
     96            $redirect_url = redirect_guess_404_permalink( $requested_url ); 
    9797 
    9898    } elseif ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) { 
     
    418418 
    419419/** 
    420  * Attempts to guess correct post based on query vars. 
     420 * Attempts to guess the correct URL from the current URL (that produced a 404) or 
     421 * the current query variables. 
    421422 * 
    422423 * @since 2.3.0 
    423424 * @uses $wpdb 
    424425 * 
    425  * @return bool|string Returns False, if it can't find post, returns correct 
    426  *      location on success. 
     426 * @param string $current_url Optional. The URL that has 404'd. 
     427 * @return bool|string The correct URL if one is found. False on failure. 
    427428 */ 
    428 function redirect_guess_404_permalink() { 
    429     global $wpdb; 
    430  
    431     if ( !get_query_var('name') ) 
    432         return false; 
    433  
    434     $where = $wpdb->prepare("post_name LIKE %s", like_escape( get_query_var('name') ) . '%'); 
    435  
    436     // if any of post_type, year, monthnum, or day are set, use them to refine the query 
    437     if ( get_query_var('post_type') ) 
    438         $where .= $wpdb->prepare(" AND post_type = %s", get_query_var('post_type')); 
    439     if ( get_query_var('year') ) 
    440         $where .= $wpdb->prepare(" AND YEAR(post_date) = %d", get_query_var('year')); 
    441     if ( get_query_var('monthnum') ) 
    442         $where .= $wpdb->prepare(" AND MONTH(post_date) = %d", get_query_var('monthnum')); 
    443     if ( get_query_var('day') ) 
    444         $where .= $wpdb->prepare(" AND DAYOFMONTH(post_date) = %d", get_query_var('day')); 
    445  
    446     $post_id = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE $where AND post_status = 'publish'"); 
    447     if ( !$post_id ) 
    448         return false; 
    449     return get_permalink($post_id); 
     429function redirect_guess_404_permalink( $current_url = '' ) { 
     430    global $wpdb, $wp_rewrite; 
     431 
     432    if ( ! empty( $current_url ) ) 
     433        $parsed_url = @parse_url( $current_url ); 
     434 
     435    // Attempt to redirect bare category slugs if the permalink structure starts 
     436    // with the %category% tag. 
     437    if ( isset( $parsed_url['path'] ) 
     438        && preg_match( '#^[^%]+%category%#', $wp_rewrite->permalink_structure ) 
     439        && $cat = get_category_by_path( $parsed_url['path'] ) 
     440    ) { 
     441        if ( ! is_wp_error( $cat ) ) 
     442            return get_term_link( $cat ); 
     443    } 
     444 
     445    if ( get_query_var('name') ) { 
     446        $where = $wpdb->prepare("post_name LIKE %s", like_escape( get_query_var('name') ) . '%'); 
     447 
     448        // if any of post_type, year, monthnum, or day are set, use them to refine the query 
     449        if ( get_query_var('post_type') ) 
     450            $where .= $wpdb->prepare(" AND post_type = %s", get_query_var('post_type')); 
     451        if ( get_query_var('year') ) 
     452            $where .= $wpdb->prepare(" AND YEAR(post_date) = %d", get_query_var('year')); 
     453        if ( get_query_var('monthnum') ) 
     454            $where .= $wpdb->prepare(" AND MONTH(post_date) = %d", get_query_var('monthnum')); 
     455        if ( get_query_var('day') ) 
     456            $where .= $wpdb->prepare(" AND DAYOFMONTH(post_date) = %d", get_query_var('day')); 
     457 
     458        $post_id = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE $where AND post_status = 'publish'"); 
     459        if ( ! $post_id ) 
     460            return false; 
     461        return get_permalink( $post_id ); 
     462    } 
     463 
     464    return false; 
    450465} 
    451466 
Note: See TracChangeset for help on using the changeset viewer.