PluginProbe
Redirection / 3.6
Redirection v3.6
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 / models / htaccess.php

htaccess.php in Redirection 3.6, at models/htaccess.php

245 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class Red_Htaccess {
4 private $items = array();
5 const INSERT_REGEX = '@\n?# Created by Redirection(?:.*?)# End of Redirection\n?@sm';
6
7 private function encode_from( $url ) {
8 $url = $this->encode( $url );
9
10 // Apache 2 does not need a leading slashing
11 $url = ltrim( $url, '/' );
12
13 // Exactly match the URL
14 return '^' . $url . '$';
15 }
16
17 private function encode2nd( $url ) {
18 $url = urlencode( $url );
19 $url = str_replace( '%2F', '/', $url );
20 $url = str_replace( '%3F', '?', $url );
21 $url = str_replace( '%3A', ':', $url );
22 $url = str_replace( '%3D', '=', $url );
23 $url = str_replace( '%26', '&', $url );
24 $url = str_replace( '%25', '%', $url );
25 $url = str_replace( '+', '%20', $url );
26 $url = str_replace( '%24', '$', $url );
27 return $url;
28 }
29
30 private function encode( $url ) {
31 $url = urlencode( $url );
32 $url = str_replace( '%2F', '/', $url );
33 $url = str_replace( '%3F', '?', $url );
34 $url = str_replace( '+', '%20', $url );
35 $url = str_replace( '.', '\\.', $url );
36 return $url;
37 }
38
39 private function encode_regex( $url ) {
40 // Remove any newlines
41 $url = preg_replace( "/[\r\n\t].*?$/s", '', $url );
42
43 // Remove invalid characters
44 $url = preg_replace( '/[^\PC\s]/u', '', $url );
45
46 // Make sure spaces are quoted
47 $url = str_replace( ' ', '%20', $url );
48 $url = str_replace( '%24', '$', $url );
49
50 // No leading slash
51 $url = ltrim( $url, '/' );
52
53 // If pattern has a ^ at the start then ensure we don't have a slash immediatley after
54 $url = preg_replace( '@^\^/@', '^', $url );
55
56 return $url;
57 }
58
59 private function add_referrer( $item, $match ) {
60 $from = $this->encode_from( ltrim( $item->get_url(), '/' ) );
61 if ( $item->is_regex() ) {
62 $from = $this->encode_regex( ltrim( $item->get_url(), '/' ) );
63 }
64
65 if ( ( $match->url_from || $match->url_notfrom ) && $match->referrer ) {
66 $this->items[] = sprintf( 'RewriteCond %%{HTTP_REFERER} %s [NC]', ( $match->regex ? $this->encode_regex( $match->referrer ) : $this->encode_from( $match->referrer ) ) );
67
68 if ( $match->url_from ) {
69 $to = $this->target( $item->get_action_type(), $match->url_from, $item->get_action_code(), $item->is_regex() );
70 $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to );
71 }
72
73 if ( $match->url_notfrom ) {
74 $to = $this->target( $item->get_action_type(), $match->url_notfrom, $item->get_action_code(), $item->is_regex() );
75 $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to );
76 }
77 }
78 }
79
80 private function add_agent( $item, $match ) {
81 $from = $this->encode( ltrim( $item->get_url(), '/' ) );
82 if ( $item->is_regex() ) {
83 $from = $this->encode_regex( ltrim( $item->get_url(), '/' ) );
84 }
85
86 if ( ( $match->url_from || $match->url_notfrom ) && $match->user_agent ) {
87 $this->items[] = sprintf( 'RewriteCond %%{HTTP_USER_AGENT} %s [NC]', ( $match->regex ? $this->encode_regex( $match->user_agent ) : $this->encode2nd( $match->user_agent ) ) );
88
89 if ( $match->url_from ) {
90 $to = $this->target( $item->get_action_type(), $match->url_from, $item->get_action_code(), $item->is_regex() );
91 $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to );
92 }
93
94 if ( $match->url_notfrom ) {
95 $to = $this->target( $item->get_action_type(), $match->url_notfrom, $item->get_action_code(), $item->is_regex() );
96 $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to );
97 }
98 }
99 }
100
101 private function add_server( $item, $match ) {
102 $match->url = $match->url_from;
103 $this->items[] = sprintf( 'RewriteCond %%{HTTP_HOST} ^%s$ [NC]', preg_quote( $match->server ) );
104 $this->add_url( $item, $match );
105 }
106
107 private function add_url( $item, $match ) {
108 $url = $item->get_url();
109
110 if ( $item->is_regex() === false && strpos( $url, '?' ) !== false || strpos( $url, '&' ) !== false ) {
111 $url_parts = wp_parse_url( $url );
112 $url = $url_parts['path'];
113 $query = isset( $url_parts['query'] ) ? $url_parts['query'] : '';
114 $this->items[] = sprintf( 'RewriteCond %%{QUERY_STRING} ^%s$', $query );
115 }
116
117 $to = $this->target( $item->get_action_type(), $match->url, $item->get_action_code(), $item->is_regex() );
118 $from = $this->encode_from( $url );
119
120 if ( $item->is_regex() ) {
121 $from = $this->encode_regex( $item->get_url() );
122 }
123
124 if ( $to ) {
125 $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to );
126 }
127 }
128
129 private function action_random( $data, $code, $regex ) {
130 // Pick a WP post at random
131 global $wpdb;
132
133 $post = $wpdb->get_var( "SELECT ID FROM {$wpdb->posts} ORDER BY RAND() LIMIT 0,1" );
134 $url = wp_parse_url( get_permalink( $post ) );
135
136 return sprintf( '%s [R=%d,L]', $this->encode( $url['path'] ), $code );
137 }
138
139 private function action_pass( $data, $code, $regex ) {
140 if ( $regex ) {
141 return sprintf( '%s [L]', $this->encode2nd( $data ), $code );
142 }
143 return sprintf( '%s [L]', $this->encode2nd( $data ), $code );
144 }
145
146 private function action_error( $data, $code, $regex ) {
147 if ( $code === 410 ) {
148 return '/ [G]';
149 }
150 return '/ [F]';
151 }
152
153 private function action_url( $data, $code, $regex ) {
154 if ( $regex ) {
155 return sprintf( '%s [R=%d,L]', $this->encode2nd( $data ), $code );
156 }
157 return sprintf( '%s [R=%d,L]', $this->encode2nd( $data ), $code );
158 }
159
160 private function target( $action, $data, $code, $regex ) {
161 $target = 'action_' . $action;
162
163 if ( method_exists( $this, $target ) ) {
164 return $this->$target( $data, $code, $regex );
165 }
166 return '';
167 }
168
169 private function generate() {
170 $version = red_get_plugin_data( dirname( dirname( __FILE__ ) ) . '/redirection.php' );
171
172 if ( count( $this->items ) === 0 ) {
173 return '';
174 }
175
176 $text[] = '# Created by Redirection';
177 $text[] = '# ' . date( 'r' );
178 $text[] = '# Redirection ' . trim( $version['Version'] ) . ' - https://redirection.me';
179 $text[] = '';
180
181 // mod_rewrite section
182 $text[] = '<IfModule mod_rewrite.c>';
183
184 // Add http => https option
185 $options = red_get_options();
186 if ( $options['https'] ) {
187 $text[] = 'RewriteCond %{HTTPS} off';
188 $text[] = 'RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}';
189 }
190
191 // Add redirects
192 $text = array_merge( $text, array_filter( $this->items ) );
193
194 // End of mod_rewrite
195 $text[] = '</IfModule>';
196 $text[] = '';
197
198 // End of redirection section
199 $text[] = '# End of Redirection';
200
201 $text = implode( "\n", $text );
202 return "\n" . $text . "\n";
203 }
204
205 public function add( $item ) {
206 $target = 'add_' . $item->get_match_type();
207
208 if ( method_exists( $this, $target ) ) {
209 $this->$target( $item, $item->match );
210 }
211 }
212
213 public function get( $existing = false ) {
214 $text = $this->generate();
215
216 if ( $existing ) {
217 if ( preg_match( self::INSERT_REGEX, $existing ) > 0 ) {
218 $text = preg_replace( self::INSERT_REGEX, str_replace( '$', '\\$', $text ), $existing );
219 } else {
220 $text = $text . "\n" . trim( $existing );
221 }
222 }
223
224 return trim( $text );
225 }
226
227 public function save( $filename, $content_to_save = false ) {
228 $existing = false;
229
230 if ( file_exists( $filename ) ) {
231 $existing = file_get_contents( $filename );
232 }
233
234 $file = @fopen( $filename, 'w' );
235 if ( $file ) {
236 $result = fwrite( $file, $this->get( $existing ) );
237 fclose( $file );
238
239 return $result !== false;
240 }
241
242 return false;
243 }
244 }
245