WordPress.org

Make WordPress Core

Ticket #18385: 18385.patch

File 18385.patch, 17.6 KB (added by dd32, 7 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 ) {