WordPress.org

Make WordPress Core

Ticket #18385: 18385.patch

File 18385.patch, 17.6 KB (added by dd32, 4 years ago)
  • wp-includes/canonical.php

     
    6666        if ( !isset($redirect['query']) ) 
    6767                $redirect['query'] = ''; 
    6868 
     69        $qv_remove = array(); 
     70 
    6971        if ( is_singular() && 1 > $wp_query->post_count && ($id = get_query_var('p')) ) { 
    7072 
    7173                $vars = $wpdb->get_results( $wpdb->prepare("SELECT post_type, post_parent FROM $wpdb->posts WHERE ID = %d", $id) ); 
     
    7577                                $id = $vars->post_parent; 
    7678 
    7779                        if ( $redirect_url = get_permalink($id) ) 
    78                                 $redirect['query'] = remove_query_arg(array('p', 'page_id', 'attachment_id', 'post_type'), $redirect['query']); 
     80                                $qv_remove = array_merge($qv_remove, array('p', 'page_id', 'attachment_id', 'post_type') ); 
    7981                } 
    80         } 
    81  
    82         // These tests give us a WP-generated permalink 
    83         if ( is_404() ) { 
    84  
     82        } elseif ( is_404() ) { 
    8583                // Redirect ?page_id, ?p=, ?attachment_id= to their respective url's 
    8684                $id = max( get_query_var('p'), get_query_var('page_id'), get_query_var('attachment_id') ); 
    8785                if ( $id && $redirect_post = get_post($id) ) { 
    88                         $post_type_obj = get_post_type_object($redirect_post->post_type); 
    89                         if ( $post_type_obj->public ) { 
     86                        if ( get_post_type_object($redirect_post->post_type)->public ) { 
    9087                                $redirect_url = get_permalink($redirect_post); 
    91                                 $redirect['query'] = remove_query_arg(array('p', 'page_id', 'attachment_id', 'post_type'), $redirect['query']); 
     88                                $qv_remove = array_merge($qv_remove, array('p', 'page_id', 'attachment_id', 'post_type') ); 
    9289                        } 
    9390                } 
    9491 
    95                 if ( ! $redirect_url ) 
     92                if ( ! $redirect_url ) { 
    9693                        $redirect_url = redirect_guess_404_permalink(); 
    97  
    98         } elseif ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) { 
    99                 // rewriting of old ?p=X, ?m=2004, ?m=200401, ?m=20040101 
    100                 if ( is_attachment() && !empty($_GET['attachment_id']) && ! $redirect_url ) { 
    101                         if ( $redirect_url = get_attachment_link(get_query_var('attachment_id')) ) 
    102                                 $redirect['query'] = remove_query_arg('attachment_id', $redirect['query']); 
    103                 } elseif ( is_single() && !empty($_GET['p']) && ! $redirect_url ) { 
    104                         if ( $redirect_url = get_permalink(get_query_var('p')) ) 
    105                                 $redirect['query'] = remove_query_arg(array('p', 'post_type'), $redirect['query']); 
    106                 } elseif ( is_single() && !empty($_GET['name'])  && ! $redirect_url ) { 
    107                         if ( $redirect_url = get_permalink( $wp_query->get_queried_object_id() ) ) 
    108                                 $redirect['query'] = remove_query_arg('name', $redirect['query']); 
    109                 } elseif ( is_page() && !empty($_GET['page_id']) && ! $redirect_url ) { 
    110                         if ( $redirect_url = get_permalink(get_query_var('page_id')) ) 
    111                                 $redirect['query'] = remove_query_arg('page_id', $redirect['query']); 
    112                 } elseif ( is_page() && !is_feed() && isset($wp_query->queried_object) && 'page' == get_option('show_on_front') && $wp_query->queried_object->ID == get_option('page_on_front')  && ! $redirect_url ) { 
     94                        if ( $redirect_url ) 
     95                                $qv_remove = array_merge($qv_remove, array('pagename', 'name') ); 
     96                } 
     97        } elseif ( is_attachment() ) { 
     98                if ( $redirect_url = get_attachment_link(get_query_var('attachment_id')) ) { 
     99                        $qv_remove[] = 'attachment_id'; 
     100                        $qv_remove[] = 'attachment'; 
     101                } 
     102        } elseif ( is_single() ) { 
     103                if ( $redirect_url = get_permalink( $wp_query->get_queried_object_id() ) ) { 
     104                        $qv_remove[] = 'p'; 
     105                        $qv_remove[] = 'post_type'; 
     106                        $qv_remove[] = 'name'; 
     107                        $qv_remove[] = 'pagename'; 
     108                } 
     109        } elseif ( is_page() ) { 
     110                if ( !is_feed() && isset($wp_query->queried_object) && 'page' == get_option('show_on_front') && $wp_query->queried_object->ID == get_option('page_on_front')  && ! $redirect_url ) 
    113111                        $redirect_url = home_url('/'); 
    114                 } elseif ( is_home() && !empty($_GET['page_id']) && 'page' == get_option('show_on_front') && get_query_var('page_id') == get_option('page_for_posts')  && ! $redirect_url ) { 
    115                         if ( $redirect_url = get_permalink(get_option('page_for_posts')) ) 
    116                                 $redirect['query'] = remove_query_arg('page_id', $redirect['query']); 
    117                 } elseif ( !empty($_GET['m']) && ( is_year() || is_month() || is_day() ) ) { 
    118                         $m = get_query_var('m'); 
    119                         switch ( strlen($m) ) { 
    120                                 case 4: // Yearly 
    121                                         $redirect_url = get_year_link($m); 
    122                                         break; 
    123                                 case 6: // Monthly 
    124                                         $redirect_url = get_month_link( substr($m, 0, 4), substr($m, 4, 2) ); 
    125                                         break; 
    126                                 case 8: // Daily 
    127                                         $redirect_url = get_day_link(substr($m, 0, 4), substr($m, 4, 2), substr($m, 6, 2)); 
    128                                         break; 
    129                         } 
    130                         if ( $redirect_url ) 
    131                                 $redirect['query'] = remove_query_arg('m', $redirect['query']); 
    132                 // now moving on to non ?m=X year/month/day links 
    133                 } elseif ( is_day() && get_query_var('year') && get_query_var('monthnum') && !empty($_GET['day']) ) { 
    134                         if ( $redirect_url = get_day_link(get_query_var('year'), get_query_var('monthnum'), get_query_var('day')) ) 
    135                                 $redirect['query'] = remove_query_arg(array('year', 'monthnum', 'day'), $redirect['query']); 
    136                 } elseif ( is_month() && get_query_var('year') && !empty($_GET['monthnum']) ) { 
    137                         if ( $redirect_url = get_month_link(get_query_var('year'), get_query_var('monthnum')) ) 
    138                                 $redirect['query'] = remove_query_arg(array('year', 'monthnum'), $redirect['query']); 
    139                 } elseif ( is_year() && !empty($_GET['year']) ) { 
    140                         if ( $redirect_url = get_year_link(get_query_var('year')) ) 
    141                                 $redirect['query'] = remove_query_arg('year', $redirect['query']); 
    142                 } elseif ( is_author() && !empty($_GET['author']) && preg_match( '|^[0-9]+$|', $_GET['author'] ) ) { 
    143                         $author = get_userdata(get_query_var('author')); 
    144                         if ( ( false !== $author ) && $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE $wpdb->posts.post_author = %d AND $wpdb->posts.post_status = 'publish' LIMIT 1", $author->ID ) ) ) { 
    145                                 if ( $redirect_url = get_author_posts_url($author->ID, $author->user_nicename) ) 
    146                                         $redirect['query'] = remove_query_arg('author', $redirect['query']); 
    147                         } 
    148                 } elseif ( is_category() || is_tag() || is_tax() ) { // Terms (Tags/categories) 
     112                else 
     113                        $redirect_url = get_permalink(get_query_var('page_id')); 
     114                if ( $redirect_url ) { 
     115                        $qv_remove[] = 'page_id'; 
     116                        $qv_remove[] = 'pagename'; 
     117                } 
     118        } elseif ( is_category() || is_tag() || is_tax() ) { // Terms (Tags/categories/Custom Taxonomies) 
    149119 
    150                         $term_count = 0; 
    151                         foreach ( $wp_query->tax_query->queries as $tax_query ) 
    152                                 $term_count += count( $tax_query['terms'] ); 
     120                // @TODO: Buggy, Doesnt account for the fact that categories include child cats in the count. 
     121                $term_count = 0; 
     122                $term_taxonomies = array_unique(wp_list_pluck($wp_query->tax_query->queries, 'taxonomy')); 
     123                foreach ( $wp_query->tax_query->queries as $tax_query ) 
     124                        $term_count += count( $tax_query['terms'] ); 
    153125 
    154                         $obj = $wp_query->get_queried_object(); 
    155                         if ( $term_count <= 1 && !empty($obj->term_id) && ( $tax_url = get_term_link((int)$obj->term_id, $obj->taxonomy) ) && !is_wp_error($tax_url) ) { 
    156                                 if ( !empty($redirect['query']) ) { 
    157                                         // Strip taxonomy query vars off the url. 
    158                                         $qv_remove = array( 'term', 'taxonomy'); 
    159                                         if ( is_category() ) { 
    160                                                 $qv_remove[] = 'category_name'; 
    161                                                 $qv_remove[] = 'cat'; 
    162                                         } elseif ( is_tag() ) { 
    163                                                 $qv_remove[] = 'tag'; 
    164                                                 $qv_remove[] = 'tag_id'; 
    165                                         } else { // Custom taxonomies will have a custom query var, remove those too: 
    166                                                 $tax_obj = get_taxonomy( $obj->taxonomy ); 
    167                                                 if ( false !== $tax_obj->query_var ) 
    168                                                         $qv_remove[] = $tax_obj->query_var; 
    169                                         } 
     126                $obj = $wp_query->get_queried_object(); 
     127                if ( $term_count <= 1 && !empty($obj->term_id) )  
     128                        $redirect_url = get_term_link((int)$obj->term_id, $obj->taxonomy); 
    170129 
    171                                         $rewrite_vars = array_diff( array_keys($wp_query->query), array_keys($_GET) ); 
     130                elseif ( $term_count > 1 && 1 == count($term_taxonomies) ) 
     131                        $redirect_url = false; // Booyakasha? Build the merged array and win the world? 
    172132 
    173                                         if ( !array_diff($rewrite_vars, array_keys($_GET))  ) { // Check to see if all the Query vars are coming from the rewrite, none are set via $_GET 
    174                                                 $redirect['query'] = remove_query_arg($qv_remove, $redirect['query']); //Remove all of the per-tax qv's 
     133                if ( $term_count == 1 ) { 
     134                        // Strip taxonomy query vars off the url. 
     135                        $qv_remove[] = 'term'; 
     136                        $qv_remove[] = 'taxonomy'; 
     137                } 
    175138 
    176                                                 // Create the destination url for this taxonomy 
    177                                                 $tax_url = parse_url($tax_url); 
    178                                                 if ( ! empty($tax_url['query']) ) { // Taxonomy accessable via ?taxonomy=..&term=.. or any custom qv.. 
    179                                                         parse_str($tax_url['query'], $query_vars); 
    180                                                         $redirect['query'] = add_query_arg($query_vars, $redirect['query']); 
    181                                                 } else { // Taxonomy is accessable via a "pretty-URL" 
    182                                                         $redirect['path'] = $tax_url['path']; 
    183                                                 } 
    184  
    185                                         } else { // Some query vars are set via $_GET. Unset those from $_GET that exist via the rewrite 
    186                                                 foreach ( $qv_remove as $_qv ) { 
    187                                                         if ( isset($rewrite_vars[$_qv]) ) 
    188                                                                 $redirect['query'] = remove_query_arg($_qv, $redirect['query']); 
    189                                                 } 
    190                                         } 
    191                                 } 
    192  
     139                if ( is_category() ) { 
     140                        $qv_remove[] = 'category_name'; 
     141                        $qv_remove[] = 'cat'; 
     142                } elseif ( is_tag() ) { 
     143                        $qv_remove[] = 'tag'; 
     144                        $qv_remove[] = 'tag_id'; 
     145                } else { // Custom taxonomies will have a custom query var, remove those too: 
     146                        $tax_obj = get_taxonomy( $obj->taxonomy ); 
     147                        if ( false !== $tax_obj->query_var ) 
     148                                $qv_remove[] = $tax_obj->query_var; 
     149                } 
     150        } elseif ( is_author() ) { 
     151                $author = get_userdata( get_query_var('author') ); 
     152                if ( false !== $author && $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE $wpdb->posts.post_author = %d AND $wpdb->posts.post_status = 'publish' LIMIT 1", $author->ID ) ) ) { 
     153                        if ( $redirect_url = get_author_posts_url($author->ID, $author->user_nicename) ) { 
     154                                $qv_remove[] = 'author'; 
     155                                $qv_remove[] = 'author_name'; 
    193156                        } 
    194                 } elseif ( is_single() && strpos($wp_rewrite->permalink_structure, '%category%') !== false ) { 
    195                         $category = get_category_by_path(get_query_var('category_name')); 
    196                         $post_terms = wp_get_object_terms($wp_query->get_queried_object_id(), 'category', array('fields' => 'tt_ids')); 
    197                         if ( (!$category || is_wp_error($category)) || ( !is_wp_error($post_terms) && !empty($post_terms) && !in_array($category->term_taxonomy_id, $post_terms) ) ) 
    198                                 $redirect_url = get_permalink($wp_query->get_queried_object_id()); 
    199157                } 
     158        } elseif ( is_year() || is_month() || is_day() ) { 
     159                if ( '' != get_query_var('m') ) { 
     160                        $m = get_query_var('m'); 
     161                        if ( strlen($m) > 6 ) 
     162                                $redirect_url = get_day_link(substr($m, 0, 4), substr($m, 4, 2), substr($m, 6, 2)); 
     163                        elseif ( strlen($m) > 4 ) 
     164                                $redirect_url = get_month_link( substr($m, 0, 4), substr($m, 4, 2) ); 
     165                        else 
     166                                $redirect_url = get_year_link($m); 
     167                        if ( $redirect_url ) 
     168                                $qv_remove[] = 'm'; 
     169                } elseif ( is_day() ) { 
     170                        if ( get_query_var('year') && get_query_var('monthnum') ) 
     171                                $redirect_url = get_day_link(get_query_var('year'), get_query_var('monthnum'), get_query_var('day')); 
     172                        $qv_remove = array_merge($qv_remove, array('year', 'monthnum', 'day')); 
     173                } elseif ( is_month() ) { 
     174                        if ( get_query_var('year') ) 
     175                                if ( $redirect_url = get_month_link(get_query_var('year'), get_query_var('monthnum')) ) 
     176                                        $qv_remove = array_merge($qv_remove, array('year', 'monthnum')); 
     177                } elseif ( is_year() ) { 
     178                        if ( $redirect_url = get_year_link(get_query_var('year')) ) 
     179                                $qv_remove[] = 'year'; 
     180                } 
     181        } elseif ( is_single() && strpos($wp_rewrite->permalink_structure, '%category%') !== false ) { 
     182                $category = get_category_by_path(get_query_var('category_name')); 
     183                $post_terms = wp_get_object_terms($wp_query->get_queried_object_id(), 'category', array('fields' => 'tt_ids')); 
     184                if ( (!$category || is_wp_error($category)) || ( !is_wp_error($post_terms) && !empty($post_terms) && !in_array($category->term_taxonomy_id, $post_terms) ) ) 
     185                        $redirect_url = get_permalink($wp_query->get_queried_object_id()); 
     186        } elseif ( is_singular() ) { 
     187                $redirect_url = get_permalink( $wp_query->get_queried_object_id() ); 
     188        } else { 
     189                $redirect_url = home_url(); 
     190        } 
     191         
     192        if ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) { 
     193                // Feeds 
     194                if ( is_feed() ) { 
     195                        $feed = get_query_var('feed'); 
     196                        $redirect_url = trailingslashit( $redirect_url ); 
     197                        if ( is_comment_feed() ) { 
     198                                $feed = str_replace('comments-', '', $feed); 
     199                                $redirect_url .= 'comments/'; 
     200                        } 
     201                        $redirect_url .= 'feed'; 
     202                        if ( $feed != get_default_feed() ) 
     203                                $redirect_url .= '/' . $feed; 
     204                        $redirect_url = user_trailingslashit( $redirect_url, 'single_single' ); 
     205                        $qv_remove[] = 'feed'; 
     206                } 
    200207 
     208                // Comment Paging 
     209                if ( get_query_var('cpage') ) { 
     210                        if ( !is_feed() && get_query_var('cpage') > 0 ) 
     211                                $redirect_url = trailingslashit($redirect_url) . user_trailingslashit( 'comment-page-' . intval(get_query_var('cpage')),  'commentpaged' ); 
     212                        $qv_remove[] = 'cpage'; 
     213                } 
     214 
    201215                // Post Paging 
    202                 if ( is_singular() && get_query_var('page') && $redirect_url ) { 
    203                         $redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( get_query_var( 'page' ), 'single_paged' ); 
    204                         $redirect['query'] = remove_query_arg( 'page', $redirect['query'] ); 
     216                if ( get_query_var('page') && ( is_singular() || (is_404() && $redirect_url) ) ) { 
     217                        $page = get_query_var('page'); 
     218                        if ( is_singular() ) { 
     219                                setup_postdata(get_queried_object()); 
     220                                global $numpages; 
     221                                $page = min($page, $numpages); 
     222                        } 
     223                        if ( !is_feed() ) // Feeds don't support paging 
     224                                $redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( $page, 'single_paged' ); 
     225                        $qv_remove[] = 'page'; 
    205226                } 
    206  
     227                 
     228                // Archive Paging 
     229                if ( get_query_var('paged') > 0 ) { 
     230                        if ( !is_feed() ) // Feeds don't support paging 
     231                                $redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( "$wp_rewrite->pagination_base/" . get_query_var( 'paged' ), 'paged' ); 
     232                        $qv_remove[] = 'paged'; 
     233                } 
     234         
     235                if ( !empty($redirect_url) && ( is_singular() || is_404() ) ) { 
     236                        // Get the query vars in the current permastruct 
     237                        if ( preg_match_all('/(%.+?%)/', $wp_rewrite->permalink_structure, $tokens) ) { 
     238                                foreach ( $tokens[0] as $token ) 
     239                                        $qv_remove[] = trim($wp_rewrite->queryreplace[ array_search($token, $wp_rewrite->rewritecode) ], '='); 
     240                        } 
     241                } 
     242        } 
     243         
     244/*  
    207245                // paging and feeds 
    208246                if ( get_query_var('paged') || is_feed() || get_query_var('cpage') ) { 
    209247                        while ( preg_match( "#/$wp_rewrite->pagination_base/?[0-9]+?(/+)?$#", $redirect['path'] ) || preg_match( '#/(comments/?)?(feed|rss|rdf|atom|rss2)(/+)?$#', $redirect['path'] ) || preg_match( '#/comment-page-[0-9]+(/+)?$#', $redirect['path'] ) ) { 
     
    265303                                $redirect['path'] = trailingslashit($redirect['path']) . $addl_path; 
    266304                        $redirect_url = $redirect['scheme'] . '://' . $redirect['host'] . $redirect['path']; 
    267305                } 
    268         } 
     306        }*/ 
    269307 
     308        if ( empty($redirect_url) ) 
     309                $redirect_url = $requested_url; 
     310 
     311        $redirect = @parse_url($redirect_url); 
     312        if ( empty($redirect['query']) ) 
     313                $redirect['query'] = ''; 
     314 
    270315        // tack on any additional query vars 
    271316        $redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] ); 
    272         if ( $redirect_url && !empty($redirect['query']) ) { 
    273                 parse_str( $redirect['query'], $_parsed_query ); 
    274                 $redirect = @parse_url($redirect_url); 
     317        global $wp; 
    275318 
    276                 if ( ! empty( $_parsed_query['name'] ) && ! empty( $redirect['query'] ) ) { 
    277                         parse_str( $redirect['query'], $_parsed_redirect_query ); 
     319        $vars = array_merge($wp->query_vars, $_GET); 
     320        $vars = array_filter($vars); //remove empty 
     321        foreach ( $qv_remove as $qv ) 
     322                unset($vars[ $qv ]); 
    278323 
    279                         if ( empty( $_parsed_redirect_query['name'] ) ) 
    280                                 unset( $_parsed_query['name'] ); 
    281                 } 
     324        $redirect['query'] = add_query_arg($vars, $redirect['query']); 
    282325 
    283                 $redirect_url = add_query_arg( $_parsed_query, $redirect_url ); 
    284         } 
    285  
    286         if ( $redirect_url ) 
    287                 $redirect = @parse_url($redirect_url); 
    288  
    289326        // www.example.com vs example.com 
    290327        $user_home = @parse_url(home_url()); 
    291328        if ( !empty($user_home['host']) ) 
     
    317354 
    318355                // Remove redundant leading ampersands 
    319356                $redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] ); 
     357 
     358                // %2c => , 
     359                $redirect['query'] = urldecode($redirect['query']); 
    320360        } 
    321361 
    322362        // strip /index.php/ when we're not using PATHINFO permalinks 
     
    349389        // Always trailing slash the Front Page URL 
    350390        if ( trailingslashit( $redirect['path'] ) == trailingslashit( $user_home['path'] ) ) 
    351391                $redirect['path'] = trailingslashit($redirect['path']); 
    352  
     392/* 
    353393        // Ignore differences in host capitalization, as this can lead to infinite redirects 
    354394        // Only redirect no-www <=> yes-www 
    355395        if ( strtolower($original['host']) == strtolower($redirect['host']) || 
     
    371411 
    372412        if ( !empty( $redirect['query'] ) ) 
    373413                $compare_redirect[] = $redirect['query']; 
     414*/ 
     415//      if ( $compare_original !== $compare_redirect ) { 
    374416 
    375         if ( $compare_original !== $compare_redirect ) { 
    376417                $redirect_url = $redirect['scheme'] . '://' . $redirect['host']; 
    377418                if ( !empty($redirect['port']) ) 
    378419                        $redirect_url .= ':' . $redirect['port']; 
    379420                $redirect_url .= $redirect['path']; 
    380421                if ( !empty($redirect['query']) ) 
    381422                        $redirect_url .= '?' . $redirect['query']; 
    382         } 
     423//      } 
    383424 
    384         if ( !$redirect_url || $redirect_url == $requested_url ) 
    385                 return false; 
     425//      if ( !$redirect_url || $redirect_url == $requested_url ) 
     426//              return false; 
    386427 
    387428        // Hex encoded octets are case-insensitive. 
    388429        if ( false !== strpos($requested_url, '%') ) { 
     
    397438        // Note that you can use the "redirect_canonical" filter to cancel a canonical redirect for whatever reason by returning FALSE 
    398439        $redirect_url = apply_filters('redirect_canonical', $redirect_url, $requested_url); 
    399440 
    400         if ( !$redirect_url || $redirect_url == $requested_url ) // yes, again -- in case the filter aborted the request 
     441        if ( !$redirect_url  || $redirect_url == $requested_url ) // yes, again -- in case the filter aborted the request 
    401442                return false; 
    402443 
    403444        if ( $do_redirect ) {