Ticket #4554: canonical.php

File canonical.php, 4.3 kB (added by markjaquith, 1 year ago)
Line 
1 <?php
2 // Based on "Permalink Redirect" from Scott Yang and "Enforce www. Preference" by Mark Jaquith
3
4 function 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
44 function 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
142 add_action('template_redirect', 'redirect_permalinks');
143
144 ?>