PluginProbe
Redirection / 4.3.2
Redirection v4.3.2
5.10.0 5.9.0 5.8.1 5.8.0 3.7.2 3.7.3 4.0 4.0.1 4.1 4.1.1 4.2 4.2.1 4.2.2 4.2.3 4.3 4.3.1 4.3.2 4.3.3 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6.2 4.7.1 All 130 releases
redirection / modules / wordpress.php

wordpress.php in Redirection 4.3.2, at modules/wordpress.php

225 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class WordPress_Module extends Red_Module {
4 const MODULE_ID = 1;
5
6 private $matched = false;
7 private $can_log = true;
8
9 public function get_id() {
10 return self::MODULE_ID;
11 }
12
13 public function get_name() {
14 return 'WordPress';
15 }
16
17 public function start() {
18 // Setup the various filters and actions that allow Redirection to happen
19 add_action( 'init', array( $this, 'init' ) );
20 add_action( 'init', array( $this, 'force_https' ) );
21 add_action( 'send_headers', array( $this, 'send_headers' ) );
22 add_filter( 'wp_redirect', array( $this, 'wp_redirect' ), 1, 2 );
23 add_action( 'redirection_visit', array( $this, 'redirection_visit' ), 10, 3 );
24 add_action( 'redirection_do_nothing', array( $this, 'redirection_do_nothing' ) );
25 add_filter( 'redirect_canonical', array( $this, 'redirect_canonical' ), 10, 2 );
26 add_action( 'template_redirect', array( $this, 'template_redirect' ) );
27
28 // Remove WordPress 2.3 redirection
29 remove_action( 'template_redirect', 'wp_old_slug_redirect' );
30 }
31
32 /**
33 * This ensures that a matched URL is not overriddden by WordPress, if the URL happens to be a WordPress URL of some kind
34 * For example: /?author=1 will be redirected to /author/name unless this returns false
35 */
36 public function redirect_canonical( $redirect_url, $requested_url ) {
37 if ( $this->matched ) {
38 return false;
39 }
40
41 return $redirect_url;
42 }
43
44 public function template_redirect() {
45 if ( ! is_404() || $this->matched ) {
46 return;
47 }
48
49 if ( $this->match_404_type() ) {
50 // Don't log an intentionally redirected 404
51 return;
52 }
53
54 $options = red_get_options();
55
56 if ( isset( $options['expire_404'] ) && $options['expire_404'] >= 0 && apply_filters( 'redirection_log_404', $this->can_log ) ) {
57 RE_404::create( Redirection_Request::get_request_url(), Redirection_Request::get_user_agent(), Redirection_Request::get_ip(), Redirection_Request::get_referrer() );
58 }
59 }
60
61 private function match_404_type() {
62 if ( ! property_exists( $this, 'redirects' ) || count( $this->redirects ) === 0 ) {
63 return false;
64 }
65
66 $page_type = array_values( array_filter( $this->redirects, array( $this, 'only_404' ) ) );
67
68 if ( count( $page_type ) > 0 ) {
69 $url = apply_filters( 'redirection_url_source', Redirection_Request::get_request_url() );
70 $first = $page_type[0];
71 return $first->is_match( $url );
72 }
73
74 return false;
75 }
76
77 private function only_404( $redirect ) {
78 return $redirect->match->get_type() === 'page';
79 }
80
81 // Return true to stop further processing of the 'do nothing'
82 public function redirection_do_nothing() {
83 $this->can_log = false;
84 return true;
85 }
86
87 public function redirection_visit( $redirect, $url, $target ) {
88 $redirect->visit( $url, $target );
89 }
90
91 public function force_https() {
92 $options = red_get_options();
93
94 if ( $options['https'] && ! is_ssl() ) {
95 $target = rtrim( parse_url( home_url(), PHP_URL_HOST ), '/' ) . esc_url_raw( Redirection_Request::get_request_url() );
96 wp_safe_redirect( 'https://' . $target, 301 );
97 die();
98 }
99 }
100
101 /**
102 * This is the key to Redirection and where requests are matched to redirects
103 */
104 public function init() {
105 $url = Redirection_Request::get_request_url();
106 $url = apply_filters( 'redirection_url_source', $url );
107 $url = rawurldecode( $url );
108
109 // Make sure we don't try and redirect something essential
110 if ( $url && ! $this->protected_url( $url ) && $this->matched === false ) {
111 do_action( 'redirection_first', $url, $this );
112
113 // Get all redirects that match the URL
114 $redirects = Red_Item::get_for_url( $url );
115
116 // Redirects will be ordered by position. Run through the list until one fires
117 foreach ( (array) $redirects as $item ) {
118 if ( $item->is_match( $url ) ) {
119 $this->matched = $item;
120 break;
121 }
122 }
123
124 do_action( 'redirection_last', $url, $this );
125
126 if ( ! $this->matched ) {
127 // Keep them for later
128 $this->redirects = $redirects;
129 }
130 }
131 }
132
133 /**
134 * Protect certain URLs from being redirected. Note we don't need to protect wp-admin, as this code doesn't run there
135 */
136 private function protected_url( $url ) {
137 $rest = wp_parse_url( red_get_rest_api() );
138 $rest_api = $rest['path'] . ( isset( $rest['query'] ) ? '?' . $rest['query'] : '' );
139
140 if ( substr( $url, 0, strlen( $rest_api ) ) === $rest_api ) {
141 // Never redirect the REST API
142 return true;
143 }
144
145 return false;
146 }
147
148 public function status_header( $status ) {
149 // Fix for incorrect headers sent when using FastCGI/IIS
150 if ( substr( php_sapi_name(), 0, 3 ) === 'cgi' ) {
151 return str_replace( 'HTTP/1.1', 'Status:', $status );
152 }
153
154 return $status;
155 }
156
157 public function send_headers( $obj ) {
158 if ( ! empty( $this->matched ) && $this->matched->action->get_code() === 410 ) {
159 add_filter( 'status_header', array( $this, 'set_header_410' ) );
160 }
161 }
162
163 public function set_header_410() {
164 return 'HTTP/1.1 410 Gone';
165 }
166
167 public function wp_redirect( $url, $status ) {
168 global $wp_version, $is_IIS;
169
170 if ( $is_IIS ) {
171 header( "Refresh: 0;url=$url" );
172 return $url;
173 }
174
175 if ( $status === 301 && php_sapi_name() === 'cgi-fcgi' ) {
176 $servers_to_check = array( 'lighttpd', 'nginx' );
177
178 foreach ( $servers_to_check as $name ) {
179 if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && stripos( $_SERVER['SERVER_SOFTWARE'], $name ) !== false ) {
180 status_header( $status );
181 header( "Location: $url" );
182 exit( 0 );
183 }
184 }
185 }
186
187 if ( intval( $status, 10 ) === 307 ) {
188 status_header( $status );
189 nocache_headers();
190 return $url;
191 }
192
193 $options = red_get_options();
194
195 // Do we need to set the cache header?
196 if ( ! headers_sent() && isset( $options['redirect_cache'] ) && $options['redirect_cache'] !== 0 && intval( $status, 10 ) === 301 ) {
197 if ( $options['redirect_cache'] === -1 ) {
198 // No cache - just use WP function
199 nocache_headers();
200 } else {
201 // Custom cache
202 header( 'Expires: ' . gmdate( 'D, d M Y H:i:s T', time() + $options['redirect_cache'] * 60 * 60 ) );
203 header( 'Cache-Control: max-age=' . $options['redirect_cache'] * 60 * 60 );
204 }
205 }
206
207 status_header( $status );
208 return $url;
209 }
210
211 public function update( array $data ) {
212 return false;
213 }
214
215 protected function load( $options ) {
216 }
217
218 protected function flush_module() {
219 }
220
221 public function reset() {
222 $this->can_log = true;
223 }
224 }
225