Safe Redirect Manager - Version 1.7.4

Version Description

(Sept. 5, 2014) = * Fix case sensitivity redirection bug. * Add more unit tests

Download this release

Release Info

Developer tlovett1
Plugin Icon 128x128 Safe Redirect Manager
Version 1.7.4
Comparing to
See all releases

Code changes from version 1.7.3 to 1.7.4

Files changed (4) hide show
  1. README.md +103 -0
  2. readme.txt +6 -2
  3. safe-redirect-manager.php +9 -9
  4. tests/test-core.php +143 -4
README.md ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Safe Redirect Manager
2
+ ==============
3
+
4
+ A WordPress plugin to safely and easily manage your website's HTTP redirects.
5
+
6
+ ## Purpose
7
+
8
+ Easily and safely manage your site's redirects the WordPress way. There are many redirect plugins available. Most of
9
+ them store redirects in the options table or in custom tables. Most of them provide tons of unnecessary options. Some
10
+ of them have serious performance implications (404 error logging). Safe Redirect Manager stores redirects as Custom
11
+ Post Types. This makes your data portable and your website scalable. Safe Redirect Manager is built to handle enterprise
12
+ level traffic and is used on major publishing websites. The plugin comes with only what you need following the
13
+ WordPress mantra decisions not options. Actions in filters make the plugin very extensible.
14
+
15
+ ## Installation
16
+
17
+ Install the plugin in WordPress. You can download a
18
+ [zip via Github](https://github.com/tlovett1/safe-redirect-manager/archive/master.zip) and upload it using the WP
19
+ plugin uploader.
20
+
21
+ ## Non-English Usage
22
+ Safe Redirect Manager is available in English, French, and Slovak. Instructions for translating the plugin into other
23
+ languages are below.
24
+
25
+ ## Configuration
26
+
27
+ There are no overarching settings for this plugin. To manager redirects navigate to the administration panel. Within
28
+ the main menu, click "Tools" > "Safe Redirect Manager".
29
+
30
+ Each redirect contains a few fields that you can utilize:
31
+
32
+ #### "Redirect From"
33
+ This should be a path relative to the root of your WordPress installation. When someone visits your site with a path
34
+ that matches this one, a redirect will occur. If your site is located at ```http://example.com/wp/``` and you wanted to
35
+ redirect ```http://example.com/wp/about``` to ```http://example.com```, your "Redirect From" would be ```/about```.
36
+
37
+ Clicking the "Enable Regex" checkbox allows you to use regular expressions in your path. There are many
38
+ [great tutorials](http://www.regular-expressions.info) on regular expressions.
39
+
40
+ You can also use wildcards in your "Redirect From" paths. By adding an ```*``` at the end of a URL, your redirect will
41
+ match any request that starts with your "Redirect From". Wildcards support replacements. This means if you have a
42
+ wildcard in your from path that matches a string, you can have that string replace a wildcard character in your
43
+ "Redirect To" path. For example, if your "Redirect From" is ```/test/*```, your "Redirect To" is
44
+ ```http://google.com/*```, and the requested path is ```/test/string```, the user would be redirect to ```http://google.com/string```.
45
+
46
+ #### "Redirect To"
47
+ This should be a path i.e. ```/test``` or a URL i.e. ```http://example.com/wp/test```. If a requested path matches
48
+ "Redirect From", they will be redirected here. "Redirect To" supports wildcard and regular expression replacements.
49
+
50
+ #### "HTTP Status Code"
51
+ [HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) are numbers that contain information about
52
+ a request i.e. whether it was successful, unauthorized, not found, etc. You should almost always use either 302,
53
+ temporarily moved, or 301, permanently moved.
54
+
55
+ *Note:*
56
+
57
+ * Redirects are cached using the Transients API. Cache busts occur when redirects are added, updated, and deleted
58
+ so you shouldn't be serving stale redirects.
59
+ * By default the plugin only allows at most 150 redirects to prevent performance issues. There is a filter
60
+ ```srm_max_redirects``` that you can utilize to up this number.
61
+ * "Redirect From" and requested paths are case insensitive by default.
62
+
63
+ ## Development
64
+
65
+ #### Setup
66
+ Follow the configuration instructions above to setup the plugin. I recommend developing the plugin locally in an
67
+ environment such as [Varying Vagrant Vagrants](https://github.com/Varying-Vagrant-Vagrants/VVV).
68
+
69
+ #### Translation
70
+ Safe Redirect Manager has a [.pot file](https://github.com/tlovett1/Safe-Redirect-Manager/blob/master/languages/safe-redirect-manager.pot)
71
+ containing strings ready for translation. You can use a program like [POedit](http://poedit.net) to generate .po/.mo
72
+ files for your language.
73
+
74
+ #### Testing
75
+ Within the terminal change directories to the plugin folder. Initialize your unit testing environment by running the
76
+ following command:
77
+
78
+ For VVV users:
79
+ ```
80
+ bash bin/install-wp-tests.sh wordpress_test root root localhost latest
81
+ ```
82
+
83
+ For VIP Quickstart users:
84
+ ```
85
+ bash bin/install-wp-tests.sh wordpress_test root '' localhost latest
86
+ ```
87
+
88
+ where:
89
+
90
+ * wordpress_test is the name of the test database (all data will be deleted!)
91
+ * root is the MySQL user name
92
+ * root is the MySQL user password (if you're running VVV). Blank if you're running VIP Quickstart.
93
+ * localhost is the MySQL server host
94
+ * latest is the WordPress version; could also be 3.7, 3.6.2 etc.
95
+
96
+ Run the plugin tests:
97
+ ```
98
+ phpunit
99
+ ```
100
+
101
+ #### Issues
102
+ If you identify any errors or have an idea for improving the plugin, please
103
+ [open an issue](https://github.com/tlovett1/safe-redirect-manager/issues?state=open).
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: tlovett1, tollmanz, taylorde, 10up, jakemgold, danielbachhuber, VentureBeat
3
  Tags: http redirects, redirect manager, url redirection, safe http redirection, multisite redirects
4
  Requires at least: 3.1
5
- Tested up to: 3.8
6
- Stable tag: 1.7.3
7
 
8
  Safely and easily manage your website's HTTP redirects.
9
 
@@ -24,6 +24,10 @@ Extract the zip file and just drop the contents in the wp-content/plugins/ direc
24
 
25
  == Changelog ==
26
 
 
 
 
 
27
  = 1.7.3 (Aug. 26, 2014) =
28
  * Check if the global $wp_query is null before using get_query_var. Props [cmmarslender](https://github.com/cmmarslender)
29
  * Unit tests
2
  Contributors: tlovett1, tollmanz, taylorde, 10up, jakemgold, danielbachhuber, VentureBeat
3
  Tags: http redirects, redirect manager, url redirection, safe http redirection, multisite redirects
4
  Requires at least: 3.1
5
+ Tested up to: 4.0
6
+ Stable tag: 1.7.4
7
 
8
  Safely and easily manage your website's HTTP redirects.
9
 
24
 
25
  == Changelog ==
26
 
27
+ = 1.7.4 (Sept. 5, 2014) =
28
+ * Fix case sensitivity redirection bug.
29
+ * Add more unit tests
30
+
31
  = 1.7.3 (Aug. 26, 2014) =
32
  * Check if the global $wp_query is null before using get_query_var. Props [cmmarslender](https://github.com/cmmarslender)
33
  * Unit tests
safe-redirect-manager.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Safe Redirect Manager
4
  Plugin URI: http://www.10up.com
5
  Description: Easily and safely manage HTTP redirects.
6
  Author: Taylor Lovett (10up LLC), VentureBeat
7
- Version: 1.7.3
8
  Author URI: http://www.10up.com
9
 
10
  GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
@@ -811,11 +811,11 @@ class SRM_Safe_Redirect_Manager {
811
  */
812
  $parsed_site_url = parse_url( site_url() );
813
  if ( isset( $parsed_site_url['path'] ) && '/' != $parsed_site_url['path'] ) {
814
- $requested_path = preg_replace( '@' . $parsed_site_url['path'] . '@i', '', $requested_path, 1 );
815
  }
816
 
817
  // Allow redirects to be filtered
818
- $redirects = apply_filters( 'srm_registered_redirects', $redirects, $requested_path );
819
 
820
  foreach ( (array)$redirects as $redirect ) {
821
 
@@ -828,13 +828,13 @@ class SRM_Safe_Redirect_Manager {
828
  $enable_regex = ( isset( $redirect['enable_regex'] ) ) ? $redirect['enable_regex'] : false;
829
 
830
  if ( apply_filters( 'srm_case_insensitive_redirects', true ) ) {
831
- $requested_path = strtolower( $requested_path );
832
  $redirect_from = strtolower( $redirect_from );
833
  }
834
 
835
  // check if requested path is the same as the redirect from path
836
  if ( $enable_regex ) {
837
- $matched_path = preg_match( '@' . $redirect_from . '@', $requested_path );
838
  } else {
839
  $matched_path = ( $unslashed_requested_path == $redirect_from );
840
 
@@ -843,9 +843,9 @@ class SRM_Safe_Redirect_Manager {
843
  $wildcard_base = substr( $redirect_from, 0, strlen( $redirect_from ) - 1 );
844
 
845
  // mark as match if requested path matches the base of the redirect from
846
- $matched_path = (substr( $requested_path, 0, strlen( $wildcard_base ) ) == $wildcard_base);
847
  if ( (strrpos( $redirect_to, '*' ) == strlen( $redirect_to ) - 1 ) ) {
848
- $redirect_to = rtrim( $redirect_to, '*' ) . ltrim( substr( $requested_path, strlen( $wildcard_base ) ), '/' );
849
  }
850
  }
851
  }
@@ -860,12 +860,12 @@ class SRM_Safe_Redirect_Manager {
860
 
861
  // Allow for regex replacement in $redirect_to
862
  if ( $enable_regex ) {
863
- $redirect_to = preg_replace( '@' . $redirect_from . '@', $redirect_to, $requested_path );
864
  }
865
 
866
  $sanitized_redirect_to = esc_url_raw( $redirect_to );
867
 
868
- do_action( 'srm_do_redirect', $requested_path, $sanitized_redirect_to, $status_code );
869
 
870
  if ( defined( 'PHPUNIT_SRM_TESTSUITE' ) && PHPUNIT_SRM_TESTSUITE ) {
871
  // Don't actually redirect if we are testing
4
  Plugin URI: http://www.10up.com
5
  Description: Easily and safely manage HTTP redirects.
6
  Author: Taylor Lovett (10up LLC), VentureBeat
7
+ Version: 1.7.4
8
  Author URI: http://www.10up.com
9
 
10
  GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
811
  */
812
  $parsed_site_url = parse_url( site_url() );
813
  if ( isset( $parsed_site_url['path'] ) && '/' != $parsed_site_url['path'] ) {
814
+ $unslashed_requested_path = preg_replace( '@' . $parsed_site_url['path'] . '@i', '', $unslashed_requested_path, 1 );
815
  }
816
 
817
  // Allow redirects to be filtered
818
+ $redirects = apply_filters( 'srm_registered_redirects', $redirects, $unslashed_requested_path );
819
 
820
  foreach ( (array)$redirects as $redirect ) {
821
 
828
  $enable_regex = ( isset( $redirect['enable_regex'] ) ) ? $redirect['enable_regex'] : false;
829
 
830
  if ( apply_filters( 'srm_case_insensitive_redirects', true ) ) {
831
+ $unslashed_requested_path = strtolower( $unslashed_requested_path );
832
  $redirect_from = strtolower( $redirect_from );
833
  }
834
 
835
  // check if requested path is the same as the redirect from path
836
  if ( $enable_regex ) {
837
+ $matched_path = preg_match( '@' . $redirect_from . '@', $unslashed_requested_path );
838
  } else {
839
  $matched_path = ( $unslashed_requested_path == $redirect_from );
840
 
843
  $wildcard_base = substr( $redirect_from, 0, strlen( $redirect_from ) - 1 );
844
 
845
  // mark as match if requested path matches the base of the redirect from
846
+ $matched_path = (substr( $unslashed_requested_path, 0, strlen( $wildcard_base ) ) == $wildcard_base);
847
  if ( (strrpos( $redirect_to, '*' ) == strlen( $redirect_to ) - 1 ) ) {
848
+ $redirect_to = rtrim( $redirect_to, '*' ) . ltrim( substr( $unslashed_requested_path, strlen( $wildcard_base ) ), '/' );
849
  }
850
  }
851
  }
860
 
861
  // Allow for regex replacement in $redirect_to
862
  if ( $enable_regex ) {
863
+ $redirect_to = preg_replace( '@' . $redirect_from . '@', $redirect_to, $unslashed_requested_path );
864
  }
865
 
866
  $sanitized_redirect_to = esc_url_raw( $redirect_to );
867
 
868
+ do_action( 'srm_do_redirect', $unslashed_requested_path, $sanitized_redirect_to, $status_code );
869
 
870
  if ( defined( 'PHPUNIT_SRM_TESTSUITE' ) && PHPUNIT_SRM_TESTSUITE ) {
871
  // Don't actually redirect if we are testing
tests/test-core.php CHANGED
@@ -5,7 +5,7 @@ class SRMTestCore extends WP_UnitTestCase {
5
  /**
6
  * Test root redirect
7
  *
8
- * @since 1.8
9
  */
10
  public function testRootRedirect() {
11
  global $safe_redirect_manager;
@@ -26,10 +26,149 @@ class SRMTestCore extends WP_UnitTestCase {
26
  $this->assertTrue( $redirected );
27
  }
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  /**
30
  * Test lots of permutations of URL trailing slashes with and without regex
31
  *
32
- * @since 1.8
33
  */
34
  public function testTrailingSlashes() {
35
  /**
@@ -136,7 +275,7 @@ class SRMTestCore extends WP_UnitTestCase {
136
  /**
137
  * Test some simple redirections
138
  *
139
- * @since 1.8
140
  */
141
  public function testSimplePath() {
142
  global $safe_redirect_manager;
@@ -198,7 +337,7 @@ class SRMTestCore extends WP_UnitTestCase {
198
  /**
199
  * Test regex redirections
200
  *
201
- * @since 1.8
202
  */
203
  public function testSimplePathRegex() {
204
  global $safe_redirect_manager;
5
  /**
6
  * Test root redirect
7
  *
8
+ * @since 1.7.3
9
  */
10
  public function testRootRedirect() {
11
  global $safe_redirect_manager;
26
  $this->assertTrue( $redirected );
27
  }
28
 
29
+ /**
30
+ * Test redirect with cases
31
+ *
32
+ * @since 1.7.4
33
+ */
34
+ public function testCaseInsensitiveRedirect() {
35
+ global $safe_redirect_manager;
36
+
37
+ $_SERVER['REQUEST_URI'] = '/ONE';
38
+ $redirected = false;
39
+ $redirect_to = '/gohere';
40
+ $safe_redirect_manager->create_redirect( '/one/', $redirect_to );
41
+
42
+ add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
43
+ if ( $redirected_to === $redirect_to ) {
44
+ $redirected = true;
45
+ }
46
+ }, 10, 3 );
47
+
48
+ $safe_redirect_manager->action_parse_request();
49
+
50
+ $this->assertTrue( $redirected );
51
+
52
+ $_SERVER['REQUEST_URI'] = '/one';
53
+ $redirected = false;
54
+ $redirect_to = '/gohere';
55
+ $safe_redirect_manager->create_redirect( '/ONE/', $redirect_to );
56
+
57
+ add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
58
+ if ( $redirected_to === $redirect_to ) {
59
+ $redirected = true;
60
+ }
61
+ }, 10, 3 );
62
+
63
+ $safe_redirect_manager->action_parse_request();
64
+
65
+ $this->assertTrue( $redirected );
66
+ }
67
+
68
+ /**
69
+ * Try a redirect after filtering case sensitivity
70
+ *
71
+ * @since 1.7.4
72
+ */
73
+ public function testCaseSensitiveRedirect() {
74
+ global $safe_redirect_manager;
75
+
76
+ $_SERVER['REQUEST_URI'] = '/ONE';
77
+ $redirected = false;
78
+ $redirect_to = '/gohere';
79
+ $safe_redirect_manager->create_redirect( '/one/', $redirect_to );
80
+
81
+ add_filter( 'srm_case_insensitive_redirects', function( $value ) {
82
+ return false;
83
+ }, 10, 1 );
84
+
85
+ add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
86
+ if ( $redirected_to === $redirect_to ) {
87
+ $redirected = true;
88
+ }
89
+ }, 10, 3 );
90
+
91
+ $safe_redirect_manager->action_parse_request();
92
+
93
+ $this->assertFalse( $redirected );
94
+ }
95
+
96
+ /**
97
+ * Test case sensitive redirect to
98
+ *
99
+ * @since 1.7.4
100
+ */
101
+ public function testCaseSensitiveRedirectTo() {
102
+ global $safe_redirect_manager;
103
+
104
+ $_SERVER['REQUEST_URI'] = '/ONE';
105
+ $redirected = false;
106
+ $redirect_to = '/goHERE';
107
+ $safe_redirect_manager->create_redirect( '/one/', $redirect_to );
108
+
109
+ add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
110
+ if ( $redirected_to === $redirect_to ) {
111
+ $redirected = true;
112
+ }
113
+ }, 10, 3 );
114
+
115
+ $safe_redirect_manager->action_parse_request();
116
+
117
+ $this->assertTrue( $redirected );
118
+ }
119
+
120
+ /**
121
+ * Test basic wildcards
122
+ *
123
+ * @since 1.7.4
124
+ */
125
+ public function testBasicWildcard() {
126
+ global $safe_redirect_manager;
127
+
128
+ $_SERVER['REQUEST_URI'] = '/one/dfsdf';
129
+ $redirected = false;
130
+ $redirect_to = '/gohere';
131
+ $safe_redirect_manager->create_redirect( '/one*', $redirect_to );
132
+
133
+ add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
134
+ if ( $redirected_to === $redirect_to ) {
135
+ $redirected = true;
136
+ }
137
+ }, 10, 3 );
138
+
139
+ $safe_redirect_manager->action_parse_request();
140
+
141
+ $this->assertTrue( $redirected );
142
+ }
143
+
144
+ /**
145
+ * Test replace wildcards
146
+ *
147
+ * @since 1.7.4
148
+ */
149
+ public function testReplaceWildcard() {
150
+ global $safe_redirect_manager;
151
+
152
+ $_SERVER['REQUEST_URI'] = '/one/two';
153
+ $redirected = false;
154
+ $redirect_to = '/gohere/*';
155
+ $safe_redirect_manager->create_redirect( '/one/*', $redirect_to );
156
+
157
+ add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
158
+ if ( $redirected_to === '/gohere/two' ) {
159
+ $redirected = true;
160
+ }
161
+ }, 10, 3 );
162
+
163
+ $safe_redirect_manager->action_parse_request();
164
+
165
+ $this->assertTrue( $redirected );
166
+ }
167
+
168
  /**
169
  * Test lots of permutations of URL trailing slashes with and without regex
170
  *
171
+ * @since 1.7.3
172
  */
173
  public function testTrailingSlashes() {
174
  /**
275
  /**
276
  * Test some simple redirections
277
  *
278
+ * @since 1.7.3
279
  */
280
  public function testSimplePath() {
281
  global $safe_redirect_manager;
337
  /**
338
  * Test regex redirections
339
  *
340
+ * @since 1.7.3
341
  */
342
  public function testSimplePathRegex() {
343
  global $safe_redirect_manager;