WP 404 Auto Redirect to Similar Post - Version 0.9

Version Description

  • Fix: 302 headers option would not save
  • Fix: Redirection loop in some specific cases - Direct match on private posts
  • Fix: Ajax URL for custom /wp-admin/ path (Preview Mode)
  • Added: New Filter available ('wp404arsp/settings', $settings)
  • Added: New Filter available ('wp404arsp/redirect', $args, $settings)
  • Added: New Action available ('wp404arsp/after_redirect', $args, $settings)
  • Added: New page header 'WP-404-Auto-Redirect: true' on redirection
  • Added: Exclude posts with the post meta: `wp404arsp_no_redirect
Download this release

Release Info

Developer hwk-fr
Plugin Icon 128x128 WP 404 Auto Redirect to Similar Post
Version 0.9
Comparing to
See all releases

Code changes from version 0.7.7 to 0.9

Files changed (4) hide show
  1. assets/admin.css +34 -6
  2. assets/admin.js +60 -26
  3. readme.txt +68 -39
  4. wp-404-auto-redirect-similar-post.php +550 -278
assets/admin.css CHANGED
@@ -1,3 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  #wp404arsp_settings #wp404arsp_settings_fallback_url{
2
  width:330px;
3
  }
@@ -6,7 +23,12 @@
6
  pointer-events:none;
7
  }
8
 
9
- #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types{
 
 
 
 
 
10
  display:block;
11
  border:1px solid #ddd;
12
  max-width:300px;
@@ -14,29 +36,34 @@
14
  overflow:auto;
15
  }
16
 
17
- #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types input{
 
18
  display: none;
19
  opacity: 0;
20
  visibility: hidden;
21
  }
22
 
23
- #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types label{
 
24
  display:block;
25
  padding:5px;
26
  margin:0 !important;
27
  position:relative;
28
  }
29
 
30
- #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types label:hover{
 
31
  background:#f1f1f1;
32
  }
33
 
34
- #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types input:checked + label{
 
35
  background:#0073aa;
36
  color:#c6d6dd;
37
  }
38
 
39
- #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types input:checked + label:after{
 
40
  position: absolute;
41
  content: "Excluded";
42
  right: 5px;
@@ -49,6 +76,7 @@
49
 
50
  #wp404arsp_settings p.submit{
51
  padding:0;
 
52
  }
53
 
54
  #wp404arsp_settings p.submit .loading.spinner{
1
+ #wp404arsp_settings a.nav-tab{
2
+ outline:none;
3
+ box-shadow:none;
4
+ text-decoration:none;
5
+ transition-property:none;
6
+ }
7
+
8
+ #wp404arsp_settings h2.nav-tab-wrapper{
9
+ margin-bottom:5px !important;
10
+ margin-top:20px !important;
11
+ display:block;
12
+ }
13
+
14
+ #wp404arsp_settings .nav-tab-panel:not(#settings){
15
+ display:none;
16
+ }
17
+
18
  #wp404arsp_settings #wp404arsp_settings_fallback_url{
19
  width:330px;
20
  }
23
  pointer-events:none;
24
  }
25
 
26
+ #wp404arsp_settings #wp404arsp_settings_priority{
27
+ width: 60px;
28
+ }
29
+
30
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types,
31
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_taxonomies{
32
  display:block;
33
  border:1px solid #ddd;
34
  max-width:300px;
36
  overflow:auto;
37
  }
38
 
39
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types input,
40
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_taxonomies input{
41
  display: none;
42
  opacity: 0;
43
  visibility: hidden;
44
  }
45
 
46
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types label,
47
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_taxonomies label{
48
  display:block;
49
  padding:5px;
50
  margin:0 !important;
51
  position:relative;
52
  }
53
 
54
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types label:hover,
55
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_taxonomies label:hover{
56
  background:#f1f1f1;
57
  }
58
 
59
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types input:checked + label,
60
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_taxonomies input:checked + label{
61
  background:#0073aa;
62
  color:#c6d6dd;
63
  }
64
 
65
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_post_types input:checked + label:after,
66
+ #wp404arsp_settings #wp404arsp_settings_rules_redirection_exclude_taxonomies input:checked + label:after{
67
  position: absolute;
68
  content: "Excluded";
69
  right: 5px;
76
 
77
  #wp404arsp_settings p.submit{
78
  padding:0;
79
+ margin-top:15px;
80
  }
81
 
82
  #wp404arsp_settings p.submit .loading.spinner{
assets/admin.js CHANGED
@@ -1,5 +1,22 @@
1
  jQuery(document).ready(function($){
2
- var ajaxurl = '/wp-admin/admin-ajax.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  if($('[name="wp404arsp_settings[fallback][type]"]').length > 0 && $('[name="wp404arsp_settings[fallback][url]"]').length > 0 && $('[name="wp404arsp_settings[fallback][home_url]"]').length > 0){
5
  $('[name="wp404arsp_settings[fallback][type]"]').change(function(){
@@ -19,33 +36,50 @@ jQuery(document).ready(function($){
19
  }
20
  });
21
  }
22
-
23
- if($('#wp404arsp_settings_redirection_preview').length > 0){
24
- $('#wp404arsp_settings_redirection_preview .button').click(function(){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  $button = $(this);
26
  $loading = $('#wp404arsp_settings_redirection_preview .loading');
27
  $button.prop('disabled', true);
28
  $loading.addClass('is-active');
29
- $request = $('#wp404arsp_settings_redirection_preview input[type=text]').val();
30
- if($request.length == 0)
31
- return;
32
-
33
- if($request.substring(0,1) != '/'){
34
- $request = '/' + $request;
35
- $('#wp404arsp_settings_redirection_preview input[type=text]').val($request)
36
- }
37
-
38
- data = {
39
- action: 'wp404arsp_ajax_test',
40
- request: $request,
41
- };
42
- $.post(ajaxurl, data)
43
- .done(function(response){
44
- $button.prop('disabled', false);
45
- $loading.removeClass('is-active');
46
- $('#wp404arsp_settings_redirection_preview .results').html(response);
47
- });
48
- });
49
- }
50
-
51
  });
1
  jQuery(document).ready(function($){
2
+
3
+ $('.nav-tab-wrapper a').click(function(event){
4
+ event.preventDefault();
5
+
6
+ var context = $(this).closest('.nav-tab-wrapper').parent();
7
+ $('.nav-tab-wrapper a', context).removeClass('nav-tab-active');
8
+ $(this).addClass('nav-tab-active');
9
+ $('.nav-tab-panel', context).hide();
10
+ $($(this).attr('href'), context).show();
11
+ });
12
+
13
+
14
+ $('.nav-tab-wrapper').each(function(){
15
+ if ( $('.nav-tab-active', this).length )
16
+ $('.nav-tab-active', this).click();
17
+ else
18
+ $('a', this).first().click();
19
+ });
20
 
21
  if($('[name="wp404arsp_settings[fallback][type]"]').length > 0 && $('[name="wp404arsp_settings[fallback][url]"]').length > 0 && $('[name="wp404arsp_settings[fallback][home_url]"]').length > 0){
22
  $('[name="wp404arsp_settings[fallback][type]"]').change(function(){
36
  }
37
  });
38
  }
39
+
40
+ function wp404arsp_disable_taxonomies(checkbox){
41
+ if(checkbox.is(':checked')){
42
+ $('.wp404arsp_settings_taxonomies').hide();
43
+ }else{
44
+ $('.wp404arsp_settings_taxonomies').show();
45
+ }
46
+ }
47
+
48
+ if($('#wp404arsp_settings_rules_redirection_disable_taxonomies').length > 0){
49
+ wp404arsp_disable_taxonomies($('#wp404arsp_settings_rules_redirection_disable_taxonomies'));
50
+
51
+ $('#wp404arsp_settings_rules_redirection_disable_taxonomies').change(function(){
52
+ wp404arsp_disable_taxonomies($(this));
53
+ });
54
+ }
55
+
56
+ if($('#wp404arsp_settings_redirection_preview').length > 0){
57
+ $('#wp404arsp_settings_redirection_preview .button').click(function(event){
58
+ event.preventDefault();
59
+
60
  $button = $(this);
61
  $loading = $('#wp404arsp_settings_redirection_preview .loading');
62
  $button.prop('disabled', true);
63
  $loading.addClass('is-active');
64
+ $request = $('#wp404arsp_settings_redirection_preview input[type=text]').val();
65
+ if($request.length == 0)
66
+ return;
67
+
68
+ if($request.substring(0,1) != '/'){
69
+ $request = '/' + $request;
70
+ $('#wp404arsp_settings_redirection_preview input[type=text]').val($request)
71
+ }
72
+
73
+ $.post(ajaxurl, {
74
+ action: 'wp404arsp_ajax_preview',
75
+ request: $request,
76
+ })
77
+ .done(function(response){
78
+ $button.prop('disabled', false);
79
+ $loading.removeClass('is-active');
80
+ $('#wp404arsp_settings_redirection_preview .results').html(response);
81
+ });
82
+ });
83
+ }
84
+
 
85
  });
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === WP 404 Auto Redirect to Similar Post ===
2
  Contributors: hwk-fr
3
- Donate link: http://hwk.fr/
4
  Tags: SEO, 404, Redirect, 301, Similar, Related, Search, Broken Link, Webmaster Tools, Google
5
  Requires at least: 4.0
6
  Tested up to: 4.9.1
7
- Stable tag: 0.7.7
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -23,8 +23,11 @@ This plugin automatically redirect all your 404 requests to similar posts based
23
  * If nothing similar is found, choose your Fallback Behavior: Redirection or Default 404.
24
  * Choose the redirection HTTP header status: 301 / 302.
25
  * Exclude one or multiple post types from possible redirections.
26
- * Debug Console for Admin: Display the Debug Console instead of being redirected.
27
- * Preview similar post found directly from the admin panel.
 
 
 
28
 
29
  = But Also: =
30
 
@@ -34,7 +37,7 @@ This plugin automatically redirect all your 404 requests to similar posts based
34
 
35
  = Compatibility: =
36
 
37
- If you missed a manual redirection and a 404 is about to be displayed, the plugin will take action. Yes, WP 404 Auto Redirect to Similar Post is 100% compatible with all popular redirection plugins:
38
 
39
  * [Redirection](https://wordpress.org/plugins/redirection/)
40
  * [Simple 301 Redirects](https://wordpress.org/plugins/simple-301-redirects/)
@@ -46,8 +49,14 @@ If you missed a manual redirection and a 404 is about to be displayed, the plugi
46
  They talk about it! :)
47
 
48
  * [Quels plugins utiliser pour corriger les erreurs 404 sous WordPress ?](https://sebastienpierrepack.com/plugins-corriger-404-wordpress/)
 
 
 
 
49
  * [Permalink Finder Plugin is deprecated](http://bhaaratham.com/permalink-finder-plugin-sanitize_url-is-deprecated/)
50
  * [Membuat halaman Error 404 menjadi SEO friendly](https://www.seosatu.com/optimalkan-seo-dengan-halaman-404/)
 
 
51
 
52
  == Installation ==
53
 
@@ -56,61 +65,81 @@ They talk about it! :)
56
  1. Upload the plugin files to the `/wp-content/plugins/wp-404-auto-redirect-similar-post` directory, or install the plugin through the WordPress plugins screen directly.
57
  2. Activate the plugin through the 'Plugins' screen in WordPress.
58
  3. Go to Settings > WP 404 Auto Redirect to change your settings.
59
- 4. Everything is ready! Modify an url in your browser to try to trigger a 404.
60
 
61
  == Screenshots ==
62
 
63
- 1. Settings Page
64
- 2. Front Debug Console (for administrators)
 
 
 
65
 
66
  == Changelog ==
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  = 0.7.7 =
69
- * Fixed PHP header() error on upgrade
70
- * Fixed Exclude Post Type from Redirections UI & Logic
71
- * Added 999 priority on template_redirect action for compatibility
72
- * Fixed 'Compatibility' typo in description
73
- * Updated Plugin Screenshot
74
 
75
  = 0.7.6 =
76
- * Added "Custom Redirect URL" as Fallback Behavior (Feature Request)
77
- * Added "Exclude Post Type" Multi-select to possible redirections (Feature Request)
78
- * Fixed Typos & added better descriptions
79
- * Better overall request validation
80
- * Fixed minor PHP Notice
81
 
82
  = 0.7.2 =
83
- * Improved direct match algorythm
84
- * Improved sanitization of requests with an extension
85
- * Improved post_type matching to only search "active" post_types
86
- * Re-introduced Term search as fallback (if no similar post found)
87
 
88
  = 0.7.1 =
89
- * Improved Post Types handle
90
- * Improved paged request handle
91
- * Fixed bug while displaying legacy 404
92
- * Fixed PHP notice on preview mode
93
 
94
  = 0.7 =
95
- * Reworked code
96
- * Added settings page
97
- * Added Debug mode for administrators (settings page)
98
- * Added the ability to disable "Redirect to Homepage" if nothing found (Feature request)
99
- * Added the ability to choose between 301 or 302 HTTP Headers
100
- * Added the ability preview URL Redirections
101
 
102
  = 0.4.0.2 =
103
- * Fixed sanitization bug
104
- * Fixed debug typo
105
 
106
  = 0.4 =
107
- * Revamped Code
108
- * Improved Speed
109
- * Better Post Type / Category / Taxonomy matching
110
 
111
  = 0.3.2 =
112
- * Added Debug monitoring
113
- * Better management of paged requests
114
 
115
  = 0.3 =
116
  * Initial Release
1
  === WP 404 Auto Redirect to Similar Post ===
2
  Contributors: hwk-fr
3
+ Donate link: https://hwk.fr/
4
  Tags: SEO, 404, Redirect, 301, Similar, Related, Search, Broken Link, Webmaster Tools, Google
5
  Requires at least: 4.0
6
  Tested up to: 4.9.1
7
+ Stable tag: 0.9
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
23
  * If nothing similar is found, choose your Fallback Behavior: Redirection or Default 404.
24
  * Choose the redirection HTTP header status: 301 / 302.
25
  * Exclude one or multiple post types from possible redirections.
26
+ * Exclude one or multiple taxonomies from possible redirections.
27
+ * Exclude one or multiple posts based on a custom post meta.
28
+ * Exclude one or multiple terms based on a custom term meta.
29
+ * Administrators: Display the Debug Console instead of being redirected.
30
+ * Preview possible results directly from the administration panel.
31
 
32
  = But Also: =
33
 
37
 
38
  = Compatibility: =
39
 
40
+ WP 404 Auto Redirect to Similar Post is 100% compatible with all popular redirection plugins. If you use one of them, but missed a manual redirection and a 404 is about to be displayed, WP 404 Auto Redirect to Similar Post will take action.
41
 
42
  * [Redirection](https://wordpress.org/plugins/redirection/)
43
  * [Simple 301 Redirects](https://wordpress.org/plugins/simple-301-redirects/)
49
  They talk about it! :)
50
 
51
  * [Quels plugins utiliser pour corriger les erreurs 404 sous WordPress ?](https://sebastienpierrepack.com/plugins-corriger-404-wordpress/)
52
+ * [6+ 404 Redirect WordPress Plugins 2018 (Free and Paid)](https://www.formget.com/404-redirect-wordpress-plugins/)
53
+ * [12 Best Free SEO Plugins for WordPress](https://uproer.com/articles/best-seo-plugins-wordpress/)
54
+ * [Recommended Plugins for WordPress](https://wpstuff.org/plugins/recommended-plugins-for-wordpress/)
55
+ * [Top WordPress Plugins I Can’t Do Without](http://blogingenuity.com/top-wordpress-plugins-i-cant-do-without/)
56
  * [Permalink Finder Plugin is deprecated](http://bhaaratham.com/permalink-finder-plugin-sanitize_url-is-deprecated/)
57
  * [Membuat halaman Error 404 menjadi SEO friendly](https://www.seosatu.com/optimalkan-seo-dengan-halaman-404/)
58
+ * [The Ultimate Guide to Starting a Travel Blog](https://www.littlemissgemtravels.com/ultimate-guide-to-starting-a-travel-blog/)
59
+ * [80 Best WordPress Plugins for 2018](https://sayoho.com/80-best-wordpress-plugins-for-2018/)
60
 
61
  == Installation ==
62
 
65
  1. Upload the plugin files to the `/wp-content/plugins/wp-404-auto-redirect-similar-post` directory, or install the plugin through the WordPress plugins screen directly.
66
  2. Activate the plugin through the 'Plugins' screen in WordPress.
67
  3. Go to Settings > WP 404 Auto Redirect to change your settings.
68
+ 4. Everything is ready! Now try to trigger a 404 page!
69
 
70
  == Screenshots ==
71
 
72
+ 1. Admin: Settings Page
73
+ 2. Admin: Post Types
74
+ 3. Admin: Taxonomies
75
+ 4. Admin: Preview
76
+ 5. Front: Debug Console
77
 
78
  == Changelog ==
79
 
80
+ = 0.9 =
81
+ * Fix: 302 headers option would not save
82
+ * Fix: Redirection loop in some specific cases - Direct match on private posts
83
+ * Fix: Ajax URL for custom `/wp-admin/` path (Preview Mode)
84
+ * Added: New Filter available `('wp404arsp/settings', $settings)`
85
+ * Added: New Filter available `('wp404arsp/redirect', $args, $settings)`
86
+ * Added: New Action available `('wp404arsp/after_redirect', $args, $settings)`
87
+ * Added: New page header 'WP-404-Auto-Redirect: true' on redirection
88
+ * Added: Exclude posts with the post meta: `wp404arsp_no_redirect = 1` from possible redirections.
89
+ * Added: Exclude terms with the term meta: `wp404arsp_no_redirect = 1` from possible redirections.
90
+ * Added: Exclude one or multiple taxonomies from possible redirections.
91
+ * Added: Disable Taxonomy Redirection - Never redirect to terms archives.
92
+ * Added: Plugin priority - Advanced users only (Default 999).
93
+ * Improvement: Revamped code
94
+ * Improvement: Administration panel with tabs
95
+ * Improvement: Plugin is now translation ready
96
+
97
  = 0.7.7 =
98
+ * Fix: PHP header() error on upgrade
99
+ * Fix: Exclude Post Type from Redirections UI & Logic
100
+ * Fix: 'Compatibility' typo in description
101
+ * Added: 999 priority on template_redirect action for compatibility
102
+ * Improvement: Updated Plugin Screenshot
103
 
104
  = 0.7.6 =
105
+ * Fix: Typos & added better descriptions
106
+ * Fix: minor PHP Notice
107
+ * Added: "Custom Redirect URL" as Fallback Behavior (Feature Request)
108
+ * Added: "Exclude Post Type" Multi-select to possible redirections (Feature Request)
109
+ * Improvement: Better overall request validation
110
 
111
  = 0.7.2 =
112
+ * Added: Re-introduced Term search as fallback (if no similar post found)
113
+ * Improvement: Direct match algorythm
114
+ * Improvement: Sanitization of requests with an extension
115
+ * Improvement: Post_type matching to only search "active" post_types
116
 
117
  = 0.7.1 =
118
+ * Fix: Bug while displaying legacy 404
119
+ * Fix: PHP notice on preview mode
120
+ * Improvement: Post Types handle
121
+ * Improvement: Paged request handle
122
 
123
  = 0.7 =
124
+ * Added: Settings page
125
+ * Added: Debug mode for administrators (settings page)
126
+ * Added: Ability to disable "Redirect to Homepage" if nothing found (Feature request)
127
+ * Added: Ability to choose between 301 or 302 HTTP Headers
128
+ * Added: Ability preview URL Redirections
129
+ * Improvement: Reworked code
130
 
131
  = 0.4.0.2 =
132
+ * Fix: Sanitization bug
133
+ * Fix: Debug typo
134
 
135
  = 0.4 =
136
+ * Improvement: Revamped Code
137
+ * Improvement: Processing speed
138
+ * Improvement: Better Post Type / Category / Taxonomy matching
139
 
140
  = 0.3.2 =
141
+ * Added: Debug monitoring
142
+ * Improvement: Better management of paged requests
143
 
144
  = 0.3 =
145
  * Initial Release
wp-404-auto-redirect-similar-post.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WP 404 Auto Redirect to Similar Post
4
  * Description: Automatically Redirect any 404 to a Similar Post based on the Title, Post Type, Category & Taxonomy using 301 Redirects!
5
  * Author: hwk-fr
6
- * Version: 0.7.7
7
  * Author URI: http://hwk.fr
8
  */
9
 
@@ -35,161 +35,320 @@ function wp404arsp_admin_page_html(){
35
  ?>
36
  <div class="wrap" id="wp404arsp_settings">
37
  <h1 class="wp-heading-inline">WP 404 Auto Redirect to Similar Post</h1>
38
- <hr class="wp-header-end">
 
 
 
 
 
 
 
39
 
40
  <div id="poststuff">
41
  <div id="post-body" class="metabox-holder columns-2">
42
-
43
  <div id="post-body-content">
44
- <div class="meta-box-sortables ui-sortable">
45
-
46
- <div class="postbox">
47
- <h2 class="hndle"><span>Settings</span></h2>
48
- <form method="post" action="options.php">
49
- <?php
50
- settings_fields('wp404arsp_settings');
51
- do_settings_sections('wp404arsp_settings');
52
- $settings = wp404arsp_get_settings();
53
- ?>
54
-
55
- <div class="inside">
56
- <table class="form-table">
57
- <tbody>
58
-
59
- <tr>
60
- <th scope="row">Debug Mode</th>
61
- <td>
62
- <fieldset>
63
- <legend class="screen-reader-text"><span>Debug</span></legend>
64
- <label for="wp404arsp_settings_debug">
65
- <input name="wp404arsp_settings[debug]" id="wp404arsp_settings_debug" value="1" type="checkbox" <?php if($settings['debug'] == "1") echo "checked"; ?>>
66
- Activate
67
- </label>
68
- </fieldset>
69
- <p class="description">Display the Debug Console instead of being redirected. <code>Administrators</code> only.</p>
70
- </td>
71
- </tr>
72
-
73
- <tr>
74
- <th scope="row">Fallback Behavior</th>
75
- <td>
76
- <fieldset>
77
- <legend class="screen-reader-text"><span>Default Redirection if nothing similar is found.</span></legend>
78
- <label for="wp404arsp_settings_fallback_type">
79
- <select name="wp404arsp_settings[fallback][type]" id="wp404arsp_settings_fallback_type">
80
- <option value="home" <?php if($settings['fallback']['type'] == 'home') echo "selected"; ?>>Redirect to Homepage</option>
81
- <option value="custom" <?php if($settings['fallback']['type'] == 'custom') echo "selected"; ?>>Custom Redirection</option>
82
- <option value="disabled" <?php if($settings['fallback']['type'] == 'disabled') echo "selected"; ?>>Default 404</option>
83
- </select>
84
- </label>
85
-
86
- <?php
87
- $fallback = array(
88
- 'value' => home_url(),
89
- 'class' => 'disabled',
90
- 'attr' => 'readonly="readonly"',
91
- );
92
-
93
- if($settings['fallback']['type'] == 'custom'){
94
- $fallback['value'] = $settings['fallback']['url'];
95
- $fallback['attr'] = '';
96
- $fallback['class'] = '';
97
- }
98
-
99
- if($settings['fallback']['type'] == 'disabled'){
100
- $fallback['value'] = '';
101
- $fallback['attr'] = '';
102
- $fallback['class'] = 'hidden';
103
- }
104
- ?>
105
-
106
- <input name="wp404arsp_settings[fallback][home_url]" id="wp404arsp_settings_fallback_home_url" type="hidden" value="<?php echo home_url(); ?>" />
107
- <input name="wp404arsp_settings[fallback][url]" id="wp404arsp_settings_fallback_url" type="text" value="<?php echo $fallback['value']; ?>" class="<?php echo $fallback['class']; ?>" <?php echo $fallback['attr']; ?> />
108
-
109
- </fieldset>
110
- <p class="description">If nothing similar is found, this behavior will be applied.</p>
111
- </td>
112
- </tr>
113
-
114
- <tr>
115
- <th scope="row">Redirect Headers</th>
116
- <td>
117
- <fieldset>
118
- <legend class="screen-reader-text"><span>Redirection Headers.</span></legend>
119
- <label for="wp404arsp_settings_method">
120
- <select name="wp404arsp_settings[method]" id="wp404arsp_settings_method">
121
- <option value="301" <?php if($settings['method'] == '301') echo "selected"; ?>>301 method</option>
122
- <option value="302" <?php if($settings['method'] == "302") echo "selected"; ?>>302 method</option>
123
- </select>
124
- </label>
125
- </fieldset>
126
- <p class="description">Learn more about <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes" target="_blank">HTTP headers & redirections</a>.</p>
127
- </td>
128
- </tr>
129
-
130
- <tr>
131
- <th scope="row">Exclude Post Type(s)</th>
132
- <td>
133
- <fieldset>
134
- <legend class="screen-reader-text"><span>Exclude one or multiple post types from possible redirections.</span></legend>
135
- <div id="wp404arsp_settings_rules_redirection_exclude_post_types">
136
- <?php foreach(get_post_types(array('public' => true), 'objects') as $post_type) { ?>
137
- <?php
138
- $checked = '';
139
- if(
140
- isset($settings['rules']['redirection']['exclude']['post_types']) &&
141
- is_array($settings['rules']['redirection']['exclude']['post_types']) &&
142
- in_array($post_type->name, $settings['rules']['redirection']['exclude']['post_types'])
143
- )
144
- $checked = 'checked="checked"'; ?>
145
- <div><input type="checkbox" name="wp404arsp_settings[rules][redirection][exclude][post_types][]" id="wp404arsp_settings_rules_redirection_exclude_post_types_<?php echo $post_type->name; ?>" value="<?php echo $post_type->name; ?>" <?php echo $checked; ?> />
146
- <label for="wp404arsp_settings_rules_redirection_exclude_post_types_<?php echo $post_type->name; ?>"><?php echo $post_type->label; ?></label></div>
147
- <?php } ?>
148
- </div>
149
- </fieldset>
150
- <p class="description">Exclude one or multiple post types from possible redirections.</p>
151
- </td>
152
- </tr>
153
-
154
- </tbody>
155
- </table>
156
-
157
- <p class="submit">
158
- <?php submit_button('Save Settings', 'primary', '', false); ?>
159
- </p>
160
- </div>
161
- </form>
162
- </div>
163
-
164
- <div id="wp404arsp_settings_redirection_preview">
165
- <div class="postbox">
166
- <h2 class="hndle"><span>Redirection Preview</span></h2>
167
- <div class="inside">
168
- <table class="form-table">
169
- <tbody>
170
-
171
- <tr>
172
- <th scope="row"><?php echo home_url(); ?></th>
173
- <td>
174
- <input class="request" type="text" value="/example-url" />
175
- <p class="description">Enter the URL you would like to test, starting with <code>/</code>.</p>
176
- </td>
177
- </tr>
178
- </tbody>
179
- </table>
180
-
181
- <p class="submit">
182
- <?php submit_button('Preview URL', 'secondary', '', false); ?>
183
- <span class="loading spinner"></span>
184
- </p>
185
-
186
- <div class="results"></div>
187
-
188
- </div>
189
- </div>
190
- </div>
191
-
192
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
  </div>
195
 
@@ -200,13 +359,13 @@ function wp404arsp_admin_page_html(){
200
  <div class="inside">
201
  <img src="<?php echo plugins_url('assets/logo.png', __FILE__); ?>" class="logo" />
202
 
203
- <p>Found a bug? Need help? Head over the <a href="https://wordpress.org/plugins/wp-404-auto-redirect-to-similar-post/" target="_blank">official plugin page</a>.</p>
204
 
205
  <hr />
206
 
207
- <p>Enjoying this plugin? Please rate it. It's always much appreciated!</p>
208
  <p>
209
- <a href="https://wordpress.org/support/plugin/wp-404-auto-redirect-to-similar-post/reviews/#new-post" target="_blank" class="button">Rate the plugin</a>
210
  </p>
211
  </div>
212
 
@@ -221,28 +380,38 @@ function wp404arsp_admin_page_html(){
221
  </div>
222
  <?php }
223
 
224
- add_action('template_redirect', 'wp404arsp_init', 999);
 
 
 
225
  function wp404arsp_init(){
226
- if(
227
- !is_404() ||
228
- wp_doing_ajax() ||
229
- is_admin() ||
230
- ( !isset($_SERVER['REQUEST_URI']) || empty($_SERVER['REQUEST_URI']) ) ||
231
- ( isset($_SERVER['SCRIPT_URI']) && !empty($_SERVER['SCRIPT_URI']) && $_SERVER['SCRIPT_URI'] == admin_url('admin-ajax.php') ) ||
232
- ( isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' )
233
- )
234
- return;
 
 
 
 
 
 
 
 
235
 
 
236
  wp404arsp_request($_SERVER['REQUEST_URI']);
237
  }
238
 
239
  function wp404arsp_request($request, $preview = false){
240
 
241
- $query = array();
242
- $query['request']['full'] = urldecode(htmlspecialchars($request));
243
-
244
- if($preview)
245
- $query['preview'] = true;
246
 
247
  if(preg_match('#/(?<slug>page|paged)/(?<page>[0-9]+)/?$#i', $request, $pagination)){
248
  $request_no_pagination = str_replace($pagination[0], '', $request);
@@ -265,21 +434,22 @@ function wp404arsp_request($request, $preview = false){
265
 
266
  // Pagination found, try the URL without pagination
267
  if(!empty($query['request']['pagination']))
268
- return wp404arsp_redirect(array_merge( $query, array(
269
- 'url' => home_url() . $request_no_pagination,
270
- 'why' => "Pagination found in the requested URL. Trying to reach same URL without pagination."
271
- ))
272
- );
 
273
 
274
  wp404arsp_setup($query);
275
 
276
  }
277
 
278
  function wp404arsp_setup($query){
279
-
280
  if(!isset($query['request']['full']) || empty($query['request']['full']))
281
  return;
282
-
 
283
  $query['process']['request'] = $query['request']['full'];
284
 
285
  global $wp_query;
@@ -306,23 +476,32 @@ function wp404arsp_setup($query){
306
  $query['process']['keywords']['explode'][] = $keyword;
307
  }
308
  $query['process']['keywords']['explode'] = array_reverse($query['process']['keywords']['explode']);
309
-
310
- return wp404arsp_redirect(wp404arsp_search($query));
311
-
312
  }
313
 
314
- function wp404arsp_search($query){
315
-
316
  // Direct
317
- if( ($get_post_types = wp404arsp_get_post_types('names')) && !empty($get_post_types) ){
318
  foreach($get_post_types as $post_type){
319
- if($post = get_page_by_path($query['process']['keywords']['explode'][0], 'object', $post_type))
320
- return array_merge( $query, array(
321
- 'score' => 'direct',
322
- 'id' => (int)$post->ID,
323
- 'url' => get_permalink((int)$post->ID),
324
- 'why' => "Part of the requested URL already exist as post of the post_type <strong>" . get_post_type((int)$post->ID) . "</strong>"
325
- ));
 
 
 
 
 
 
 
 
 
326
  }
327
  }
328
 
@@ -332,44 +511,45 @@ function wp404arsp_search($query){
332
 
333
  // Term
334
  if(empty($sql['result']) || $sql['result']['score'] < 1){
 
 
 
 
 
335
  $sql = wp404arsp_search_sql(array('keywords' => $keywords, 'mode' => 'term'));
336
 
337
  if(empty($sql['result']) || $sql['result']['score'] < 1)
338
- return array_merge( $query, array(
339
- 'why' => "Nothing similar found matching the requested URL."
340
- )
341
- );
342
 
343
- return array_merge( $query, array(
344
- 'score' => $sql['result']['score'],
345
- 'id' => (int)$sql['result']['term_id'],
346
- 'url' => get_term_link((int)$sql['result']['term_id']),
347
- 'why' => "No similar post found, but a similar <strong>term</strong> was found."
348
- )
349
- );
350
  }
351
 
352
  // Post
353
- $return = array_merge( $query, array(
354
- 'score' => $sql['result']['score'],
355
- 'id' => (int)$sql['result']['ID'],
356
- 'url' => get_permalink((int)$sql['result']['ID']),
357
- 'why' => "Similar post of post_type <strong>" . get_post_type((int)$sql['result']['ID']) . "</strong> was found."
358
- )
359
- );
360
 
361
  // Post: If Post Type found, check other post types & compare score
362
  if(isset($query['process']['post_type']) && !empty($query['process']['post_type'])){
363
 
364
  $sql = wp404arsp_search_sql(array('keywords' => $keywords, 'post_type' => $query['process']['post_type']));
365
  if(!empty($sql['result']) && $sql['result']['score'] >= 1 && $sql['result']['score'] >= $return['score']){
366
- $return = array_merge( $query, array(
367
- 'score' => $sql['result']['score'],
368
- 'id' => (int)$sql['result']['ID'],
369
- 'url' => get_permalink((int)$sql['result']['ID']),
370
- 'why' => "Similar post of post_type <strong>" . $query['process']['post_type'] . "</strong> was found."
371
- )
372
- );
373
 
374
  }else{
375
  $return['why'] = "Post of post_type <strong>" . $query['process']['post_type'] . "</strong> was found, but the highest score was found within the post_type <strong>" . get_post_type($return['id']) . "</strong>";
@@ -382,32 +562,58 @@ function wp404arsp_search($query){
382
 
383
  }
384
 
385
- function wp404arsp_redirect($args){
386
- $settings = wp404arsp_get_settings();
387
- $method = $settings['method'];
388
- $fallback = $settings['fallback']['type'] != 'disabled' ? $settings['fallback']['url'] : false;
389
 
390
- if( is_user_logged_in() && current_user_can('manage_options') && ($settings['debug'] || (isset($args['preview']) && $args['preview'])) )
391
  return wp404arsp_debug($args);
392
-
393
- if(isset($args['url']) && !empty($args['url'])){
394
- wp_redirect($args['url'], $method);
395
- exit;
396
- }
397
 
398
- if($fallback){
399
- wp_redirect($fallback, $method);
400
- exit;
401
- }
402
-
403
  return;
404
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  }
406
 
407
  function wp404arsp_debug($args){
408
  $settings = wp404arsp_get_settings();
409
  $method = $settings['method'];
410
- $fallback = $settings['fallback']['type'] != 'disabled' ? $settings['fallback']['url'] : false;
411
 
412
  $title = '';
413
  if(isset($args['url']) && !empty($args['url'])){
@@ -443,16 +649,19 @@ Details: <?php echo $args['why']; ?></pre>
443
  <pre><?php print_r($args); ?></pre>
444
  </div>
445
 
446
- <?php echo ob_get_clean(); exit;
 
 
447
  }
448
 
449
  function wp404arsp_search_sql($args = array()){
450
  global $wpdb;
451
- $settings = wp404arsp_get_settings();
452
- $args = wp_parse_args($args, array(
453
- 'keywords' => null,
454
- 'mode' => null,
455
- 'post_type' => null,
 
456
  ));
457
 
458
  if(empty($args['mode']) || !empty($args['post_type'])){
@@ -463,16 +672,26 @@ function wp404arsp_search_sql($args = array()){
463
  if(INSTR(LCASE(p.post_name), '" . $k . "'), 1, 0) + ";
464
  }
465
 
466
- $sql .= "0 as score FROM " . $wpdb->posts . " AS p
467
- WHERE p.post_status = 'publish' AND ";
468
-
 
 
 
 
 
 
 
 
 
 
469
  if(!empty($args['post_type'])){
470
  $sql .= "
471
  p.post_type = '" . $args['post_type'] . "'";
472
 
473
  }else{
474
 
475
- if( ($get_post_types = wp404arsp_get_post_types('names')) && !empty($get_post_types) ){
476
  foreach($get_post_types as $pt){
477
  $post_types[] = "
478
  p.post_type = '" . $pt . "'";
@@ -495,26 +714,50 @@ function wp404arsp_search_sql($args = array()){
495
  }
496
 
497
  $sql .= "
498
- 0 as score FROM " . $wpdb->terms . " AS t ORDER BY score DESC LIMIT 1";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
 
500
  }
501
 
502
  return array(
503
- 'result' => $wpdb->get_row($sql, 'ARRAY_A'),
504
- 'dump' => $sql
505
- );
506
  }
507
 
508
- function wp404arsp_ajax_test() {
509
- if( !defined('DOING_AJAX') || !DOING_AJAX || !isset($_POST['action']) || !current_user_can('manage_options') )
 
510
  return;
511
 
512
  $request = $_POST['request'];
513
  wp404arsp_request($request, true);
514
- die();
515
-
516
  }
517
- add_action('wp_ajax_wp404arsp_ajax_test', 'wp404arsp_ajax_test');
518
 
519
  function wp404arsp_sanitize($input){
520
  return sanitize_title(str_replace(array('_', '/'), '-', $input));
@@ -522,47 +765,52 @@ function wp404arsp_sanitize($input){
522
 
523
  function wp404arsp_get_settings(){
524
  $option = get_option('wp404arsp_settings');
525
- $return = wp404arsp_wp_parse_args_recursive($option,
526
- array(
527
- 'debug' => null,
528
- 'logs' => null,
529
- 'fallback' => array(
530
- 'type' => 'home',
531
- 'url' => home_url(),
532
- 'home_url' => home_url(),
533
- ),
534
- 'rules' => array(
535
- 'redirection' => array(
536
- 'exclude' => array(
537
- 'post_types' => array(),
538
- ),
539
- ),
540
- ),
541
- 'method' => 301
542
- )
543
- );
 
 
 
 
544
 
545
  if($return['fallback']['type'] == 'home')
546
  $return['fallback']['url'] = home_url();
547
 
548
- if(((int)$return['method'] !== 301) || ((int)$return['method'] !== 302))
549
  $return['method'] = 301;
550
 
551
- return $return;
552
-
553
  }
554
 
555
  function wp404arsp_wp_parse_args_recursive(&$a, $b){
556
  $a = (array) $a;
557
  $b = (array) $b;
558
  $result = $b;
559
- foreach ( $a as $k => &$v ) {
560
- if ( is_array( $v ) && isset( $result[ $k ] ) ) {
561
- $result[ $k ] = wp404arsp_wp_parse_args_recursive( $v, $result[ $k ] );
562
- } else {
563
- $result[ $k ] = $v;
 
564
  }
565
  }
 
566
  return $result;
567
  }
568
 
@@ -590,6 +838,30 @@ function wp404arsp_get_post_types($type = 'names'){
590
  return $filtered_post_types;
591
  }
592
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
593
  function wp404arsp_remove_stop_words($input){
594
  $words = array('a', 'about', 'above', 'after', 'again', 'against', 'all', 'am', 'an', 'and', 'any', 'are', 'arent', 'as', 'at', 'be', 'because', 'been', 'before', 'being', 'below', 'between', 'both', 'but', 'by', 'cant', 'cannot', 'could', 'couldnt', 'did', 'didnt', 'do', 'does', 'doesnt', 'doing', 'dont', 'down', 'during', 'each', 'few', 'for', 'from', 'further', 'had', 'hadnt', 'has', 'hasnt', 'have', 'havent', 'having', 'he', 'hed', 'hell', 'hes', 'her', 'here', 'heres', 'hers', 'herself', 'him', 'himself', 'his', 'how', 'hows', 'i', 'id', 'ill', 'im', 'ive', 'if', 'in', 'into', 'is', 'isnt', 'it', 'its', 'itself', 'lets', 'me', 'more', 'most', 'mustnt', 'my', 'myself', 'no', 'nor', 'not', 'of', 'off', 'on', 'once', 'only', 'or', 'other', 'ought', 'our', 'ours', 'ourselves', 'out', 'over', 'own', 'same', 'shant', 'she', 'shed', 'shell', 'shes', 'should', 'shouldnt', 'so', 'some', 'such', 'than', 'that', 'thats', 'the', 'their', 'theirs', 'them', 'themselves', 'then', 'there', 'theres', 'these', 'they', 'theyd', 'theyll', 'theyre', 'theyve', 'this', 'those', 'to', 'too', 'under', 'until', 'up', 'very', 'was', 'wasnt', 'we', 'wed', 'well', 'were', 'weve', 'werent', 'what', 'whats', 'when', 'whens', 'where', 'wheres', 'which', 'while', 'who', 'whos', 'whom', 'why', 'whys', 'with', 'wont', 'would', 'wouldnt', 'you', 'youd', 'youll', 'youre', 'youve', 'your', 'yours', 'category', 'page', 'paged');
595
 
3
  * Plugin Name: WP 404 Auto Redirect to Similar Post
4
  * Description: Automatically Redirect any 404 to a Similar Post based on the Title, Post Type, Category & Taxonomy using 301 Redirects!
5
  * Author: hwk-fr
6
+ * Version: 0.9
7
  * Author URI: http://hwk.fr
8
  */
9
 
35
  ?>
36
  <div class="wrap" id="wp404arsp_settings">
37
  <h1 class="wp-heading-inline">WP 404 Auto Redirect to Similar Post</h1>
38
+ <hr class="wp-header-end" />
39
+
40
+ <h2 class="nav-tab-wrapper">
41
+ <a href="#settings" class="nav-tab nav-tab-active"><?php _e('Settings', 'wp404-auto-redirect'); ?></a>
42
+ <a href="#post-types" class="nav-tab"><?php _e('Post Types', 'wp404-auto-redirect'); ?></a>
43
+ <a href="#taxonomies" class="nav-tab"><?php _e('Taxonomies', 'wp404-auto-redirect'); ?></a>
44
+ <a href="#preview" class="nav-tab"><?php _e('Preview', 'wp404-auto-redirect'); ?></a>
45
+ </h2>
46
 
47
  <div id="poststuff">
48
  <div id="post-body" class="metabox-holder columns-2">
 
49
  <div id="post-body-content">
50
+
51
+ <form method="post" action="options.php">
52
+ <?php
53
+ settings_fields('wp404arsp_settings');
54
+ do_settings_sections('wp404arsp_settings');
55
+ $settings = wp404arsp_get_settings();
56
+ ?>
57
+
58
+ <div class="meta-box-sortables ui-sortable">
59
+
60
+ <!-- Tab: Settings -->
61
+ <div class="nav-tab-panel" id="settings">
62
+
63
+ <div class="postbox">
64
+ <div class="inside">
65
+ <table class="form-table">
66
+ <tbody>
67
+
68
+ <tr>
69
+ <th scope="row"><?php _e('Debug Mode', 'wp404-auto-redirect'); ?></th>
70
+ <td>
71
+ <fieldset>
72
+ <legend class="screen-reader-text"><span><?php _e('Debug Mode', 'wp404-auto-redirect'); ?></span></legend>
73
+ <label for="wp404arsp_settings_debug">
74
+ <input
75
+ name="wp404arsp_settings[debug]"
76
+ id="wp404arsp_settings_debug"
77
+ value="1"
78
+ type="checkbox"
79
+ <?php checked(1, $settings['debug'], true); ?>
80
+ />
81
+ <?php _e('Enable', 'wp404-auto-redirect'); ?>
82
+ </label>
83
+ </fieldset>
84
+ <p class="description"><?php _e('Display the Debug Console instead of being redirected. <code>Administrators</code> only.', 'wp404-auto-redirect'); ?></p>
85
+ </td>
86
+ </tr>
87
+
88
+ <tr>
89
+ <th scope="row"><?php _e('Fallback Behavior', 'wp404-auto-redirect'); ?></th>
90
+ <td>
91
+ <fieldset>
92
+ <legend class="screen-reader-text"><span><?php _e('Fallback Behavior', 'wp404-auto-redirect'); ?></span></legend>
93
+ <label for="wp404arsp_settings_fallback_type">
94
+ <select name="wp404arsp_settings[fallback][type]" id="wp404arsp_settings_fallback_type">
95
+ <option value="home" <?php if($settings['fallback']['type'] == 'home') echo "selected"; ?>><?php _e('Redirect to Homepage', 'wp404-auto-redirect'); ?></option>
96
+ <option value="custom" <?php if($settings['fallback']['type'] == 'custom') echo "selected"; ?>><?php _e('Custom Redirection', 'wp404-auto-redirect'); ?></option>
97
+ <option value="disabled" <?php if($settings['fallback']['type'] == 'disabled') echo "selected"; ?>><?php _e('Default 404', 'wp404-auto-redirect'); ?></option>
98
+ </select>
99
+ </label>
100
+
101
+ <?php
102
+ $fallback = array(
103
+ 'value' => home_url(),
104
+ 'class' => 'disabled',
105
+ 'attr' => 'readonly="readonly"',
106
+ );
107
+
108
+ if($settings['fallback']['type'] == 'custom'){
109
+ $fallback['value'] = $settings['fallback']['url'];
110
+ $fallback['attr'] = '';
111
+ $fallback['class'] = '';
112
+ }
113
+
114
+ if($settings['fallback']['type'] == 'disabled'){
115
+ $fallback['value'] = '';
116
+ $fallback['attr'] = '';
117
+ $fallback['class'] = 'hidden';
118
+ }
119
+ ?>
120
+
121
+ <input name="wp404arsp_settings[fallback][home_url]" id="wp404arsp_settings_fallback_home_url" type="hidden" value="<?php echo home_url(); ?>" />
122
+ <input name="wp404arsp_settings[fallback][url]" id="wp404arsp_settings_fallback_url" type="text" value="<?php echo $fallback['value']; ?>" class="<?php echo $fallback['class']; ?>" <?php echo $fallback['attr']; ?> />
123
+
124
+ </fieldset>
125
+ <p class="description"><?php _e('If nothing similar is found, this behavior will be applied.', 'wp404-auto-redirect'); ?></p>
126
+ </td>
127
+ </tr>
128
+
129
+ <tr>
130
+ <th scope="row"><?php _e('Redirect Headers', 'wp404-auto-redirect'); ?></th>
131
+ <td>
132
+ <fieldset>
133
+ <legend class="screen-reader-text"><span><?php _e('Redirect Headers', 'wp404-auto-redirect'); ?></span></legend>
134
+ <label for="wp404arsp_settings_method">
135
+ <select name="wp404arsp_settings[method]" id="wp404arsp_settings_method">
136
+ <option value="301" <?php if($settings['method'] == 301) echo "selected"; ?>>301 method</option>
137
+ <option value="302" <?php if($settings['method'] == 302) echo "selected"; ?>>302 method</option>
138
+ </select>
139
+ </label>
140
+ </fieldset>
141
+ <p class="description"><?php _e('Learn more about <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes" target="_blank">HTTP headers & redirections</a>.', 'wp404-auto-redirect'); ?></p>
142
+ </td>
143
+ </tr>
144
+
145
+ <tr>
146
+ <th scope="row"><?php _e('Plugin Priority', 'wp404-auto-redirect'); ?></th>
147
+ <td>
148
+ <fieldset>
149
+ <legend class="screen-reader-text"><span><?php _e('Plugin Priority', 'wp404-auto-redirect'); ?></span></legend>
150
+ <label for="wp404arsp_settings_priority">
151
+ <input
152
+ type="number"
153
+ name="wp404arsp_settings[priority]"
154
+ id="wp404arsp_settings_priority"
155
+ value="<?php echo isset($settings['priority']) ? $settings['priority'] : '999'; ?>"
156
+ required
157
+ />
158
+ </label>
159
+ </fieldset>
160
+ <p class="description"><?php _e('Advanced users only. Default: <code>999</code>', 'wp404-auto-redirect'); ?></p>
161
+ </td>
162
+ </tr>
163
+
164
+ </tbody>
165
+ </table>
166
+
167
+ </div>
168
+ </div>
169
+ </div>
170
+
171
+ <!-- Tab: Post Types -->
172
+ <div class="nav-tab-panel" id="post-types">
173
+
174
+ <div class="postbox">
175
+ <div class="inside">
176
+ <table class="form-table">
177
+ <tbody>
178
+
179
+ <tr>
180
+ <th scope="row"><?php _e('Exclude Post Meta', 'wp404-auto-redirect'); ?></th>
181
+ <td>
182
+ <fieldset>
183
+ <legend class="screen-reader-text"><span><?php _e('Exclude Post Meta', 'wp404-auto-redirect'); ?></span></legend>
184
+ <label for="wp404arsp_settings_rules_redirection_exclude_post_meta">
185
+ <input
186
+ name="wp404arsp_settings[rules][redirection][exclude][post_meta]"
187
+ id="wp404arsp_settings_rules_redirection_exclude_post_meta"
188
+ type="checkbox"
189
+ value="1"
190
+ <?php checked(1, $settings['rules']['redirection']['exclude']['post_meta'], true); ?>
191
+ />
192
+ <?php _e('Enable', 'wp404-auto-redirect'); ?>
193
+ </label>
194
+ </fieldset>
195
+ <p class="description"><?php _e('Exclude posts with the post meta: <code>wp404arsp_no_redirect = 1</code> from possible redirections.', 'wp404-auto-redirect'); ?></p>
196
+ </td>
197
+ </tr>
198
+
199
+ <tr>
200
+ <th scope="row"><?php _e('Exclude Post Type(s)', 'wp404-auto-redirect'); ?></th>
201
+ <td>
202
+ <fieldset>
203
+ <legend class="screen-reader-text"><span><?php _e('Exclude Post Type(s)', 'wp404-auto-redirect'); ?></span></legend>
204
+ <div id="wp404arsp_settings_rules_redirection_exclude_post_types">
205
+ <?php foreach(get_post_types(array('public' => true), 'objects') as $post_type) { ?>
206
+ <?php
207
+ $checked = '';
208
+ if(
209
+ isset($settings['rules']['redirection']['exclude']['post_types']) &&
210
+ is_array($settings['rules']['redirection']['exclude']['post_types']) &&
211
+ in_array($post_type->name, $settings['rules']['redirection']['exclude']['post_types'])
212
+ )
213
+ $checked = 'checked="checked"'; ?>
214
+ <div><input type="checkbox" name="wp404arsp_settings[rules][redirection][exclude][post_types][]" id="wp404arsp_settings_rules_redirection_exclude_post_types_<?php echo $post_type->name; ?>" value="<?php echo $post_type->name; ?>" <?php echo $checked; ?> />
215
+ <label for="wp404arsp_settings_rules_redirection_exclude_post_types_<?php echo $post_type->name; ?>"><?php echo $post_type->label; ?></label></div>
216
+ <?php } ?>
217
+ </div>
218
+ </fieldset>
219
+ <p class="description"><?php _e('Exclude one or multiple post types from possible redirections.', 'wp404-auto-redirect'); ?></p>
220
+ </td>
221
+ </tr>
222
+
223
+ </tbody>
224
+ </table>
225
+ </div>
226
+ </div>
227
+
228
+ </div>
229
+
230
+ <!-- Tab: Taxonomies -->
231
+ <div class="nav-tab-panel" id="taxonomies">
232
+
233
+ <div class="postbox">
234
+ <div class="inside">
235
+ <table class="form-table">
236
+ <tbody>
237
+
238
+ <tr>
239
+ <th scope="row"><?php _e('Disable Taxonomy Redirection', 'wp404-auto-redirect'); ?></th>
240
+ <td>
241
+ <fieldset>
242
+ <legend class="screen-reader-text"><span><?php _e('Disable Taxonomy Redirection', 'wp404-auto-redirect'); ?></span></legend>
243
+ <label for="wp404arsp_settings_rules_redirection_disable_taxonomies">
244
+ <input
245
+ name="wp404arsp_settings[rules][redirection][disable][taxonomies]"
246
+ id="wp404arsp_settings_rules_redirection_disable_taxonomies"
247
+ type="checkbox"
248
+ value="1"
249
+ <?php checked(1, $settings['rules']['redirection']['disable']['taxonomies'], true); ?>
250
+ />
251
+ <?php _e('Disable', 'wp404-auto-redirect'); ?>
252
+ </label>
253
+ </fieldset>
254
+ <p class="description"><?php _e('Never redirect to terms archives.', 'wp404-auto-redirect'); ?></p>
255
+ </td>
256
+ </tr>
257
+
258
+ <tr class="wp404arsp_settings_taxonomies">
259
+ <th scope="row"><?php _e('Exclude Term Meta', 'wp404-auto-redirect'); ?></th>
260
+ <td>
261
+ <fieldset>
262
+ <legend class="screen-reader-text"><span><?php _e('Exclude Term Meta', 'wp404-auto-redirect'); ?></span></legend>
263
+ <label for="wp404arsp_settings_rules_redirection_exclude_term_meta">
264
+ <input
265
+ name="wp404arsp_settings[rules][redirection][exclude][term_meta]"
266
+ id="wp404arsp_settings_rules_redirection_exclude_term_meta"
267
+ type="checkbox"
268
+ value="1"
269
+ <?php checked(1, $settings['rules']['redirection']['exclude']['term_meta'], true); ?>
270
+ />
271
+ <?php _e('Enable', 'wp404-auto-redirect'); ?>
272
+ </label>
273
+ </fieldset>
274
+ <p class="description"><?php _e('Exclude terms with the term meta: <code>wp404arsp_no_redirect = 1</code> from possible redirections.', 'wp404-auto-redirect'); ?></p>
275
+ </td>
276
+ </tr>
277
+
278
+ <tr class="wp404arsp_settings_taxonomies">
279
+ <th scope="row"><?php _e('Exclude Taxonomie(s)', 'wp404-auto-redirect'); ?></th>
280
+ <td>
281
+ <fieldset>
282
+ <legend class="screen-reader-text"><span><?php _e('Exclude Taxonomie(s)', 'wp404-auto-redirect'); ?></span></legend>
283
+ <div id="wp404arsp_settings_rules_redirection_exclude_taxonomies">
284
+ <?php foreach(get_taxonomies(array('public' => true), 'objects') as $taxonomy) { ?>
285
+ <?php
286
+ $checked = '';
287
+ if(
288
+ isset($settings['rules']['redirection']['exclude']['taxonomies']) &&
289
+ is_array($settings['rules']['redirection']['exclude']['taxonomies']) &&
290
+ in_array($taxonomy->name, $settings['rules']['redirection']['exclude']['taxonomies'])
291
+ )
292
+ $checked = 'checked="checked"'; ?>
293
+ <div><input type="checkbox" name="wp404arsp_settings[rules][redirection][exclude][taxonomies][]" id="wp404arsp_settings_rules_redirection_exclude_taxonomies_<?php echo $taxonomy->name; ?>" value="<?php echo $taxonomy->name; ?>" <?php echo $checked; ?> />
294
+ <label for="wp404arsp_settings_rules_redirection_exclude_taxonomies_<?php echo $taxonomy->name; ?>"><?php echo $taxonomy->label; ?></label></div>
295
+ <?php } ?>
296
+ </div>
297
+ </fieldset>
298
+ <p class="description"><?php _e('Exclude one or multiple taxonomies from possible redirections.', 'wp404-auto-redirect'); ?></p>
299
+ </td>
300
+ </tr>
301
+
302
+ </tbody>
303
+ </table>
304
+ </div>
305
+ </div>
306
+
307
+ </div>
308
+
309
+ <!-- Tab: Preview -->
310
+ <div class="nav-tab-panel" id="preview">
311
+
312
+ <div id="wp404arsp_settings_redirection_preview">
313
+ <div class="postbox">
314
+ <div class="inside">
315
+ <table class="form-table">
316
+ <tbody>
317
+
318
+ <tr>
319
+ <th scope="row"><?php echo home_url(); ?></th>
320
+ <td>
321
+ <input class="request" type="text" value="/example-url" />
322
+ <p class="description"><?php _e('Enter the URL you would like to test, starting with <code>/</code>.', 'wp404-auto-redirect'); ?></p>
323
+
324
+ <p class="submit">
325
+ <?php submit_button(__('Preview URL', 'wp404-auto-redirect'), 'secondary', '', false); ?>
326
+ <span class="loading spinner"></span>
327
+ </p>
328
+ </td>
329
+ </tr>
330
+ </tbody>
331
+ </table>
332
+
333
+ <div class="results"></div>
334
+
335
+ </div>
336
+ </div>
337
+ </div>
338
+
339
+ </div>
340
+
341
+ </div>
342
+
343
+ <div class="postbox">
344
+ <div class="inside">
345
+ <p class="submit">
346
+ <?php submit_button(__('Save Settings', 'wp404-auto-redirect'), 'primary', '', false); ?>
347
+ </p>
348
+ </div>
349
+ </div>
350
+
351
+ </form>
352
 
353
  </div>
354
 
359
  <div class="inside">
360
  <img src="<?php echo plugins_url('assets/logo.png', __FILE__); ?>" class="logo" />
361
 
362
+ <p><?php _e('Found a bug? Need help? Head over the <a href="https://wordpress.org/plugins/wp-404-auto-redirect-to-similar-post/" target="_blank">official plugin page</a>.', 'wp404-auto-redirect'); ?></p>
363
 
364
  <hr />
365
 
366
+ <p><?php _e('Enjoying this plugin? Please rate it. It\'s always much appreciated!', 'wp404-auto-redirect'); ?></p>
367
  <p>
368
+ <a href="https://wordpress.org/support/plugin/wp-404-auto-redirect-to-similar-post/reviews/#new-post" target="_blank" class="button"><?php _e('Rate the plugin', 'wp404-auto-redirect'); ?></a>
369
  </p>
370
  </div>
371
 
380
  </div>
381
  <?php }
382
 
383
+ $wp404arsp_settings = get_option('wp404arsp_settings');
384
+ $wp404arsp_priority = isset($wp404arsp_settings['priority']) ? $wp404arsp_settings['priority'] : 999;
385
+
386
+ add_action('template_redirect', 'wp404arsp_init', $wp404arsp_priority);
387
  function wp404arsp_init(){
388
+ if(!is_404())
389
+ return;
390
+
391
+ if(wp_doing_ajax())
392
+ return;
393
+
394
+ if(is_admin())
395
+ return;
396
+
397
+ if(!isset($_SERVER['REQUEST_URI']) || empty($_SERVER['REQUEST_URI']))
398
+ return;
399
+
400
+ if(isset($_SERVER['SCRIPT_URI']) && !empty($_SERVER['SCRIPT_URI']) && $_SERVER['SCRIPT_URI'] == admin_url('admin-ajax.php'))
401
+ return;
402
+
403
+ if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
404
+ return;
405
 
406
+
407
  wp404arsp_request($_SERVER['REQUEST_URI']);
408
  }
409
 
410
  function wp404arsp_request($request, $preview = false){
411
 
412
+ $query = array();
413
+ $query['request']['full'] = urldecode(htmlspecialchars($request));
414
+ $query['preview'] = $preview;
 
 
415
 
416
  if(preg_match('#/(?<slug>page|paged)/(?<page>[0-9]+)/?$#i', $request, $pagination)){
417
  $request_no_pagination = str_replace($pagination[0], '', $request);
434
 
435
  // Pagination found, try the URL without pagination
436
  if(!empty($query['request']['pagination']))
437
+ return wp404arsp_redirect(
438
+ array_merge($query, array(
439
+ 'url' => home_url() . $request_no_pagination,
440
+ 'why' => "Pagination found in the requested URL. Trying to reach same URL without pagination."
441
+ ))
442
+ );
443
 
444
  wp404arsp_setup($query);
445
 
446
  }
447
 
448
  function wp404arsp_setup($query){
 
449
  if(!isset($query['request']['full']) || empty($query['request']['full']))
450
  return;
451
+
452
+ $settings = wp404arsp_get_settings();
453
  $query['process']['request'] = $query['request']['full'];
454
 
455
  global $wp_query;
476
  $query['process']['keywords']['explode'][] = $keyword;
477
  }
478
  $query['process']['keywords']['explode'] = array_reverse($query['process']['keywords']['explode']);
479
+
480
+ $args = wp404arsp_search($query, $settings);
481
+ return wp404arsp_redirect($args, $settings);
482
  }
483
 
484
+ function wp404arsp_search($query, $settings){
485
+
486
  // Direct
487
+ if(($get_post_types = wp404arsp_get_post_types('names')) && !empty($get_post_types)){
488
  foreach($get_post_types as $post_type){
489
+ if(!$post = get_page_by_path($query['process']['keywords']['explode'][0], 'object', $post_type))
490
+ continue;
491
+
492
+ if(get_post_status($post->ID) != 'publish')
493
+ break;
494
+
495
+ if($settings['rules']['redirection']['exclude']['post_meta'] && get_post_meta($post->ID, 'wp404arsp_no_redirect', true) == '1')
496
+ break;
497
+
498
+ return array_merge($query, array(
499
+ 'score' => 'direct',
500
+ 'id' => (int)$post->ID,
501
+ 'url' => get_permalink((int)$post->ID),
502
+ 'why' => "Part of the requested URL already exist as post of the post_type <strong>" . get_post_type((int)$post->ID) . "</strong>"
503
+ ));
504
+
505
  }
506
  }
507
 
511
 
512
  // Term
513
  if(empty($sql['result']) || $sql['result']['score'] < 1){
514
+ if($settings['rules']['redirection']['disable']['taxonomies'])
515
+ return array_merge($query, array(
516
+ 'why' => "Nothing similar found matching the requested URL."
517
+ ));
518
+
519
  $sql = wp404arsp_search_sql(array('keywords' => $keywords, 'mode' => 'term'));
520
 
521
  if(empty($sql['result']) || $sql['result']['score'] < 1)
522
+ return array_merge($query, array(
523
+ 'why' => "Nothing similar found matching the requested URL."
524
+ ));
 
525
 
526
+ return array_merge($query, array(
527
+ 'score' => $sql['result']['score'],
528
+ 'id' => (int)$sql['result']['term_id'],
529
+ 'url' => get_term_link((int)$sql['result']['term_id']),
530
+ 'why' => "No similar post found, but a similar <strong>term</strong> was found."
531
+ ));
 
532
  }
533
 
534
  // Post
535
+ $return = array_merge($query, array(
536
+ 'score' => $sql['result']['score'],
537
+ 'id' => (int)$sql['result']['ID'],
538
+ 'url' => get_permalink((int)$sql['result']['ID']),
539
+ 'why' => "Similar post of post_type <strong>" . get_post_type((int)$sql['result']['ID']) . "</strong> was found."
540
+ ));
 
541
 
542
  // Post: If Post Type found, check other post types & compare score
543
  if(isset($query['process']['post_type']) && !empty($query['process']['post_type'])){
544
 
545
  $sql = wp404arsp_search_sql(array('keywords' => $keywords, 'post_type' => $query['process']['post_type']));
546
  if(!empty($sql['result']) && $sql['result']['score'] >= 1 && $sql['result']['score'] >= $return['score']){
547
+ $return = array_merge($query, array(
548
+ 'score' => $sql['result']['score'],
549
+ 'id' => (int)$sql['result']['ID'],
550
+ 'url' => get_permalink((int)$sql['result']['ID']),
551
+ 'why' => "Similar post of post_type <strong>" . $query['process']['post_type'] . "</strong> was found."
552
+ ));
 
553
 
554
  }else{
555
  $return['why'] = "Post of post_type <strong>" . $query['process']['post_type'] . "</strong> was found, but the highest score was found within the post_type <strong>" . get_post_type($return['id']) . "</strong>";
562
 
563
  }
564
 
565
+ function wp404arsp_redirect($args, $settings){
566
+ $args = apply_filters('wp404arsp/redirect', $args, $settings);
 
 
567
 
568
+ if(is_user_logged_in() && current_user_can('administrator') && ($settings['debug'] || (isset($args['preview']) && $args['preview'])))
569
  return wp404arsp_debug($args);
 
 
 
 
 
570
 
571
+ wp404arsp_redirect_to($args, $settings);
572
+
 
 
 
573
  return;
574
+ }
575
+
576
+ function wp404arsp_redirect_to($args, $settings){
577
+ // Copy/paste from legacy WP_Redirect function()
578
+ // File: wp-includes/pluggable.php
579
+ // Added: WP404ARSP header & exit;
580
+
581
+ global $is_IIS;
582
+
583
+ $status = $settings['method'];
584
+ $fallback = $settings['fallback']['type'] != 'disabled' ? $settings['fallback']['url'] : false;
585
+
586
+ if((!isset($args['url']) || empty($args['url'])) && !$fallback)
587
+ return;
588
+
589
+ $location = $fallback;
590
+
591
+ if(isset($args['url']) && !empty($args['url']))
592
+ $location = $args['url'];
593
+
594
+ $location = apply_filters('wp_redirect', $location, $status);
595
+ $status = apply_filters('wp_redirect_status', $status, $location);
596
+
597
+ if(!$location)
598
+ return false;
599
+
600
+ $location = wp_sanitize_redirect($location);
601
+
602
+ if(!$is_IIS && PHP_SAPI != 'cgi-fcgi')
603
+ status_header($status);
604
+
605
+ header("Location: $location", true, $status);
606
+ header('WP-404-Auto-Redirect: true');
607
+
608
+ do_action('wp404arsp/after_redirect', $args, $settings);
609
+
610
+ exit;
611
  }
612
 
613
  function wp404arsp_debug($args){
614
  $settings = wp404arsp_get_settings();
615
  $method = $settings['method'];
616
+ $fallback = $settings['fallback']['type'] != 'disabled' ? $settings['fallback']['url'] : false;
617
 
618
  $title = '';
619
  if(isset($args['url']) && !empty($args['url'])){
649
  <pre><?php print_r($args); ?></pre>
650
  </div>
651
 
652
+ <?php
653
+ echo ob_get_clean();
654
+ exit;
655
  }
656
 
657
  function wp404arsp_search_sql($args = array()){
658
  global $wpdb;
659
+
660
+ $settings = wp404arsp_get_settings();
661
+ $args = wp_parse_args($args, array(
662
+ 'keywords' => null,
663
+ 'mode' => null,
664
+ 'post_type' => null,
665
  ));
666
 
667
  if(empty($args['mode']) || !empty($args['post_type'])){
672
  if(INSTR(LCASE(p.post_name), '" . $k . "'), 1, 0) + ";
673
  }
674
 
675
+ $sql .= "0 AS score FROM " . $wpdb->posts . " AS p";
676
+
677
+ if($settings['rules']['redirection']['exclude']['post_meta']){
678
+ $sql .= "
679
+ INNER JOIN " . $wpdb->postmeta . " AS pm ON(p.ID = pm.post_id)
680
+ WHERE p.post_status = 'publish' AND (pm.meta_key = 'wp404arsp_no_redirect' AND pm.meta_value != '1') AND ";
681
+
682
+ }else{
683
+ $sql .= "
684
+ WHERE p.post_status = 'publish' AND ";
685
+
686
+ }
687
+
688
  if(!empty($args['post_type'])){
689
  $sql .= "
690
  p.post_type = '" . $args['post_type'] . "'";
691
 
692
  }else{
693
 
694
+ if(($get_post_types = wp404arsp_get_post_types('names')) && !empty($get_post_types)){
695
  foreach($get_post_types as $pt){
696
  $post_types[] = "
697
  p.post_type = '" . $pt . "'";
714
  }
715
 
716
  $sql .= "
717
+ 0 AS score FROM " . $wpdb->terms . " AS t";
718
+
719
+ $sql .= "
720
+ INNER JOIN " . $wpdb->term_taxonomy . " AS tt ON(t.term_id = tt.term_id)";
721
+
722
+ if($settings['rules']['redirection']['exclude']['term_meta']){
723
+ $sql .= "
724
+ INNER JOIN " . $wpdb->termmeta . " AS tm ON(t.term_id = tm.term_id)";
725
+ }
726
+
727
+ if(($get_taxonomies = wp404arsp_get_taxonomies('names')) && !empty($get_taxonomies)){
728
+ foreach($get_taxonomies as $tax){
729
+ $taxonomies[] = "
730
+ tt.taxonomy = '" . $tax . "'";
731
+ }
732
+ $sql .= '
733
+ WHERE (' . implode(' OR ', $taxonomies) . ')';
734
+
735
+ if($settings['rules']['redirection']['exclude']['term_meta']){
736
+ $sql .= "
737
+ AND (tm.meta_key = 'wp404arsp_no_redirect' AND tm.meta_value != '1')";
738
+ }
739
+ }
740
+
741
+ $sql .= "
742
+ ORDER BY score DESC LIMIT 1";
743
 
744
  }
745
 
746
  return array(
747
+ 'result' => $wpdb->get_row($sql, 'ARRAY_A'),
748
+ 'dump' => $sql
749
+ );
750
  }
751
 
752
+ add_action('wp_ajax_wp404arsp_ajax_preview', 'wp404arsp_ajax_preview');
753
+ function wp404arsp_ajax_preview() {
754
+ if(!current_user_can('administrator'))
755
  return;
756
 
757
  $request = $_POST['request'];
758
  wp404arsp_request($request, true);
759
+ wp_die();
 
760
  }
 
761
 
762
  function wp404arsp_sanitize($input){
763
  return sanitize_title(str_replace(array('_', '/'), '-', $input));
765
 
766
  function wp404arsp_get_settings(){
767
  $option = get_option('wp404arsp_settings');
768
+ $return = wp404arsp_wp_parse_args_recursive($option, array(
769
+ 'debug' => null,
770
+ 'logs' => null,
771
+ 'method' => 301,
772
+ 'fallback' => array(
773
+ 'type' => 'home',
774
+ 'url' => home_url(),
775
+ 'home_url' => home_url(),
776
+ ),
777
+ 'rules' => array(
778
+ 'redirection' => array(
779
+ 'exclude' => array(
780
+ 'post_types' => array(),
781
+ 'post_meta' => null,
782
+ 'taxonomies' => array(),
783
+ 'term_meta' => null,
784
+ ),
785
+ 'disable' => array(
786
+ 'taxonomies' => null
787
+ )
788
+ ),
789
+ )
790
+ ));
791
 
792
  if($return['fallback']['type'] == 'home')
793
  $return['fallback']['url'] = home_url();
794
 
795
+ if(((int)$return['method'] != 301) && ((int)$return['method'] != 302))
796
  $return['method'] = 301;
797
 
798
+ return apply_filters('wp404arsp/settings', $return);
 
799
  }
800
 
801
  function wp404arsp_wp_parse_args_recursive(&$a, $b){
802
  $a = (array) $a;
803
  $b = (array) $b;
804
  $result = $b;
805
+
806
+ foreach($a as $k => &$v){
807
+ if(is_array($v) && isset($result[$k])){
808
+ $result[$k] = wp404arsp_wp_parse_args_recursive($v, $result[$k]);
809
+ }else{
810
+ $result[$k] = $v;
811
  }
812
  }
813
+
814
  return $result;
815
  }
816
 
838
  return $filtered_post_types;
839
  }
840
 
841
+ function wp404arsp_get_taxonomies($type = 'names'){
842
+ $settings = wp404arsp_get_settings();
843
+ $get_taxonomies = get_taxonomies(array('public' => true), $type);
844
+
845
+ // No exclude
846
+ if( !isset($settings['rules']['redirection']['exclude']['taxonomies']) || !is_array($settings['rules']['redirection']['exclude']['taxonomies']) || empty($settings['rules']['redirection']['exclude']['taxonomies']) )
847
+ return $get_taxonomies;
848
+
849
+ // Exclude
850
+ $filtered_taxonomies = array();
851
+ foreach($get_taxonomies as $taxonomy){
852
+ $search = $taxonomy;
853
+ if($type == 'objects')
854
+ $search = $taxonomy->name;
855
+
856
+ if(in_array($search, $settings['rules']['redirection']['exclude']['taxonomies']))
857
+ continue;
858
+
859
+ $filtered_taxonomies[] = $search;
860
+ }
861
+
862
+ return $filtered_taxonomies;
863
+ }
864
+
865
  function wp404arsp_remove_stop_words($input){
866
  $words = array('a', 'about', 'above', 'after', 'again', 'against', 'all', 'am', 'an', 'and', 'any', 'are', 'arent', 'as', 'at', 'be', 'because', 'been', 'before', 'being', 'below', 'between', 'both', 'but', 'by', 'cant', 'cannot', 'could', 'couldnt', 'did', 'didnt', 'do', 'does', 'doesnt', 'doing', 'dont', 'down', 'during', 'each', 'few', 'for', 'from', 'further', 'had', 'hadnt', 'has', 'hasnt', 'have', 'havent', 'having', 'he', 'hed', 'hell', 'hes', 'her', 'here', 'heres', 'hers', 'herself', 'him', 'himself', 'his', 'how', 'hows', 'i', 'id', 'ill', 'im', 'ive', 'if', 'in', 'into', 'is', 'isnt', 'it', 'its', 'itself', 'lets', 'me', 'more', 'most', 'mustnt', 'my', 'myself', 'no', 'nor', 'not', 'of', 'off', 'on', 'once', 'only', 'or', 'other', 'ought', 'our', 'ours', 'ourselves', 'out', 'over', 'own', 'same', 'shant', 'she', 'shed', 'shell', 'shes', 'should', 'shouldnt', 'so', 'some', 'such', 'than', 'that', 'thats', 'the', 'their', 'theirs', 'them', 'themselves', 'then', 'there', 'theres', 'these', 'they', 'theyd', 'theyll', 'theyre', 'theyve', 'this', 'those', 'to', 'too', 'under', 'until', 'up', 'very', 'was', 'wasnt', 'we', 'wed', 'well', 'were', 'weve', 'werent', 'what', 'whats', 'when', 'whens', 'where', 'wheres', 'which', 'while', 'who', 'whos', 'whom', 'why', 'whys', 'with', 'wont', 'would', 'wouldnt', 'you', 'youd', 'youll', 'youre', 'youve', 'your', 'yours', 'category', 'page', 'paged');
867