Safe Redirect Manager - Version 1.10.0

Version Description

  • Added: 410 Gone status code to the list of HTTP status codes and srm_additional_status_codes to add additional status codes (@dinhtungdu, @helen, @PopVeKind).
  • Added: Option to ignore query parameters, previous behaviour still available via the new srm_match_query_params filter (props @bradleyt, @dinhtungdu).
  • Added: Extracts redirect matching logic from maybe_redirect to match_redirect method, plus srm_match_redirect function to expose matching redirect logic to themes and plugins (props @nicholas_io, @dinhtungdu).
  • Added: Redirect Post ID to response headers where a redirect rule is invoked (props @jamesmorrison, @dinhtungdu).
  • Added: Banner and icon images (props @lea10up).
  • Added: Documentation and unit test updates (props @noplanman, @dinhtungdu, @kevinbrands, @jeffpaul, @davidegreenwald, @barryceelen).
  • Fixed: Use proper hook for setting up SRM_Redirect (props @dinhtungdu, @icaleb).
  • Fixed: Regression related to wildcard matching (props @amyevans, @dinhtungdu, @jeffreybetts).
  • Fixed: Missing order column in CSV import WP-CLI command (props @barryceelen).
  • Security: Bump lodash from 4.17.15 to 4.17.19 (props @dependabot).
Download this release

Release Info

Developer 10upbot
Plugin Icon 128x128 Safe Redirect Manager
Version 1.10.0
Comparing to
See all releases

Code changes from version 1.9.3 to 1.10.0

