From 446a67449ff576fcd0ac7d8f780378a733efc34c Mon Sep 17 00:00:00 2001 From: markjaquith Date: Sat, 7 Apr 2012 01:03:55 +0000 Subject: [PATCH] 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 --- wp-includes/canonical.php | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/wp-includes/canonical.php b/wp-includes/canonical.php index 3fbe46c18..f098dae77 100644 --- a/wp-includes/canonical.php +++ b/wp-includes/canonical.php @@ -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.