| @@ -1,16 +1,9 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | -/** | |
| 4 | - * Convert redirects to .htaccess format | |
| 5 | - * | |
| 6 | - * Ignores: | |
| 7 | - * - Trailing slash flag | |
| 8 | - * - Query flags | |
| 9 | - */ | |
| 10 | 3 | class Red_Htaccess { |
| 11 | 4 | private $items = array(); |
| 12 | - const INSERT_REGEX = '@\n?# Created by Redirection(?:.*?)# End of Redirection\n?@sm'; | |
| 5 | + const INSERT_REGEX = '@\n?# Created by Redirection(.*?)# End of Redirection\n?@sm'; | |
| 13 | 6 | |
| 14 | 7 | private function encode_from( $url ) { |
| 15 | 8 | $url = $this->encode( $url ); |
| 16 | 9 | |
| @@ -17,46 +10,31 @@ | ||
| 17 | 10 | // Apache 2 does not need a leading slashing |
| 18 | 11 | $url = ltrim( $url, '/' ); |
| 19 | 12 | |
| 20 | 13 | // Exactly match the URL |
| 21 | - return '^' . $url . '$'; | |
| 14 | + return '^'.$url.'$'; | |
| 22 | 15 | } |
| 23 | 16 | |
| 24 | - // URL encode some things, but other things can be passed through | |
| 25 | 17 | private function encode2nd( $url ) { |
| 26 | - $allowed = [ | |
| 27 | - '%2F' => '/', | |
| 28 | - '%3F' => '?', | |
| 29 | - '%3A' => ':', | |
| 30 | - '%3D' => '=', | |
| 31 | - '%26' => '&', | |
| 32 | - '%25' => '%', | |
| 33 | - '+' => '%20', | |
| 34 | - '%24' => '$', | |
| 35 | - '%23' => '#', | |
| 36 | - ]; | |
| 37 | - | |
| 38 | 18 | $url = urlencode( $url ); |
| 39 | - return $this->replace_encoding( $url, $allowed ); | |
| 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; | |
| 40 | 28 | } |
| 41 | 29 | |
| 42 | - private function replace_encoding( $str, $allowed ) { | |
| 43 | - foreach ( $allowed as $before => $after ) { | |
| 44 | - $str = str_replace( $before, $after, $str ); | |
| 45 | - } | |
| 46 | - | |
| 47 | - return $str; | |
| 48 | - } | |
| 49 | - | |
| 50 | 30 | private function encode( $url ) { |
| 51 | - $allowed = [ | |
| 52 | - '%2F' => '/', | |
| 53 | - '%3F' => '?', | |
| 54 | - '+' => '%20', | |
| 55 | - '.' => '\\.', | |
| 56 | - ]; | |
| 57 | - | |
| 58 | - return $this->replace_encoding( urlencode( $url ), $allowed ); | |
| 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; | |
| 59 | 37 | } |
| 60 | 38 | |
| 61 | 39 | private function encode_regex( $url ) { |
| 62 | 40 | // Remove any newlines |
| @@ -79,22 +57,21 @@ | ||
| 79 | 57 | } |
| 80 | 58 | |
| 81 | 59 | private function add_referrer( $item, $match ) { |
| 82 | 60 | $from = $this->encode_from( ltrim( $item->get_url(), '/' ) ); |
| 83 | - if ( $item->is_regex() ) { | |
| 61 | + if ( $item->is_regex() ) | |
| 84 | 62 | $from = $this->encode_regex( ltrim( $item->get_url(), '/' ) ); |
| 85 | - } | |
| 86 | 63 | |
| 87 | 64 | if ( ( $match->url_from || $match->url_notfrom ) && $match->referrer ) { |
| 88 | 65 | $this->items[] = sprintf( 'RewriteCond %%{HTTP_REFERER} %s [NC]', ( $match->regex ? $this->encode_regex( $match->referrer ) : $this->encode_from( $match->referrer ) ) ); |
| 89 | 66 | |
| 90 | 67 | if ( $match->url_from ) { |
| 91 | - $to = $this->target( $item->get_action_type(), $match->url_from, $item->get_action_code(), $item->get_match_data() ); | |
| 68 | + $to = $this->target( $item->get_action_type(), $match->url_from, $item->get_action_code(), $item->is_regex() ); | |
| 92 | 69 | $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to ); |
| 93 | 70 | } |
| 94 | 71 | |
| 95 | 72 | if ( $match->url_notfrom ) { |
| 96 | - $to = $this->target( $item->get_action_type(), $match->url_notfrom, $item->get_action_code(), $item->get_match_data() ); | |
| 73 | + $to = $this->target( $item->get_action_type(), $match->url_notfrom, $item->get_action_code(), $item->is_regex() ); | |
| 97 | 74 | $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to ); |
| 98 | 75 | } |
| 99 | 76 | } |
| 100 | 77 | } |
| @@ -100,44 +77,36 @@ | ||
| 100 | 77 | } |
| 101 | 78 | |
| 102 | 79 | private function add_agent( $item, $match ) { |
| 103 | 80 | $from = $this->encode( ltrim( $item->get_url(), '/' ) ); |
| 104 | - if ( $item->is_regex() ) { | |
| 81 | + if ( $item->is_regex() ) | |
| 105 | 82 | $from = $this->encode_regex( ltrim( $item->get_url(), '/' ) ); |
| 106 | - } | |
| 107 | 83 | |
| 108 | 84 | if ( ( $match->url_from || $match->url_notfrom ) && $match->user_agent ) { |
| 109 | 85 | $this->items[] = sprintf( 'RewriteCond %%{HTTP_USER_AGENT} %s [NC]', ( $match->regex ? $this->encode_regex( $match->user_agent ) : $this->encode2nd( $match->user_agent ) ) ); |
| 110 | 86 | |
| 111 | - if ( $match->url_from ) { | |
| 112 | - $to = $this->target( $item->get_action_type(), $match->url_from, $item->get_action_code(), $item->get_match_data() ); | |
| 87 | + if ( $match->url_from ) { | |
| 88 | + $to = $this->target( $item->get_action_type(), $match->url_from, $item->get_action_code(), $item->is_regex() ); | |
| 113 | 89 | $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to ); |
| 114 | 90 | } |
| 115 | 91 | |
| 116 | 92 | if ( $match->url_notfrom ) { |
| 117 | - $to = $this->target( $item->get_action_type(), $match->url_notfrom, $item->get_action_code(), $item->get_match_data() ); | |
| 93 | + $to = $this->target( $item->get_action_type(), $match->url_notfrom, $item->get_action_code(), $item->is_regex() ); | |
| 118 | 94 | $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to ); |
| 119 | 95 | } |
| 120 | 96 | } |
| 121 | 97 | } |
| 122 | 98 | |
| 123 | - private function add_server( $item, $match ) { | |
| 124 | - $match->url = $match->url_from; | |
| 125 | - $this->items[] = sprintf( 'RewriteCond %%{HTTP_HOST} ^%s$ [NC]', preg_quote( $match->server ) ); | |
| 126 | - $this->add_url( $item, $match ); | |
| 127 | - } | |
| 128 | - | |
| 129 | 99 | private function add_url( $item, $match ) { |
| 130 | 100 | $url = $item->get_url(); |
| 131 | 101 | |
| 132 | 102 | if ( $item->is_regex() === false && strpos( $url, '?' ) !== false || strpos( $url, '&' ) !== false ) { |
| 133 | - $url_parts = wp_parse_url( $url ); | |
| 103 | + $url_parts = parse_url( $url ); | |
| 134 | 104 | $url = $url_parts['path']; |
| 135 | - $query = isset( $url_parts['query'] ) ? $url_parts['query'] : ''; | |
| 136 | - $this->items[] = sprintf( 'RewriteCond %%{QUERY_STRING} ^%s$', $query ); | |
| 105 | + $this->items[] = sprintf( 'RewriteCond %%{QUERY_STRING} ^%s$', $url_parts['query'] ); | |
| 137 | 106 | } |
| 138 | 107 | |
| 139 | - $to = $this->target( $item->get_action_type(), $match->url, $item->get_action_code(), $item->get_match_data() ); | |
| 108 | + $to = $this->target( $item->get_action_type(), $match->url, $item->get_action_code(), $item->is_regex() ); | |
| 140 | 109 | $from = $this->encode_from( $url ); |
| 141 | 110 | |
| 142 | 111 | if ( $item->is_regex() ) { |
| 143 | 112 | $from = $this->encode_regex( $item->get_url() ); |
| @@ -142,99 +111,61 @@ | ||
| 142 | 111 | if ( $item->is_regex() ) { |
| 143 | 112 | $from = $this->encode_regex( $item->get_url() ); |
| 144 | 113 | } |
| 145 | 114 | |
| 146 | - if ( $to ) { | |
| 115 | + if ( $to ) | |
| 147 | 116 | $this->items[] = sprintf( 'RewriteRule %s %s', $from, $to ); |
| 148 | - } | |
| 149 | 117 | } |
| 150 | 118 | |
| 151 | - private function add_flags( $current, array $flags ) { | |
| 152 | - return $current . ' [' . implode( ',', $flags ) . ']'; | |
| 153 | - } | |
| 154 | - | |
| 155 | - private function get_source_flags( array $existing, array $source ) { | |
| 156 | - $flags = []; | |
| 157 | - | |
| 158 | - if ( isset( $source['flag_case'] ) && $source['flag_case'] ) { | |
| 159 | - $flags[] = 'NC'; | |
| 160 | - } | |
| 161 | - | |
| 162 | - return array_merge( $existing, $flags ); | |
| 163 | - } | |
| 164 | - | |
| 165 | - private function action_random( $data, $code, $match_data ) { | |
| 119 | + private function action_random( $data, $code, $regex ) { | |
| 166 | 120 | // Pick a WP post at random |
| 167 | 121 | global $wpdb; |
| 168 | 122 | |
| 169 | 123 | $post = $wpdb->get_var( "SELECT ID FROM {$wpdb->posts} ORDER BY RAND() LIMIT 0,1" ); |
| 170 | - $url = wp_parse_url( get_permalink( $post ) ); | |
| 124 | + $url = parse_url( get_permalink( $post ) ); | |
| 171 | 125 | |
| 172 | - $flags = [ sprintf( 'R=%d', $code ) ]; | |
| 173 | - $flags[] = 'L'; | |
| 174 | - $flags = $this->get_source_flags( $flags, $match_data['source'] ); | |
| 175 | - | |
| 176 | - return $this->add_flags( $this->encode( $url['path'] ), $flags ); | |
| 126 | + return sprintf( '%s [R=%d,L]', $this->encode( $url['path'] ), $code ); | |
| 177 | 127 | } |
| 178 | 128 | |
| 179 | - private function action_pass( $data, $code, $match_data ) { | |
| 180 | - $flags = $this->get_source_flags( [ 'L' ], $match_data['source'] ); | |
| 181 | - | |
| 182 | - return $this->add_flags( $this->encode2nd( $data ), $flags ); | |
| 129 | + private function action_pass( $data, $code, $regex ) { | |
| 130 | + if ( $regex ) | |
| 131 | + return sprintf( '%s [L]', $this->encode2nd( $data ), $code ); | |
| 132 | + return sprintf( '%s [L]', $this->encode2nd( $data ), $code ); | |
| 183 | 133 | } |
| 184 | 134 | |
| 185 | - private function action_error( $data, $code, $match_data ) { | |
| 186 | - $flags = $this->get_source_flags( [ 'F' ], $match_data['source'] ); | |
| 187 | - | |
| 188 | - if ( $code === 410 ) { | |
| 189 | - $flags = $this->get_source_flags( [ 'G' ], $match_data['source'] ); | |
| 190 | - } | |
| 191 | - | |
| 192 | - return $this->add_flags( '/', $flags ); | |
| 135 | + private function action_error( $data, $code, $regex ) { | |
| 136 | + if ( $code === 410 ) | |
| 137 | + return '/ [G]'; | |
| 138 | + return '/ [F]'; | |
| 193 | 139 | } |
| 194 | 140 | |
| 195 | - private function action_url( $data, $code, $match_data ) { | |
| 196 | - $flags = [ sprintf( 'R=%d', $code ) ]; | |
| 197 | - $flags[] = 'L'; | |
| 198 | - $flags = $this->get_source_flags( $flags, $match_data['source'] ); | |
| 199 | - | |
| 200 | - return $this->add_flags( $this->encode2nd( $data ), $flags ); | |
| 141 | + private function action_url( $data, $code, $regex ) { | |
| 142 | + if ( $regex ) | |
| 143 | + return sprintf( '%s [R=%d,L]', $this->encode2nd( $data ), $code ); | |
| 144 | + return sprintf( '%s [R=%d,L]', $this->encode2nd( $data ), $code ); | |
| 201 | 145 | } |
| 202 | 146 | |
| 203 | - private function target( $action, $data, $code, $match_data ) { | |
| 204 | - $target = 'action_' . $action; | |
| 147 | + private function target( $action, $data, $code, $regex ) { | |
| 148 | + $target = 'action_'.$action; | |
| 205 | 149 | |
| 206 | - if ( method_exists( $this, $target ) ) { | |
| 207 | - return $this->$target( $data, $code, $match_data ); | |
| 208 | - } | |
| 209 | - | |
| 150 | + if ( method_exists( $this, $target ) ) | |
| 151 | + return $this->$target( $data, $code, $regex ); | |
| 210 | 152 | return ''; |
| 211 | 153 | } |
| 212 | 154 | |
| 213 | 155 | private function generate() { |
| 214 | - $version = red_get_plugin_data( dirname( dirname( __FILE__ ) ) . '/redirection.php' ); | |
| 156 | + $version = get_plugin_data( dirname( dirname( __FILE__ ) ).'/redirection.php' ); | |
| 215 | 157 | |
| 216 | - if ( count( $this->items ) === 0 ) { | |
| 217 | - return ''; | |
| 218 | - } | |
| 219 | - | |
| 220 | 158 | $text[] = '# Created by Redirection'; |
| 221 | - $text[] = '# ' . date( 'r' ); | |
| 222 | - $text[] = '# Redirection ' . trim( $version['Version'] ) . ' - https://redirection.me'; | |
| 159 | + $text[] = '# '.date( 'r' ); | |
| 160 | + $text[] = '# Redirection '.trim( $version['Version'] ).' - http://urbangiraffe.com/plugins/redirection/'; | |
| 223 | 161 | $text[] = ''; |
| 224 | 162 | |
| 225 | 163 | // mod_rewrite section |
| 226 | 164 | $text[] = '<IfModule mod_rewrite.c>'; |
| 227 | 165 | |
| 228 | - // Add http => https option | |
| 229 | - $options = red_get_options(); | |
| 230 | - if ( $options['https'] ) { | |
| 231 | - $text[] = 'RewriteCond %{HTTPS} off'; | |
| 232 | - $text[] = 'RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}'; | |
| 233 | - } | |
| 234 | - | |
| 235 | 166 | // Add redirects |
| 236 | - $text = array_merge( $text, array_filter( array_map( [ $this, 'sanitize_redirect' ], $this->items ) ) ); | |
| 167 | + $text = array_merge( $text, $this->items ); | |
| 237 | 168 | |
| 238 | 169 | // End of mod_rewrite |
| 239 | 170 | $text[] = '</IfModule>'; |
| 240 | 171 | $text[] = ''; |
| @@ -241,18 +172,17 @@ | ||
| 241 | 172 | |
| 242 | 173 | // End of redirection section |
| 243 | 174 | $text[] = '# End of Redirection'; |
| 244 | 175 | |
| 245 | - $text = implode( "\n", $text ); | |
| 246 | - return "\n" . $text . "\n"; | |
| 176 | + $text = implode( "\r\n", $text ); | |
| 177 | + return "\n".$text."\n"; | |
| 247 | 178 | } |
| 248 | 179 | |
| 249 | 180 | public function add( $item ) { |
| 250 | - $target = 'add_' . $item->get_match_type(); | |
| 181 | + $target = 'add_'.$item->get_match_type(); | |
| 251 | 182 | |
| 252 | - if ( method_exists( $this, $target ) && $item->is_enabled() ) { | |
| 183 | + if ( method_exists( $this, $target ) ) | |
| 253 | 184 | $this->$target( $item, $item->match ); |
| 254 | - } | |
| 255 | 185 | } |
| 256 | 186 | |
| 257 | 187 | public function get( $existing = false ) { |
| 258 | 188 | $text = $this->generate(); |
| @@ -257,29 +187,19 @@ | ||
| 257 | 187 | public function get( $existing = false ) { |
| 258 | 188 | $text = $this->generate(); |
| 259 | 189 | |
| 260 | 190 | if ( $existing ) { |
| 261 | - if ( preg_match( self::INSERT_REGEX, $existing ) > 0 ) { | |
| 262 | - $text = preg_replace( self::INSERT_REGEX, str_replace( '$', '\\$', $text ), $existing ); | |
| 263 | - } else { | |
| 264 | - $text = $text . "\n" . trim( $existing ); | |
| 265 | - } | |
| 191 | + if ( preg_match( self::INSERT_REGEX, $existing ) > 0 ) | |
| 192 | + $text = preg_replace( self::INSERT_REGEX, $text, $existing ); | |
| 193 | + else | |
| 194 | + $text = trim( $existing )."\n".$text; | |
| 266 | 195 | } |
| 267 | 196 | |
| 268 | 197 | return trim( $text ); |
| 269 | 198 | } |
| 270 | 199 | |
| 271 | - public function sanitize_redirect( $text ) { | |
| 272 | - return str_replace( [ '<?', '>' ], '', $text ); | |
| 273 | - } | |
| 274 | - | |
| 275 | - public function sanitize_filename( $filename ) { | |
| 276 | - return str_replace( '.php', '', $filename ); | |
| 277 | - } | |
| 278 | - | |
| 279 | 200 | public function save( $filename, $content_to_save = false ) { |
| 280 | 201 | $existing = false; |
| 281 | - $filename = $this->sanitize_filename( $filename ); | |
| 282 | 202 | |
| 283 | 203 | if ( file_exists( $filename ) ) { |
| 284 | 204 | $existing = file_get_contents( $filename ); |
| 285 | 205 | } |