WordPress.org

Make WordPress Core

Ticket #33581: 33581.1.diff

File 33581.1.diff, 6.0 KB (added by peterwilsoncc, 5 years ago)
  • src/wp-includes/canonical.php

    diff --git a/src/wp-includes/canonical.php b/src/wp-includes/canonical.php
    index 4caaa65..1f385ba 100644
    a b function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    5959                return;
    6060        }
    6161
     62        // Redirect to the canonical URL using JavaScript's history.replaceState()
     63        // function. If this is false, a 301 redirect will be used.
     64        $use_javascript_history_api = true;
     65
    6266        if ( ! $requested_url && isset( $_SERVER['HTTP_HOST'] ) ) {
    6367                // build the URL in the address bar
    6468                $requested_url  = is_ssl() ? 'https://' : 'http://';
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    96100        }
    97101
    98102        if ( is_feed() && ( $id = get_query_var( 'p' ) ) ) {
     103                $use_javascript_history_api = false;
    99104                if ( $redirect_url = get_post_comments_feed_link( $id, get_query_var( 'feed' ) ) ) {
    100105                        $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type', 'feed'), $redirect_url );
    101106                        $redirect['path'] = parse_url( $redirect_url, PHP_URL_PATH );
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    117122
    118123        // These tests give us a WP-generated permalink
    119124        if ( is_404() ) {
     125                $use_javascript_history_api = false;
    120126
    121127                // Redirect ?page_id, ?p=, ?attachment_id= to their respective url's
    122128                $id = max( get_query_var('p'), get_query_var('page_id'), get_query_var('attachment_id') );
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    371377        $redirect['path'] = preg_replace('|/' . preg_quote( $wp_rewrite->index, '|' ) . '/*?$|', '/', $redirect['path']);
    372378
    373379        // Remove trailing spaces from the path
    374         $redirect['path'] = preg_replace( '#(%20| )+$#', '', $redirect['path'] );
     380        $count = 0;
     381        $redirect['path'] = preg_replace( '#(%20| )+$#', '', $redirect['path'], -1, $count );
     382        if ( $count > 0 ) {
     383                $use_javascript_history_api = false;
     384        }
    375385
    376386        if ( !empty( $redirect['query'] ) ) {
    377387                // Remove trailing spaces from certain terminating query string args
    378                 $redirect['query'] = preg_replace( '#((p|page_id|cat|tag)=[^&]*?)(%20| )+$#', '$1', $redirect['query'] );
     388                $count = 0;
     389                $redirect['query'] = preg_replace( '#((p|page_id|cat|tag)=[^&]*?)(%20| )+$#', '$1', $redirect['query'], -1,  $count );
     390                if ( $count > 0 ) {
     391                        $use_javascript_history_api = false;
     392                }
    379393
    380394                // Clean up empty query strings
    381395                $redirect['query'] = trim(preg_replace( '#(^|&)(p|page_id|cat|tag)=?(&|$)#', '&', $redirect['query']), '&');
    382396
    383397                // Redirect obsolete feeds
    384                 $redirect['query'] = preg_replace( '#(^|&)feed=rss(&|$)#', '$1feed=rss2$2', $redirect['query'] );
     398                $count = 0;
     399                $redirect['query'] = preg_replace( '#(^|&)feed=rss(&|$)#', '$1feed=rss2$2', $redirect['query'], -1, $count );
     400                if ( $count > 0 ) {
     401                        $use_javascript_history_api = false;
     402                }
    385403
    386404                // Remove redundant leading ampersands
    387405                $redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] );
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    411429        }
    412430
    413431        // Strip multiple slashes out of the URL
    414         if ( strpos($redirect['path'], '//') > -1 )
     432        if ( strpos($redirect['path'], '//') > -1 ) {
     433                $use_javascript_history_api = false;
    415434                $redirect['path'] = preg_replace('|/+|', '/', $redirect['path']);
     435        }
    416436
    417437        // Always trailing slash the Front Page URL
    418438        if ( trailingslashit( $redirect['path'] ) == trailingslashit( $user_home['path'] ) )
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    429449        if ( !empty( $original['port'] ) )
    430450                $compare_original[] = $original['port'];
    431451
     452        $compare_original_origin = $compare_original;
     453
    432454        if ( !empty( $original['query'] ) )
    433455                $compare_original[] = $original['query'];
    434456
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    437459        if ( !empty( $redirect['port'] ) )
    438460                $compare_redirect[] = $redirect['port'];
    439461
     462        $compare_redirect_origin = $compare_redirect;
     463
    440464        if ( !empty( $redirect['query'] ) )
    441465                $compare_redirect[] = $redirect['query'];
    442466
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    449473                        $redirect_url .= '?' . $redirect['query'];
    450474        }
    451475
     476        if ( $compare_redirect_origin != $compare_original_origin ) {
     477                $use_javascript_history_api = false;
     478        }
     479
    452480        if ( ! $redirect_url || $redirect_url == $requested_url ) {
    453481                return;
    454482        }
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    463491                $requested_url = preg_replace_callback('|%[a-fA-F0-9][a-fA-F0-9]|', 'lowercase_octets', $requested_url);
    464492        }
    465493
     494        $pre_filter_redirect_url = $redirect_url;
     495
    466496        /**
    467497         * Filter the canonical redirect URL.
    468498         *
    function redirect_canonical( $requested_url = null, $do_redirect = true ) { 
    475505         */
    476506        $redirect_url = apply_filters( 'redirect_canonical', $redirect_url, $requested_url );
    477507
     508        if ( $pre_filter_redirect_url !== $redirect_url ) {
     509                $use_javascript_history_api = false;
     510        }
     511
    478512        // yes, again -- in case the filter aborted the request
    479513        if ( ! $redirect_url || $redirect_url == $requested_url ) {
    480514                return;
    481515        }
    482516
    483         if ( $do_redirect ) {
     517        if ( $do_redirect && $use_javascript_history_api ) {
     518                add_action( 'wp_head', 'redirect_canonical_history_replace', 5 );
     519        }
     520        elseif ( $do_redirect ) {
    484521                // protect against chained redirects
    485522                if ( !redirect_canonical($redirect_url, false) ) {
    486523                        wp_redirect($redirect_url, 301);
    function wp_redirect_admin_locations() { 
    595632                exit;
    596633        }
    597634}
     635
     636/**
     637 * Replace the URL as displayed in the browser with the canonical URL
     638 */
     639function redirect_canonical_history_replace() {
     640        $canonical_url = redirect_canonical( null, false );
     641        ?>
     642        <script>
     643        (function( window, url ){
     644                var history = window.history;
     645                if ( history.replaceState ) {
     646                        history.replaceState( {}, '', url+window.location.hash );
     647                }
     648        }( window, '<?php echo $canonical_url; ?>' ));
     649        </script>
     650        <?php
     651}
     652 No newline at end of file