Version Description
- Made the timeout value used when checking links user-configurable.
- The plugin will now report an error instead of failing silently when it can't create the necessary database tables.
- Added a table listing assorted debug info to the settings page. Click the small "Show debug info" link to display it.
- Cleaned up some redundant/useless code.
Download this release
Release Info
Developer | whiteshadow |
Plugin | Broken Link Checker |
Version | 0.5.14 |
Comparing to | |
See all releases |
Code changes from version 0.5.13 to 0.5.14
- broken-link-checker.php +7 -3
- config-manager.php +3 -0
- core.php +279 -29
- highlighter-class.php +14 -1
- link-classes.php +23 -19
- readme.txt +8 -3
- utility-class.php +2 -1
broken-link-checker.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
Plugin Name: Broken Link Checker
|
5 |
Plugin URI: http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/
|
6 |
Description: Checks your posts for broken links and missing images and notifies you on the dashboard if any are found.
|
7 |
-
Version: 0.5.
|
8 |
Author: Janis Elsts
|
9 |
Author URI: http://w-shadow.com/blog/
|
10 |
*/
|
@@ -14,10 +14,12 @@ Created by Janis Elsts (email : whiteshadow@w-shadow.com)
|
|
14 |
MySQL 4.0 compatibility by Jeroen (www.yukka.eu)
|
15 |
*/
|
16 |
|
|
|
|
|
17 |
/*
|
18 |
//FirePHP for debugging
|
19 |
if ( !class_exists('FB') ) {
|
20 |
-
|
21 |
}
|
22 |
//FB::setEnabled(false);
|
23 |
|
@@ -70,7 +72,9 @@ $blc_config_manager = new blcConfigurationManager(
|
|
70 |
|
71 |
'custom_tmp_dir' => '', //The lockfile will be stored in this directory.
|
72 |
//If this option is not set, the plugin's own directory or the
|
73 |
-
//system-wide /tmp directory will be used instead.
|
|
|
|
|
74 |
)
|
75 |
);
|
76 |
|
4 |
Plugin Name: Broken Link Checker
|
5 |
Plugin URI: http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/
|
6 |
Description: Checks your posts for broken links and missing images and notifies you on the dashboard if any are found.
|
7 |
+
Version: 0.5.14
|
8 |
Author: Janis Elsts
|
9 |
Author URI: http://w-shadow.com/blog/
|
10 |
*/
|
14 |
MySQL 4.0 compatibility by Jeroen (www.yukka.eu)
|
15 |
*/
|
16 |
|
17 |
+
define('BLC_DEBUG', false);
|
18 |
+
|
19 |
/*
|
20 |
//FirePHP for debugging
|
21 |
if ( !class_exists('FB') ) {
|
22 |
+
require_once 'FirePHPCore/fb.php4';
|
23 |
}
|
24 |
//FB::setEnabled(false);
|
25 |
|
72 |
|
73 |
'custom_tmp_dir' => '', //The lockfile will be stored in this directory.
|
74 |
//If this option is not set, the plugin's own directory or the
|
75 |
+
//system-wide /tmp directory will be used instead.
|
76 |
+
|
77 |
+
'timeout' => 30, //Links that take longer than this to respond will be treated as broken.
|
78 |
)
|
79 |
);
|
80 |
|
config-manager.php
CHANGED
@@ -5,6 +5,8 @@
|
|
5 |
* @copyright 2009
|
6 |
*/
|
7 |
|
|
|
|
|
8 |
class blcConfigurationManager {
|
9 |
|
10 |
var $option_name;
|
@@ -82,4 +84,5 @@ class blcConfigurationManager {
|
|
82 |
}
|
83 |
}
|
84 |
|
|
|
85 |
?>
|
5 |
* @copyright 2009
|
6 |
*/
|
7 |
|
8 |
+
if ( !class_exists('blcConfigurationManager') ){
|
9 |
+
|
10 |
class blcConfigurationManager {
|
11 |
|
12 |
var $option_name;
|
84 |
}
|
85 |
}
|
86 |
|
87 |
+
}
|
88 |
?>
|
core.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
//The plugin will use Snoopy in case CURL is not available
|
4 |
//TODO: Use WP_HTTP instead of Snoopy
|
5 |
-
if (!class_exists('Snoopy')) require_once(ABSPATH.'/
|
6 |
|
7 |
/**
|
8 |
* Simple function to replicate PHP 5 behaviour
|
@@ -15,7 +15,7 @@ if ( !function_exists( 'microtime_float' ) ) {
|
|
15 |
}
|
16 |
}
|
17 |
|
18 |
-
if (!class_exists('
|
19 |
|
20 |
class wsBrokenLinkChecker {
|
21 |
var $conf;
|
@@ -56,7 +56,7 @@ class wsBrokenLinkChecker {
|
|
56 |
add_action('edit_link', array(&$this,'hook_edit_link'));
|
57 |
add_action('delete_link', array(&$this,'hook_delete_link'));
|
58 |
|
59 |
-
//Load jQuery on Dashboard pages (
|
60 |
add_action('admin_print_scripts', array(&$this,'admin_print_scripts'));
|
61 |
|
62 |
//The dashboard widget
|
@@ -314,9 +314,10 @@ class wsBrokenLinkChecker {
|
|
314 |
* ws_broken_link_checker::upgrade_database()
|
315 |
* Create and/or upgrade database tables
|
316 |
*
|
|
|
317 |
* @return void
|
318 |
*/
|
319 |
-
function upgrade_database(){
|
320 |
global $wpdb;
|
321 |
|
322 |
//Do we need to upgrade?
|
@@ -330,9 +331,9 @@ class wsBrokenLinkChecker {
|
|
330 |
return false;
|
331 |
}
|
332 |
|
333 |
-
require_once (ABSPATH . 'wp-admin/includes/upgrade.php');
|
334 |
|
335 |
-
//Create the link table if it doesn't exist yet.
|
336 |
$q = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}blc_links (
|
337 |
link_id int(20) unsigned NOT NULL auto_increment,
|
338 |
url text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
|
@@ -352,8 +353,8 @@ class wsBrokenLinkChecker {
|
|
352 |
KEY timeout (timeout)
|
353 |
)";
|
354 |
if ( $wpdb->query( $q ) === false ){
|
355 |
-
|
356 |
-
|
357 |
};
|
358 |
|
359 |
//Fix URL fields so that they are collated as case-sensitive (this can't be done via dbDelta)
|
@@ -361,8 +362,8 @@ class wsBrokenLinkChecker {
|
|
361 |
MODIFY url text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
|
362 |
MODIFY final_url text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL";
|
363 |
if ( $wpdb->query( $q ) === false ){
|
364 |
-
|
365 |
-
|
366 |
};
|
367 |
|
368 |
//Create the instance table if it doesn't exist yet.
|
@@ -379,8 +380,8 @@ class wsBrokenLinkChecker {
|
|
379 |
KEY source_id (source_id,source_type)
|
380 |
)";
|
381 |
if ( $wpdb->query( $q ) === false ){
|
382 |
-
|
383 |
-
|
384 |
};
|
385 |
|
386 |
//....
|
@@ -393,8 +394,8 @@ class wsBrokenLinkChecker {
|
|
393 |
KEY synched (synched)
|
394 |
)";
|
395 |
if ( $wpdb->query( $q ) === false ){
|
396 |
-
|
397 |
-
|
398 |
};
|
399 |
|
400 |
$this->conf->options['current_db_version'] = $this->db_version;
|
@@ -416,8 +417,11 @@ class wsBrokenLinkChecker {
|
|
416 |
}
|
417 |
|
418 |
function admin_menu(){
|
419 |
-
add_options_page('Link Checker Settings', 'Link Checker', 'manage_options',
|
420 |
'link-checker-settings',array(&$this, 'options_page'));
|
|
|
|
|
|
|
421 |
if (current_user_can('manage_options'))
|
422 |
add_filter('plugin_action_links', array(&$this, 'plugin_action_links'), 10, 2);
|
423 |
|
@@ -452,11 +456,13 @@ class wsBrokenLinkChecker {
|
|
452 |
if(isset($_POST['submit'])) {
|
453 |
check_admin_referer('link-checker-options');
|
454 |
|
|
|
455 |
$new_execution_time = intval($_POST['max_execution_time']);
|
456 |
if( $new_execution_time > 0 ){
|
457 |
$this->conf->options['max_execution_time'] = $new_execution_time;
|
458 |
}
|
459 |
|
|
|
460 |
$new_check_threshold=intval($_POST['check_threshold']);
|
461 |
if( $new_check_threshold > 0 ){
|
462 |
$this->conf->options['check_threshold'] = $new_check_threshold;
|
@@ -466,17 +472,34 @@ class wsBrokenLinkChecker {
|
|
466 |
$new_broken_link_css = trim($_POST['broken_link_css']);
|
467 |
$this->conf->options['broken_link_css'] = $new_broken_link_css;
|
468 |
|
469 |
-
|
470 |
-
|
471 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
472 |
|
473 |
-
|
474 |
-
|
|
|
|
|
|
|
|
|
475 |
$diff1 = array_diff( $new_custom_fields, $this->conf->options['custom_fields'] );
|
476 |
$diff2 = array_diff( $this->conf->options['custom_fields'], $new_custom_fields );
|
477 |
$this->conf->options['custom_fields'] = $new_custom_fields;
|
478 |
|
|
|
479 |
$this->conf->options['custom_tmp_dir'] = trim(stripslashes(strval($_POST['custom_tmp_dir'])));
|
|
|
|
|
|
|
|
|
|
|
|
|
480 |
|
481 |
$this->conf->save_options();
|
482 |
|
@@ -492,8 +515,11 @@ class wsBrokenLinkChecker {
|
|
492 |
$base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
|
493 |
wp_redirect( add_query_arg( array( 'updated' => 1), $base_url ) );
|
494 |
}
|
|
|
|
|
|
|
|
|
495 |
|
496 |
-
?>
|
497 |
<div class="wrap"><h2>Broken Link Checker Options</h2>
|
498 |
|
499 |
<form name="link_checker_options" method="post" action="<?php
|
@@ -506,7 +532,11 @@ class wsBrokenLinkChecker {
|
|
506 |
<table class="form-table">
|
507 |
|
508 |
<tr valign="top">
|
509 |
-
<th scope="row">
|
|
|
|
|
|
|
|
|
510 |
<td>
|
511 |
|
512 |
|
@@ -539,6 +569,23 @@ class wsBrokenLinkChecker {
|
|
539 |
</script>
|
540 |
<?php //JHS: Recheck all posts link: ?>
|
541 |
<p><input class="button" type="button" name="recheckbutton" value="Re-check all pages" onclick="location.replace('<?php echo basename($_SERVER['PHP_SELF']); ?>?page=link-checker-settings&recheck=true')" /></p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
542 |
</td>
|
543 |
</tr>
|
544 |
|
@@ -547,7 +594,7 @@ class wsBrokenLinkChecker {
|
|
547 |
<td>
|
548 |
|
549 |
Every <input type="text" name="check_threshold" id="check_threshold"
|
550 |
-
value="<?php echo $this->conf->options['check_threshold']; ?>" size='5' maxlength='
|
551 |
hours
|
552 |
<br/>
|
553 |
<span class="description">
|
@@ -596,9 +643,31 @@ class wsBrokenLinkChecker {
|
|
596 |
</td>
|
597 |
</tr>
|
598 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
599 |
<tr valign="top">
|
600 |
<th scope="row">
|
601 |
-
<a name='lockfile_directory'></a>Custom temporary directory
|
602 |
<td>
|
603 |
|
604 |
<input type="text" name="custom_tmp_dir" id="custom_tmp_dir"
|
@@ -627,11 +696,11 @@ class wsBrokenLinkChecker {
|
|
627 |
</tr>
|
628 |
|
629 |
<tr valign="top">
|
630 |
-
<th scope="row">Max. execution time
|
631 |
<td>
|
632 |
|
633 |
<input type="text" name="max_execution_time" id="max_execution_time"
|
634 |
-
value="<?php echo $this->conf->options['max_execution_time']; ?>" size='5' maxlength='
|
635 |
seconds
|
636 |
<br/><span class="description">
|
637 |
The plugin works by periodically creating a background worker instance that parses your posts looking for links,
|
@@ -641,14 +710,77 @@ class wsBrokenLinkChecker {
|
|
641 |
|
642 |
</td>
|
643 |
</tr>
|
644 |
-
|
645 |
</table>
|
646 |
-
|
647 |
<p class="submit"><input type="submit" name="submit" class='button-primary' value="<?php _e('Save Changes') ?>" /></p>
|
648 |
</form>
|
649 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
650 |
<?php
|
651 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
652 |
|
653 |
function links_page(){
|
654 |
global $wpdb;
|
@@ -1659,7 +1791,7 @@ jQuery(function($){
|
|
1659 |
if ( !$this->is_excluded( $link['url'] ) ) {
|
1660 |
//Yes, do it
|
1661 |
//FB::log("Checking link {$link[link_id]}");
|
1662 |
-
$link_obj->check();
|
1663 |
$link_obj->save();
|
1664 |
} else {
|
1665 |
//Nope, mark it as already checked.
|
@@ -2168,6 +2300,124 @@ jQuery(function($){
|
|
2168 |
</div>',
|
2169 |
$action_notice);
|
2170 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2171 |
|
2172 |
}//class ends here
|
2173 |
|
2 |
|
3 |
//The plugin will use Snoopy in case CURL is not available
|
4 |
//TODO: Use WP_HTTP instead of Snoopy
|
5 |
+
if (!class_exists('Snoopy')) require_once(ABSPATH. WPINC . '/class-snoopy.php');
|
6 |
|
7 |
/**
|
8 |
* Simple function to replicate PHP 5 behaviour
|
15 |
}
|
16 |
}
|
17 |
|
18 |
+
if (!class_exists('wsBrokenLinkChecker')) {
|
19 |
|
20 |
class wsBrokenLinkChecker {
|
21 |
var $conf;
|
56 |
add_action('edit_link', array(&$this,'hook_edit_link'));
|
57 |
add_action('delete_link', array(&$this,'hook_delete_link'));
|
58 |
|
59 |
+
//Load jQuery on Dashboard pages (probably redundant as WP already does that)
|
60 |
add_action('admin_print_scripts', array(&$this,'admin_print_scripts'));
|
61 |
|
62 |
//The dashboard widget
|
314 |
* ws_broken_link_checker::upgrade_database()
|
315 |
* Create and/or upgrade database tables
|
316 |
*
|
317 |
+
* @param bool $die_on_error Whether the function should stop the script and display an error message if a DB error is encountered.
|
318 |
* @return void
|
319 |
*/
|
320 |
+
function upgrade_database( $die_on_error = true ){
|
321 |
global $wpdb;
|
322 |
|
323 |
//Do we need to upgrade?
|
331 |
return false;
|
332 |
}
|
333 |
|
334 |
+
//require_once (ABSPATH . 'wp-admin/includes/upgrade.php');
|
335 |
|
336 |
+
//Create the link table if it doesn't exist yet.
|
337 |
$q = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}blc_links (
|
338 |
link_id int(20) unsigned NOT NULL auto_increment,
|
339 |
url text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
|
353 |
KEY timeout (timeout)
|
354 |
)";
|
355 |
if ( $wpdb->query( $q ) === false ){
|
356 |
+
if ( $die_on_error )
|
357 |
+
die('Database error : ' . $wpdb->last_error);
|
358 |
};
|
359 |
|
360 |
//Fix URL fields so that they are collated as case-sensitive (this can't be done via dbDelta)
|
362 |
MODIFY url text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
|
363 |
MODIFY final_url text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL";
|
364 |
if ( $wpdb->query( $q ) === false ){
|
365 |
+
if ( $die_on_error )
|
366 |
+
die('Database error : ' . $wpdb->last_error);
|
367 |
};
|
368 |
|
369 |
//Create the instance table if it doesn't exist yet.
|
380 |
KEY source_id (source_id,source_type)
|
381 |
)";
|
382 |
if ( $wpdb->query( $q ) === false ){
|
383 |
+
if ( $die_on_error )
|
384 |
+
die('Database error : ' . $wpdb->last_error);
|
385 |
};
|
386 |
|
387 |
//....
|
394 |
KEY synched (synched)
|
395 |
)";
|
396 |
if ( $wpdb->query( $q ) === false ){
|
397 |
+
if ( $die_on_error )
|
398 |
+
die('Database error : ' . $wpdb->last_error);
|
399 |
};
|
400 |
|
401 |
$this->conf->options['current_db_version'] = $this->db_version;
|
417 |
}
|
418 |
|
419 |
function admin_menu(){
|
420 |
+
$options_page_hook = add_options_page('Link Checker Settings', 'Link Checker', 'manage_options',
|
421 |
'link-checker-settings',array(&$this, 'options_page'));
|
422 |
+
//Add the hook that will add the plugin's CSS styles to it's settings page
|
423 |
+
add_action( 'admin_print_styles-' . $options_page_hook, array(&$this, 'options_page_css') );
|
424 |
+
|
425 |
if (current_user_can('manage_options'))
|
426 |
add_filter('plugin_action_links', array(&$this, 'plugin_action_links'), 10, 2);
|
427 |
|
456 |
if(isset($_POST['submit'])) {
|
457 |
check_admin_referer('link-checker-options');
|
458 |
|
459 |
+
//The execution time limit must be above zero
|
460 |
$new_execution_time = intval($_POST['max_execution_time']);
|
461 |
if( $new_execution_time > 0 ){
|
462 |
$this->conf->options['max_execution_time'] = $new_execution_time;
|
463 |
}
|
464 |
|
465 |
+
//The check threshold also must be > 0
|
466 |
$new_check_threshold=intval($_POST['check_threshold']);
|
467 |
if( $new_check_threshold > 0 ){
|
468 |
$this->conf->options['check_threshold'] = $new_check_threshold;
|
472 |
$new_broken_link_css = trim($_POST['broken_link_css']);
|
473 |
$this->conf->options['broken_link_css'] = $new_broken_link_css;
|
474 |
|
475 |
+
//TODO: Maybe update affected links when exclusion list changes (could be expensive resource-wise).
|
476 |
+
$this->conf->options['exclusion_list'] = array_filter(
|
477 |
+
preg_split(
|
478 |
+
'/[\s\r\n]+/', //split on newlines and whitespace
|
479 |
+
$_POST['exclusion_list'],
|
480 |
+
-1,
|
481 |
+
PREG_SPLIT_NO_EMPTY //skip empty values
|
482 |
+
)
|
483 |
+
);
|
484 |
|
485 |
+
//Parse the custom field list
|
486 |
+
$new_custom_fields = array_filter(
|
487 |
+
preg_split( '/[\s\r\n]+/', $_POST['blc_custom_fields'], -1, PREG_SPLIT_NO_EMPTY )
|
488 |
+
);
|
489 |
+
|
490 |
+
//Calculate the difference between the old custom field list and the new one (used later)
|
491 |
$diff1 = array_diff( $new_custom_fields, $this->conf->options['custom_fields'] );
|
492 |
$diff2 = array_diff( $this->conf->options['custom_fields'], $new_custom_fields );
|
493 |
$this->conf->options['custom_fields'] = $new_custom_fields;
|
494 |
|
495 |
+
//Temporary file directory
|
496 |
$this->conf->options['custom_tmp_dir'] = trim(stripslashes(strval($_POST['custom_tmp_dir'])));
|
497 |
+
|
498 |
+
//HTTP timeout
|
499 |
+
$new_timeout = intval($_POST['timeout']);
|
500 |
+
if( $new_timeout > 0 ){
|
501 |
+
$this->conf->options['timeout'] = $new_timeout ;
|
502 |
+
}
|
503 |
|
504 |
$this->conf->save_options();
|
505 |
|
515 |
$base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
|
516 |
wp_redirect( add_query_arg( array( 'updated' => 1), $base_url ) );
|
517 |
}
|
518 |
+
|
519 |
+
$debug = $this->get_debug_info();
|
520 |
+
|
521 |
+
?>
|
522 |
|
|
|
523 |
<div class="wrap"><h2>Broken Link Checker Options</h2>
|
524 |
|
525 |
<form name="link_checker_options" method="post" action="<?php
|
532 |
<table class="form-table">
|
533 |
|
534 |
<tr valign="top">
|
535 |
+
<th scope="row">
|
536 |
+
Status
|
537 |
+
<br>
|
538 |
+
<a href="javascript:void(0)" id="blc-debug-info-toggle">Show debug info</a>
|
539 |
+
</th>
|
540 |
<td>
|
541 |
|
542 |
|
569 |
</script>
|
570 |
<?php //JHS: Recheck all posts link: ?>
|
571 |
<p><input class="button" type="button" name="recheckbutton" value="Re-check all pages" onclick="location.replace('<?php echo basename($_SERVER['PHP_SELF']); ?>?page=link-checker-settings&recheck=true')" /></p>
|
572 |
+
|
573 |
+
<table id="blc-debug-info">
|
574 |
+
<?php
|
575 |
+
|
576 |
+
//Output the debug info in a table
|
577 |
+
foreach( $debug as $key => $value ){
|
578 |
+
printf (
|
579 |
+
'<tr valign="top" class="blc-debug-item-%s"><th scope="row">%s</th><td>%s<div class="blc-debug-message">%s</div></td></tr>',
|
580 |
+
$value['state'],
|
581 |
+
$key,
|
582 |
+
$value['value'],
|
583 |
+
( array_key_exists('message', $value)?$value['message']:'')
|
584 |
+
);
|
585 |
+
}
|
586 |
+
?>
|
587 |
+
</table>
|
588 |
+
|
589 |
</td>
|
590 |
</tr>
|
591 |
|
594 |
<td>
|
595 |
|
596 |
Every <input type="text" name="check_threshold" id="check_threshold"
|
597 |
+
value="<?php echo $this->conf->options['check_threshold']; ?>" size='5' maxlength='5'/>
|
598 |
hours
|
599 |
<br/>
|
600 |
<span class="description">
|
643 |
</td>
|
644 |
</tr>
|
645 |
|
646 |
+
</table>
|
647 |
+
|
648 |
+
<h3>Advanced</h3>
|
649 |
+
|
650 |
+
<table class="form-table">
|
651 |
+
|
652 |
+
|
653 |
+
<tr valign="top">
|
654 |
+
<th scope="row">Timeout</th>
|
655 |
+
<td>
|
656 |
+
|
657 |
+
<input type="text" name="timeout" id="blc_timeout"
|
658 |
+
value="<?php echo $this->conf->options['timeout']; ?>" size='5' maxlength='3'/>
|
659 |
+
seconds
|
660 |
+
<br/><span class="description">
|
661 |
+
Links that take longer than this to load will be marked as broken.
|
662 |
+
</span>
|
663 |
+
|
664 |
+
</td>
|
665 |
+
</tr>
|
666 |
+
|
667 |
+
|
668 |
<tr valign="top">
|
669 |
<th scope="row">
|
670 |
+
<a name='lockfile_directory'></a>Custom temporary directory</th>
|
671 |
<td>
|
672 |
|
673 |
<input type="text" name="custom_tmp_dir" id="custom_tmp_dir"
|
696 |
</tr>
|
697 |
|
698 |
<tr valign="top">
|
699 |
+
<th scope="row">Max. execution time</th>
|
700 |
<td>
|
701 |
|
702 |
<input type="text" name="max_execution_time" id="max_execution_time"
|
703 |
+
value="<?php echo $this->conf->options['max_execution_time']; ?>" size='5' maxlength='5'/>
|
704 |
seconds
|
705 |
<br/><span class="description">
|
706 |
The plugin works by periodically creating a background worker instance that parses your posts looking for links,
|
710 |
|
711 |
</td>
|
712 |
</tr>
|
713 |
+
|
714 |
</table>
|
715 |
+
|
716 |
<p class="submit"><input type="submit" name="submit" class='button-primary' value="<?php _e('Save Changes') ?>" /></p>
|
717 |
</form>
|
718 |
</div>
|
719 |
+
|
720 |
+
<script type='text/javascript'>
|
721 |
+
jQuery(function($){
|
722 |
+
var toggleButton = $('#blc-debug-info-toggle');
|
723 |
+
|
724 |
+
toggleButton.click(function(){
|
725 |
+
|
726 |
+
var box = $('#blc-debug-info');
|
727 |
+
box.toggle();
|
728 |
+
if( box.is(':visible') ){
|
729 |
+
toggleButton.text('Hide debug info');
|
730 |
+
} else {
|
731 |
+
toggleButton.text('Show debug info');
|
732 |
+
}
|
733 |
+
|
734 |
+
});
|
735 |
+
});
|
736 |
+
</script>
|
737 |
<?php
|
738 |
}
|
739 |
+
|
740 |
+
function options_page_css(){
|
741 |
+
?>
|
742 |
+
<style type='text/css'>
|
743 |
+
#blc-debug-info-toggle {
|
744 |
+
font-size: smaller;
|
745 |
+
}
|
746 |
+
|
747 |
+
.blc-debug-item-ok {
|
748 |
+
background-color: #d7ffa2;
|
749 |
+
}
|
750 |
+
.blc-debug-item-warning {
|
751 |
+
background-color: #fcffa2;
|
752 |
+
}
|
753 |
+
.blc-debug-item-error {
|
754 |
+
background-color: #ffc4c4;
|
755 |
+
}
|
756 |
+
|
757 |
+
#blc-debug-info {
|
758 |
+
display: none;
|
759 |
+
|
760 |
+
text-align: left;
|
761 |
+
|
762 |
+
border-width: 1px;
|
763 |
+
border-color: gray;
|
764 |
+
border-style: solid;
|
765 |
+
|
766 |
+
border-spacing: 0px;
|
767 |
+
border-collapse: collapse;
|
768 |
+
}
|
769 |
+
|
770 |
+
#blc-debug-info th, #blc-debug-info td {
|
771 |
+
padding: 6px;
|
772 |
+
font-weight: normal;
|
773 |
+
text-shadow: none;
|
774 |
+
|
775 |
+
border-width: 1px ;
|
776 |
+
border-color: silver;
|
777 |
+
border-style: solid;
|
778 |
+
|
779 |
+
border-collapse: collapse;
|
780 |
+
}
|
781 |
+
</style>
|
782 |
+
<?php
|
783 |
+
}
|
784 |
|
785 |
function links_page(){
|
786 |
global $wpdb;
|
1791 |
if ( !$this->is_excluded( $link['url'] ) ) {
|
1792 |
//Yes, do it
|
1793 |
//FB::log("Checking link {$link[link_id]}");
|
1794 |
+
$link_obj->check( $this->conf->options['timeout'] );
|
1795 |
$link_obj->save();
|
1796 |
} else {
|
1797 |
//Nope, mark it as already checked.
|
2300 |
</div>',
|
2301 |
$action_notice);
|
2302 |
}
|
2303 |
+
|
2304 |
+
/**
|
2305 |
+
* wsBrokenLinkChecker::get_debug_info()
|
2306 |
+
* Collect various debugging information and return it in an associative array
|
2307 |
+
*
|
2308 |
+
* @return array
|
2309 |
+
*/
|
2310 |
+
function get_debug_info(){
|
2311 |
+
global $wpdb;
|
2312 |
+
|
2313 |
+
//Collect some information that's useful for debugging
|
2314 |
+
$debug = array();
|
2315 |
+
|
2316 |
+
//PHP version. Any one is fine as long as WP supports it.
|
2317 |
+
$debug['PHP version'] = array(
|
2318 |
+
'state' => 'ok',
|
2319 |
+
'value' => phpversion(),
|
2320 |
+
);
|
2321 |
+
|
2322 |
+
//MySQL version
|
2323 |
+
$debug['MySQL version'] = array(
|
2324 |
+
'state' => 'ok',
|
2325 |
+
'value' => @mysql_get_server_info( $wpdb->dbh ),
|
2326 |
+
);
|
2327 |
+
|
2328 |
+
//CURL presence and version
|
2329 |
+
if ( function_exists('curl_version') ){
|
2330 |
+
$version = curl_version();
|
2331 |
+
|
2332 |
+
if ( version_compare( $version['version'], '7.16.0', '<=' ) ){
|
2333 |
+
$data = array(
|
2334 |
+
'state' => 'warning',
|
2335 |
+
'value' => $version['version'],
|
2336 |
+
'message' => 'You have an old version of CURL. Redirect detection may not work properly.',
|
2337 |
+
);
|
2338 |
+
} else {
|
2339 |
+
$data = array(
|
2340 |
+
'state' => 'ok',
|
2341 |
+
'value' => $version['version'],
|
2342 |
+
);
|
2343 |
+
}
|
2344 |
+
|
2345 |
+
} else {
|
2346 |
+
$data = array(
|
2347 |
+
'state' => 'warning',
|
2348 |
+
'value' => 'Not installed',
|
2349 |
+
);
|
2350 |
+
}
|
2351 |
+
$debug['CURL version'] = $data;
|
2352 |
+
|
2353 |
+
//Snoopy presence
|
2354 |
+
if ( class_exists('Snoopy') ){
|
2355 |
+
$data = array(
|
2356 |
+
'state' => 'ok',
|
2357 |
+
'value' => 'Installed',
|
2358 |
+
);
|
2359 |
+
} else {
|
2360 |
+
//No Snoopy? This should never happen, but if it does we *must* have CURL.
|
2361 |
+
if ( function_exists('curl_init') ){
|
2362 |
+
$data = array(
|
2363 |
+
'state' => 'ok',
|
2364 |
+
'value' => 'Not installed',
|
2365 |
+
);
|
2366 |
+
} else {
|
2367 |
+
$data = array(
|
2368 |
+
'state' => 'error',
|
2369 |
+
'value' => 'Not installed',
|
2370 |
+
'message' => 'You must have either CURL or Snoopy installed for the plugin to work!',
|
2371 |
+
);
|
2372 |
+
}
|
2373 |
+
|
2374 |
+
}
|
2375 |
+
$debug['Snoopy'] = $data;
|
2376 |
+
|
2377 |
+
//Safe_mode status
|
2378 |
+
if ( ini_get('safe_mode') ){
|
2379 |
+
$debug['Safe mode'] = array(
|
2380 |
+
'state' => 'warning',
|
2381 |
+
'value' => 'On',
|
2382 |
+
'message' => 'Redirects may be detected as broken links when safe_mode is on.',
|
2383 |
+
);
|
2384 |
+
} else {
|
2385 |
+
$debug['Safe mode'] = array(
|
2386 |
+
'state' => 'ok',
|
2387 |
+
'value' => 'Off',
|
2388 |
+
);
|
2389 |
+
}
|
2390 |
+
|
2391 |
+
//Open_basedir status
|
2392 |
+
if ( ini_get('open_basedir') ){
|
2393 |
+
$debug['open_basedir'] = array(
|
2394 |
+
'state' => 'warning',
|
2395 |
+
'value' => 'On',
|
2396 |
+
'message' => 'Redirects may be detected as broken links when open_basedir is on.',
|
2397 |
+
);
|
2398 |
+
} else {
|
2399 |
+
$debug['open_basedir'] = array(
|
2400 |
+
'state' => 'ok',
|
2401 |
+
'value' => 'Off',
|
2402 |
+
);
|
2403 |
+
}
|
2404 |
+
|
2405 |
+
//Lockfile location
|
2406 |
+
$lockfile = $this->lockfile_name();
|
2407 |
+
if ( $lockfile ){
|
2408 |
+
$debug['Lockfile'] = array(
|
2409 |
+
'state' => 'ok',
|
2410 |
+
'value' => $lockfile,
|
2411 |
+
);
|
2412 |
+
} else {
|
2413 |
+
$debug['Lockfile'] = array(
|
2414 |
+
'state' => 'error',
|
2415 |
+
'message' => 'Can\'t create a lockfile. Please specify a custom temporary directory.',
|
2416 |
+
);
|
2417 |
+
}
|
2418 |
+
|
2419 |
+
return $debug;
|
2420 |
+
}
|
2421 |
|
2422 |
}//class ends here
|
2423 |
|
highlighter-class.php
CHANGED
@@ -7,6 +7,8 @@
|
|
7 |
* @requires blcUtility
|
8 |
*/
|
9 |
|
|
|
|
|
10 |
class blcLinkHighlighter {
|
11 |
|
12 |
var $links_to_remove;
|
@@ -52,7 +54,16 @@ class blcLinkHighlighter {
|
|
52 |
$this->links_to_remove[$row['url']] = $row;
|
53 |
}
|
54 |
$content = preg_replace_callback( blcUtility::link_pattern(), array(&$this,'mark_broken_links'), $content );
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
return $content;
|
58 |
}
|
@@ -60,6 +71,7 @@ class blcLinkHighlighter {
|
|
60 |
function mark_broken_links($matches){
|
61 |
//TODO: Tooltip-style popups with more info
|
62 |
$url = blcUtility::normalize_url( html_entity_decode( $matches[3] ), $this->current_permalink );
|
|
|
63 |
if( isset( $this->links_to_remove[$url] ) ){
|
64 |
return $matches[1].$matches[2].$matches[3].$matches[2].' class="broken_link" '.$matches[4].
|
65 |
$matches[5].$matches[6];
|
@@ -73,4 +85,5 @@ class blcLinkHighlighter {
|
|
73 |
}
|
74 |
}
|
75 |
|
|
|
76 |
?>
|
7 |
* @requires blcUtility
|
8 |
*/
|
9 |
|
10 |
+
if ( !class_exists('blcLinkHighlighter') ){
|
11 |
+
|
12 |
class blcLinkHighlighter {
|
13 |
|
14 |
var $links_to_remove;
|
54 |
$this->links_to_remove[$row['url']] = $row;
|
55 |
}
|
56 |
$content = preg_replace_callback( blcUtility::link_pattern(), array(&$this,'mark_broken_links'), $content );
|
57 |
+
|
58 |
+
if ( BLC_DEBUG ){
|
59 |
+
$content .= '<p><strong>Broken links in this post : </strong></p><ul>';
|
60 |
+
$content .= '<li>' . implode('</li><li>', array_keys($this->links_to_remove)) . '</li></ul>';
|
61 |
+
}
|
62 |
+
} else {
|
63 |
+
if ( BLC_DEBUG ){
|
64 |
+
$content .= '<p><strong>This post contains no broken links.</strong></p>';
|
65 |
+
}
|
66 |
+
};
|
67 |
|
68 |
return $content;
|
69 |
}
|
71 |
function mark_broken_links($matches){
|
72 |
//TODO: Tooltip-style popups with more info
|
73 |
$url = blcUtility::normalize_url( html_entity_decode( $matches[3] ), $this->current_permalink );
|
74 |
+
|
75 |
if( isset( $this->links_to_remove[$url] ) ){
|
76 |
return $matches[1].$matches[2].$matches[3].$matches[2].' class="broken_link" '.$matches[4].
|
77 |
$matches[5].$matches[6];
|
85 |
}
|
86 |
}
|
87 |
|
88 |
+
}
|
89 |
?>
|
link-classes.php
CHANGED
@@ -94,7 +94,7 @@ class blcLink {
|
|
94 |
*
|
95 |
* @return bool
|
96 |
*/
|
97 |
-
function check(){
|
98 |
if ( !$this->valid() ) return false;
|
99 |
|
100 |
//General note : there is usually no need to save() the result of the check
|
@@ -157,14 +157,16 @@ class blcLink {
|
|
157 |
//Add a semi-plausible referer header to avoid tripping up some bot traps
|
158 |
curl_setopt($ch, CURLOPT_REFERER, get_option('home'));
|
159 |
|
160 |
-
|
161 |
-
|
162 |
-
|
|
|
163 |
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
|
164 |
-
|
165 |
-
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
|
166 |
-
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
167 |
|
|
|
|
|
|
|
|
|
168 |
if (defined('WP_PROXY_HOST')) {
|
169 |
curl_setopt($ch, CURLOPT_PROXY, WP_PROXY_HOST);
|
170 |
}
|
@@ -181,25 +183,25 @@ class blcLink {
|
|
181 |
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $auth);
|
182 |
}
|
183 |
|
|
|
184 |
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
185 |
|
186 |
-
$nobody=false;
|
187 |
if( $parts['scheme'] == 'https' ){
|
188 |
//TODO: Redirects don't work with HTTPS
|
189 |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
190 |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
191 |
} else {
|
192 |
-
$nobody=true;
|
193 |
-
curl_setopt($ch, CURLOPT_NOBODY, true);
|
194 |
-
//curl_setopt($ch, CURLOPT_RANGE, '0-1023');
|
195 |
}
|
196 |
|
197 |
-
|
198 |
-
|
199 |
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$this,'read_header'));
|
200 |
|
201 |
//Execute the request
|
202 |
-
|
203 |
|
204 |
$info = curl_getinfo($ch);
|
205 |
$code = intval( $info['http_code'] );
|
@@ -211,10 +213,12 @@ class blcLink {
|
|
211 |
$this->log .= "Trying a second time with different settings...\n";
|
212 |
$this->last_headers = '';
|
213 |
|
214 |
-
curl_setopt($ch, CURLOPT_NOBODY, false);
|
215 |
-
curl_setopt($ch, CURLOPT_HTTPGET, true);
|
216 |
-
curl_setopt($ch, CURLOPT_RANGE, '0-2047')
|
217 |
-
|
|
|
|
|
218 |
|
219 |
$info = curl_getinfo($ch);
|
220 |
$code = intval( $info['http_code'] );
|
@@ -238,7 +242,7 @@ class blcLink {
|
|
238 |
$start_time = microtime_float(true);
|
239 |
|
240 |
$snoopy = new Snoopy;
|
241 |
-
$snoopy->read_timeout =
|
242 |
$snoopy->maxlength = 1024*5; //load up to 5 kilobytes
|
243 |
$snoopy->fetch($url);
|
244 |
|
94 |
*
|
95 |
* @return bool
|
96 |
*/
|
97 |
+
function check( $timeout = 40 ){
|
98 |
if ( !$this->valid() ) return false;
|
99 |
|
100 |
//General note : there is usually no need to save() the result of the check
|
157 |
//Add a semi-plausible referer header to avoid tripping up some bot traps
|
158 |
curl_setopt($ch, CURLOPT_REFERER, get_option('home'));
|
159 |
|
160 |
+
//Redirects don't work when safe mode or open_basedir is enabled.
|
161 |
+
if ( !ini_get('safe_mode') && !ini_get('open_basedir') ) {
|
162 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
163 |
+
}
|
164 |
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
|
|
|
|
|
|
|
165 |
|
166 |
+
//Set the timeout
|
167 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
168 |
+
|
169 |
+
//Set the proxy configuration. The user can provide this in wp-config.php
|
170 |
if (defined('WP_PROXY_HOST')) {
|
171 |
curl_setopt($ch, CURLOPT_PROXY, WP_PROXY_HOST);
|
172 |
}
|
183 |
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $auth);
|
184 |
}
|
185 |
|
186 |
+
//Is this even necessary?
|
187 |
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
188 |
|
189 |
+
$nobody = false;
|
190 |
if( $parts['scheme'] == 'https' ){
|
191 |
//TODO: Redirects don't work with HTTPS
|
192 |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
193 |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
194 |
} else {
|
195 |
+
$nobody = true;
|
196 |
+
curl_setopt($ch, CURLOPT_NOBODY, true); //Use the HEAD method for non-https URLs
|
|
|
197 |
}
|
198 |
|
199 |
+
//Register a callback function which will process the HTTP header(s).
|
200 |
+
//It can be called multiple times if the remote server performs a redirect.
|
201 |
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$this,'read_header'));
|
202 |
|
203 |
//Execute the request
|
204 |
+
curl_exec($ch);
|
205 |
|
206 |
$info = curl_getinfo($ch);
|
207 |
$code = intval( $info['http_code'] );
|
213 |
$this->log .= "Trying a second time with different settings...\n";
|
214 |
$this->last_headers = '';
|
215 |
|
216 |
+
curl_setopt($ch, CURLOPT_NOBODY, false); //Don't send a HEAD request this time
|
217 |
+
curl_setopt($ch, CURLOPT_HTTPGET, true); //Switch back to GET instead.
|
218 |
+
curl_setopt($ch, CURLOPT_RANGE, '0-2047');//But limit the desired response size,
|
219 |
+
//we don't want to eat the user's bandwidth.
|
220 |
+
//Run it again
|
221 |
+
curl_exec($ch);
|
222 |
|
223 |
$info = curl_getinfo($ch);
|
224 |
$code = intval( $info['http_code'] );
|
242 |
$start_time = microtime_float(true);
|
243 |
|
244 |
$snoopy = new Snoopy;
|
245 |
+
$snoopy->read_timeout = $timeout; //read timeout in seconds
|
246 |
$snoopy->maxlength = 1024*5; //load up to 5 kilobytes
|
247 |
$snoopy->fetch($url);
|
248 |
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: whiteshadow
|
|
3 |
Tags: links, broken, maintenance, blogroll, custom fields, admin
|
4 |
Requires at least: 2.7.0
|
5 |
Tested up to: 2.9
|
6 |
-
Stable tag: 0.5.
|
7 |
|
8 |
This plugin will check your posts, custom fields and the blogroll for broken links and missing images and notify you if any are found.
|
9 |
|
@@ -60,7 +60,11 @@ To upgrade your installation
|
|
60 |
|
61 |
*This is an automatically generated changelog*
|
62 |
|
63 |
-
|
|
|
|
|
|
|
|
|
64 |
|
65 |
= 0.5.13 =
|
66 |
* Fixed the bug where the plugin would ignore FORCE\_ADMIN\_SSL setting and always use plain HTTP for it's forms and AJAX.
|
@@ -250,4 +254,5 @@ To upgrade your installation
|
|
250 |
* *There are no release notes for this version*
|
251 |
|
252 |
= 0.1 =
|
253 |
-
* *There are no release notes for this version*
|
|
3 |
Tags: links, broken, maintenance, blogroll, custom fields, admin
|
4 |
Requires at least: 2.7.0
|
5 |
Tested up to: 2.9
|
6 |
+
Stable tag: 0.5.14
|
7 |
|
8 |
This plugin will check your posts, custom fields and the blogroll for broken links and missing images and notify you if any are found.
|
9 |
|
60 |
|
61 |
*This is an automatically generated changelog*
|
62 |
|
63 |
+
= 0.5.14 =
|
64 |
+
* Made the timeout value used when checking links user-configurable.
|
65 |
+
* The plugin will now report an error instead of failing silently when it can't create the necessary database tables.
|
66 |
+
* Added a table listing assorted debug info to the settings page. Click the small "Show debug info" link to display it.
|
67 |
+
* Cleaned up some redundant/useless code.
|
68 |
|
69 |
= 0.5.13 =
|
70 |
* Fixed the bug where the plugin would ignore FORCE\_ADMIN\_SSL setting and always use plain HTTP for it's forms and AJAX.
|
254 |
* *There are no release notes for this version*
|
255 |
|
256 |
= 0.1 =
|
257 |
+
* *There are no release notes for this version*
|
258 |
+
|
utility-class.php
CHANGED
@@ -166,7 +166,8 @@ class blcUtility {
|
|
166 |
$url
|
167 |
);
|
168 |
}
|
169 |
-
|
|
|
170 |
}//class
|
171 |
|
172 |
}//class_exists
|
166 |
$url
|
167 |
);
|
168 |
}
|
169 |
+
|
170 |
+
|
171 |
}//class
|
172 |
|
173 |
}//class_exists
|