PluginProbe
Redirection / 4.4.2
Redirection v4.4.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.4.2, at modules/wordpress.php

229 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_types = array_values( array_filter( $this->redirects, [ $this, 'only_404' ] ) );
67
68 if ( count( $page_types ) > 0 ) {
69 $url = apply_filters( 'redirection_url_source', Redirection_Request::get_request_url() );
70
71 foreach ( $page_types as $page_type ) {
72 if ( $page_type->is_match( $url ) ) {
73 return true;
74 }
75 }
76 }
77
78 return false;
79 }
80
81 private function only_404( $redirect ) {
82 return $redirect->match->get_type() === 'page';
83 }
84
85 // Return true to stop further processing of the 'do nothing'
86 public function redirection_do_nothing() {
87 $this->can_log = false;
88 return true;
89 }
90
91 public function redirection_visit( $redirect, $url, $target ) {
92 $redirect->visit( $url, $target );
93 }
94
95 public function force_https() {
96 $options = red_get_options();
97
98 if ( $options['https'] && ! is_ssl() ) {
99 $target = rtrim( parse_url( home_url(), PHP_URL_HOST ), '/' ) . esc_url_raw( Redirection_Request::get_request_url() );
100 wp_safe_redirect( 'https://' . $target, 301 );
101 die();
102 }
103 }
104
105 /**
106 * This is the key to Redirection and where requests are matched to redirects
107 */
108 public function init() {
109 $url = Redirection_Request::get_request_url();
110 $url = apply_filters( 'redirection_url_source', $url );
111 $url = rawurldecode( $url );
112
113 // Make sure we don't try and redirect something essential
114 if ( $url && ! $this->protected_url( $url ) && $this->matched === false ) {
115 do_action( 'redirection_first', $url, $this );
116
117 // Get all redirects that match the URL
118 $redirects = Red_Item::get_for_url( $url );
119
120 // Redirects will be ordered by position. Run through the list until one fires
121 foreach ( (array) $redirects as $item ) {
122 if ( $item->is_match( $url ) ) {
123 $this->matched = $item;
124 break;
125 }
126 }
127
128 do_action( 'redirection_last', $url, $this );
129
130 if ( ! $this->matched ) {
131 // Keep them for later
132 $this->redirects = $redirects;
133 }
134 }
135 }
136
137 /**
138 * Protect certain URLs from being redirected. Note we don't need to protect wp-admin, as this code doesn't run there
139 */
140 private function protected_url( $url ) {
141 $rest = wp_parse_url( red_get_rest_api() );
142 $rest_api = $rest['path'] . ( isset( $rest['query'] ) ? '?' . $rest['query'] : '' );
143
144 if ( substr( $url, 0, strlen( $rest_api ) ) === $rest_api ) {
145 // Never redirect the REST API
146 return true;
147 }
148
149 return false;
150 }
151
152 public function status_header( $status ) {
153 // Fix for incorrect headers sent when using FastCGI/IIS
154 if ( substr( php_sapi_name(), 0, 3 ) === 'cgi' ) {
155 return str_replace( 'HTTP/1.1', 'Status:', $status );
156 }
157
158 return $status;
159 }
160
161 public function send_headers( $obj ) {
162 if ( ! empty( $this->matched ) && $this->matched->action->get_code() === 410 ) {
163 add_filter( 'status_header', array( $this, 'set_header_410' ) );
164 }
165 }
166
167 public function set_header_410() {
168 return 'HTTP/1.1 410 Gone';
169 }
170
171 public function wp_redirect( $url, $status ) {
172 global $wp_version, $is_IIS;
173
174 if ( $is_IIS ) {
175 header( "Refresh: 0;url=$url" );
176 return $url;
177 }
178
179 if ( $status === 301 && php_sapi_name() === 'cgi-fcgi' ) {
180 $servers_to_check = array( 'lighttpd', 'nginx' );
181
182 foreach ( $servers_to_check as $name ) {
183 if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && stripos( $_SERVER['SERVER_SOFTWARE'], $name ) !== false ) {
184 status_header( $status );
185 header( "Location: $url" );
186 exit( 0 );
187 }
188 }
189 }
190
191 if ( intval( $status, 10 ) === 307 ) {
192 status_header( $status );
193 nocache_headers();
194 return $url;
195 }
196
197 $options = red_get_options();
198
199 // Do we need to set the cache header?
200 if ( ! headers_sent() && isset( $options['redirect_cache'] ) && $options['redirect_cache'] !== 0 && intval( $status, 10 ) === 301 ) {
201 if ( $options['redirect_cache'] === -1 ) {
202 // No cache - just use WP function
203 nocache_headers();
204 } else {
205 // Custom cache
206 header( 'Expires: ' . gmdate( 'D, d M Y H:i:s T', time() + $options['redirect_cache'] * 60 * 60 ) );
207 header( 'Cache-Control: max-age=' . $options['redirect_cache'] * 60 * 60 );
208 }
209 }
210
211 status_header( $status );
212 return $url;
213 }
214
215 public function update( array $data ) {
216 return false;
217 }
218
219 protected function load( $options ) {
220 }
221
222 protected function flush_module() {
223 }
224
225 public function reset() {
226 $this->can_log = true;
227 }
228 }
229