WordPress.org

Make WordPress Core

Ticket #4554: canonical.php

File canonical.php, 4.3 KB (added by markjaquith, 7 years ago)
Line 
1<?php
2// Based on "Permalink Redirect" from Scott Yang and "Enforce www. Preference" by Mark Jaquith
3
4function redirect_permalinks() {
5        global $withcomments;
6
7        $requested = @parse_url( $_SERVER['REQUEST_URI'] );
8        if ( false === $requested )
9                return;
10
11        $requested = $requested['path'];
12        $requested_scheme = ( isset($_SERVER['HTTPS'] ) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
13
14        if ( is_feed() || is_trackback() || is_search() || is_comments_popup() )
15                return;
16
17        $link = redirect_guess_permalink();
18        if ( !$link )
19                return;
20        $permalink = @parse_url( $link );
21
22        // WP2.1: If a static page has been set as the front-page, we'll get
23        // empty string here.
24        if ( !$permalink['path'] )
25                $permalink['path'] = '/';
26
27        if ( $requested != $permalink['path'] ) {
28                $redirect = $link;
29        } else {
30                $user_home = parse_url(get_option('home'));
31
32                $user_home['scheme'] . '://' . $user_home['host'];
33
34                if ( $user_home['host'] != $_SERVER['HTTP_HOST'] )
35                        $redirect = $requested_scheme . $user_home['host'] . $_SERVER['REQUEST_URI'];
36        }
37
38        if ( $redirect ) {
39                wp_redirect($redirect, 301);
40                exit();
41        }
42}
43
44function redirect_guess_permalink() {
45        global $posts;
46
47        // For partial links
48        if ( is_404() ) {
49                global $wp_query, $wpdb;
50                if ( !get_query_var( 'name' ) )
51                        return;
52
53                $where = "post_name LIKE '" . $wpdb->escape( get_query_var( 'name' ) ) . "%'";
54
55                // if any of year, monthnum, or day are set, use them to refine the query
56                if ( get_query_var('year') )
57                        $where .= " AND YEAR(post_date) = '" . $wpdb->escape(get_query_var('year')) . "'";
58                if ( get_query_var('monthnum') )
59                        $where .= " AND MONTH(post_date) = '" . $wpdb->escape(get_query_var('monthnum')) . "'";
60                if ( get_query_var('day') )
61                        $where .= " AND DAYOFMONTH(post_date) = '" . $wpdb->escape(get_query_var('day')) . "'";
62
63                $post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE $where AND post_status = 'publish'" );
64                if ( !$post_id )
65                        return false;
66                return get_permalink( $post_id );
67        }
68
69        $haspost = count( $posts ) > 0;
70        if ( get_query_var('m') ) {
71                // Handling special case with '?m=yyyymmddHHMMSS'
72                // Since there is no code for producing the archive links for
73                // is_time, we will give up and not trying any redirection.
74                $m = preg_replace( '/[^0-9]/', '', get_query_var('m') );
75                switch ( strlen($m) ) {
76                        case 4: // Yearly
77                                $link = get_year_link($m);
78                                break;
79                        case 6: // Monthly
80                                $link = get_month_link( substr($m, 0, 4), substr($m, 4, 2) );
81                                break;
82                        case 8: // Daily
83                                $link = get_day_link(substr($m, 0, 4), substr($m, 4, 2), substr($m, 6, 2));
84                                break;
85                        default:
86                                return false;
87                }
88        } elseif ( ( is_single() || is_page() ) && ( sizeof( $posts ) > 0 ) ) {
89                $post = $posts[0];
90                $link = get_permalink($post->ID);
91                $page = get_query_var('page');
92                if ( $page && $page > 1 )
93                        $link = trailingslashit( $link ) . user_trailingslashit($page);
94        } elseif ( is_author() && $haspost ) {
95                global $wp_version;
96                if ( $wp_version >= '2' ) {
97                        $author = get_userdata(get_query_var('author'));
98                        if ( false === $author )
99                                return false;
100                        $link = get_author_link( false, $author->ID, $author->user_nicename );
101                } else {
102                        // XXX: get_author_link() bug in WP 1.5.1.2
103                        //      s/author_nicename/user_nicename/
104                        global $cache_userdata;
105                        $userid = get_query_var('author');
106                        $link = get_author_link(false, $userid,
107                                $cache_userdata[$userid]->user_nicename);
108                }
109        } elseif ( is_category() && $haspost ) {
110                $link = get_category_link(get_query_var('cat'));
111        } elseif ( is_day() && $haspost ) {
112                $link = get_day_link(get_query_var('year'),
113                                                         get_query_var('monthnum'),
114                                                         get_query_var('day'));
115        } elseif (is_month() && $haspost) {
116                $link = get_month_link(get_query_var('year'),
117                                                           get_query_var('monthnum'));
118        } elseif (is_year() && $haspost) {
119                $link = get_year_link(get_query_var('year'));
120        } elseif ( is_home() ) {
121                // WP2.1. Handling "Posts page" option.
122                if ((get_option('show_on_front') == 'page') &&
123                        ($reqpage = get_option('page_for_posts'))) 
124                {
125                        $link = get_permalink($reqpage);
126                } else {
127                        $link = trailingslashit(get_settings('home'));
128                }
129        } else {
130                return false;
131        }
132
133        if ( is_paged() ) {
134                $paged = get_query_var('paged');
135                if ($paged)
136                        $link = trailingslashit($link) . user_trailingslashit("page/$paged");
137        }
138
139        return $link;
140}
141
142add_action('template_redirect', 'redirect_permalinks');
143
144?>