Better removal of query args in canonical redirects. Only remove them when they are not present in the redirect_url. fixes #20374

git-svn-id: http://svn.automattic.com/wordpress/trunk@20395 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
markjaquith 2012-04-07 01:03:55 +00:00
parent e60bdb8dc3
commit 446a67449f
1 changed files with 24 additions and 4 deletions

View File

@ -75,7 +75,7 @@ function redirect_canonical( $requested_url = null, $do_redirect = true ) {
$id = $vars->post_parent;
if ( $redirect_url = get_permalink($id) )
$redirect['query'] = remove_query_arg(array('p', 'page_id', 'attachment_id', 'post_type'), $redirect['query']);
$redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
}
}
@ -88,13 +88,14 @@ function redirect_canonical( $requested_url = null, $do_redirect = true ) {
$post_type_obj = get_post_type_object($redirect_post->post_type);
if ( $post_type_obj->public ) {
$redirect_url = get_permalink($redirect_post);
$redirect['query'] = remove_query_arg(array('p', 'page_id', 'attachment_id', 'post_type'), $redirect['query']);
$redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
}
}
if ( ! $redirect_url ) {
$redirect_url = redirect_guess_404_permalink( $requested_url );
$redirect['query'] = remove_query_arg( array( 'post_type', 'pagename', 'name' ), $redirect['query'] );
if ( $redirect_url = redirect_guess_404_permalink( $requested_url ) ) {
$redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
}
}
} elseif ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) {
@ -418,6 +419,25 @@ function redirect_canonical( $requested_url = null, $do_redirect = true ) {
}
}
/**
* Removes arguments from a query string if they are not present in a URL
* DO NOT use this in plugin code.
*
* @since 3.4
* @access private
*
* @return string The altered query string
*/
function _remove_qs_args_if_not_in_url( $query_string, Array $args_to_check, $url ) {
$parsed_url = @parse_url( $url );
parse_str( $parsed_url['query'], $parsed_query );
foreach ( $args_to_check as $qv ) {
if ( !isset( $parsed_query[$qv] ) )
$query_string = remove_query_arg( $qv, $query_string );
}
return $query_string;
}
/**
* Attempts to guess the correct URL from the current URL (that produced a 404) or
* the current query variables.