Version Description
- Improved direct match algorythm
- Improved sanitization of requests with an extension
- Improved post_type matching to only search "active" post_types
- Re-introduced Term search as fallback (if no similar post found)
Download this release
Release Info
Developer | hwk-fr |
Plugin | WP 404 Auto Redirect to Similar Post |
Version | 0.7.2 |
Comparing to | |
See all releases |
Code changes from version 0.7.1 to 0.7.2
- readme.txt +12 -6
- wp-404-auto-redirect-similar-post.php +118 -72
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: 404, Redirect, 301, Similar
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 4.8.2
|
7 |
-
Stable tag: 0.7.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -14,7 +14,7 @@ Automatically Redirect any 404 to a Similar Post based on the Requested URL Titl
|
|
14 |
|
15 |
Welcome to WP 404 Auto Redirect to Similar Post!
|
16 |
|
17 |
-
This plugin
|
18 |
|
19 |
= Features: =
|
20 |
|
@@ -22,7 +22,7 @@ This plugin will automatically redirect all your 404 to a similar post based on
|
|
22 |
* Automatically detect any 404
|
23 |
* Automatically search a similar post based on the Title, Post Type, Category & Taxonomy
|
24 |
* **NEW** Choose to Redirect to Homepage if no similar post is found
|
25 |
-
* **NEW** Choose the redirection HTTP header
|
26 |
* **NEW** Debug console for administrators
|
27 |
* **NEW** Preview URL directly from the admin panel
|
28 |
|
@@ -46,9 +46,15 @@ This plugin will automatically redirect all your 404 to a similar post based on
|
|
46 |
|
47 |
== Changelog ==
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
= 0.7.1 =
|
50 |
-
*
|
51 |
-
*
|
52 |
* Fixed bug while displaying legacy 404
|
53 |
* Fixed PHP notice on preview mode
|
54 |
|
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.8.2
|
7 |
+
Stable tag: 0.7.2
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
14 |
|
15 |
Welcome to WP 404 Auto Redirect to Similar Post!
|
16 |
|
17 |
+
This plugin automatically redirect all your 404 requests to similar posts based on Title & Post Types. If nothing similar is found, it will redirect to the homepage.
|
18 |
|
19 |
= Features: =
|
20 |
|
22 |
* Automatically detect any 404
|
23 |
* Automatically search a similar post based on the Title, Post Type, Category & Taxonomy
|
24 |
* **NEW** Choose to Redirect to Homepage if no similar post is found
|
25 |
+
* **NEW** Choose the redirection HTTP header status: 301 or 302
|
26 |
* **NEW** Debug console for administrators
|
27 |
* **NEW** Preview URL directly from the admin panel
|
28 |
|
46 |
|
47 |
== Changelog ==
|
48 |
|
49 |
+
= 0.7.2 =
|
50 |
+
* Improved direct match algorythm
|
51 |
+
* Improved sanitization of requests with an extension
|
52 |
+
* Improved post_type matching to only search "active" post_types
|
53 |
+
* Re-introduced Term search as fallback (if no similar post found)
|
54 |
+
|
55 |
= 0.7.1 =
|
56 |
+
* Improved Post Types handle
|
57 |
+
* Improved paged request handle
|
58 |
* Fixed bug while displaying legacy 404
|
59 |
* Fixed PHP notice on preview mode
|
60 |
|
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 |
* Author URI: http://hwk.fr
|
8 |
*/
|
9 |
|
@@ -222,12 +222,12 @@ function wp404arsp_setup($query){
|
|
222 |
$query['process']['request'] = $query['request']['full'];
|
223 |
|
224 |
global $wp_query;
|
225 |
-
$
|
226 |
|
227 |
-
if(isset($
|
228 |
|
229 |
-
$query['process']['post_type'] = $
|
230 |
-
$post_type = get_post_type_object($
|
231 |
if( stripos($query['request']['full'], $post_type->rewrite['slug']) !== false )
|
232 |
$query['process']['request'] = str_replace('//', '/', substr_replace($query['request']['full'], '', stripos($query['request']['full'], $post_type->rewrite['slug']), strlen($post_type->rewrite['slug'])));
|
233 |
|
@@ -239,24 +239,12 @@ function wp404arsp_setup($query){
|
|
239 |
|
240 |
$keywords = explode('/', trim($query['process']['request'], '/'));
|
241 |
foreach($keywords as $keyword){
|
242 |
-
$query['
|
|
|
|
|
|
|
243 |
}
|
244 |
$query['process']['keywords']['explode'] = array_reverse($query['process']['keywords']['explode']);
|
245 |
-
|
246 |
-
|
247 |
-
foreach($query['process']['keywords']['explode'] as $keyword){
|
248 |
-
$get_posts_types = get_post_types(array('public' => true), 'names');
|
249 |
-
foreach($get_posts_types as $post_type){
|
250 |
-
if($post = get_page_by_path($keyword, 'object', $post_type))
|
251 |
-
return wp404arsp_redirect(array_merge( $query, array(
|
252 |
-
'score' => 'direct',
|
253 |
-
'id' => (int)$post->ID,
|
254 |
-
'url' => get_permalink((int)$post->ID),
|
255 |
-
'why' => "The request url already exist as post of the post type " . get_post_type((int)$post->ID)
|
256 |
-
))
|
257 |
-
);
|
258 |
-
}
|
259 |
-
}
|
260 |
|
261 |
return wp404arsp_redirect(wp404arsp_search($query));
|
262 |
|
@@ -264,43 +252,69 @@ function wp404arsp_setup($query){
|
|
264 |
|
265 |
function wp404arsp_search($query){
|
266 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
$keywords = explode('-', $query['process']['keywords']['sanitized']);
|
268 |
-
$
|
269 |
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
|
|
284 |
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
$sql = wp404arsp_search_sql($keywords, $post_type);
|
289 |
-
if(!empty($sql['post']) && $sql['post']['score'] >= 1 && $sql['post']['score'] >= $return['score']){
|
290 |
-
$return = array_merge( $query, array(
|
291 |
-
'score' => $sql['post']['score'],
|
292 |
-
'id' => (int)$sql['post']['ID'],
|
293 |
-
'url' => get_permalink((int)$sql['post']['ID']),
|
294 |
-
'why' => "Highest score based on the requested url was found"
|
295 |
-
)
|
296 |
-
);
|
297 |
|
298 |
-
|
299 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
|
301 |
}
|
302 |
-
|
303 |
-
}
|
304 |
|
305 |
return $return;
|
306 |
|
@@ -331,13 +345,13 @@ function wp404arsp_debug($args){
|
|
331 |
|
332 |
$title = '';
|
333 |
if(isset($args['url']) && !empty($args['url'])){
|
334 |
-
$title = '
|
335 |
|
336 |
}elseif($wp404arsp_settings['home'] == "1"){
|
337 |
$title = 'Redirect to Home disabled. Displaying 404.';
|
338 |
|
339 |
}else{
|
340 |
-
$title = '
|
341 |
|
342 |
}
|
343 |
|
@@ -354,40 +368,72 @@ function wp404arsp_debug($args){
|
|
354 |
<div class="wp404arsp_debug_page">
|
355 |
<?php if(!isset($args['preview'])){ ?>
|
356 |
<h2>WP 404 Auto Redirect to Similar Post</h2>
|
357 |
-
<p>This is the <strong>debug console</strong> of WP 404 Auto redirect to Similar Post Plugin which is only visible to administrators.
|
358 |
<hr />
|
359 |
<?php } ?>
|
360 |
<pre>Requested URL: <a href="<?php echo home_url(); ?><?php echo $args['request']['full']; ?>"><?php echo home_url(); ?><?php echo $args['request']['full']; ?></a><br />
|
361 |
<?php echo $title; ?><br />
|
362 |
-
Details: <?php echo $args['why'];
|
363 |
-
</pre>
|
364 |
<pre><?php print_r($args); ?></pre>
|
365 |
</div>
|
366 |
|
367 |
<?php echo ob_get_clean(); exit;
|
368 |
}
|
369 |
|
370 |
-
function wp404arsp_search_sql($
|
|
|
371 |
global $wpdb;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
372 |
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
382 |
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
|
388 |
return array(
|
389 |
-
'
|
390 |
-
'dump'
|
391 |
);
|
392 |
}
|
393 |
|
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.2
|
7 |
* Author URI: http://hwk.fr
|
8 |
*/
|
9 |
|
222 |
$query['process']['request'] = $query['request']['full'];
|
223 |
|
224 |
global $wp_query;
|
225 |
+
$current_wp_query = $wp_query->query;
|
226 |
|
227 |
+
if(isset($current_wp_query['post_type'])){
|
228 |
|
229 |
+
$query['process']['post_type'] = $current_wp_query['post_type'];
|
230 |
+
$post_type = get_post_type_object($current_wp_query['post_type']);
|
231 |
if( stripos($query['request']['full'], $post_type->rewrite['slug']) !== false )
|
232 |
$query['process']['request'] = str_replace('//', '/', substr_replace($query['request']['full'], '', stripos($query['request']['full'], $post_type->rewrite['slug']), strlen($post_type->rewrite['slug'])));
|
233 |
|
239 |
|
240 |
$keywords = explode('/', trim($query['process']['request'], '/'));
|
241 |
foreach($keywords as $keyword){
|
242 |
+
if(isset($query['request']['extension']) && !empty($query['request']['extension']))
|
243 |
+
$keyword = str_replace('.' . $query['request']['extension'], '', $keyword);
|
244 |
+
|
245 |
+
$query['process']['keywords']['explode'][] = $keyword;
|
246 |
}
|
247 |
$query['process']['keywords']['explode'] = array_reverse($query['process']['keywords']['explode']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
|
249 |
return wp404arsp_redirect(wp404arsp_search($query));
|
250 |
|
252 |
|
253 |
function wp404arsp_search($query){
|
254 |
|
255 |
+
// Direct
|
256 |
+
$get_post_types = get_post_types(array('public' => true), 'names');
|
257 |
+
foreach($get_post_types as $post_type){
|
258 |
+
if($post = get_page_by_path($query['process']['keywords']['explode'][0], 'object', $post_type))
|
259 |
+
return array_merge( $query, array(
|
260 |
+
'score' => 'direct',
|
261 |
+
'id' => (int)$post->ID,
|
262 |
+
'url' => get_permalink((int)$post->ID),
|
263 |
+
'why' => "Part of the requested URL already exist as post of the post_type <strong>" . get_post_type((int)$post->ID) . "</strong>"
|
264 |
+
));
|
265 |
+
}
|
266 |
+
|
267 |
+
// Search
|
268 |
$keywords = explode('-', $query['process']['keywords']['sanitized']);
|
269 |
+
$sql = wp404arsp_search_sql(array('keywords' => $keywords));
|
270 |
|
271 |
+
// Term
|
272 |
+
if(empty($sql['result']) || $sql['result']['score'] < 1){
|
273 |
+
$sql = wp404arsp_search_sql(array('keywords' => $keywords, 'mode' => 'term'));
|
274 |
+
|
275 |
+
if(empty($sql['result']) || $sql['result']['score'] < 1)
|
276 |
+
return array_merge( $query, array(
|
277 |
+
'why' => "Nothing found in DB matching the request url."
|
278 |
+
)
|
279 |
+
);
|
280 |
+
|
281 |
+
return array_merge( $query, array(
|
282 |
+
'score' => $sql['result']['score'],
|
283 |
+
'id' => (int)$sql['result']['term_id'],
|
284 |
+
'url' => get_term_link((int)$sql['result']['term_id']),
|
285 |
+
'why' => "No similar post found, but a similar <strong>term</strong> was found."
|
286 |
+
)
|
287 |
+
);
|
288 |
+
}
|
289 |
|
290 |
+
// Post
|
291 |
+
$return = array_merge( $query, array(
|
292 |
+
'score' => $sql['result']['score'],
|
293 |
+
'id' => (int)$sql['result']['ID'],
|
294 |
+
'url' => get_permalink((int)$sql['result']['ID']),
|
295 |
+
'why' => "Similar post of post_type <strong>" . get_post_type((int)$sql['result']['ID']) . "</strong> was found."
|
296 |
+
)
|
297 |
+
);
|
298 |
|
299 |
+
// Post: If Post Type found, check other post types & compare score
|
300 |
+
if(isset($query['process']['post_type']) && !empty($query['process']['post_type'])){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
|
302 |
+
$sql = wp404arsp_search_sql(array('keywords' => $keywords, 'post_type' => $query['process']['post_type']));
|
303 |
+
if(!empty($sql['result']) && $sql['result']['score'] >= 1 && $sql['result']['score'] >= $return['score']){
|
304 |
+
$return = array_merge( $query, array(
|
305 |
+
'score' => $sql['result']['score'],
|
306 |
+
'id' => (int)$sql['result']['ID'],
|
307 |
+
'url' => get_permalink((int)$sql['result']['ID']),
|
308 |
+
'why' => "Similar post of post_type <strong>" . $query['process']['post_type'] . "</strong> was found."
|
309 |
+
)
|
310 |
+
);
|
311 |
+
|
312 |
+
}else{
|
313 |
+
$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>";
|
314 |
+
|
315 |
+
}
|
316 |
|
317 |
}
|
|
|
|
|
318 |
|
319 |
return $return;
|
320 |
|
345 |
|
346 |
$title = '';
|
347 |
if(isset($args['url']) && !empty($args['url'])){
|
348 |
+
$title = 'Redirect to: ' . "<a href='" . $args['url'] . "'>" . $args['url'] . "</a>" . ' (' . $method . ' Headers)';
|
349 |
|
350 |
}elseif($wp404arsp_settings['home'] == "1"){
|
351 |
$title = 'Redirect to Home disabled. Displaying 404.';
|
352 |
|
353 |
}else{
|
354 |
+
$title = 'Redirect to: ' . "<a href='" . home_url() . "'>" . home_url() . "</a>" . ' (' . $method . ' Headers)';
|
355 |
|
356 |
}
|
357 |
|
368 |
<div class="wp404arsp_debug_page">
|
369 |
<?php if(!isset($args['preview'])){ ?>
|
370 |
<h2>WP 404 Auto Redirect to Similar Post</h2>
|
371 |
+
<p>This is the <strong>debug console</strong> of WP 404 Auto redirect to Similar Post Plugin which is only visible to administrators. Head over your <a href="<?php echo admin_url('options-general.php?page=wp-404-auto-redirect'); ?>">settings page</a> if you would like to disable it.</p>
|
372 |
<hr />
|
373 |
<?php } ?>
|
374 |
<pre>Requested URL: <a href="<?php echo home_url(); ?><?php echo $args['request']['full']; ?>"><?php echo home_url(); ?><?php echo $args['request']['full']; ?></a><br />
|
375 |
<?php echo $title; ?><br />
|
376 |
+
Details: <?php echo $args['why']; ?></pre>
|
|
|
377 |
<pre><?php print_r($args); ?></pre>
|
378 |
</div>
|
379 |
|
380 |
<?php echo ob_get_clean(); exit;
|
381 |
}
|
382 |
|
383 |
+
function wp404arsp_search_sql($args = array()){
|
384 |
+
|
385 |
global $wpdb;
|
386 |
+
$args = wp_parse_args($args, array(
|
387 |
+
'keywords' => null,
|
388 |
+
'mode' => null,
|
389 |
+
'post_type' => null,
|
390 |
+
));
|
391 |
+
|
392 |
+
if(empty($args['mode']) || !empty($args['post_type'])){
|
393 |
|
394 |
+
$sql = "SELECT p.ID, ";
|
395 |
+
foreach($args['keywords'] as $k){
|
396 |
+
$sql .= "
|
397 |
+
if(INSTR(LCASE(p.post_name), '" . $k . "'), 1, 0) + ";
|
398 |
+
}
|
399 |
+
|
400 |
+
$sql .= "0 as score FROM " . $wpdb->posts . " AS p
|
401 |
+
WHERE p.post_status = 'publish' AND ";
|
402 |
+
|
403 |
+
if(!empty($args['post_type'])){
|
404 |
+
$sql .= "
|
405 |
+
p.post_type = '" . $args['post_type'] . "'";
|
406 |
+
|
407 |
+
}else{
|
408 |
+
$get_post_types = get_post_types(array('public' => true), 'names');
|
409 |
+
foreach($get_post_types as $pt){
|
410 |
+
$post_types[] = "
|
411 |
+
p.post_type = '" . $pt . "'";
|
412 |
+
}
|
413 |
+
$sql .= '(' . implode(' OR ', $post_types) . ')';
|
414 |
+
|
415 |
+
}
|
416 |
+
|
417 |
+
$sql .= "
|
418 |
+
ORDER BY score DESC, post_modified DESC LIMIT 1";
|
419 |
+
|
420 |
+
}elseif($args['mode'] == 'term'){
|
421 |
|
422 |
+
$sql = "SELECT t.term_id, ";
|
423 |
+
|
424 |
+
foreach($args['keywords'] as $k){
|
425 |
+
$sql .= "
|
426 |
+
if(INSTR(LCASE(t.slug), '" . $k . "'), 1, 0) + ";
|
427 |
+
}
|
428 |
+
|
429 |
+
$sql .= "
|
430 |
+
0 as score FROM " . $wpdb->terms . " AS t ORDER BY score DESC LIMIT 1";
|
431 |
+
|
432 |
+
}
|
433 |
|
434 |
return array(
|
435 |
+
'result' => $wpdb->get_row($sql, 'ARRAY_A'),
|
436 |
+
'dump' => $sql
|
437 |
);
|
438 |
}
|
439 |
|