README.md ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Safe Redirect Manager
2
+
3
+ > A WordPress plugin to safely and easily manage your website's HTTP redirects.
4
+
5
+ [![Support Level](https://img.shields.io/badge/support-active-green.svg)](#support-level) [![Build Status](https://travis-ci.org/10up/safe-redirect-manager.svg?branch=develop)](https://travis-ci.org/10up/safe-redirect-manager) [![Release Version](https://img.shields.io/github/release/10up/safe-redirect-manager.svg)](https://github.com/10up/safe-redirect-manager/releases/latest) ![WordPress tested up to version](https://img.shields.io/badge/WordPress-v5.5.3%20tested-success.svg) [![GPLv2 License](https://img.shields.io/github/license/10up/safe-redirect-manager.svg)](https://github.com/10up/safe-redirect-manager/blob/develop/LICENSE.md)
6
+
7
+ ## Purpose
8
+
9
+ Easily and safely manage your site's redirects the WordPress way. There are many redirect plugins available. Most of
10
+ them store redirects in the options table or in custom tables. Most of them provide tons of unnecessary options. Some
11
+ of them have serious performance implications (404 error logging). Safe Redirect Manager stores redirects as Custom
12
+ Post Types. This makes your data portable and your website scalable. Safe Redirect Manager is built to handle enterprise
13
+ level traffic and is used on major publishing websites. The plugin comes with only what you need following the
14
+ WordPress mantra, decisions not options. Actions and filters make the plugin very extensible.
15
+
16
+ ## Installation
17
+
18
+ Install the plugin in WordPress. You can download a
19
+ [zip via GitHub](https://github.com/10up/safe-redirect-manager/archive/master.zip) and upload it using the WordPress
20
+ plugin uploader ("Plugins" > "Add New" > "Upload Plugin").
21
+
22
+ ## Configuration
23
+
24
+ There are no overarching settings for this plugin. To manage redirects, navigate to the administration panel ("Tools" > "Safe Redirect Manager").
25
+
26
+ Each redirect contains a few fields that you can utilize:
27
+
28
+ #### "Redirect From"
29
+ This should be a path relative to the root of your WordPress installation. When someone visits your site with a path
30
+ that matches this one, a redirect will occur. If your site is located at `http://example.com/wp/` and you wanted to redirect `http://example.com/wp/about` to `http://example.com`, your "Redirect From" would be `/about`.
31
+
32
+ Clicking the "Enable Regex" checkbox allows you to use regular expressions in your path. There are many
33
+ [great tutorials](http://www.regular-expressions.info) on regular expressions.
34
+
35
+ You can also use wildcards in your "Redirect From" paths. By adding an `*` at the end of a URL, your redirect will
36
+ match any request that starts with your "Redirect From". Wildcards support replacements. This means if you have a
37
+ wildcard in your from path that matches a string, you can have that string replace a wildcard character in your
38
+ "Redirect To" path. For example, if your "Redirect From" is `/test/*`, your "Redirect To" is
39
+ `http://google.com/*`, and the requested path is `/test/string`, the user would be redirect to `http://google.com/string`.
40
+
41
+ #### "Redirect To"
42
+ This should be a path (i.e. `/test`) or a URL (i.e. `http://example.com/wp/test`). If a requested path matches
43
+ "Redirect From", they will be redirected here. "Redirect To" supports wildcard and regular expression replacements.
44
+
45
+ #### "HTTP Status Code"
46
+ [HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) are numbers that contain information about
47
+ a request (i.e. whether it was successful, unauthorized, not found, etc). You should almost always use either 302 (temporarily moved) or 301 (permanently moved).
48
+
49
+ *Note:*
50
+
51
+ * Redirects are cached using the Transients API. Cache busts occur when redirects are added, updated, and deleted
52
+ so you shouldn't be serving stale redirects.
53
+ * By default the plugin only allows at most 250 redirects to prevent performance issues. There is a filter
54
+ `srm_max_redirects` that you can utilize to up this number.
55
+ * "Redirect From" and requested paths are case insensitive by default.
56
+ * Developers can use `srm_additional_status_codes` filter to add status codes if needed.
57
+
58
+ ## Filters
59
+
60
+ ### Redirect loops detection
61
+
62
+ By default redirect loop detection is disabled. To prevent redirect loops you can filter `srm_check_for_possible_redirect_loops`.
63
+
64
+ ```php
65
+ add_filter( 'srm_check_for_possible_redirect_loops', '__return_true' );
66
+ ```
67
+
68
+ ### Only redirect if 404 occurs
69
+
70
+ By default every matched URL is redirected. To only redirect matched but not found URLs (i.e., 404 pages), use `srm_redirect_only_on_404`.
71
+
72
+ ```php
73
+ add_filter( 'srm_redirect_only_on_404', '__return_true' );
74
+ ```
75
+
76
+ ## CLI commands
77
+
78
+ The following WP-CLI commands are supported by Safe Redirect Manager:
79
+
80
+ * **`wp safe-redirect-manager list`**
81
+
82
+ List all of the currently configured redirects.
83
+
84
+ * **`wp safe-redirect-manager create <from> <to> [<status-code>] [<enable-regex>] [<post-status>]`**
85
+
86
+ Create a redirect. `<from>` and `<to>` are required parameters.
87
+
88
+ * `<from>`: Redirect from path. Required.
89
+
90
+ * `<to>`: Redirect to path. Required.
91
+
92
+ * `<status-code>`: HTTP Status Code. Optional. Default to `302`.
93
+
94
+ * `<enable-regex>`: Whether to enable Regular expression. Optional. Default to `false`.
95
+
96
+ * `<post-status>`: The status of the redirect. Optional. Default to `publish`.
97
+
98
+ **Example:** `wp safe-redirect-manager create /about-us /contact-us 301`
99
+
100
+ * **`wp safe-redirect-manager delete <id>`**
101
+
102
+ Delete a redirect by `<id>`.
103
+
104
+ * **`wp safe-redirect-manager update-cache`**
105
+
106
+ Update the redirect cache.
107
+
108
+ * **`wp safe-redirect-manager import <file> [--source=<source-column>] [--target=<target-column>] [--regex=<regex-column>] [--code=<code-column>] [--order=<order-column>]`**
109
+
110
+ Imports redirects from a CSV file.
111
+
112
+ * `<file>`: Path to one or more valid CSV file for import. This file should contain redirection from and to URLs, regex flag and HTTP redirection code. Here is the example table:
113
+
114
+ | source | target | regex | code | order |
115
+ |----------------------------|--------------------|-------|------|-------|
116
+ | /legacy-url | /new-url | 0 | 301 | 0 |
117
+ | /category-1 | /new-category-slug | 0 | 302 | 1 |
118
+ | /tes?t/[0-9]+/path/[^/]+/? | /go/here | 1 | 302 | 3 |
119
+ | ... | ... | ... | ... | ... |
120
+
121
+ _You can also use exported redirects from "Redirection" plugin, which you can download here: /wp-admin/tools.php?page=redirection.php&sub=modules_
122
+
123
+ * `--source`: Header title for source ("from" URL) column mapping.
124
+
125
+ * `--target`: Header title for target ("to" URL) column mapping.
126
+
127
+ * `--regex`: Header title for regex column mapping.
128
+
129
+ * `--code`: Header title for code column mapping.
130
+
131
+ * `--order`: Header title for order column mapping.
132
+
133
+ * **`wp safe-redirect-manager import-htaccess <file>`**
134
+
135
+ Import .htaccess file redirects.
136
+
137
+ ## Development
138
+
139
+ #### Setup
140
+ Follow the configuration instructions above to setup the plugin. We recommend developing the plugin locally in an
141
+ environment such as [WP Local Docker](https://github.com/10up/wp-local-docker).
142
+
143
+ #### Testing
144
+ Within the terminal change directories to the plugin folder. Initialize your unit testing environment by running the
145
+ following command:
146
+
147
+ ```bash
148
+ bash bin/install-wp-tests.sh database username password host version
149
+ ```
150
+
151
+ Run the plugin tests:
152
+ ```bash
153
+ phpunit
154
+ ```
155
+
156
+ #### Issues
157
+ If you identify any errors or have an idea for improving the plugin, please
158
+ [open an issue](https://github.com/10up/safe-redirect-manager/issues?state=open).
159
+
160
+ ## Translations
161
+ Safe Redirect Manager is available in English and other languages. A listing of those languages and instructions for translating the plugin into other languages is available on [Translating WordPress](https://translate.wordpress.org/projects/wp-plugins/safe-redirect-manager/). Many thanks to the [contributors on the translation teams](https://translate.wordpress.org/projects/wp-plugins/safe-redirect-manager/contributors/)!
162
+
163
+ ## Support Level
164
+
165
+ **Active:** 10up is actively working on this, and we expect to continue work for the foreseeable future including keeping tested up to the most recent version of WordPress. Bug reports, feature requests, questions, and pull requests are welcome.
166
+
167
+ ## Changelog
168
+
169
+ A complete listing of all notable changes to Safe Redirect Manager are documented in [CHANGELOG.md](https://github.com/10up/safe-redirect-manager/blob/develop/CHANGELOG.md).
170
+
171
+ ## Contributing
172
+
173
+ Please read [CODE_OF_CONDUCT.md](https://github.com/10up/safe-redirect-manager/blob/develop/CODE_OF_CONDUCT.md) for details on our code of conduct, [CONTRIBUTING.md](https://github.com/10up/safe-redirect-manager/blob/develop/CONTRIBUTING.md) for details on the process for submitting pull requests to us, and [CREDITS.md](https://github.com/10up/safe-redirect-manager/blob/develop/CREDITS.md) for a listing of maintainers of, contributors to, and libraries used by Safe Redirect Manager.
174
+
175
+ ## Like what you see?
176
+
177
+ <p align="center">
178
+ <a href="http://10up.com/contact/"><img src="https://10updotcom-wpengine.s3.amazonaws.com/uploads/2016/10/10up-Github-Banner.png" width="850"></a>
179
+ </p>
inc/classes/class-srm-post-type.php CHANGED
@@ -30,14 +30,7 @@ class SRM_Post_Type {
30
  * @since 1.8
31
  */
32
  public function setup() {
33
- $this->status_code_labels = array(
34
- 301 => esc_html__( 'Moved Permanently', 'safe-redirect-manager' ),
35
- 302 => esc_html__( 'Found', 'safe-redirect-manager' ),
36
- 303 => esc_html__( 'See Other', 'safe-redirect-manager' ),
37
- 307 => esc_html__( 'Temporary Redirect', 'safe-redirect-manager' ),
38
- 403 => esc_html__( 'Forbidden', 'safe-redirect-manager' ),
39
- 404 => esc_html__( 'Not Found', 'safe-redirect-manager' ),
40
- );
41
 
42
  add_action( 'init', array( $this, 'action_register_post_types' ) );
43
  add_action( 'admin_init', array( $this, 'init_search_filters' ) );
@@ -568,7 +561,7 @@ class SRM_Post_Type {
568
  <input type="checkbox" name="srm_redirect_rule_from_regex" id="srm_redirect_rule_from_regex" <?php checked( true, (bool) $enable_regex ); ?> value="1" />
569
  <label for="srm_redirect_rule_from_regex"><?php esc_html_e( 'Enable Regular Expressions (advanced)', 'safe-redirect-manager' ); ?></label>
570
  </p>
571
- <p class="description"><?php esc_html_e( 'This path should be relative to the root of this WordPress installation (or the sub-site, if you are running a multi-site). Appending a (*) wildcard character will match all requests with the base. Warning: Enabling regular expressions will disable wildcards and completely change the way the * symbol is interpretted.', 'safe-redirect-manager' ); ?></p>
572
 
573
  <p>
574
  <label for="srm_redirect_rule_to"><strong><?php esc_html_e( '* Redirect To:', 'safe-redirect-manager' ); ?></strong></label><br />
30
  * @since 1.8
31
  */
32
  public function setup() {
33
+ $this->status_code_labels = srm_get_valid_status_codes_data();
 
 
 
 
 
 
 
34
 
35
  add_action( 'init', array( $this, 'action_register_post_types' ) );
36
  add_action( 'admin_init', array( $this, 'init_search_filters' ) );
561
  <input type="checkbox" name="srm_redirect_rule_from_regex" id="srm_redirect_rule_from_regex" <?php checked( true, (bool) $enable_regex ); ?> value="1" />
562
  <label for="srm_redirect_rule_from_regex"><?php esc_html_e( 'Enable Regular Expressions (advanced)', 'safe-redirect-manager' ); ?></label>
563
  </p>
564
+ <p class="description"><?php esc_html_e( 'This path should be relative to the root of this WordPress installation (or the sub-site, if you are running a multi-site). Appending a (*) wildcard character will match all requests with the base. Warning: Enabling regular expressions will disable wildcards and completely change the way the * symbol is interpreted.', 'safe-redirect-manager' ); ?></p>
565
 
566
  <p>
567
  <label for="srm_redirect_rule_to"><strong><?php esc_html_e( '* Redirect To:', 'safe-redirect-manager' ); ?></strong></label><br />
inc/classes/class-srm-redirect.php CHANGED
@@ -17,11 +17,20 @@ class SRM_Redirect {
17
  private $whitelist_host;
18
 
19
  /**
20
- * Initialize redirect listening
21
  *
22
  * @since 1.8
23
  */
24
  public function setup() {
 
 
 
 
 
 
 
 
 
25
  /**
26
  * To only redirect on 404 pages, use:
27
  * add_filter( 'srm_redirect_only_on_404', '__return_true' );
@@ -51,28 +60,20 @@ class SRM_Redirect {
51
  }
52
 
53
  /**
54
- * Check current url against redirects
55
  *
56
- * @since 1.8
 
 
57
  */
58
- public function maybe_redirect() {
59
-
60
- // Don't redirect unless not on admin. If 404 filter enabled, require query is a 404.
61
- if ( is_admin() || ( apply_filters( 'srm_redirect_only_on_404', false ) && ! is_404() ) ) {
62
- return;
63
- }
64
-
65
  $redirects = srm_get_redirects();
66
 
67
  // If we have no redirects, there is no need to continue
68
  if ( empty( $redirects ) ) {
69
- return;
70
  }
71
 
72
- // get requested path and add a / before it
73
- $requested_path = esc_url_raw( apply_filters( 'srm_requested_path', $_SERVER['REQUEST_URI'] ) );
74
- $requested_path = untrailingslashit( stripslashes( $requested_path ) );
75
-
76
  /**
77
  * If WordPress resides in a directory that is not the public root, we have to chop
78
  * the pre-WP path off the requested path.
@@ -99,13 +100,26 @@ class SRM_Redirect {
99
 
100
  if ( $case_insensitive ) {
101
  $regex_flag = 'i';
102
- // normalized path is used for matching but not for replace
103
  $normalized_requested_path = strtolower( $requested_path );
104
  } else {
105
  $regex_flag = '';
106
  $normalized_requested_path = $requested_path;
107
  }
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  foreach ( (array) $redirects as $redirect ) {
110
 
111
  $redirect_from = untrailingslashit( $redirect['redirect_from'] );
@@ -116,6 +130,7 @@ class SRM_Redirect {
116
  $redirect_to = $redirect['redirect_to'];
117
  $status_code = $redirect['status_code'];
118
  $enable_regex = ( isset( $redirect['enable_regex'] ) ) ? $redirect['enable_regex'] : false;
 
119
 
120
  // check if the redirection destination is valid, otherwise just skip it
121
  if ( empty( $redirect_to ) ) {
@@ -124,23 +139,25 @@ class SRM_Redirect {
124
 
125
  // check if requested path is the same as the redirect from path
126
  if ( $enable_regex ) {
127
- $matched_path = preg_match( '@' . $redirect_from . '@' . $regex_flag, $requested_path );
 
128
  } else {
129
  if ( $case_insensitive ) {
130
  $redirect_from = strtolower( $redirect_from );
131
  }
132
 
133
- $matched_path = ( $normalized_requested_path === $redirect_from );
 
 
 
 
134
 
135
  // check if the redirect_from ends in a wildcard
136
  if ( ! $matched_path && ( strrpos( $redirect_from, '*' ) === strlen( $redirect_from ) - 1 ) ) {
137
  $wildcard_base = substr( $redirect_from, 0, strlen( $redirect_from ) - 1 );
138
 
139
- // Remove the trailing slash from the wildcard base, matching removal from request path.
140
- $wildcard_base = untrailingslashit( $wildcard_base );
141
-
142
  // Mark as path match if requested path matches the base of the redirect from.
143
- $matched_path = ( substr( $normalized_requested_path, 0, strlen( $wildcard_base ) ) === $wildcard_base );
144
  if ( ( strrpos( $redirect_to, '*' ) === strlen( $redirect_to ) - 1 ) ) {
145
  $redirect_to = rtrim( $redirect_to, '*' ) . ltrim( substr( $requested_path, strlen( $wildcard_base ) ), '/' );
146
  }
@@ -167,27 +184,71 @@ class SRM_Redirect {
167
  $redirect_to = preg_replace( '@' . $redirect_from . '@' . $regex_flag, $redirect_to, $requested_path );
168
  }
169
 
 
 
 
 
 
 
170
  $sanitized_redirect_to = esc_url_raw( apply_filters( 'srm_redirect_to', $redirect_to ) );
171
 
172
- do_action( 'srm_do_redirect', $requested_path, $sanitized_redirect_to, $status_code );
 
 
 
 
 
 
 
173
 
174
- if ( defined( 'PHPUNIT_SRM_TESTSUITE' ) && PHPUNIT_SRM_TESTSUITE ) {
175
- // Don't actually redirect if we are testing
176
- return;
177
- }
178
 
179
- header( 'X-Safe-Redirect-Manager: true' );
 
 
 
 
 
180
 
181
- // if we have a valid status code, then redirect with it
182
- if ( in_array( $status_code, srm_get_valid_status_codes(), true ) ) {
183
- wp_safe_redirect( $sanitized_redirect_to, $status_code );
184
- } else {
185
- wp_safe_redirect( $sanitized_redirect_to );
186
- }
187
 
188
- exit;
189
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  }
 
 
191
  }
192
 
193
  /**
17
  private $whitelist_host;
18
 
19
  /**
20
+ * Setup hook.
21
  *
22
  * @since 1.8
23
  */
24
  public function setup() {
25
+ add_action( 'init', array( $this, 'setup_redirect' ), 0 );
26
+ }
27
+
28
+ /**
29
+ * Initialize redirect listening
30
+ *
31
+ * @since 1.9.4
32
+ */
33
+ public function setup_redirect() {
34
  /**
35
  * To only redirect on 404 pages, use:
36
  * add_filter( 'srm_redirect_only_on_404', '__return_true' );
60
  }
61
 
62
  /**
63
+ * Matches a redirect given a path.
64
  *
65
+ * @param string $requested_path The path to check redirects for.
66
+ *
67
+ * @return array|bool The redirect url. False if no redirect is found.
68
  */
69
+ public function match_redirect( $requested_path ) {
 
 
 
 
 
 
70
  $redirects = srm_get_redirects();
71
 
72
  // If we have no redirects, there is no need to continue
73
  if ( empty( $redirects ) ) {
74
+ return false;
75
  }
76
 
 
 
 
 
77
  /**
78
  * If WordPress resides in a directory that is not the public root, we have to chop
79
  * the pre-WP path off the requested path.
100
 
101
  if ( $case_insensitive ) {
102
  $regex_flag = 'i';
103
+ // Normalized path is used for matching but not for replace
104
  $normalized_requested_path = strtolower( $requested_path );
105
  } else {
106
  $regex_flag = '';
107
  $normalized_requested_path = $requested_path;
108
  }
109
 
110
+ if ( function_exists( 'wp_parse_url' ) ) {
111
+ $parsed_requested_path = wp_parse_url( $normalized_requested_path );
112
+ } else {
113
+ $parsed_requested_path = parse_url( $normalized_requested_path );
114
+ }
115
+ // Normalize the request path with and without query strings, for comparison later
116
+ $requested_query_params = '';
117
+ if ( ! empty( $parsed_requested_path['query'] ) ) {
118
+ $requested_query_params = $parsed_requested_path['query'];
119
+ }
120
+
121
+ $normalized_requested_path_no_query = untrailingslashit( stripslashes( $parsed_requested_path['path'] ) );
122
+
123
  foreach ( (array) $redirects as $redirect ) {
124
 
125
  $redirect_from = untrailingslashit( $redirect['redirect_from'] );
130
  $redirect_to = $redirect['redirect_to'];
131
  $status_code = $redirect['status_code'];
132
  $enable_regex = ( isset( $redirect['enable_regex'] ) ) ? $redirect['enable_regex'] : false;
133
+ $redirect_id = $redirect['ID'];
134
 
135
  // check if the redirection destination is valid, otherwise just skip it
136
  if ( empty( $redirect_to ) ) {
139
 
140
  // check if requested path is the same as the redirect from path
141
  if ( $enable_regex ) {
142
+ $match_query_params = false;
143
+ $matched_path = preg_match( '@' . $redirect_from . '@' . $regex_flag, $requested_path );
144
  } else {
145
  if ( $case_insensitive ) {
146
  $redirect_from = strtolower( $redirect_from );
147
  }
148
 
149
+ // only compare query params if the $redirect_from value contains parameters
150
+ $match_query_params = apply_filters( 'srm_match_query_params', strpos( $redirect_from, '?' ) );
151
+
152
+ $to_match = ( ! $match_query_params && ! empty( $normalized_requested_path_no_query ) ) ? $normalized_requested_path_no_query : $normalized_requested_path;
153
+ $matched_path = ( $to_match === $redirect_from );
154
 
155
  // check if the redirect_from ends in a wildcard
156
  if ( ! $matched_path && ( strrpos( $redirect_from, '*' ) === strlen( $redirect_from ) - 1 ) ) {
157
  $wildcard_base = substr( $redirect_from, 0, strlen( $redirect_from ) - 1 );
158
 
 
 
 
159
  // Mark as path match if requested path matches the base of the redirect from.
160
+ $matched_path = ( substr( trailingslashit( $normalized_requested_path ), 0, strlen( $wildcard_base ) ) === $wildcard_base );
161
  if ( ( strrpos( $redirect_to, '*' ) === strlen( $redirect_to ) - 1 ) ) {
162
  $redirect_to = rtrim( $redirect_to, '*' ) . ltrim( substr( $requested_path, strlen( $wildcard_base ) ), '/' );
163
  }
184
  $redirect_to = preg_replace( '@' . $redirect_from . '@' . $regex_flag, $redirect_to, $requested_path );
185
  }
186
 
187
+ // re-add the query params if they've not already been added by the wildcard
188
+ // query params are forwarded to allow for attribution and marketing params to be maintained
189
+ if ( ! $match_query_params && ! empty( $requested_query_params ) && ! strpos( $redirect_to, '?' ) ) {
190
+ $redirect_to .= '?' . $requested_query_params;
191
+ }
192
+
193
  $sanitized_redirect_to = esc_url_raw( apply_filters( 'srm_redirect_to', $redirect_to ) );
194
 
195
+ return [
196
+ 'redirect_to' => $sanitized_redirect_to,
197
+ 'status_code' => $status_code,
198
+ 'enable_regex' => $enable_regex,
199
+ 'redirect_id' => $redirect_id,
200
+ ];
201
+ }
202
+ }
203
 
204
+ return false;
205
+ }
 
 
206
 
207
+ /**
208
+ * Check current url against redirects
209
+ *
210
+ * @since 1.8
211
+ */
212
+ public function maybe_redirect() {
213
 
214
+ // Don't redirect unless not on admin. If 404 filter enabled, require query is a 404.
215
+ if ( is_admin() || ( apply_filters( 'srm_redirect_only_on_404', false ) && ! is_404() ) ) {
216
+ return;
217
+ }
 
 
218
 
219
+ // get requested path and add a / before it
220
+ $requested_path = esc_url_raw( apply_filters( 'srm_requested_path', $_SERVER['REQUEST_URI'] ) );
221
+ $requested_path = untrailingslashit( stripslashes( $requested_path ) );
222
+
223
+ $matched_redirect = $this->match_redirect( $requested_path );
224
+
225
+ if ( empty( $matched_redirect ) ) {
226
+ return;
227
+ }
228
+
229
+ do_action(
230
+ 'srm_do_redirect',
231
+ $requested_path,
232
+ $matched_redirect['redirect_to'],
233
+ $matched_redirect['status_code']
234
+ );
235
+
236
+ if ( defined( 'PHPUNIT_SRM_TESTSUITE' ) && PHPUNIT_SRM_TESTSUITE ) {
237
+ // Don't actually redirect if we are testing
238
+ return;
239
+ }
240
+
241
+ header( 'X-Safe-Redirect-Manager: true' );
242
+ header( 'X-Safe-Redirect-ID: ' . esc_attr( $matched_redirect['redirect_id'] ) );
243
+
244
+ // if we have a valid status code, then redirect with it
245
+ if ( in_array( $matched_redirect['status_code'], srm_get_valid_status_codes(), true ) ) {
246
+ wp_safe_redirect( $matched_redirect['redirect_to'], $matched_redirect['status_code'] );
247
+ } else {
248
+ wp_safe_redirect( $matched_redirect['redirect_to'] );
249
  }
250
+
251
+ exit;
252
  }
253
 
254
  /**
inc/classes/class-srm-wp-cli.php CHANGED
@@ -244,6 +244,7 @@ class SRM_WP_CLI extends WP_CLI_Command {
244
  'target' => 'target',
245
  'regex' => 'regex',
246
  'code' => 'code',
 
247
  )
248
  );
249
 
244
  'target' => 'target',
245
  'regex' => 'regex',
246
  'code' => 'code',
247
+ 'order' => 'order',
248
  )
249
  );
250
 
inc/functions.php CHANGED
@@ -99,7 +99,32 @@ function srm_max_redirects_reached() {
99
  * @return array
100
  */
101
  function srm_get_valid_status_codes() {
102
- return apply_filters( 'srm_valid_status_codes', array( 301, 302, 303, 307, 403, 404 ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
 
105
  /**
@@ -366,3 +391,20 @@ function srm_import_file( $file, $args ) {
366
  'skipped' => $skipped,
367
  );
368
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  * @return array
100
  */
101
  function srm_get_valid_status_codes() {
102
+ return apply_filters( 'srm_valid_status_codes', array_keys( srm_get_valid_status_codes_data() ) );
103
+ }
104
+
105
+ /**
106
+ * Get valid HTTP status codes and their labels.
107
+ *
108
+ * @since 2.0.0
109
+ * @return array
110
+ */
111
+ function srm_get_valid_status_codes_data() {
112
+ $status_codes = array(
113
+ 301 => esc_html__( 'Moved Permanently', 'safe-redirect-manager' ),
114
+ 302 => esc_html__( 'Found', 'safe-redirect-manager' ),
115
+ 303 => esc_html__( 'See Other', 'safe-redirect-manager' ),
116
+ 307 => esc_html__( 'Temporary Redirect', 'safe-redirect-manager' ),
117
+ 403 => esc_html__( 'Forbidden', 'safe-redirect-manager' ),
118
+ 404 => esc_html__( 'Not Found', 'safe-redirect-manager' ),
119
+ 410 => esc_html__( 'Gone', 'safe-redirect-manager' ),
120
+ );
121
+
122
+ $additional_status_codes = apply_filters(
123
+ 'srm_additional_status_codes',
124
+ array()
125
+ );
126
+
127
+ return $status_codes + $additional_status_codes;
128
  }
129
 
130
  /**
391
  'skipped' => $skipped,
392
  );
393
  }
394
+
395
+ /**
396
+ * Tries to match a redirect given a path. Return the redirect array or false on failure.
397
+ *
398
+ * @param string $path The path to check redirects for.
399
+ *
400
+ * @return array|bool {
401
+ * Redirect array config.
402
+ *
403
+ * @type string $redirect_to The redirect to url.
404
+ * @type int $status_code The redirect status code.
405
+ * @type bool $enable_regex Whether this redirect has regex enabled or not.
406
+ * }
407
+ */
408
+ function srm_match_redirect( $path ) {
409
+ return SRM_Redirect::factory()->match_redirect( $path );
410
+ }
lang/safe-redirect-manager-sk_SK.mo DELETED
Binary file
lang/safe-redirect-manager-sk_SK.po DELETED
@@ -1,142 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: \n"
4
- "POT-Creation-Date: \n"
5
- "PO-Revision-Date: \n"
6
- "Last-Translator: \n"
7
- "Language-Team: \n"
8
- "MIME-Version: 1.0\n"
9
- "Content-Type: text/plain; charset=iso-8859-1\n"
10
- "Content-Transfer-Encoding: 8bit\n"
11
- "X-Generator: Poedit 1.5.4\n"
12
-
13
- #: safe-redirect-manager.php:367 safe-redirect-manager.php:370
14
- msgid "Redirect rule updated."
15
- msgstr "Presmerovat pravidlo aktualizovany."
16
-
17
- #: safe-redirect-manager.php:368
18
- msgid "Custom field updated."
19
- msgstr "Vlastne aktualizacie pola."
20
-
21
- #: safe-redirect-manager.php:369
22
- msgid "Custom field deleted."
23
- msgstr "Vlastne vypustaju pola."
24
-
25
- #. translators: %s: date and time of the revision
26
- #: safe-redirect-manager.php:372
27
- msgid "Redirect rule restored to revision from %s"
28
- msgstr "Presmerovat pravidlo obnovena reviziu z %s"
29
-
30
- #: safe-redirect-manager.php:373
31
- msgid "Redirect rule published."
32
- msgstr "Presmerovat pravidlo zverejneny."
33
-
34
- #: safe-redirect-manager.php:374
35
- msgid "Redirect rule saved."
36
- msgstr "Presmerovat pravidlo ulozeny."
37
-
38
- #: safe-redirect-manager.php:375
39
- msgid "Redirect rule submitted."
40
- msgstr "Presmerovat pravidlo predlozene."
41
-
42
- #: safe-redirect-manager.php:376
43
- msgid "Redirect rule scheduled for: <strong>%1$s</strong>."
44
- msgstr "Presmerovat pravidlo naplanovany:. <strong>%1$s</strong>."
45
-
46
- #. translators: Publish box date format, see http:php.net/date
47
- #: safe-redirect-manager.php:378
48
- msgid "M j, Y @ G:i"
49
- msgstr "M j, Y @ G: i"
50
-
51
- #: safe-redirect-manager.php:379
52
- msgid "Redirect rule draft updated."
53
- msgstr "Presmerovat pravidlo aktualizovany navrh."
54
-
55
- #: safe-redirect-manager.php:431
56
- msgid "Redirect To"
57
- msgstr "Presmerovat na"
58
-
59
- #: safe-redirect-manager.php:432
60
- msgid "HTTP Status Code"
61
- msgstr "HTTP Status Code"
62
-
63
- #: safe-redirect-manager.php:435
64
- msgid "Redirect From"
65
- msgstr "Presmerovanie od"
66
-
67
- #: safe-redirect-manager.php:439
68
- msgid "Date"
69
- msgstr "Datum"
70
-
71
- #: safe-redirect-manager.php:491
72
- msgctxt "post type general name"
73
- msgid "Safe Redirect Manager"
74
- msgstr "Safe Redirect Manager"
75
-
76
- #: safe-redirect-manager.php:492
77
- msgctxt "post type singular name"
78
- msgid "Redirect"
79
- msgstr "Presmerovanie"
80
-
81
- #. #-#-#-#-# plugin.pot (Safe Redirect Manager 1.4-working) #-#-#-#-#
82
- #. Plugin Name of the plugin/theme
83
- #: safe-redirect-manager.php:494 safe-redirect-manager.php:497
84
- #: safe-redirect-manager.php:503
85
- msgid "Safe Redirect Manager"
86
- msgstr "Safe Redirect Manager"
87
-
88
- #: safe-redirect-manager.php:495
89
- msgid "Edit Redirect Rule"
90
- msgstr "Upravit presmerovanie pravidlo"
91
-
92
- #: safe-redirect-manager.php:496
93
- msgid "New Redirect Rule"
94
- msgstr "Nova Presmerovanie pravidlo"
95
-
96
- #: safe-redirect-manager.php:498
97
- msgid "View Redirect Rule"
98
- msgstr "Zobrazit Presmerovanie pravidlo"
99
-
100
- #: safe-redirect-manager.php:499
101
- msgid "Search Redirects"
102
- msgstr "Hladat Presmerovanie"
103
-
104
- #: safe-redirect-manager.php:500
105
- msgid "No redirect rules found."
106
- msgstr "Ziadne presmerovanie najdene pravidla."
107
-
108
- #: safe-redirect-manager.php:501
109
- msgid "No redirect rules found in trash."
110
- msgstr "Ziadne presmerovanie pravidla najdene v smetiaku."
111
-
112
- #: safe-redirect-manager.php:544
113
- msgid "Redirect Settings"
114
- msgstr "Presmerovanie Nastavenie"
115
-
116
- #: safe-redirect-manager.php:565
117
- msgid "Redirect From:"
118
- msgstr "Presmerovat From:"
119
-
120
- #: safe-redirect-manager.php:571
121
- msgid "Redirect To:"
122
- msgstr "Presmerovat na:"
123
-
124
- #: safe-redirect-manager.php:577
125
- msgid "HTTP Status Code:"
126
- msgstr "HTTP Status Code:"
127
-
128
- #. #-#-#-#-# plugin.pot (Safe Redirect Manager 1.4-working) #-#-#-#-#
129
- #. Plugin URI of the plugin/theme
130
- #. #-#-#-#-# plugin.pot (Safe Redirect Manager 1.4-working) #-#-#-#-#
131
- #. Author URI of the plugin/theme
132
- #: safe-redirect-manager.php:583
133
- msgid "http://www.10up.com"
134
- msgstr "http://www.10up.com"
135
-
136
- #. Description of the plugin/theme
137
- msgid "Easily and safely manage HTTP redirects."
138
- msgstr "Lahko a bezpecne spravovat presmerovanie HTTP."
139
-
140
- #. Author of the plugin/theme
141
- msgid "Taylor Lovett (10up LLC), VentureBeat"
142
- msgstr "Taylor Lovett (10up LLC), VentureBeat"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lang/safe-redirect-manager.pot DELETED
@@ -1,237 +0,0 @@
1
- # Copyright (C) 2018 10up
2
- # This file is distributed under the GPLv2 or later.
3
- msgid ""
4
- msgstr ""
5
- "Project-Id-Version: Safe Redirect Manager 1.9.1\n"
6
- "Report-Msgid-Bugs-To: "
7
- "https://wordpress.org/support/plugin/safe-redirect-manager\n"
8
- "POT-Creation-Date: 2018-11-22 02:09:56+00:00\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=utf-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
13
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
- "Language-Team: LANGUAGE <LL@li.org>\n"
15
- "X-Generator: node-wp-i18n 1.2.1\n"
16
-
17
- #: inc/classes/class-srm-post-type.php:34
18
- msgid "Moved Permanently"
19
- msgstr ""
20
-
21
- #: inc/classes/class-srm-post-type.php:35
22
- msgid "Found"
23
- msgstr ""
24
-
25
- #: inc/classes/class-srm-post-type.php:36
26
- msgid "See Other"
27
- msgstr ""
28
-
29
- #: inc/classes/class-srm-post-type.php:37
30
- msgid "Temporary Redirect"
31
- msgstr ""
32
-
33
- #: inc/classes/class-srm-post-type.php:38
34
- msgid "Forbidden"
35
- msgstr ""
36
-
37
- #: inc/classes/class-srm-post-type.php:39
38
- msgid "Not Found"
39
- msgstr ""
40
-
41
- #: inc/classes/class-srm-post-type.php:237
42
- msgid ""
43
- "Safe Redirect Manager Warning: Possible redirect loops and/or chains have "
44
- "been created."
45
- msgstr ""
46
-
47
- #: inc/classes/class-srm-post-type.php:251
48
- msgid ""
49
- "Safe Redirect Manager Error: You have reached the maximum allowable number "
50
- "of redirects"
51
- msgstr ""
52
-
53
- #: inc/classes/class-srm-post-type.php:302
54
- #: inc/classes/class-srm-post-type.php:305
55
- msgid "Redirect rule updated."
56
- msgstr ""
57
-
58
- #: inc/classes/class-srm-post-type.php:303
59
- msgid "Custom field updated."
60
- msgstr ""
61
-
62
- #: inc/classes/class-srm-post-type.php:304
63
- msgid "Custom field deleted."
64
- msgstr ""
65
-
66
- #: inc/classes/class-srm-post-type.php:307
67
- #. translators: %s: date and time of the revision
68
- msgid "Redirect rule restored to revision from %s"
69
- msgstr ""
70
-
71
- #: inc/classes/class-srm-post-type.php:308
72
- msgid "Redirect rule published."
73
- msgstr ""
74
-
75
- #: inc/classes/class-srm-post-type.php:309
76
- msgid "Redirect rule saved."
77
- msgstr ""
78
-
79
- #: inc/classes/class-srm-post-type.php:310
80
- msgid "Redirect rule submitted."
81
- msgstr ""
82
-
83
- #: inc/classes/class-srm-post-type.php:312
84
- msgid "Redirect rule scheduled for: %1$s."
85
- msgstr ""
86
-
87
- #: inc/classes/class-srm-post-type.php:314
88
- #. translators: Publish box date format, see http:php.net/date
89
- msgid "M j, Y @ G:i"
90
- msgstr ""
91
-
92
- #: inc/classes/class-srm-post-type.php:317
93
- msgid "Redirect rule draft updated."
94
- msgstr ""
95
-
96
- #: inc/classes/class-srm-post-type.php:371
97
- msgid "Redirect To"
98
- msgstr ""
99
-
100
- #: inc/classes/class-srm-post-type.php:372
101
- msgid "HTTP Status Code"
102
- msgstr ""
103
-
104
- #: inc/classes/class-srm-post-type.php:373
105
- msgid "Order"
106
- msgstr ""
107
-
108
- #: inc/classes/class-srm-post-type.php:376
109
- msgid "Redirect From"
110
- msgstr ""
111
-
112
- #: inc/classes/class-srm-post-type.php:380
113
- msgid "Date"
114
- msgstr ""
115
-
116
- #. Plugin Name of the plugin/theme
117
- msgid "Safe Redirect Manager"
118
- msgstr ""
119
-
120
- #: inc/classes/class-srm-post-type.php:490
121
- msgid "Edit Redirect Rule"
122
- msgstr ""
123
-
124
- #: inc/classes/class-srm-post-type.php:491
125
- msgid "New Redirect Rule"
126
- msgstr ""
127
-
128
- #: inc/classes/class-srm-post-type.php:493
129
- msgid "View Redirect Rule"
130
- msgstr ""
131
-
132
- #: inc/classes/class-srm-post-type.php:494
133
- msgid "Search Redirects"
134
- msgstr ""
135
-
136
- #: inc/classes/class-srm-post-type.php:495
137
- msgid "No redirect rules found."
138
- msgstr ""
139
-
140
- #: inc/classes/class-srm-post-type.php:496
141
- msgid "No redirect rules found in trash."
142
- msgstr ""
143
-
144
- #: inc/classes/class-srm-post-type.php:541
145
- msgid "Redirect Settings"
146
- msgstr ""
147
-
148
- #: inc/classes/class-srm-post-type.php:566
149
- msgid "* Redirect From:"
150
- msgstr ""
151
-
152
- #: inc/classes/class-srm-post-type.php:569
153
- msgid "Enable Regular Expressions (advanced)"
154
- msgstr ""
155
-
156
- #: inc/classes/class-srm-post-type.php:571
157
- msgid ""
158
- "This path should be relative to the root of this WordPress installation (or "
159
- "the sub-site, if you are running a multi-site). Appending a (*) wildcard "
160
- "character will match all requests with the base. Warning: Enabling regular "
161
- "expressions will disable wildcards and completely change the way the * "
162
- "symbol is interpretted."
163
- msgstr ""
164
-
165
- #: inc/classes/class-srm-post-type.php:574
166
- msgid "* Redirect To:"
167
- msgstr ""
168
-
169
- #: inc/classes/class-srm-post-type.php:577
170
- msgid ""
171
- "This can be a URL or a path relative to the root of your website (not your "
172
- "WordPress installation). Ending with a (*) wildcard character will append "
173
- "the request match to the redirect."
174
- msgstr ""
175
-
176
- #: inc/classes/class-srm-post-type.php:580
177
- msgid "* HTTP Status Code:"
178
- msgstr ""
179
-
180
- #: inc/classes/class-srm-post-type.php:586
181
- msgid "If you don't know what this is, leave it as is."
182
- msgstr ""
183
-
184
- #: inc/classes/class-srm-post-type.php:590
185
- msgid "Notes:"
186
- msgstr ""
187
-
188
- #: inc/classes/class-srm-post-type.php:592
189
- msgid "Optionally leave notes on this redirect e.g. why was it created."
190
- msgstr ""
191
-
192
- #: inc/functions.php:193
193
- msgid "Redirect from and/or redirect to arguments are invalid."
194
- msgstr ""
195
-
196
- #: inc/functions.php:197
197
- msgid "Invalid status code."
198
- msgstr ""
199
-
200
- #: inc/functions.php:202
201
- msgid "Redirect already exists for %s"
202
- msgstr ""
203
-
204
- #: inc/functions.php:216
205
- msgid "An error occurred creating the redirect."
206
- msgstr ""
207
-
208
- #. Plugin URI of the plugin/theme
209
- msgid "https://wordpress.org/plugins/safe-redirect-manager"
210
- msgstr ""
211
-
212
- #. Description of the plugin/theme
213
- msgid "Easily and safely manage HTTP redirects."
214
- msgstr ""
215
-
216
- #. Author of the plugin/theme
217
- msgid "10up"
218
- msgstr ""
219
-
220
- #. Author URI of the plugin/theme
221
- msgid "https://10up.com"
222
- msgstr ""
223
-
224
- #: inc/classes/class-srm-post-type.php:486
225
- msgctxt "post type general name"
226
- msgid "Safe Redirect Manager"
227
- msgstr ""
228
-
229
- #: inc/classes/class-srm-post-type.php:487
230
- msgctxt "post type singular name"
231
- msgid "Redirect"
232
- msgstr ""
233
-
234
- #: inc/classes/class-srm-post-type.php:488
235
- msgctxt "redirect rule"
236
- msgid "Create Redirect Rule"
237
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -1,12 +1,12 @@
1
  === Safe Redirect Manager ===
2
  Contributors: tlovett1, tollmanz, taylorde, 10up, jakemgold, danielbachhuber, VentureBeat
3
  Tags: http redirects, redirect manager, url redirection, safe http redirection, multisite redirects, redirects
4
- Requires at least: 3.1
5
- Tested up to: 5.3
6
- Stable tag: 1.9.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
-
10
  Safely and easily manage your website's HTTP redirects.
11
 
12
  == Description ==
@@ -17,7 +17,7 @@ Easily and safely manage your site's redirects the WordPress way. There are many
17
 
18
  == Installation ==
19
 
20
- Install the plugin in WordPress. You can download a [zip via Github](https://github.com/10up/safe-redirect-manager/archive/master.zip) and upload it using the WordPress plugin uploader ("Plugins" > "Add New" > "Upload Plugin").
21
 
22
  == Configuration ==
23
 
@@ -26,47 +26,47 @@ There are no overarching settings for this plugin. To manage redirects, navigate
26
  Each redirect contains a few fields that you can utilize:
27
 
28
  === "Redirect From" ===
29
- This should be a path relative to the root of your WordPress installation. When someone visits your site with a path
30
- that matches this one, a redirect will occur. If your site is located at `http://example.com/wp/`` and you wanted to redirect `http://example.com/wp/about` to `http://example.com`, your "Redirect From" would be `/about`.
31
 
32
- Clicking the "Enable Regex" checkbox allows you to use regular expressions in your path. There are many
33
- [great tutorials](http://www.regular-expressions.info) on regular expressions.
34
 
35
- You can also use wildcards in your "Redirect From" paths. By adding an `*` at the end of a URL, your redirect will
36
- match any request that starts with your "Redirect From". Wildcards support replacements. This means if you have a
37
- wildcard in your from path that matches a string, you can have that string replace a wildcard character in your
38
- "Redirect To" path. For example, if your "Redirect From" is `/test/*`, your "Redirect To" is
39
- `http://google.com/*`, and the requested path is `/test/string`, the user would be redirect to `http://google.com/string`.
40
 
41
  === "Redirect To" ===
42
- This should be a path (i.e. `/test`) or a URL (i.e. `http://example.com/wp/test`). If a requested path matches
43
- "Redirect From", they will be redirected here. "Redirect To" supports wildcard and regular expression replacements.
44
 
45
  === "HTTP Status Code" ===
46
- [HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) are numbers that contain information about
47
- a request (i.e. whether it was successful, unauthorized, not found, etc). You should almost always use either 302 (temporarily moved) or 301 (permanently moved).
48
 
49
  *Note:*
50
 
51
- * Redirects are cached using the Transients API. Cache busts occur when redirects are added, updated, and deleted
52
- so you shouldn't be serving stale redirects.
53
- * By default the plugin only allows at most 250 redirects to prevent performance issues. There is a filter
54
- `srm_max_redirects` that you can utilize to up this number.
55
  * "Redirect From" and requested paths are case insensitive by default.
 
56
 
57
  == Changelog ==
58
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  = 1.9.3 =
60
- Changed
61
- * Allow for escaped values on `_redirect_rule_from`, useful when importing regex (props [@raymondware](https://profiles.wordpress.org/raymondware))
62
- * Check `current_user_can` cap later to prevent the notice being thrown during Jetpack sitemap cron event runs (props [@rebeccahum](https://profiles.wordpress.org/rebasaurus))
63
- * Updated tests and documentation (props [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein), [@jeffpaul](https://profiles.wordpress.org/jeffpaul), [@helen](https://profiles.wordpress.org/helen))
64
- * Check correct meta field when updating notes (props [@lucymtc](https://profiles.wordpress.org/lucymtc), [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein))
65
- * Bump WordPress version "tested up to" 5.3 (props [@jeffpaul](https://profiles.wordpress.org/jeffpaul))
66
- Fixed
67
- * Update the logic for wildcard matching to properly match URLs with query parameters (props [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein), [@mslinnea](https://profiles.wordpress.org/linsoftware)
68
- Security
69
- * Bump lodash from 4.17.11 to 4.17.15 (props [@dependabot](https://github.com/dependabot))
70
 
71
  = 1.9.2 =
72
  * Fix CLI list function name for PHP 5
@@ -156,7 +156,7 @@ Security
156
  * safe-redirect-manager.php - Globalize SRM class for use in themes/plugins/scripts. Added create_redirect method to make importing easier.
157
 
158
  = 1.2 =
159
- * safe-redirect-manager.php - manage_options capabilitiy required to use redirect manager, remove checkbox column, hide view switcher, fix search feature, hide privacy stuff for bulk edit
160
 
161
  = 1.1 =
162
  * safe-redirect-manager.php - plugin_url() used properly, is_plugin_page function
1
  === Safe Redirect Manager ===
2
  Contributors: tlovett1, tollmanz, taylorde, 10up, jakemgold, danielbachhuber, VentureBeat
3
  Tags: http redirects, redirect manager, url redirection, safe http redirection, multisite redirects, redirects
4
+ Requires at least: 4.6
5
+ Tested up to: 5.8
6
+ Stable tag: 1.10.0
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+
10
  Safely and easily manage your website's HTTP redirects.
11
 
12
  == Description ==
17
 
18
  == Installation ==
19
 
20
+ Install the plugin in WordPress. You can download a [zip via GitHub](https://github.com/10up/safe-redirect-manager/archive/trunk.zip) and upload it using the WordPress plugin uploader ("Plugins" > "Add New" > "Upload Plugin").
21
 
22
  == Configuration ==
23
 
26
  Each redirect contains a few fields that you can utilize:
27
 
28
  === "Redirect From" ===
29
+ This should be a path relative to the root of your WordPress installation. When someone visits your site with a path that matches this one, a redirect will occur. If your site is located at `http://example.com/wp/` and you wanted to redirect `http://example.com/wp/about` to `http://example.com`, your "Redirect From" would be `/about`.
 
30
 
31
+ Clicking the "Enable Regex" checkbox allows you to use regular expressions in your path. There are many [great tutorials](http://www.regular-expressions.info) on regular expressions.
 
32
 
33
+ You can also use wildcards in your "Redirect From" paths. By adding an `*` at the end of a URL, your redirect will match any request that starts with your "Redirect From". Wildcards support replacements. This means if you have a wildcard in your from path that matches a string, you can have that string replace a wildcard character in your "Redirect To" path. For example, if your "Redirect From" is `/test/*`, your "Redirect To" is `http://google.com/*`, and the requested path is `/test/string`, the user would be redirect to `http://google.com/string`.
 
 
 
 
34
 
35
  === "Redirect To" ===
36
+ This should be a path (i.e. `/test`) or a URL (i.e. `http://example.com/wp/test`). If a requested path matches "Redirect From", they will be redirected here. "Redirect To" supports wildcard and regular expression replacements.
 
37
 
38
  === "HTTP Status Code" ===
39
+ [HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) are numbers that contain information about a request (i.e. whether it was successful, unauthorized, not found, etc). You should almost always use either 302 (temporarily moved) or 301 (permanently moved).
 
40
 
41
  *Note:*
42
 
43
+ * Redirects are cached using the Transients API. Cache busts occur when redirects are added, updated, and deleted so you shouldn't be serving stale redirects.
44
+ * By default the plugin only allows at most 250 redirects to prevent performance issues. There is a filter `srm_max_redirects` that you can utilize to up this number.
 
 
45
  * "Redirect From" and requested paths are case insensitive by default.
46
+ * Developers can use `srm_additional_status_codes` filter to add status codes if needed.
47
 
48
  == Changelog ==
49
 
50
+ = 1.10.0 =
51
+ * **Added:** `410 Gone` status code to the list of HTTP status codes and `srm_additional_status_codes` to add additional status codes ([@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@helen](https://profiles.wordpress.org/helen), [@PopVeKind](https://profiles.wordpress.org/popvekind/)).
52
+ * **Added:** Option to ignore query parameters, previous behaviour still available via the new `srm_match_query_params` filter (props [@bradleyt](https://profiles.wordpress.org/bradleyt/), [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/)).
53
+ * **Added:** Extracts redirect matching logic from `maybe_redirect` to `match_redirect` method, plus `srm_match_redirect` function to expose matching redirect logic to themes and plugins (props [@nicholas_io](https://profiles.wordpress.org/nicholas_io/), [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/)).
54
+ * **Added:** Redirect Post ID to response headers where a redirect rule is invoked (props [@jamesmorrison](https://profiles.wordpress.org/jamesmorrison/), [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/)).
55
+ * **Added:** Banner and icon images (props [@lea10up](https://profiles.wordpress.org/lea10up/)).
56
+ * **Added:** Documentation and unit test updates (props [@noplanman](https://profiles.wordpress.org/noplanman/), [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@kevinbrands](https://profiles.wordpress.org/kevinbrands/), [@jeffpaul](https://profiles.wordpress.org/jeffpaul/), [@davidegreenwald](https://profiles.wordpress.org/davidegreenwald/), [@barryceelen](https://profiles.wordpress.org/barryceelen/)).
57
+ * **Fixed:** Use proper hook for setting up `SRM_Redirect` (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@icaleb](https://profiles.wordpress.org/icaleb/)).
58
+ * **Fixed:** Regression related to wildcard matching (props [@amyevans](https://github.com/amyevans), [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@jeffreybetts](https://github.com/jeffreybetts)).
59
+ * **Fixed:** Missing `order` column in CSV import WP-CLI command (props [@barryceelen](https://profiles.wordpress.org/barryceelen/)).
60
+ * **Security:** Bump `lodash` from 4.17.15 to 4.17.19 (props [@dependabot](https://github.com/dependabot)).
61
+
62
  = 1.9.3 =
63
+ * **Changed:** Allow for escaped values on `_redirect_rule_from`, useful when importing regex (props [@raymondware](https://profiles.wordpress.org/raymondware)).
64
+ * **Changed:** Check `current_user_can` cap later to prevent the notice being thrown during Jetpack sitemap cron event runs (props [@rebeccahum](https://profiles.wordpress.org/rebasaurus)).
65
+ * **Changed:** Updated tests and documentation (props [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein), [@jeffpaul](https://profiles.wordpress.org/jeffpaul), [@helen](https://profiles.wordpress.org/helen)).
66
+ * **Changed:** Check correct meta field when updating notes (props [@lucymtc](https://profiles.wordpress.org/lucymtc), [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein)).
67
+ * **Changed:** Bump WordPress version "tested up to" 5.3 (props [@jeffpaul](https://profiles.wordpress.org/jeffpaul)).
68
+ * **Fixed:** Update the logic for wildcard matching to properly match URLs with query parameters (props [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein), [@mslinnea](https://profiles.wordpress.org/linsoftware).
69
+ * **Security:** Bump lodash from 4.17.11 to 4.17.15 (props [@dependabot](https://github.com/dependabot)).
 
 
 
70
 
71
  = 1.9.2 =
72
  * Fix CLI list function name for PHP 5
156
  * safe-redirect-manager.php - Globalize SRM class for use in themes/plugins/scripts. Added create_redirect method to make importing easier.
157
 
158
  = 1.2 =
159
+ * safe-redirect-manager.php - manage_options capability required to use redirect manager, remove checkbox column, hide view switcher, fix search feature, hide privacy stuff for bulk edit
160
 
161
  = 1.1 =
162
  * safe-redirect-manager.php - plugin_url() used properly, is_plugin_page function
safe-redirect-manager.php CHANGED
@@ -4,9 +4,8 @@
4
  * Plugin URI: https://wordpress.org/plugins/safe-redirect-manager
5
  * Description: Easily and safely manage HTTP redirects.
6
  * Author: 10up
7
- * Version: 1.9.3
8
  * Text Domain: safe-redirect-manager
9
- * Domain Path: /lang/
10
  * Author URI: https://10up.com
11
  * License: GPLv2 or later
12
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -14,16 +13,7 @@
14
  * @package safe-redirect-manager
15
  */
16
 
17
- /**
18
- * Localize plugin
19
- *
20
- * @since 1.8
21
- */
22
- function srm_load_textdomain() {
23
- load_plugin_textdomain( 'safe-redirect-manager', false, dirname( __FILE__ ) . '/lang' );
24
- }
25
- add_action( 'plugins_loaded', 'srm_load_textdomain' );
26
-
27
  require_once dirname( __FILE__ ) . '/inc/functions.php';
28
  require_once dirname( __FILE__ ) . '/inc/classes/class-srm-post-type.php';
29
  require_once dirname( __FILE__ ) . '/inc/classes/class-srm-redirect.php';
4
  * Plugin URI: https://wordpress.org/plugins/safe-redirect-manager
5
  * Description: Easily and safely manage HTTP redirects.
6
  * Author: 10up
7
+ * Version: 1.10.0
8
  * Text Domain: safe-redirect-manager
 
9
  * Author URI: https://10up.com
10
  * License: GPLv2 or later
11
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
  * @package safe-redirect-manager
14
  */
15
 
16
+ // Load helper functions and classes
 
 
 
 
 
 
 
 
 
17
  require_once dirname( __FILE__ ) . '/inc/functions.php';
18
  require_once dirname( __FILE__ ) . '/inc/classes/class-srm-post-type.php';
19
  require_once dirname( __FILE__ ) . '/inc/classes/class-srm-redirect.php';