Make WordPress Core

Changeset 19778


Ignore:
Timestamp:
01/28/2012 08:40:55 PM (15 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.