Broken Link Checker - Version 1.10

Version Description

  • Added a way to hide individual link actions like "Dismiss" and "Unlink".
  • Added a "Fix redirect" link action. It replaces a redirect with a direct link. It is hidden by default and can be enabled through the settings page.
  • Added a "Recheck" link action. Unlike the bulk action by the same name, it checks a link immediately and displays the results without having to refresh the page.
  • Added a "Dismiss" bulk action.
  • Added a note below the "link tweaks" settings explaining that they only apply to the contents of posts (and pages, and CPTs), not comments or custom fields.
  • Made the "Redirect URL" column sortable.
  • Added a "Details" link to the "Status" column.
  • Added a "Warnings" section to Tools -> Broken Links. It shows problems that might be temporary or false positives. Warnings can be disabled through the settings page.
  • Fixed a conflict with plugins that use PHP sessions.
  • Fixed the "post statuses" option. Now disabling a post status (e.g. "Draft") should take effect immediately.
  • Fixed the Mediafire link checker.
  • Fixed the text in the "Status" column being slightly offset vertically when compared to other columns.
  • Fixed search box position in WP 4.1-alpha.
  • Added a few workarounds for situations where a custom post type is removed without first removing the posts.
  • Removed the screen icon. WordPress has deprecated it.
  • Other minor fixes.
Download this release

Release Info

Developer whiteshadow
Plugin Icon 128x128 Broken Link Checker
Version 1.10
Comparing to
See all releases

Code changes from version 1.9.5 to 1.10

broken-link-checker.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Broken Link Checker
4
  Plugin URI: http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/
5
  Description: Checks your blog for broken links and missing images and notifies you on the dashboard if any are found.
6
- Version: 1.9.5
7
  Author: Janis Elsts
8
  Author URI: http://w-shadow.com/
9
  Text Domain: broken-link-checker
3
  Plugin Name: Broken Link Checker
4
  Plugin URI: http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/
5
  Description: Checks your blog for broken links and missing images and notifies you on the dashboard if any are found.
6
+ Version: 1.10
7
  Author: Janis Elsts
8
  Author URI: http://w-shadow.com/
9
  Text Domain: broken-link-checker
core/core.php CHANGED
@@ -37,12 +37,10 @@ class wsBrokenLinkChecker {
37
  * @param blcConfigurationManager $conf An instance of the configuration manager
38
  * @return void
39
  */
40
- function wsBrokenLinkChecker ( $loader, &$conf ) {
41
- global $wpdb;
42
-
43
  $this->db_version = BLC_DATABASE_VERSION;
44
 
45
- $this->conf = &$conf;
46
  $this->loader = $loader;
47
  $this->my_basename = plugin_basename( $this->loader );
48
 
@@ -51,25 +49,27 @@ class wsBrokenLinkChecker {
51
  //Unlike the activation hook, the deactivation callback *can* be registered in this file
52
  //because deactivation happens after this class has already been instantiated (durinng the
53
  //'init' action).
54
- register_deactivation_hook($loader, array(&$this, 'deactivation'));
55
 
56
- add_action('admin_menu', array(&$this,'admin_menu'));
57
 
58
  //Load jQuery on Dashboard pages (probably redundant as WP already does that)
59
- add_action('admin_print_scripts', array(&$this,'admin_print_scripts'));
60
 
61
  //The dashboard widget
62
- add_action('wp_dashboard_setup', array(&$this, 'hook_wp_dashboard_setup'));
63
 
64
  //AJAXy hooks
65
- add_action( 'wp_ajax_blc_full_status', array(&$this,'ajax_full_status') );
66
- add_action( 'wp_ajax_blc_dashboard_status', array(&$this,'ajax_dashboard_status') );
67
- add_action( 'wp_ajax_blc_work', array(&$this,'ajax_work') );
68
- add_action( 'wp_ajax_blc_discard', array(&$this,'ajax_discard') );
69
- add_action( 'wp_ajax_blc_edit', array(&$this,'ajax_edit') );
70
- add_action( 'wp_ajax_blc_link_details', array(&$this,'ajax_link_details') );
71
- add_action( 'wp_ajax_blc_unlink', array(&$this,'ajax_unlink') );
72
- add_action( 'wp_ajax_blc_current_load', array(&$this,'ajax_current_load') );
 
 
73
 
74
  add_action( 'wp_ajax_blc_dismiss', array($this, 'ajax_dismiss') );
75
  add_action( 'wp_ajax_blc_undismiss', array($this, 'ajax_undismiss') );
@@ -78,13 +78,13 @@ class wsBrokenLinkChecker {
78
  $this->setup_cron_events();
79
 
80
  //Set hooks that listen for our Cron actions
81
- add_action('blc_cron_email_notifications', array( &$this, 'maybe_send_email_notifications' ));
82
- add_action('blc_cron_check_links', array(&$this, 'cron_check_links'));
83
- add_action('blc_cron_database_maintenance', array(&$this, 'database_maintenance'));
84
- add_action('blc_cron_check_news', array(&$this, 'check_news'));
85
 
86
  //Set the footer hook that will call the worker function via AJAX.
87
- add_action('admin_footer', array(&$this,'admin_footer'));
88
 
89
  //Add a "Screen Options" panel to the "Broken Links" page
90
  add_screen_options_panel(
@@ -95,6 +95,9 @@ class wsBrokenLinkChecker {
95
  array($this, 'ajax_save_screen_options'),
96
  true
97
  );
 
 
 
98
  }
99
 
100
  /**
@@ -162,7 +165,7 @@ class wsBrokenLinkChecker {
162
  'action' : 'blc_dashboard_status',
163
  'random' : Math.random()
164
  },
165
- function (data, textStatus){
166
  if ( data && ( typeof(data.text) != 'undefined' ) ) {
167
  $('#wsblc_activity_box').html(data.text);
168
  <?php if ( $this->conf->options['autoexpand_widget'] ) { ?>
@@ -289,13 +292,13 @@ class wsBrokenLinkChecker {
289
  */
290
  function admin_menu(){
291
  if (current_user_can('manage_options'))
292
- add_filter('plugin_action_links', array(&$this, 'plugin_action_links'), 10, 2);
293
 
294
  $options_page_hook = add_options_page(
295
  __('Link Checker Settings', 'broken-link-checker'),
296
  __('Link Checker', 'broken-link-checker'),
297
  'manage_options',
298
- 'link-checker-settings',array(&$this, 'options_page')
299
  );
300
 
301
  $menu_title = __('Broken Links', 'broken-link-checker');
@@ -317,14 +320,14 @@ class wsBrokenLinkChecker {
317
  __('View Broken Links', 'broken-link-checker'),
318
  $menu_title,
319
  'edit_others_posts',
320
- 'view-broken-links',array(&$this, 'links_page')
321
  );
322
 
323
  //Add plugin-specific scripts and CSS only to the it's own pages
324
- add_action( 'admin_print_styles-' . $options_page_hook, array(&$this, 'options_page_css') );
325
- add_action( 'admin_print_styles-' . $links_page_hook, array(&$this, 'links_page_css') );
326
- add_action( 'admin_print_scripts-' . $options_page_hook, array(&$this, 'enqueue_settings_scripts') );
327
- add_action( 'admin_print_scripts-' . $links_page_hook, array(&$this, 'enqueue_link_page_scripts') );
328
 
329
  //Add a "Feedback" button that links to the plugin's UserVoice forum
330
  add_screen_meta_link(
@@ -371,8 +374,6 @@ class wsBrokenLinkChecker {
371
  }
372
 
373
  function options_page(){
374
- global $blclog;
375
-
376
  $moduleManager = blcModuleManager::getInstance();
377
 
378
  //Prior to 1.5.2 (released 2012-05-27), there was a bug that would cause the donation flag to be
@@ -395,6 +396,15 @@ class wsBrokenLinkChecker {
395
  wp_redirect( add_query_arg( array( 'recheck-initiated' => true), $base_url ) );
396
  die();
397
  }
 
 
 
 
 
 
 
 
 
398
 
399
  if(isset($_POST['submit'])) {
400
  check_admin_referer('link-checker-options');
@@ -421,9 +431,14 @@ class wsBrokenLinkChecker {
421
  if ( empty($enabled_post_statuses) ){
422
  $enabled_post_statuses = array('publish');
423
  }
 
 
 
 
 
 
424
  $this->conf->options['enabled_post_statuses'] = $enabled_post_statuses;
425
- //TODO: Resynch enabled post types when enabled statuses change.
426
-
427
  //The execution time limit must be above zero
428
  $new_execution_time = intval($_POST['max_execution_time']);
429
  if( $new_execution_time > 0 ){
@@ -466,8 +481,15 @@ class wsBrokenLinkChecker {
466
  $diff1 = array_diff( $new_custom_fields, $this->conf->options['custom_fields'] );
467
  $diff2 = array_diff( $this->conf->options['custom_fields'], $new_custom_fields );
468
  $this->conf->options['custom_fields'] = $new_custom_fields;
469
-
470
- //HTTP timeout
 
 
 
 
 
 
 
471
  $new_timeout = intval($_POST['timeout']);
472
  if( $new_timeout > 0 ){
473
  $this->conf->options['timeout'] = $new_timeout ;
@@ -523,6 +545,14 @@ class wsBrokenLinkChecker {
523
  $this->conf->options['dashboard_widget_capability'] = $widget_cap;
524
  }
525
 
 
 
 
 
 
 
 
 
526
  //Logging. The plugin can log various events and results for debugging purposes.
527
  $this->conf->options['logging_enabled'] = !empty($_POST['logging_enabled']);
528
  $this->conf->options['custom_log_file_enabled'] = !empty($_POST['custom_log_file_enabled']);
@@ -574,6 +604,17 @@ class wsBrokenLinkChecker {
574
  blc_got_unsynched_items();
575
  }
576
  }
 
 
 
 
 
 
 
 
 
 
 
577
 
578
  //Redirect back to the settings page
579
  $base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
@@ -605,8 +646,7 @@ class wsBrokenLinkChecker {
605
 
606
  $debug = $this->get_debug_info();
607
 
608
- $details_text = __('Details', 'broken-link-checker');
609
- add_filter('blc-module-settings-custom_field', array(&$this, 'make_custom_field_input'), 10, 2);
610
 
611
  //Translate and markup-ify module headers for display
612
  $modules = $moduleManager->get_modules_by_category('', true, true);
@@ -638,7 +678,7 @@ class wsBrokenLinkChecker {
638
  <![endif]-->
639
 
640
  <div class="wrap" id="blc-settings-wrap">
641
- <?php screen_icon(); ?><h2><?php _e('Broken Link Checker Options', 'broken-link-checker'); ?></h2>
642
 
643
 
644
  <div id="blc-sidebar">
@@ -782,7 +822,7 @@ class wsBrokenLinkChecker {
782
  |
783
  <a id="toggle-broken-link-css-editor" href="#" class="blc-toggle-link"><?php
784
  _e('Edit CSS', 'broken-link-checker');
785
- ?></a>
786
  </p>
787
 
788
  <div id="broken-link-css-wrap"<?php
@@ -790,7 +830,7 @@ class wsBrokenLinkChecker {
790
  echo ' class="hidden"';
791
  }
792
  ?>>
793
- <textarea name="broken_link_css" id="broken_link_css" cols='45' rows='4'/><?php
794
  if( isset($this->conf->options['broken_link_css']) ) {
795
  echo $this->conf->options['broken_link_css'];
796
  }
@@ -821,7 +861,7 @@ class wsBrokenLinkChecker {
821
  echo ' class="hidden"';
822
  }
823
  ?>>
824
- <textarea name="removed_link_css" id="removed_link_css" cols='45' rows='4'/><?php
825
  if( isset($this->conf->options['removed_link_css']) )
826
  echo $this->conf->options['removed_link_css'];
827
  ?></textarea>
@@ -845,22 +885,43 @@ class wsBrokenLinkChecker {
845
  </label>
846
  </p>
847
 
 
 
 
 
 
 
 
 
 
848
  </td>
849
  </tr>
850
 
851
  <tr valign="top">
852
  <th scope="row"><?php echo _x('Suggestions', 'settings page', 'broken-link-checker'); ?></th>
853
  <td>
854
- <p>
855
- <label>
856
- <input type="checkbox" name="suggestions_enabled" id="suggestions_enabled"
857
- <?php checked($this->conf->options['suggestions_enabled']); ?>/>
858
- <?php _e('Suggest alternatives to broken links', 'broken-link-checker'); ?>
859
- </label>
860
- </p>
861
  </td>
862
  </tr>
863
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
864
  </table>
865
 
866
  </div>
@@ -930,7 +991,7 @@ class wsBrokenLinkChecker {
930
  <tr valign="top">
931
  <th scope="row"><?php _e('Exclusion list', 'broken-link-checker'); ?></th>
932
  <td><?php _e("Don't check links where the URL contains any of these words (one per line) :", 'broken-link-checker'); ?><br/>
933
- <textarea name="exclusion_list" id="exclusion_list" cols='45' rows='4' wrap='off'/><?php
934
  if( isset($this->conf->options['exclusion_list']) )
935
  echo implode("\n", $this->conf->options['exclusion_list']);
936
  ?></textarea>
@@ -1033,6 +1094,24 @@ class wsBrokenLinkChecker {
1033
  ?>
1034
  </td>
1035
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1036
 
1037
  <tr valign="top">
1038
  <th scope="row"><?php _e('Max. execution time', 'broken-link-checker'); ?></th>
@@ -1322,7 +1401,7 @@ class wsBrokenLinkChecker {
1322
  'broken-link-checker'
1323
  ) .
1324
  '</span>';
1325
- $html .= '<br><textarea name="blc_custom_fields" id="blc_custom_fields" cols="45" rows="4" />';
1326
  if( isset($current_settings['custom_fields']) )
1327
  $html .= implode("\n", $current_settings['custom_fields']);
1328
  $html .= '</textarea>';
@@ -1336,7 +1415,7 @@ class wsBrokenLinkChecker {
1336
  * @return void
1337
  */
1338
  function options_page_css(){
1339
- wp_enqueue_style('blc-options-page', plugins_url('css/options-page.css', BLC_PLUGIN_FILE), array(), '20140818');
1340
  wp_enqueue_style('dashboard');
1341
  }
1342
 
@@ -1347,7 +1426,7 @@ class wsBrokenLinkChecker {
1347
  * @return void
1348
  */
1349
  function links_page(){
1350
- global $wpdb, $blclog; /* @var wpdb $wpdb */
1351
 
1352
  $blc_link_query = blcLinkQuery::getInstance();
1353
 
@@ -1414,6 +1493,10 @@ class wsBrokenLinkChecker {
1414
  list($message, $msg_class) = $this->do_bulk_discard($selected_links);
1415
  break;
1416
 
 
 
 
 
1417
  case 'bulk-edit':
1418
  list($message, $msg_class) = $this->do_bulk_edit($selected_links);
1419
  break;
@@ -1459,7 +1542,7 @@ class wsBrokenLinkChecker {
1459
  var blc_suggestions_enabled = <?php echo $this->conf->options['suggestions_enabled'] ? 'true' : 'false'; ?>;
1460
  </script>
1461
 
1462
- <div class="wrap"><?php screen_icon(); ?>
1463
  <?php
1464
  $blc_link_query->print_filter_heading($current_filter);
1465
  $blc_link_query->print_filter_menu($filter_id);
@@ -2015,12 +2098,13 @@ class wsBrokenLinkChecker {
2015
  }
2016
 
2017
  //Skip links that weren't actually detected as broken
2018
- if ( !$link->broken ){
2019
  continue;
2020
  }
2021
 
2022
  //Make it appear "not broken"
2023
- $link->broken = false;
 
2024
  $link->false_positive = true;
2025
  $link->last_check_attempt = time();
2026
  $link->log = __("This link was manually marked as working by the user.", 'broken-link-checker');
@@ -2052,6 +2136,64 @@ class wsBrokenLinkChecker {
2052
 
2053
  return array(implode('<br>', $messages), $msg_class);
2054
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2055
 
2056
 
2057
  /**
@@ -2060,7 +2202,60 @@ class wsBrokenLinkChecker {
2060
  * @return void
2061
  */
2062
  function links_page_css(){
2063
- wp_enqueue_style('blc-links-page', plugins_url('css/links-page.css', $this->loader), array(), '20131008');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2064
  }
2065
 
2066
  /**
@@ -2186,7 +2381,16 @@ class wsBrokenLinkChecker {
2186
  * @return void
2187
  */
2188
  function work(){
2189
- global $wpdb, $blclog;
 
 
 
 
 
 
 
 
 
2190
 
2191
  if ( !$this->acquire_lock() ){
2192
  //FB::warn("Another instance of BLC is already working. Stop.");
@@ -2221,11 +2425,15 @@ class wsBrokenLinkChecker {
2221
 
2222
  //Don't stop the script when the connection is closed
2223
  ignore_user_abort( true );
2224
-
2225
  //Close the connection as per http://www.php.net/manual/en/features.connection-handling.php#71172
2226
  //This reduces resource usage.
2227
  //(Disable when debugging or you won't get the FirePHP output)
2228
- if ( !headers_sent() && (!defined('BLC_DEBUG') || !constant('BLC_DEBUG')) ){
 
 
 
 
2229
  @ob_end_clean(); //Discard the existing buffer, if any
2230
  header("Connection: close");
2231
  ob_start();
@@ -2455,7 +2663,7 @@ class wsBrokenLinkChecker {
2455
  * @return int|blcLink[]
2456
  */
2457
  function get_links_to_check($max_results = 0, $count_only = false){
2458
- global $wpdb, $blclog; /* @var wpdb $wpdb */
2459
 
2460
  $check_threshold = date('Y-m-d H:i:s', strtotime('-'.$this->conf->options['check_threshold'].' hours'));
2461
  $recheck_threshold = date('Y-m-d H:i:s', time() - $this->conf->options['recheck_threshold']);
@@ -2661,7 +2869,6 @@ class wsBrokenLinkChecker {
2661
  * @return array
2662
  */
2663
  function get_status(){
2664
- global $wpdb;
2665
  $blc_link_query = blcLinkQuery::getInstance();
2666
 
2667
  $check_threshold=date('Y-m-d H:i:s', strtotime('-'.$this->conf->options['check_threshold'].' hours'));
@@ -2710,6 +2917,7 @@ class wsBrokenLinkChecker {
2710
  }
2711
  //Make it appear "not broken"
2712
  $link->broken = false;
 
2713
  $link->false_positive = true;
2714
  $link->last_check_attempt = time();
2715
  $link->log = __("This link was manually marked as working by the user.", 'broken-link-checker');
@@ -2831,8 +3039,10 @@ class wsBrokenLinkChecker {
2831
  'status_text' => $new_status['text'],
2832
  'status_code' => $new_status['code'],
2833
  'http_code' => empty($new_link->http_code) ? '' : $new_link->http_code,
 
2834
 
2835
  'url' => $new_link->url,
 
2836
  'link_text' => isset($new_text) ? $new_text : null,
2837
  'ui_link_text' => isset($new_text) ? $ui_link_text : null,
2838
 
@@ -2897,6 +3107,108 @@ class wsBrokenLinkChecker {
2897
  )));
2898
  }
2899
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2900
 
2901
  function ajax_link_details(){
2902
  global $wpdb; /* @var wpdb $wpdb */
@@ -2984,8 +3296,8 @@ class wsBrokenLinkChecker {
2984
  wp_add_dashboard_widget(
2985
  'blc_dashboard_widget',
2986
  __('Broken Link Checker', 'broken-link-checker'),
2987
- array( &$this, 'dashboard_widget' ),
2988
- array( &$this, 'dashboard_widget_control' )
2989
  );
2990
  }
2991
  }
@@ -3313,7 +3625,7 @@ class wsBrokenLinkChecker {
3313
 
3314
  function send_html_email($email_address, $subject, $body) {
3315
  //Need to override the default 'text/plain' content type to send a HTML email.
3316
- add_filter('wp_mail_content_type', array(&$this, 'override_mail_content_type'));
3317
 
3318
  //Let auto-responders and similar software know this is an auto-generated email
3319
  //that they shouldn't respond to.
@@ -3323,7 +3635,7 @@ class wsBrokenLinkChecker {
3323
 
3324
  //Remove the override so that it doesn't interfere with other plugins that might
3325
  //want to send normal plaintext emails.
3326
- remove_filter('wp_mail_content_type', array(&$this, 'override_mail_content_type'));
3327
 
3328
  $this->conf->options['last_email'] = array(
3329
  'subject' => $subject,
@@ -3379,9 +3691,27 @@ class wsBrokenLinkChecker {
3379
  }
3380
  }
3381
 
3382
- function override_mail_content_type($content_type){
3383
  return 'text/html';
3384
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3385
 
3386
  /**
3387
  * Install or uninstall the plugin's Cron events based on current settings.
37
  * @param blcConfigurationManager $conf An instance of the configuration manager
38
  * @return void
39
  */
40
+ function wsBrokenLinkChecker ( $loader, $conf ) {
 
 
41
  $this->db_version = BLC_DATABASE_VERSION;
42
 
43
+ $this->conf = $conf;
44
  $this->loader = $loader;
45
  $this->my_basename = plugin_basename( $this->loader );
46
 
49
  //Unlike the activation hook, the deactivation callback *can* be registered in this file
50
  //because deactivation happens after this class has already been instantiated (durinng the
51
  //'init' action).
52
+ register_deactivation_hook($loader, array($this, 'deactivation'));
53
 
54
+ add_action('admin_menu', array($this,'admin_menu'));
55
 
56
  //Load jQuery on Dashboard pages (probably redundant as WP already does that)
57
+ add_action('admin_print_scripts', array($this,'admin_print_scripts'));
58
 
59
  //The dashboard widget
60
+ add_action('wp_dashboard_setup', array($this, 'hook_wp_dashboard_setup'));
61
 
62
  //AJAXy hooks
63
+ add_action( 'wp_ajax_blc_full_status', array($this,'ajax_full_status') );
64
+ add_action( 'wp_ajax_blc_dashboard_status', array($this,'ajax_dashboard_status') );
65
+ add_action( 'wp_ajax_blc_work', array($this,'ajax_work') );
66
+ add_action( 'wp_ajax_blc_discard', array($this,'ajax_discard') );
67
+ add_action( 'wp_ajax_blc_edit', array($this,'ajax_edit') );
68
+ add_action( 'wp_ajax_blc_link_details', array($this,'ajax_link_details') );
69
+ add_action( 'wp_ajax_blc_unlink', array($this,'ajax_unlink') );
70
+ add_action( 'wp_ajax_blc_recheck', array($this,'ajax_recheck') );
71
+ add_action( 'wp_ajax_blc_deredirect', array($this,'ajax_deredirect') );
72
+ add_action( 'wp_ajax_blc_current_load', array($this,'ajax_current_load') );
73
 
74
  add_action( 'wp_ajax_blc_dismiss', array($this, 'ajax_dismiss') );
75
  add_action( 'wp_ajax_blc_undismiss', array($this, 'ajax_undismiss') );
78
  $this->setup_cron_events();
79
 
80
  //Set hooks that listen for our Cron actions
81
+ add_action('blc_cron_email_notifications', array( $this, 'maybe_send_email_notifications' ));
82
+ add_action('blc_cron_check_links', array($this, 'cron_check_links'));
83
+ add_action('blc_cron_database_maintenance', array($this, 'database_maintenance'));
84
+ add_action('blc_cron_check_news', array($this, 'check_news'));
85
 
86
  //Set the footer hook that will call the worker function via AJAX.
87
+ add_action('admin_footer', array($this,'admin_footer'));
88
 
89
  //Add a "Screen Options" panel to the "Broken Links" page
90
  add_screen_options_panel(
95
  array($this, 'ajax_save_screen_options'),
96
  true
97
  );
98
+
99
+ //Display an explanatory note on the "Tools -> Broken Links -> Warnings" page.
100
+ add_action('admin_notices', array($this, 'show_warnings_section_notice'));
101
  }
102
 
103
  /**
165
  'action' : 'blc_dashboard_status',
166
  'random' : Math.random()
167
  },
168
+ function (data){
169
  if ( data && ( typeof(data.text) != 'undefined' ) ) {
170
  $('#wsblc_activity_box').html(data.text);
171
  <?php if ( $this->conf->options['autoexpand_widget'] ) { ?>
292
  */
293
  function admin_menu(){
294
  if (current_user_can('manage_options'))
295
+ add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
296
 
297
  $options_page_hook = add_options_page(
298
  __('Link Checker Settings', 'broken-link-checker'),
299
  __('Link Checker', 'broken-link-checker'),
300
  'manage_options',
301
+ 'link-checker-settings',array($this, 'options_page')
302
  );
303
 
304
  $menu_title = __('Broken Links', 'broken-link-checker');
320
  __('View Broken Links', 'broken-link-checker'),
321
  $menu_title,
322
  'edit_others_posts',
323
+ 'view-broken-links',array($this, 'links_page')
324
  );
325
 
326
  //Add plugin-specific scripts and CSS only to the it's own pages
327
+ add_action( 'admin_print_styles-' . $options_page_hook, array($this, 'options_page_css') );
328
+ add_action( 'admin_print_styles-' . $links_page_hook, array($this, 'links_page_css') );
329
+ add_action( 'admin_print_scripts-' . $options_page_hook, array($this, 'enqueue_settings_scripts') );
330
+ add_action( 'admin_print_scripts-' . $links_page_hook, array($this, 'enqueue_link_page_scripts') );
331
 
332
  //Add a "Feedback" button that links to the plugin's UserVoice forum
333
  add_screen_meta_link(
374
  }
375
 
376
  function options_page(){
 
 
377
  $moduleManager = blcModuleManager::getInstance();
378
 
379
  //Prior to 1.5.2 (released 2012-05-27), there was a bug that would cause the donation flag to be
396
  wp_redirect( add_query_arg( array( 'recheck-initiated' => true), $base_url ) );
397
  die();
398
  }
399
+
400
+ $available_link_actions = array(
401
+ 'edit' => __('Edit URL' , 'broken-link-checker'),
402
+ 'delete' => __('Unlink', 'broken-link-checker'),
403
+ 'blc-discard-action' => __('Not broken', 'broken-link-checker'),
404
+ 'blc-dismiss-action' => __('Dismiss', 'broken-link-checker'),
405
+ 'blc-recheck-action' => __('Recheck', 'broken-link-checker'),
406
+ 'blc-deredirect-action' => _x('Fix redirect', 'link action; replace one redirect with a direct link', 'broken-link-checker')
407
+ );
408
 
409
  if(isset($_POST['submit'])) {
410
  check_admin_referer('link-checker-options');
431
  if ( empty($enabled_post_statuses) ){
432
  $enabled_post_statuses = array('publish');
433
  }
434
+
435
+ //Did the user add/remove any post statuses?
436
+ $same_statuses = array_intersect($enabled_post_statuses, $this->conf->options['enabled_post_statuses']);
437
+ $post_statuses_changed = (count($same_statuses) != count($enabled_post_statuses))
438
+ || (count($same_statuses) !== count($this->conf->options['enabled_post_statuses']));
439
+
440
  $this->conf->options['enabled_post_statuses'] = $enabled_post_statuses;
441
+
 
442
  //The execution time limit must be above zero
443
  $new_execution_time = intval($_POST['max_execution_time']);
444
  if( $new_execution_time > 0 ){
481
  $diff1 = array_diff( $new_custom_fields, $this->conf->options['custom_fields'] );
482
  $diff2 = array_diff( $this->conf->options['custom_fields'], $new_custom_fields );
483
  $this->conf->options['custom_fields'] = $new_custom_fields;
484
+
485
+ //Turning off warnings turns existing warnings into "broken" links.
486
+ $warnings_enabled = !empty($_POST['warnings_enabled']);
487
+ if ( $this->conf->get('warnings_enabled') && !$warnings_enabled ) {
488
+ $this->promote_warnings_to_broken();
489
+ }
490
+ $this->conf->options['warnings_enabled'] = $warnings_enabled;
491
+
492
+ //HTTP timeout
493
  $new_timeout = intval($_POST['timeout']);
494
  if( $new_timeout > 0 ){
495
  $this->conf->options['timeout'] = $new_timeout ;
545
  $this->conf->options['dashboard_widget_capability'] = $widget_cap;
546
  }
547
 
548
+ //Link actions. The user can hide some of them to reduce UI clutter.
549
+ $show_link_actions = array();
550
+ foreach(array_keys($available_link_actions) as $action) {
551
+ $show_link_actions[$action] = isset($_POST['show_link_actions']) &&
552
+ !empty($_POST['show_link_actions'][$action]);
553
+ }
554
+ $this->conf->set('show_link_actions', $show_link_actions);
555
+
556
  //Logging. The plugin can log various events and results for debugging purposes.
557
  $this->conf->options['logging_enabled'] = !empty($_POST['logging_enabled']);
558
  $this->conf->options['custom_log_file_enabled'] = !empty($_POST['custom_log_file_enabled']);
604
  blc_got_unsynched_items();
605
  }
606
  }
607
+
608
+ //Resynchronize posts when the user enables or disables post statuses.
609
+ if ( $post_statuses_changed ) {
610
+ $overlord = blcPostTypeOverlord::getInstance();
611
+ $overlord->enabled_post_statuses = $this->conf->get('enabled_post_statuses', array());
612
+ $overlord->resynch('wsh_status_resynch_trigger');
613
+
614
+ blc_got_unsynched_items();
615
+ blc_cleanup_instances();
616
+ blc_cleanup_links();
617
+ }
618
 
619
  //Redirect back to the settings page
620
  $base_url = remove_query_arg( array('_wpnonce', 'noheader', 'updated', 'error', 'action', 'message') );
646
 
647
  $debug = $this->get_debug_info();
648
 
649
+ add_filter('blc-module-settings-custom_field', array($this, 'make_custom_field_input'), 10, 2);
 
650
 
651
  //Translate and markup-ify module headers for display
652
  $modules = $moduleManager->get_modules_by_category('', true, true);
678
  <![endif]-->
679
 
680
  <div class="wrap" id="blc-settings-wrap">
681
+ <h2><?php _e('Broken Link Checker Options', 'broken-link-checker'); ?></h2>
682
 
683
 
684
  <div id="blc-sidebar">
822
  |
823
  <a id="toggle-broken-link-css-editor" href="#" class="blc-toggle-link"><?php
824
  _e('Edit CSS', 'broken-link-checker');
825
+ ?></a>
826
  </p>
827
 
828
  <div id="broken-link-css-wrap"<?php
830
  echo ' class="hidden"';
831
  }
832
  ?>>
833
+ <textarea name="broken_link_css" id="broken_link_css" cols='45' rows='4'><?php
834
  if( isset($this->conf->options['broken_link_css']) ) {
835
  echo $this->conf->options['broken_link_css'];
836
  }
861
  echo ' class="hidden"';
862
  }
863
  ?>>
864
+ <textarea name="removed_link_css" id="removed_link_css" cols='45' rows='4'><?php
865
  if( isset($this->conf->options['removed_link_css']) )
866
  echo $this->conf->options['removed_link_css'];
867
  ?></textarea>
885
  </label>
886
  </p>
887
 
888
+ <p class="description">
889
+ <?php
890
+ echo _x(
891
+ 'These settings only apply to the content of posts, not comments or custom fields.',
892
+ '"Link tweaks" settings',
893
+ 'broken-link-checker'
894
+ );
895
+ ?>
896
+ </p>
897
  </td>
898
  </tr>
899
 
900
  <tr valign="top">
901
  <th scope="row"><?php echo _x('Suggestions', 'settings page', 'broken-link-checker'); ?></th>
902
  <td>
903
+ <label>
904
+ <input type="checkbox" name="suggestions_enabled" id="suggestions_enabled"
905
+ <?php checked($this->conf->options['suggestions_enabled']); ?>/>
906
+ <?php _e('Suggest alternatives to broken links', 'broken-link-checker'); ?>
907
+ </label>
 
 
908
  </td>
909
  </tr>
910
+
911
+ <tr valign="top">
912
+ <th scope="row"><?php echo _x('Warnings', 'settings page', 'broken-link-checker'); ?></th>
913
+ <td id="blc_warning_settings">
914
+ <label>
915
+ <input type="checkbox" name="warnings_enabled" id="warnings_enabled"
916
+ <?php checked($this->conf->options['warnings_enabled']); ?>/>
917
+ <?php _e('Show uncertain or minor problems as "warnings" instead of "broken"', 'broken-link-checker'); ?>
918
+ </label>
919
+ <p class="description"><?php
920
+ _e('Turning off this option will make the plugin report all problems as broken links.', 'broken-link-checker');
921
+ ?></p>
922
+ </td>
923
+ </tr>
924
+
925
  </table>
926
 
927
  </div>
991
  <tr valign="top">
992
  <th scope="row"><?php _e('Exclusion list', 'broken-link-checker'); ?></th>
993
  <td><?php _e("Don't check links where the URL contains any of these words (one per line) :", 'broken-link-checker'); ?><br/>
994
+ <textarea name="exclusion_list" id="exclusion_list" cols='45' rows='4'><?php
995
  if( isset($this->conf->options['exclusion_list']) )
996
  echo implode("\n", $this->conf->options['exclusion_list']);
997
  ?></textarea>
1094
  ?>
1095
  </td>
1096
  </tr>
1097
+
1098
+ <tr valign="top">
1099
+ <th scope="row"><?php echo _x('Show link actions', 'settings page', 'broken-link-checker'); ?></th>
1100
+ <td>
1101
+ <?php
1102
+ $show_link_actions = $this->conf->get('show_link_actions', array());
1103
+ foreach($available_link_actions as $action => $text) {
1104
+ $enabled = isset($show_link_actions[$action]) ? (bool)($show_link_actions[$action]) : true;
1105
+ printf(
1106
+ '<p><label><input type="checkbox" name="show_link_actions[%1$s]" %3$s> %2$s</label></p>',
1107
+ $action,
1108
+ $text,
1109
+ checked($enabled, true, false)
1110
+ );
1111
+ }
1112
+ ?>
1113
+ </td>
1114
+ </tr>
1115
 
1116
  <tr valign="top">
1117
  <th scope="row"><?php _e('Max. execution time', 'broken-link-checker'); ?></th>
1401
  'broken-link-checker'
1402
  ) .
1403
  '</span>';
1404
+ $html .= '<br><textarea name="blc_custom_fields" id="blc_custom_fields" cols="45" rows="4">';
1405
  if( isset($current_settings['custom_fields']) )
1406
  $html .= implode("\n", $current_settings['custom_fields']);
1407
  $html .= '</textarea>';
1415
  * @return void
1416
  */
1417
  function options_page_css(){
1418
+ wp_enqueue_style('blc-options-page', plugins_url('css/options-page.css', BLC_PLUGIN_FILE), array(), '20141113');
1419
  wp_enqueue_style('dashboard');
1420
  }
1421
 
1426
  * @return void
1427
  */
1428
  function links_page(){
1429
+ global $wpdb; /* @var wpdb $wpdb */
1430
 
1431
  $blc_link_query = blcLinkQuery::getInstance();
1432
 
1493
  list($message, $msg_class) = $this->do_bulk_discard($selected_links);
1494
  break;
1495
 
1496
+ case 'bulk-dismiss':
1497
+ list($message, $msg_class) = $this->do_bulk_dismiss($selected_links);
1498
+ break;
1499
+
1500
  case 'bulk-edit':
1501
  list($message, $msg_class) = $this->do_bulk_edit($selected_links);
1502
  break;
1542
  var blc_suggestions_enabled = <?php echo $this->conf->options['suggestions_enabled'] ? 'true' : 'false'; ?>;
1543
  </script>
1544
 
1545
+ <div class="wrap">
1546
  <?php
1547
  $blc_link_query->print_filter_heading($current_filter);
1548
  $blc_link_query->print_filter_menu($filter_id);
2098
  }
2099
 
2100
  //Skip links that weren't actually detected as broken
2101
+ if ( !$link->broken && !$link->warning ){
2102
  continue;
2103
  }
2104
 
2105
  //Make it appear "not broken"
2106
+ $link->broken = false;
2107
+ $link->warning = false;
2108
  $link->false_positive = true;
2109
  $link->last_check_attempt = time();
2110
  $link->log = __("This link was manually marked as working by the user.", 'broken-link-checker');
2136
 
2137
  return array(implode('<br>', $messages), $msg_class);
2138
  }
2139
+
2140
+ /**
2141
+ * Dismiss multiple links.
2142
+ *
2143
+ * @param array $selected_links An array of link IDs
2144
+ * @return array Confirmation message and the CSS class to use with that message.
2145
+ */
2146
+ function do_bulk_dismiss($selected_links){
2147
+ check_admin_referer( 'bulk-action' );
2148
+
2149
+ $messages = array();
2150
+ $msg_class = 'updated';
2151
+ $processed_links = 0;
2152
+
2153
+ if ( count($selected_links) > 0 ){
2154
+ foreach($selected_links as $link_id){
2155
+ //Load the link
2156
+ $link = new blcLink( intval($link_id) );
2157
+
2158
+ //Skip links that don't actually exist
2159
+ if ( !$link->valid() ){
2160
+ continue;
2161
+ }
2162
+
2163
+ //We can only dismiss broken links and redirects.
2164
+ if ( !($link->broken || $link->warning || ($link->redirect_count > 0)) ){
2165
+ continue;
2166
+ }
2167
+
2168
+ $link->dismissed = true;
2169
+
2170
+ //Save the changes
2171
+ if ( $link->save() ){
2172
+ $processed_links++;
2173
+ } else {
2174
+ $messages[] = sprintf(
2175
+ __("Couldn't modify link %d", 'broken-link-checker'),
2176
+ $link_id
2177
+ );
2178
+ $msg_class = 'error';
2179
+ }
2180
+ }
2181
+ }
2182
+
2183
+ if ( $processed_links > 0 ){
2184
+ $messages[] = sprintf(
2185
+ _n(
2186
+ '%d link dismissed',
2187
+ '%d links dismissed',
2188
+ $processed_links,
2189
+ 'broken-link-checker'
2190
+ ),
2191
+ $processed_links
2192
+ );
2193
+ }
2194
+
2195
+ return array(implode('<br>', $messages), $msg_class);
2196
+ }
2197
 
2198
 
2199
  /**
2202
  * @return void
2203
  */
2204
  function links_page_css(){
2205
+ wp_enqueue_style('blc-links-page', plugins_url('css/links-page.css', $this->loader), array(), '20141113-2');
2206
+ }
2207
+
2208
+ /**
2209
+ * Show an admin notice that explains what the "Warnings" section under "Tools -> Broken Links" does.
2210
+ * The user can hide the notice.
2211
+ */
2212
+ public function show_warnings_section_notice() {
2213
+ $is_warnings_section = isset($_GET['filter_id'])
2214
+ && ($_GET['filter_id'] === 'warnings')
2215
+ && isset($_GET['page'])
2216
+ && ($_GET['page'] === 'view-broken-links');
2217
+
2218
+ if ( !($is_warnings_section && current_user_can('edit_others_posts')) ) {
2219
+ return;
2220
+ }
2221
+
2222
+ //Let the user hide the notice.
2223
+ $conf = blc_get_configuration();
2224
+ $notice_name = 'show_warnings_section_hint';
2225
+
2226
+ if ( isset($_GET[$notice_name]) && is_numeric($_GET[$notice_name]) ) {
2227
+ $conf->set($notice_name, (bool)$_GET[$notice_name]);
2228
+ $conf->save_options();
2229
+ }
2230
+ if ( !$conf->get($notice_name, true) ) {
2231
+ return;
2232
+ }
2233
+
2234
+ printf(
2235
+ '<div class="updated">
2236
+ <p>%1$s</p>
2237
+ <p>
2238
+ <a href="%2$s">%3$s</a> |
2239
+ <a href="%4$s">%5$s</a>
2240
+ <p>
2241
+ </div>',
2242
+ __(
2243
+ 'The "Warnings" page lists problems that are probably temporary or suspected to be false positives.<br> Warnings that persist for a long time will usually be reclassified as broken links.',
2244
+ 'broken-link-checker'
2245
+ ),
2246
+ add_query_arg($notice_name, '0'),
2247
+ _x(
2248
+ 'Hide notice',
2249
+ 'admin notice under Tools - Broken links - Warnings',
2250
+ 'broken-link-checker'
2251
+ ),
2252
+ admin_url('options-general.php?page=link-checker-settings#blc_warning_settings'),
2253
+ _x(
2254
+ 'Change warning settings',
2255
+ 'a link from the admin notice under Tools - Broken links - Warnings',
2256
+ 'broken-link-checker'
2257
+ )
2258
+ );
2259
  }
2260
 
2261
  /**
2381
  * @return void
2382
  */
2383
  function work(){
2384
+ global $blclog;
2385
+
2386
+ //Close the session to prevent lock-ups.
2387
+ //PHP sessions are blocking. session_start() will wait until all other scripts that are using the same session
2388
+ //are finished. As a result, a long-running script that unintentionally keeps the session open can cause
2389
+ //the entire site to "lock up" for the current user/browser. WordPress itself doesn't use sessions, but some
2390
+ //plugins do, so we should explicitly close the session (if any) before starting the worker.
2391
+ if ( session_id() != '' ) {
2392
+ session_write_close();
2393
+ }
2394
 
2395
  if ( !$this->acquire_lock() ){
2396
  //FB::warn("Another instance of BLC is already working. Stop.");
2425
 
2426
  //Don't stop the script when the connection is closed
2427
  ignore_user_abort( true );
2428
+
2429
  //Close the connection as per http://www.php.net/manual/en/features.connection-handling.php#71172
2430
  //This reduces resource usage.
2431
  //(Disable when debugging or you won't get the FirePHP output)
2432
+ if (
2433
+ !headers_sent()
2434
+ && (defined('DOING_AJAX') && constant('DOING_AJAX'))
2435
+ && (!defined('BLC_DEBUG') || !constant('BLC_DEBUG'))
2436
+ ){
2437
  @ob_end_clean(); //Discard the existing buffer, if any
2438
  header("Connection: close");
2439
  ob_start();
2663
  * @return int|blcLink[]
2664
  */
2665
  function get_links_to_check($max_results = 0, $count_only = false){
2666
+ global $wpdb; /* @var wpdb $wpdb */
2667
 
2668
  $check_threshold = date('Y-m-d H:i:s', strtotime('-'.$this->conf->options['check_threshold'].' hours'));
2669
  $recheck_threshold = date('Y-m-d H:i:s', time() - $this->conf->options['recheck_threshold']);
2869
  * @return array
2870
  */
2871
  function get_status(){
 
2872
  $blc_link_query = blcLinkQuery::getInstance();
2873
 
2874
  $check_threshold=date('Y-m-d H:i:s', strtotime('-'.$this->conf->options['check_threshold'].' hours'));
2917
  }
2918
  //Make it appear "not broken"
2919
  $link->broken = false;
2920
+ $link->warning = false;
2921
  $link->false_positive = true;
2922
  $link->last_check_attempt = time();
2923
  $link->log = __("This link was manually marked as working by the user.", 'broken-link-checker');
3039
  'status_text' => $new_status['text'],
3040
  'status_code' => $new_status['code'],
3041
  'http_code' => empty($new_link->http_code) ? '' : $new_link->http_code,
3042
+ 'redirect_count' => $new_link->redirect_count,
3043
 
3044
  'url' => $new_link->url,
3045
+ 'final_url' => $new_link->final_url,
3046
  'link_text' => isset($new_text) ? $new_text : null,
3047
  'ui_link_text' => isset($new_text) ? $ui_link_text : null,
3048
 
3107
  )));
3108
  }
3109
  }
3110
+
3111
+ public function ajax_deredirect() {
3112
+ if ( !current_user_can('edit_others_posts') || !check_ajax_referer('blc_deredirect', false, false) ){
3113
+ die( json_encode( array(
3114
+ 'error' => __("You're not allowed to do that!", 'broken-link-checker')
3115
+ )));
3116
+ }
3117
+
3118
+ if ( !isset($_POST['link_id']) || !is_numeric($_POST['link_id']) ) {
3119
+ die( json_encode( array(
3120
+ 'error' => __("Error : link_id not specified", 'broken-link-checker')
3121
+ )));
3122
+ }
3123
+
3124
+ $id = intval($_POST['link_id']);
3125
+ $link = new blcLink($id);
3126
+
3127
+ if ( !$link->valid() ){
3128
+ die( json_encode( array(
3129
+ 'error' => sprintf(__("Oops, I can't find the link %d", 'broken-link-checker'), $id)
3130
+ )));
3131
+ }
3132
+
3133
+ //The actual task is simple; it's error handling that's complicated.
3134
+ $result = $link->deredirect();
3135
+ if ( is_wp_error($result) ) {
3136
+ die( json_encode( array(
3137
+ 'error' => sprintf('%s [%s]', $result->get_error_message(), $result->get_error_code())
3138
+ )));
3139
+ }
3140
+
3141
+ $link = $result['new_link'] /** @var blcLink $link */;
3142
+
3143
+ $status = $link->analyse_status();
3144
+ $response = array(
3145
+ 'url' => $link->url,
3146
+ 'new_link_id' => $result['new_link_id'],
3147
+
3148
+ 'status_text' => $status['text'],
3149
+ 'status_code' => $status['code'],
3150
+ 'http_code' => empty($link->http_code) ? '' : $link->http_code,
3151
+ 'redirect_count' => $link->redirect_count,
3152
+ 'final_url' => $link->final_url,
3153
+
3154
+ 'cnt_okay' => $result['cnt_okay'],
3155
+ 'cnt_error' => $result['cnt_error'],
3156
+ 'errors' => array(),
3157
+ );
3158
+
3159
+ //Convert WP_Error's to simple strings.
3160
+ if ( !empty($result['errors']) ) {
3161
+ foreach($result['errors'] as $error) { /** @var WP_Error $error */
3162
+ $response['errors'][] = $error->get_error_message();
3163
+ }
3164
+ }
3165
+
3166
+ die(json_encode($response));
3167
+ }
3168
+
3169
+ /**
3170
+ * AJAX hook for the "Recheck" action.
3171
+ */
3172
+ public function ajax_recheck() {
3173
+ if (!current_user_can('edit_others_posts') || !check_ajax_referer('blc_recheck', false, false)){
3174
+ die( json_encode( array(
3175
+ 'error' => __("You're not allowed to do that!", 'broken-link-checker')
3176
+ )));
3177
+ }
3178
+
3179
+ if ( !isset($_POST['link_id']) || !is_numeric($_POST['link_id']) ) {
3180
+ die( json_encode( array(
3181
+ 'error' => __("Error : link_id not specified", 'broken-link-checker')
3182
+ )));
3183
+ }
3184
+
3185
+ $id = intval($_POST['link_id']);
3186
+ $link = new blcLink($id);
3187
+
3188
+ if ( !$link->valid() ){
3189
+ die( json_encode( array(
3190
+ 'error' => sprintf(__("Oops, I can't find the link %d", 'broken-link-checker'), $id)
3191
+ )));
3192
+ }
3193
+
3194
+ //In case the immediate check fails, this will ensure the link is checked during the next work() run.
3195
+ $link->last_check_attempt = 0;
3196
+ $link->save();
3197
+
3198
+ //Check the link and save the results.
3199
+ $link->check(true);
3200
+
3201
+ $status = $link->analyse_status();
3202
+ $response = array(
3203
+ 'status_text' => $status['text'],
3204
+ 'status_code' => $status['code'],
3205
+ 'http_code' => empty($link->http_code) ? '' : $link->http_code,
3206
+ 'redirect_count' => $link->redirect_count,
3207
+ 'final_url' => $link->final_url,
3208
+ );
3209
+
3210
+ die(json_encode($response));
3211
+ }
3212
 
3213
  function ajax_link_details(){
3214
  global $wpdb; /* @var wpdb $wpdb */
3296
  wp_add_dashboard_widget(
3297
  'blc_dashboard_widget',
3298
  __('Broken Link Checker', 'broken-link-checker'),
3299
+ array( $this, 'dashboard_widget' ),
3300
+ array( $this, 'dashboard_widget_control' )
3301
  );
3302
  }
3303
  }
3625
 
3626
  function send_html_email($email_address, $subject, $body) {
3627
  //Need to override the default 'text/plain' content type to send a HTML email.
3628
+ add_filter('wp_mail_content_type', array($this, 'override_mail_content_type'));
3629
 
3630
  //Let auto-responders and similar software know this is an auto-generated email
3631
  //that they shouldn't respond to.
3635
 
3636
  //Remove the override so that it doesn't interfere with other plugins that might
3637
  //want to send normal plaintext emails.
3638
+ remove_filter('wp_mail_content_type', array($this, 'override_mail_content_type'));
3639
 
3640
  $this->conf->options['last_email'] = array(
3641
  'subject' => $subject,
3691
  }
3692
  }
3693
 
3694
+ function override_mail_content_type(/** @noinspection PhpUnusedParameterInspection */ $content_type){
3695
  return 'text/html';
3696
  }
3697
+
3698
+ /**
3699
+ * Promote all links with the "warning" status to "broken".
3700
+ */
3701
+ private function promote_warnings_to_broken() {
3702
+ global $wpdb; /** @var wpdb $wpdb */
3703
+ $wpdb->update(
3704
+ $wpdb->prefix . 'blc_links',
3705
+ array(
3706
+ 'broken' => 1,
3707
+ 'warning' => 0,
3708
+ ),
3709
+ array(
3710
+ 'warning' => 1,
3711
+ ),
3712
+ '%d'
3713
+ );
3714
+ }
3715
 
3716
  /**
3717
  * Install or uninstall the plugin's Cron events based on current settings.
core/init.php CHANGED
@@ -86,7 +86,10 @@ $blc_config_manager = new blcConfigurationManager(
86
  'last_notification_sent' => 0, //When the last email notification was sent (Unix timestamp)
87
 
88
  'suggestions_enabled' => true, //Whether to suggest alternative URLs for broken links.
89
-
 
 
 
90
  'server_load_limit' => null, //Stop parsing stuff & checking links if the 1-minute load average
91
  //goes over this value. Only works on Linux servers. 0 = no limit.
92
  'enable_load_limit' => true, //Enable/disable load monitoring.
@@ -122,6 +125,9 @@ $blc_config_manager = new blcConfigurationManager(
122
 
123
  'user_has_donated' => false, //Whether the user has donated to the plugin.
124
  'donation_flag_fixed' => false,
 
 
 
125
  )
126
  );
127
 
86
  'last_notification_sent' => 0, //When the last email notification was sent (Unix timestamp)
87
 
88
  'suggestions_enabled' => true, //Whether to suggest alternative URLs for broken links.
89
+
90
+ 'warnings_enabled' => true, //Try to automatically detect temporary problems and false positives,
91
+ //and report them as "Warnings" instead of broken links.
92
+
93
  'server_load_limit' => null, //Stop parsing stuff & checking links if the 1-minute load average
94
  //goes over this value. Only works on Linux servers. 0 = no limit.
95
  'enable_load_limit' => true, //Enable/disable load monitoring.
125
 
126
  'user_has_donated' => false, //Whether the user has donated to the plugin.
127
  'donation_flag_fixed' => false,
128
+
129
+ //Visible link actions.
130
+ 'show_link_actions' => array('blc-deredirect-action' => false),
131
  )
132
  );
133
 
css/links-page.css CHANGED
@@ -84,6 +84,10 @@ td.column-new-url .mini-status {
84
  color: black;
85
  }
86
 
 
 
 
 
87
  /* Styles for broken links, redirects and other link states or types */
88
 
89
  .blc-redirect .blc-link-url {
@@ -200,6 +204,15 @@ td.column-status {
200
  display: none;
201
  }
202
 
 
 
 
 
 
 
 
 
 
203
  /* Misc table styles */
204
 
205
  .blc-link-url {
@@ -455,7 +468,7 @@ div.search-box{
455
  }
456
 
457
  /* Filter-related styles */
458
- .base-filter-all .blc-dismiss-button {
459
  display: none;
460
  }
461
 
84
  color: black;
85
  }
86
 
87
+ table.mini-status {
88
+ border-spacing: 0;
89
+ }
90
+
91
  /* Styles for broken links, redirects and other link states or types */
92
 
93
  .blc-redirect .blc-link-url {
204
  display: none;
205
  }
206
 
207
+
208
+ /* Only show the "Details" link in the compact view. */
209
+ #blc-links .column-status .row-actions {
210
+ display: none;
211
+ }
212
+ #blc-links.compact .column-status .row-actions {
213
+ display: block;
214
+ }
215
+
216
  /* Misc table styles */
217
 
218
  .blc-link-url {
468
  }
469
 
470
  /* Filter-related styles */
471
+ .base-filter-all .blc-dismiss-action {
472
  display: none;
473
  }
474
 
css/options-page.css CHANGED
@@ -235,4 +235,9 @@ ul.ui-tabs-nav li.ui-tabs-active a {
235
 
236
  #blc-settings-wrap .hndle {
237
  cursor: default;
 
 
 
 
 
238
  }
235
 
236
  #blc-settings-wrap .hndle {
237
  cursor: default;
238
+ }
239
+
240
+ /* Miscellaneous */
241
+ td:target, label:target {
242
+ background: #ffffaa;
243
  }
includes/admin/db-schema.php CHANGED
@@ -62,7 +62,8 @@ function blc_get_db_schema(){
62
  `status_text` varchar(250) DEFAULT '',
63
  `request_duration` float NOT NULL DEFAULT '0',
64
  `timeout` tinyint(1) unsigned NOT NULL DEFAULT '0',
65
- `broken` tinyint(1) NOT NULL DEFAULT '0',
 
66
  `may_recheck` tinyint(1) NOT NULL DEFAULT '1',
67
  `being_checked` tinyint(1) NOT NULL DEFAULT '0',
68
 
62
  `status_text` varchar(250) DEFAULT '',
63
  `request_duration` float NOT NULL DEFAULT '0',
64
  `timeout` tinyint(1) unsigned NOT NULL DEFAULT '0',
65
+ `broken` tinyint(1) unsigned NOT NULL DEFAULT '0',
66
+ `warning` tinyint(1) unsigned NOT NULL DEFAULT '0',
67
  `may_recheck` tinyint(1) NOT NULL DEFAULT '1',
68
  `being_checked` tinyint(1) NOT NULL DEFAULT '0',
69
 
includes/admin/links-page-js.php CHANGED
@@ -57,6 +57,7 @@ jQuery(function($){
57
  var master = $(this).parents('.blc-row');
58
  var link_id = master.attr('id').split('-')[2];
59
  $('#link-details-'+link_id).toggle();
 
60
  });
61
 
62
  var ajaxInProgressHtml = '<?php echo esc_js(__('Wait...', 'broken-link-checker')); ?>';
@@ -89,9 +90,11 @@ jQuery(function($){
89
  master.attr('class', classNames);
90
 
91
  //Flash the main row green to indicate success, then remove it if the current view
92
- //is supposed to show only broken links.
 
 
93
  flashElementGreen(master, function(){
94
- if ( blc_is_broken_filter ){
95
  details.remove();
96
  master.remove();
97
  } else {
@@ -100,7 +103,7 @@ jQuery(function($){
100
  });
101
 
102
  //Update the elements displaying the number of results for the current filter.
103
- if( blc_is_broken_filter ){
104
  alterLinkCounter(-1);
105
  }
106
  } else {
@@ -121,7 +124,7 @@ jQuery(function($){
121
 
122
  var master = me.closest('.blc-row');
123
  var link_id = master.attr('id').split('-')[2];
124
- var should_hide_link = (blc_current_base_filter == 'broken') || (blc_current_base_filter == 'redirects');
125
 
126
  $.post(
127
  "<?php echo admin_url('admin-ajax.php'); ?>",
@@ -206,12 +209,134 @@ jQuery(function($){
206
  return false;
207
  });
208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  function flashElementGreen(element, callback) {
210
  var oldColor = element.css('background-color');
211
  element.animate({ backgroundColor: "#E0FFB3" }, 200).animate({ backgroundColor: oldColor }, 300, callback);
212
  }
213
 
214
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  /**
216
  * Display the inline link editor.
217
  *
@@ -375,84 +500,73 @@ jQuery(function($){
375
  progressIndicator.hide();
376
  updateButton.prop('disabled', false);
377
 
378
- if (response && (typeof(response['error']) != 'undefined')){
379
- //An internal error occurred before the link could be edited.
380
- alert(response.error);
381
- } else if (response.errors.length > 0) {
382
- //Build and display an error message.
383
- var msg = '';
384
-
385
- if ( response.cnt_okay > 0 ){
386
- var fragment = sprintf(
387
- '<?php echo esc_js(__('%d instances of the link were successfully modified.', 'broken-link-checker')); ?>',
388
- response.cnt_okay
389
- );
390
- msg = msg + fragment + '\n';
391
- if ( response.cnt_error > 0 ){
392
- fragment = sprintf(
393
- '<?php echo esc_js(__("However, %d instances couldn't be edited and still point to the old URL.", 'broken-link-checker')); ?>',
394
- response.cnt_error
395
- );
396
- msg = msg + fragment + "\n";
397
- }
398
- } else {
399
- msg = msg + '<?php echo esc_js(__('The link could not be modified.', 'broken-link-checker')); ?>\n';
400
- }
401
-
402
- msg = msg + '\n<?php echo esc_js(__("The following error(s) occurred :", 'broken-link-checker')); ?>\n* ';
403
- msg = msg + response.errors.join('\n* ');
404
-
405
- alert(msg);
406
- } else {
407
- //Everything went well. Update the link row with the new values.
408
 
409
- //Replace the displayed link URL with the new one.
410
- urlElement.attr('href', response.url).text(response.url);
411
-
412
- //Save the new ID
413
- replaceLinkId(linkId, response.new_link_id);
414
- //Load up the new link info
415
- reloadDetailsRow(response.new_link_id);
416
 
417
- //Update the link text if it was edited.
418
- if ((newText !== null) && (response.link_text !== null)) {
419
- master.data('link-text', response.link_text);
420
- if (response.ui_link_text !== null) {
421
- master.find('.column-new-link-text').html(response.ui_link_text);
422
- }
423
- }
424
 
425
- //Update the status code and class.
426
- var statusColumn = master.find('td.column-status');
427
- if (response.status_text) {
428
- statusColumn.find('.status-text').text(response.status_text);
429
- }
430
- statusColumn.find('.http-code').text(response.http_code ? response.http_code : '');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
 
432
- var oldStatusClass = master.attr('class').match(/(?:^|\s)(link-status-[^\s]+)(?:\s|$)/);
433
- oldStatusClass = oldStatusClass ? oldStatusClass[1] : '';
434
- var newStatusClass = 'link-status-' + response.status_code;
435
 
436
- statusColumn.find('.link-status-row').removeClass(oldStatusClass).addClass(newStatusClass);
437
- master.removeClass(oldStatusClass).addClass(newStatusClass);
 
 
438
 
439
- //Last check time and failure duration are complicated to update, so we'll just hide them.
440
- //The user can refresh the page to get the new values.
441
- statusColumn.find('.link-last-checked td').html('&nbsp;');
442
- statusColumn.find('.link-broken-for td').html('&nbsp;');
443
 
444
- //We don't know if the link is still a redirect.
445
- master.removeClass('blc-redirect');
 
 
446
 
447
- //Flash the row green to indicate success
448
- flashElementGreen(master);
 
 
 
449
  }
 
450
 
451
- hideLinkEditor(editRow);
452
- },
453
- 'json'
454
- );
455
 
 
 
 
 
 
456
  }
457
 
458
  //The "Edit URL" button - displays the inline editor
@@ -598,25 +712,19 @@ jQuery(function($){
598
  dialogClass : 'blc-search-container',
599
  resizable: false
600
  });
601
-
602
  $('#blc-open-search-box').click(function(){
603
  if ( searchForm.dialog('isOpen') ){
604
  searchForm.dialog('close');
605
  } else {
606
- //Display the search form under the "Search" button
607
- var button_position = $('#blc-open-search-box').offset();
608
- var button_height = $('#blc-open-search-box').outerHeight(true);
609
- var button_width = $('#blc-open-search-box').outerWidth(true);
610
-
611
- var dialog_width = searchForm.dialog('option', 'width');
612
-
613
- searchForm.dialog('option', 'position',
614
- [
615
- button_position.left - dialog_width + button_width/2,
616
- button_position.top + button_height + 1 - $(document).scrollTop()
617
- ]
618
- );
619
- searchForm.dialog('open');
620
  }
621
  });
622
 
@@ -687,6 +795,24 @@ jQuery(function($){
687
  }
688
  }
689
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
690
 
691
  //------------------------------------------------------------
692
  // Manipulate highlight settings for permanently broken links
@@ -799,6 +925,8 @@ jQuery(function($){
799
  e.preventDefault();
800
  }
801
  });
 
 
802
  });
803
 
804
  </script>
57
  var master = $(this).parents('.blc-row');
58
  var link_id = master.attr('id').split('-')[2];
59
  $('#link-details-'+link_id).toggle();
60
+ return false;
61
  });
62
 
63
  var ajaxInProgressHtml = '<?php echo esc_js(__('Wait...', 'broken-link-checker')); ?>';
90
  master.attr('class', classNames);
91
 
92
  //Flash the main row green to indicate success, then remove it if the current view
93
+ //is supposed to show only broken links or warnings.
94
+ var should_hide_link = blc_is_broken_filter || (blc_current_base_filter == 'warnings');
95
+
96
  flashElementGreen(master, function(){
97
+ if ( should_hide_link ){
98
  details.remove();
99
  master.remove();
100
  } else {
103
  });
104
 
105
  //Update the elements displaying the number of results for the current filter.
106
+ if( should_hide_link ){
107
  alterLinkCounter(-1);
108
  }
109
  } else {
124
 
125
  var master = me.closest('.blc-row');
126
  var link_id = master.attr('id').split('-')[2];
127
+ var should_hide_link = $.inArray(blc_current_base_filter, ['broken', 'redirects', 'warnings']) > -1;
128
 
129
  $.post(
130
  "<?php echo admin_url('admin-ajax.php'); ?>",
209
  return false;
210
  });
211
 
212
+ //The "Recheck" button.
213
+ $(".blc-recheck-button").click(function () {
214
+ var me = $(this);
215
+ var oldButtonHtml = me.html();
216
+ me.html(ajaxInProgressHtml);
217
+
218
+ var master = me.closest('.blc-row');
219
+ var link_id = master.attr('id').split('-')[2];
220
+
221
+ $.post(
222
+ "<?php echo admin_url('admin-ajax.php'); ?>",
223
+ {
224
+ 'action' : 'blc_recheck',
225
+ 'link_id' : link_id,
226
+ '_ajax_nonce' : '<?php echo esc_js(wp_create_nonce('blc_recheck')); ?>'
227
+ },
228
+ function (response){
229
+ me.html(oldButtonHtml);
230
+
231
+ if (response && (typeof(response['error']) != 'undefined')){
232
+ //An internal error occurred before the plugin could check the link (e.g. database error).
233
+ alert(response.error);
234
+ } else {
235
+ //Display the new status in the link row.
236
+ displayLinkStatus(master, response);
237
+ reloadDetailsRow(link_id);
238
+
239
+ //Flash the row green to indicate success
240
+ flashElementGreen(master);
241
+ }
242
+ },
243
+ 'json'
244
+ );
245
+
246
+ return false;
247
+ });
248
+
249
+ //The "Fix redirect" action.
250
+ $('.blc-deredirect-button').click(function() {
251
+ //This action can only be used once. If it succeeds, it will no longer be applicable to the current link.
252
+ //If it fails, something is broken and trying again probably won't help.
253
+ var me = $(this);
254
+ me.text(ajaxInProgressHtml);
255
+
256
+ var master = me.closest('.blc-row');
257
+ var linkId = master.attr('id').split('-')[2];
258
+ var shouldHideLink = blc_current_base_filter == 'redirects';
259
+ var details = $('#link-details-' + linkId);
260
+
261
+ $.post(
262
+ "<?php echo admin_url('admin-ajax.php'); ?>",
263
+ {
264
+ 'action' : 'blc_deredirect',
265
+ 'link_id' : linkId,
266
+ '_ajax_nonce' : '<?php echo esc_js(wp_create_nonce('blc_deredirect')); ?>'
267
+ },
268
+ function (response){
269
+ me.closest('span').hide();
270
+
271
+ if (handleEditResponse(response, master, linkId, null)) {
272
+ if (shouldHideLink) {
273
+ details.remove();
274
+ master.remove();
275
+ }
276
+ }
277
+ },
278
+ 'json'
279
+ );
280
+
281
+ return false;
282
+ });
283
+
284
  function flashElementGreen(element, callback) {
285
  var oldColor = element.css('background-color');
286
  element.animate({ backgroundColor: "#E0FFB3" }, 200).animate({ backgroundColor: oldColor }, 300, callback);
287
  }
288
 
289
 
290
+ /**
291
+ * Update status indicators for a link. This includes the contents of the "Status" column, CSS classes and so on.
292
+ *
293
+ * @param {Object} row Table row as a jQuery object.
294
+ * @param {Object} status
295
+ */
296
+ function displayLinkStatus(row, status) {
297
+ //Update the status code and class.
298
+ var statusColumn = row.find('td.column-status');
299
+ if (status.status_text) {
300
+ statusColumn.find('.status-text').text(status.status_text);
301
+ }
302
+ statusColumn.find('.http-code').text(status.http_code ? status.http_code : '');
303
+
304
+ var oldStatusClass = row.attr('class').match(/(?:^|\s)(link-status-[^\s]+)(?:\s|$)/);
305
+ oldStatusClass = oldStatusClass ? oldStatusClass[1] : '';
306
+ var newStatusClass = 'link-status-' + status.status_code;
307
+
308
+ statusColumn.find('.link-status-row').removeClass(oldStatusClass).addClass(newStatusClass);
309
+ row.removeClass(oldStatusClass).addClass(newStatusClass);
310
+
311
+ //Last check time and failure duration are complicated to update, so we'll just hide them.
312
+ //The user can refresh the page to get the new values.
313
+ statusColumn.find('.link-last-checked td').html('&nbsp;');
314
+ statusColumn.find('.link-broken-for td').html('&nbsp;');
315
+
316
+ //The link may or may not be a redirect now.
317
+ row.toggleClass('blc-redirect', status.redirect_count > 0);
318
+
319
+ if (typeof status['redirect_count'] !== 'undefined') {
320
+ var redirectColumn = row.find('td.column-redirect-url').empty();
321
+
322
+ if (status.redirect_count > 0 && status.final_url) {
323
+ redirectColumn.append(
324
+ $(
325
+ '<a></a>',
326
+ {
327
+ href: status.final_url,
328
+ text: status.final_url,
329
+ title: status.final_url,
330
+ 'class': 'blc-redirect-url',
331
+ target: '_blank'
332
+ }
333
+ )
334
+ );
335
+ }
336
+ }
337
+ }
338
+
339
+
340
  /**
341
  * Display the inline link editor.
342
  *
500
  progressIndicator.hide();
501
  updateButton.prop('disabled', false);
502
 
503
+ handleEditResponse(response, master, linkId, newText);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
 
505
+ hideLinkEditor(editRow);
506
+ },
507
+ 'json'
508
+ );
 
 
 
509
 
510
+ }
 
 
 
 
 
 
511
 
512
+ function handleEditResponse(response, master, linkId, newText) {
513
+ if (response && (typeof(response['error']) != 'undefined')){
514
+ //An internal error occurred before the link could be edited.
515
+ alert(response.error);
516
+ return false;
517
+ } else if (response.errors.length > 0) {
518
+ //Build and display an error message.
519
+ var msg = '';
520
+
521
+ if ( response.cnt_okay > 0 ){
522
+ var fragment = sprintf(
523
+ '<?php echo esc_js(__('%d instances of the link were successfully modified.', 'broken-link-checker')); ?>',
524
+ response.cnt_okay
525
+ );
526
+ msg = msg + fragment + '\n';
527
+ if ( response.cnt_error > 0 ){
528
+ fragment = sprintf(
529
+ '<?php echo esc_js(__("However, %d instances couldn't be edited and still point to the old URL.", 'broken-link-checker')); ?>',
530
+ response.cnt_error
531
+ );
532
+ msg = msg + fragment + "\n";
533
+ }
534
+ } else {
535
+ msg = msg + '<?php echo esc_js(__('The link could not be modified.', 'broken-link-checker')); ?>\n';
536
+ }
537
 
538
+ msg = msg + '\n<?php echo esc_js(__("The following error(s) occurred :", 'broken-link-checker')); ?>\n* ';
539
+ msg = msg + response.errors.join('\n* ');
 
540
 
541
+ alert(msg);
542
+ return false;
543
+ } else {
544
+ //Everything went well. Update the link row with the new values.
545
 
546
+ //Replace the displayed link URL with the new one.
547
+ master.find('a.blc-link-url').attr('href', response.url).text(response.url);
 
 
548
 
549
+ //Save the new ID
550
+ replaceLinkId(linkId, response.new_link_id);
551
+ //Load up the new link info
552
+ reloadDetailsRow(response.new_link_id);
553
 
554
+ //Update the link text if it was edited.
555
+ if ((newText !== null) && (response.link_text !== null)) {
556
+ master.data('link-text', response.link_text);
557
+ if (response.ui_link_text !== null) {
558
+ master.find('.column-new-link-text').html(response.ui_link_text);
559
  }
560
+ }
561
 
562
+ //Update the status code and class.
563
+ displayLinkStatus(master, response);
 
 
564
 
565
+ //Flash the row green to indicate success
566
+ flashElementGreen(master);
567
+
568
+ return true;
569
+ }
570
  }
571
 
572
  //The "Edit URL" button - displays the inline editor
712
  dialogClass : 'blc-search-container',
713
  resizable: false
714
  });
715
+
716
  $('#blc-open-search-box').click(function(){
717
  if ( searchForm.dialog('isOpen') ){
718
  searchForm.dialog('close');
719
  } else {
720
+ searchForm
721
+ .dialog('open')
722
+ .dialog('widget')
723
+ .position({
724
+ my: 'right top',
725
+ at: 'right bottom',
726
+ of: $('#blc-open-search-box')
727
+ });
 
 
 
 
 
 
728
  }
729
  });
730
 
795
  }
796
  }
797
  });
798
+
799
+ //Automatically disable bulk actions that don't apply to the currently selected links.
800
+ $('#blc-bulk-action').focus(function() {
801
+ var redirectsSelected = false, brokenLinksSelected = false;
802
+ $('tr th.check-column input:checked', '#blc-links').each(function() {
803
+ var row = $(this).closest('tr');
804
+ if (row.hasClass('blc-redirect')) {
805
+ redirectsSelected = true
806
+ }
807
+ if (row.hasClass('link-status-error') || row.hasClass('link-status-warning')) {
808
+ brokenLinksSelected = true;
809
+ }
810
+ });
811
+
812
+ var bulkAction = $(this);
813
+ bulkAction.find('option[value="bulk-deredirect"]').prop('disabled', !redirectsSelected);
814
+ bulkAction.find('option[value="bulk-not-broken"]').prop('disabled', !brokenLinksSelected);
815
+ });
816
 
817
  //------------------------------------------------------------
818
  // Manipulate highlight settings for permanently broken links
925
  e.preventDefault();
926
  }
927
  });
928
+
929
+
930
  });
931
 
932
  </script>
includes/admin/table-printer.php CHANGED
@@ -235,6 +235,8 @@ class blcTablePrinter {
235
  'redirect-url' => array(
236
  'heading' => __('Redirect URL', 'broken-link-checker'),
237
  'content' => array($this, 'column_redirect_url'),
 
 
238
  ),
239
  );
240
  }
@@ -286,6 +288,7 @@ class blcTablePrinter {
286
  "bulk-recheck" => __('Recheck', 'broken-link-checker'),
287
  "bulk-deredirect" => __('Fix redirects', 'broken-link-checker'),
288
  "bulk-not-broken" => __('Mark as not broken', 'broken-link-checker'),
 
289
  "bulk-unlink" => __('Unlink', 'broken-link-checker'),
290
  );
291
  if ( EMPTY_TRASH_DAYS ){
@@ -528,7 +531,11 @@ class blcTablePrinter {
528
  if ( $last_check < strtotime('-10 years') ){
529
  _e('Never', 'broken-link-checker');
530
  } else {
531
- echo date_i18n(get_option('date_format'), $last_check);
 
 
 
 
532
  }
533
  ?></span></li>
534
 
@@ -557,7 +564,7 @@ class blcTablePrinter {
557
  print count($link->get_instances());
558
  ?></span></li>
559
 
560
- <?php if ( $link->broken && (intval( $link->check_count ) > 0) ){ ?>
561
  <li><br/>
562
  <?php
563
  printf(
@@ -645,6 +652,15 @@ class blcTablePrinter {
645
  }
646
 
647
  echo '</table>';
 
 
 
 
 
 
 
 
 
648
  }
649
 
650
 
@@ -659,35 +675,71 @@ class blcTablePrinter {
659
  //Output inline action links for the link/URL
660
  $actions = array();
661
 
662
- $actions['edit'] = "<span class='edit'><a href='javascript:void(0)' class='blc-edit-button' title='" . esc_attr( __('Edit this link' , 'broken-link-checker') ) . "'>". __('Edit URL' , 'broken-link-checker') ."</a>";
663
 
664
- $actions['delete'] = "<span class='delete'><a class='submitdelete blc-unlink-button' title='" . esc_attr( __('Remove this link from all posts', 'broken-link-checker') ). "' ".
665
  "href='javascript:void(0);'>" . __('Unlink', 'broken-link-checker') . "</a>";
666
 
667
- if ( $link->broken ){
668
- $actions['discard'] = sprintf(
669
- '<span><a href="#" title="%s" class="blc-discard-button">%s</a>',
670
  esc_attr(__('Remove this link from the list of broken links and mark it as valid', 'broken-link-checker')),
671
  __('Not broken', 'broken-link-checker')
672
  );
673
  }
674
 
675
- if ( !$link->dismissed && ($link->broken || ($link->redirect_count > 0)) ) {
676
- $actions['dismiss'] = sprintf(
677
- '<span><a href="#" title="%s" class="blc-dismiss-button">%s</a>',
678
  esc_attr(__('Hide this link and do not report it again unless its status changes' , 'broken-link-checker')),
679
  __('Dismiss', 'broken-link-checker')
680
  );
681
  } else if ( $link->dismissed ) {
682
- $actions['undismiss'] = sprintf(
683
- '<span><a href="#" title="%s" class="blc-undismiss-button">%s</a>',
684
  esc_attr(__('Undismiss this link', 'broken-link-checker')),
685
  __('Undismiss', 'broken-link-checker')
686
  );
687
  }
688
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
689
  echo '<div class="row-actions">';
690
- echo implode(' | </span>', $actions) .'</span>';
691
  echo '</div>';
692
 
693
  ?>
235
  'redirect-url' => array(
236
  'heading' => __('Redirect URL', 'broken-link-checker'),
237
  'content' => array($this, 'column_redirect_url'),
238
+ 'sortable' => true,
239
+ 'orderby' => 'redirect_url',
240
  ),
241
  );
242
  }
288
  "bulk-recheck" => __('Recheck', 'broken-link-checker'),
289
  "bulk-deredirect" => __('Fix redirects', 'broken-link-checker'),
290
  "bulk-not-broken" => __('Mark as not broken', 'broken-link-checker'),
291
+ "bulk-dismiss" => __('Dismiss', 'broken-link-checker'),
292
  "bulk-unlink" => __('Unlink', 'broken-link-checker'),
293
  );
294
  if ( EMPTY_TRASH_DAYS ){
531
  if ( $last_check < strtotime('-10 years') ){
532
  _e('Never', 'broken-link-checker');
533
  } else {
534
+ printf(
535
+ '<time datetime="%s">%s</time>',
536
+ esc_attr(date('c', $last_check)),
537
+ date_i18n(get_option('date_format'), $last_check)
538
+ );
539
  }
540
  ?></span></li>
541
 
564
  print count($link->get_instances());
565
  ?></span></li>
566
 
567
+ <?php if ( ($link->broken || $link->warning) && (intval( $link->check_count ) > 0) ){ ?>
568
  <li><br/>
569
  <?php
570
  printf(
652
  }
653
 
654
  echo '</table>';
655
+
656
+ //"Details" link.
657
+ echo '<div class="row-actions">';
658
+ printf(
659
+ '<span><a href="#" class="blc-details-button" title="%s">%s</a></span>',
660
+ esc_attr(__('Show more info about this link', 'broken-link-checker')),
661
+ _x('Details', 'link in the "Status" column', 'broken-link-checker')
662
+ );
663
+ echo '</div>';
664
  }
665
 
666
 
675
  //Output inline action links for the link/URL
676
  $actions = array();
677
 
678
+ $actions['edit'] = "<a href='javascript:void(0)' class='blc-edit-button' title='" . esc_attr( __('Edit this link' , 'broken-link-checker') ) . "'>". __('Edit URL' , 'broken-link-checker') ."</a>";
679
 
680
+ $actions['delete'] = "<a class='submitdelete blc-unlink-button' title='" . esc_attr( __('Remove this link from all posts', 'broken-link-checker') ). "' ".
681
  "href='javascript:void(0);'>" . __('Unlink', 'broken-link-checker') . "</a>";
682
 
683
+ if ( $link->broken || $link->warning ){
684
+ $actions['blc-discard-action'] = sprintf(
685
+ '<a href="#" title="%s" class="blc-discard-button">%s</a>',
686
  esc_attr(__('Remove this link from the list of broken links and mark it as valid', 'broken-link-checker')),
687
  __('Not broken', 'broken-link-checker')
688
  );
689
  }
690
 
691
+ if ( !$link->dismissed && ($link->broken || $link->warning || ($link->redirect_count > 0)) ) {
692
+ $actions['blc-dismiss-action'] = sprintf(
693
+ '<a href="#" title="%s" class="blc-dismiss-button">%s</a>',
694
  esc_attr(__('Hide this link and do not report it again unless its status changes' , 'broken-link-checker')),
695
  __('Dismiss', 'broken-link-checker')
696
  );
697
  } else if ( $link->dismissed ) {
698
+ $actions['blc-undismiss-action'] = sprintf(
699
+ '<a href="#" title="%s" class="blc-undismiss-button">%s</a>',
700
  esc_attr(__('Undismiss this link', 'broken-link-checker')),
701
  __('Undismiss', 'broken-link-checker')
702
  );
703
  }
704
 
705
+ $actions['blc-recheck-action'] = sprintf(
706
+ '<a href="#" class="blc-recheck-button">%s</a>',
707
+ __('Recheck', 'broken-link-checker')
708
+ );
709
+
710
+ if ( $link->redirect_count > 0 && !empty($link->final_url) && ($link->url != $link->final_url) ) {
711
+ //TODO: Check if at least one instance has an editable URL. Otherwise this won't work.
712
+ $actions['blc-deredirect-action'] = sprintf(
713
+ '<a href="#" class="blc-deredirect-button" title="%s">%s</a>',
714
+ __('Replace this redirect with a direct link', 'broken-link-checker'),
715
+ _x('Fix redirect', 'link action; replace one redirect with a direct link', 'broken-link-checker')
716
+ );
717
+ }
718
+
719
+ //Only show the enabled actions.
720
+ $conf = blc_get_configuration();
721
+ foreach($conf->get('show_link_actions', $actions) as $name => $enabled) {
722
+ if ( !$enabled ) {
723
+ unset($actions[$name]);
724
+ }
725
+ }
726
+
727
+ //Wrap actions with <span></span> and separate them with | characters.
728
+ //Basically, this emulates the HTML structure that WP uses for post actions under Posts -> All Posts.
729
+ $spans = array();
730
+ $is_first_action = true;
731
+ foreach($actions as $name => $html) {
732
+ $spans[] = sprintf(
733
+ '<span class="%s">%s%s</span>',
734
+ esc_attr($name),
735
+ $is_first_action ? '' : ' | ',
736
+ $html
737
+ );
738
+ $is_first_action = false;
739
+ }
740
+
741
  echo '<div class="row-actions">';
742
+ echo implode('', $spans);
743
  echo '</div>';
744
 
745
  ?>
includes/any-post.php CHANGED
@@ -223,7 +223,26 @@ class blcPostTypeOverlord {
223
  $elapsed = microtime(true) - $start;
224
  $blclog->debug($q);
225
  $blclog->log(sprintf('...... %d rows deleted in %.3f seconds', $wpdb->rows_affected, $elapsed));
226
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  //Remove the 'synched' flag from all posts that have been updated
228
  //since the last time they were parsed/synchronized.
229
  $blclog->log('...... Marking changed posts as unsynched');
@@ -280,7 +299,7 @@ class blcPostTypeOverlord {
280
  return $content;
281
  }
282
 
283
- //Retrieve info about all occurences of broken links in the current post
284
  $q = "
285
  SELECT instances.raw_url
286
  FROM {$wpdb->prefix}blc_instances AS instances JOIN {$wpdb->prefix}blc_links AS links
223
  $elapsed = microtime(true) - $start;
224
  $blclog->debug($q);
225
  $blclog->log(sprintf('...... %d rows deleted in %.3f seconds', $wpdb->rows_affected, $elapsed));
226
+
227
+ //Delete records where the post status is not one of the enabled statuses.
228
+ $blclog->log('...... Deleting synch records for posts that have a disallowed status');
229
+ $start = microtime(true);
230
+ $q = "DELETE synch.*
231
+ FROM
232
+ {$wpdb->prefix}blc_synch AS synch
233
+ LEFT JOIN {$wpdb->posts} AS posts
234
+ ON (synch.container_id = posts.ID and synch.container_type = posts.post_type)
235
+ WHERE
236
+ posts.post_status NOT IN (%s)";
237
+ $q = sprintf(
238
+ $q,
239
+ "'" . implode("', '", $escaped_post_statuses) . "'"
240
+ );
241
+ $wpdb->query( $q );
242
+ $elapsed = microtime(true) - $start;
243
+ $blclog->debug($q);
244
+ $blclog->log(sprintf('...... %d rows deleted in %.3f seconds', $wpdb->rows_affected, $elapsed));
245
+
246
  //Remove the 'synched' flag from all posts that have been updated
247
  //since the last time they were parsed/synchronized.
248
  $blclog->log('...... Marking changed posts as unsynched');
299
  return $content;
300
  }
301
 
302
+ //Retrieve info about all occurrences of broken links in the current post
303
  $q = "
304
  SELECT instances.raw_url
305
  FROM {$wpdb->prefix}blc_instances AS instances JOIN {$wpdb->prefix}blc_links AS links
includes/link-query.php CHANGED
@@ -18,6 +18,16 @@ class blcLinkQuery {
18
  function __construct(){
19
  //Init. the available native filters.
20
  $this->native_filters = array(
 
 
 
 
 
 
 
 
 
 
21
  'broken' => array(
22
  'params' => array(
23
  'where_expr' => '( broken = 1 )',
@@ -27,17 +37,27 @@ class blcLinkQuery {
27
  'heading' => __('Broken Links', 'broken-link-checker'),
28
  'heading_zero' => __('No broken links found', 'broken-link-checker'),
29
  'native' => true,
30
- ),
31
- 'redirects' => array(
32
- 'params' => array(
 
 
 
 
 
 
 
 
 
 
33
  'where_expr' => '( redirect_count > 0 )',
34
- 's_include_dismissed' => false,
35
  ),
36
  'name' => __('Redirects', 'broken-link-checker'),
37
  'heading' => __('Redirected Links', 'broken-link-checker'),
38
  'heading_zero' => __('No redirects found', 'broken-link-checker'),
39
  'native' => true,
40
- ),
41
 
42
  'dismissed' => array(
43
  'params' => array(
@@ -48,17 +68,13 @@ class blcLinkQuery {
48
  'heading_zero' => __('No dismissed links found', 'broken-link-checker'),
49
  'native' => true,
50
  ),
51
-
52
- 'all' => array(
53
- 'params' => array(
54
- 'where_expr' => '1',
55
- ),
56
- 'name' => __('All', 'broken-link-checker'),
57
- 'heading' => __('Detected Links', 'broken-link-checker'),
58
- 'heading_zero' => __('No links found (yet)', 'broken-link-checker'),
59
- 'native' => true,
60
- ),
61
  );
 
 
 
 
 
 
62
 
63
  //Create the special "search" filter
64
  $this->search_filter = array(
@@ -446,6 +462,7 @@ class blcLinkQuery {
446
  $allowed_columns = array(
447
  'url' => 'links.url',
448
  'link_text' => 'instances.link_text',
 
449
  );
450
  $column = $params['orderby'];
451
 
@@ -455,6 +472,11 @@ class blcLinkQuery {
455
  }
456
 
457
  if ( array_key_exists($column, $allowed_columns) ) {
 
 
 
 
 
458
  $order_exprs[] = $allowed_columns[$column] . ' ' . $direction;
459
  }
460
  }
18
  function __construct(){
19
  //Init. the available native filters.
20
  $this->native_filters = array(
21
+ 'all' => array(
22
+ 'params' => array(
23
+ 'where_expr' => '1',
24
+ ),
25
+ 'name' => __('All', 'broken-link-checker'),
26
+ 'heading' => __('Detected Links', 'broken-link-checker'),
27
+ 'heading_zero' => __('No links found (yet)', 'broken-link-checker'),
28
+ 'native' => true,
29
+ ),
30
+
31
  'broken' => array(
32
  'params' => array(
33
  'where_expr' => '( broken = 1 )',
37
  'heading' => __('Broken Links', 'broken-link-checker'),
38
  'heading_zero' => __('No broken links found', 'broken-link-checker'),
39
  'native' => true,
40
+ ),
41
+ 'warnings' => array(
42
+ 'params' => array(
43
+ 'where_expr' => '( warning = 1 )',
44
+ 's_include_dismissed' => false,
45
+ ),
46
+ 'name' => _x('Warnings', 'filter name', 'broken-link-checker'),
47
+ 'heading' => __('Warnings', 'filter heading', 'broken-link-checker'),
48
+ 'heading_zero' => __('No warnings found', 'broken-link-checker'),
49
+ 'native' => true,
50
+ ),
51
+ 'redirects' => array(
52
+ 'params' => array(
53
  'where_expr' => '( redirect_count > 0 )',
54
+ 's_include_dismissed' => false,
55
  ),
56
  'name' => __('Redirects', 'broken-link-checker'),
57
  'heading' => __('Redirected Links', 'broken-link-checker'),
58
  'heading_zero' => __('No redirects found', 'broken-link-checker'),
59
  'native' => true,
60
+ ),
61
 
62
  'dismissed' => array(
63
  'params' => array(
68
  'heading_zero' => __('No dismissed links found', 'broken-link-checker'),
69
  'native' => true,
70
  ),
 
 
 
 
 
 
 
 
 
 
71
  );
72
+
73
+ //The user can turn off warnings. In that case, all errors will show up in the "broken" filter instead.
74
+ $conf = blc_get_configuration();
75
+ if ( !$conf->get('warnings_enabled') ) {
76
+ unset($this->native_filters['warnings']);
77
+ }
78
 
79
  //Create the special "search" filter
80
  $this->search_filter = array(
462
  $allowed_columns = array(
463
  'url' => 'links.url',
464
  'link_text' => 'instances.link_text',
465
+ 'redirect_url' => 'links.final_url',
466
  );
467
  $column = $params['orderby'];
468
 
472
  }
473
 
474
  if ( array_key_exists($column, $allowed_columns) ) {
475
+ if ( $column === 'redirect_url' ) {
476
+ //Sort links that are not redirects last.
477
+ $order_exprs[] = '(links.redirect_count > 0) DESC';
478
+ }
479
+
480
  $order_exprs[] = $allowed_columns[$column] . ' ' . $direction;
481
  }
482
  }
includes/links.php CHANGED
@@ -34,6 +34,7 @@ class blcLink {
34
  var $final_url = '';
35
 
36
  var $broken = false;
 
37
  var $first_failure = 0;
38
  var $last_success = 0;
39
  var $may_recheck = 1;
@@ -123,6 +124,7 @@ class blcLink {
123
  'timeout' => 'bool',
124
  'result_hash' => '%s',
125
  'broken' => 'bool',
 
126
  'false_positive' => 'bool',
127
  'may_recheck' => 'bool',
128
  'being_checked' => 'bool',
@@ -245,6 +247,7 @@ class blcLink {
245
 
246
  $defaults = array(
247
  'broken' => false,
 
248
  'http_code' => 0,
249
  'redirect_count' => 0,
250
  'final_url' => $this->url,
@@ -277,20 +280,19 @@ class blcLink {
277
  //Check the link
278
  $rez = $checker->check($this->get_ascii_url());
279
  //FB::info($rez, "Check results");
280
-
 
 
 
 
 
281
  //Filter the returned array to leave only the restricted set of keys that we're interested in.
282
- $results = array();
283
- foreach($rez as $name => $value){
284
- if ( array_key_exists($name, $defaults) ){
285
- $results[$name] = $value;
286
- }
287
- }
288
- $results = array_merge($defaults, $results);
289
-
290
  //The result hash is special - see blcLink::status_changed()
291
  $new_result_hash = $results['result_hash'];
292
  unset($results['result_hash']);
293
-
294
  //Update the object's fields with the new results
295
  $this->set_values($results);
296
 
@@ -305,6 +307,137 @@ class blcLink {
305
 
306
  return $this->broken;
307
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
 
309
  /**
310
  * A helper method used to update timestamps & other state-dependent fields
@@ -333,10 +466,11 @@ class blcLink {
333
  //If the link has been marked as a (probable) false positive,
334
  //mark it as broken *only* if the new result is different from
335
  //the one that caused the user to mark it as a false positive.
336
- if ( $broken ){
337
  if ( $this->result_hash == $new_result_hash ){
338
  //Got the same result as before, assume it's still incorrect and the link actually works.
339
- $broken = false;
 
340
  } else {
341
  //Got a new result. Assume (quite optimistically) that it's not a false positive.
342
  $this->false_positive = false;
@@ -353,7 +487,7 @@ class blcLink {
353
 
354
  //Update timestamps
355
  $this->last_check = $this->last_check_attempt;
356
- if ( $this->broken ){
357
  if ( empty($this->first_failure) ){
358
  $this->first_failure = $this->last_check;
359
  }
@@ -364,10 +498,10 @@ class blcLink {
364
  }
365
 
366
  //Add a line indicating link status to the log
367
- if ( !$broken ) {
368
- $this->log .= "\n" . __("Link is valid.", 'broken-link-checker');
369
- } else {
370
  $this->log .= "\n" . __("Link is broken.", 'broken-link-checker');
 
 
371
  }
372
  }
373
 
@@ -381,6 +515,11 @@ class blcLink {
381
  global $wpdb, $blclog; /** @var wpdb $wpdb */
382
 
383
  if ( !$this->valid() ) return false;
 
 
 
 
 
384
 
385
  //Make a list of fields to be saved and their values in DB format
386
  $values = array();
@@ -526,7 +665,7 @@ class blcLink {
526
  function to_native_format($values){
527
 
528
  foreach($values as $name => $value){
529
- //Don't process ffields that don't exist in the blc_links table.
530
  if ( !isset($this->field_format[$name]) ){
531
  continue;
532
  }
@@ -864,8 +1003,7 @@ class blcLink {
864
 
865
  } else {
866
 
867
- if ( $this->broken ){
868
-
869
  $code = BLC_LINK_STATUS_WARNING;
870
  $text = __('Unknown Error', 'link status', 'broken-link-checker');
871
 
@@ -916,6 +1054,32 @@ class blcLink {
916
  return blcUtility::idn_to_ascii($this->url);
917
  }
918
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
919
  /**
920
  * Remove the query string from an URL.
921
  *
34
  var $final_url = '';
35
 
36
  var $broken = false;
37
+ public $warning = false;
38
  var $first_failure = 0;
39
  var $last_success = 0;
40
  var $may_recheck = 1;
124
  'timeout' => 'bool',
125
  'result_hash' => '%s',
126
  'broken' => 'bool',
127
+ 'warning' => 'bool',
128
  'false_positive' => 'bool',
129
  'may_recheck' => 'bool',
130
  'being_checked' => 'bool',
247
 
248
  $defaults = array(
249
  'broken' => false,
250
+ 'warning' => false,
251
  'http_code' => 0,
252
  'redirect_count' => 0,
253
  'final_url' => $this->url,
280
  //Check the link
281
  $rez = $checker->check($this->get_ascii_url());
282
  //FB::info($rez, "Check results");
283
+
284
+ $results = array_merge($defaults, $rez);
285
+
286
+ //Some HTTP errors can be treated as warnings.
287
+ $results = $this->decide_warning_state($results);
288
+
289
  //Filter the returned array to leave only the restricted set of keys that we're interested in.
290
+ $results = array_intersect_key($results, $defaults);
291
+
 
 
 
 
 
 
292
  //The result hash is special - see blcLink::status_changed()
293
  $new_result_hash = $results['result_hash'];
294
  unset($results['result_hash']);
295
+
296
  //Update the object's fields with the new results
297
  $this->set_values($results);
298
 
307
 
308
  return $this->broken;
309
  }
310
+
311
+ /**
312
+ * Decide whether the result of the latest check means that the link is really broken
313
+ * or should just be reported as a warning.
314
+ *
315
+ * @param array $check_results
316
+ * @return array
317
+ */
318
+ private function decide_warning_state($check_results) {
319
+ if ( !$check_results['broken'] && !$check_results['warning'] ) {
320
+ //Nothing to do, this is a working link.
321
+ return $check_results;
322
+ }
323
+
324
+ $configuration = blc_get_configuration();
325
+ if ( !$configuration->get('warnings_enabled', true) ) {
326
+ //The user wants all failures to be reported as "broken", regardless of severity.
327
+ if ( $check_results['warning'] ) {
328
+ $check_results['broken'] = true;
329
+ $check_results['warning'] = false;
330
+ }
331
+ return $check_results;
332
+ }
333
+
334
+ $warning_reason = null;
335
+ $failure_count = $this->check_count;
336
+ $failure_duration = ($this->first_failure != 0) ? (time() - $this->first_failure) : 0;
337
+ //These could be configurable, but lets put that off until someone actually asks for it.
338
+ $duration_threshold = 24 * 3600;
339
+ $count_threshold = 3;
340
+
341
+ //We can't just use ($check_results['status_code'] == 'warning' because some "warning" problems are not
342
+ //temporary. For example, region-restricted YouTube videos use the "warning" status code.
343
+ $maybe_temporary_error = false;
344
+
345
+ //Some basic heuristics to determine if this failure might be temporary.
346
+ //----------------------------------------------------------------------
347
+ if ( $check_results['timeout'] ) {
348
+ $maybe_temporary_error = true;
349
+ $warning_reason = 'Timeouts are sometimes caused by high server load or other temporary issues.';
350
+ }
351
+
352
+ $error_code = isset($check_results['error_code']) ? $check_results['error_code'] : '';
353
+ if ( $error_code === 'connection_failed' ) {
354
+ $maybe_temporary_error = true;
355
+ $warning_reason = 'Connection failures are sometimes caused by high server load or other temporary issues.';
356
+ }
357
+
358
+ $http_code = intval($check_results['http_code']);
359
+ $temporary_http_errors = array(
360
+ 408, //Request timeout. Probably a plugin bug, but could just be an overloaded client server.
361
+ 420, //Custom Twitter code returned when the client gets rate-limited.
362
+ 429, //Client has sent too many requests in a given amount of time.
363
+ 502, //Bad Gateway. Often a sign of a temporarily overloaded or misconfigured server.
364
+ 503, //Service Unavailable.
365
+ 504, //Gateway Timeout.
366
+ 509, //Bandwidth Limit Exceeded.
367
+ 520, //CloudFlare-specific "Origin Error" code.
368
+ 522, //CloudFlare-specific "Connection timed out" code.
369
+ 524, //Another CloudFlare-specific timeout code.
370
+ );
371
+ if ( in_array($http_code, $temporary_http_errors) ) {
372
+ $maybe_temporary_error = true;
373
+
374
+ if ( in_array($http_code, array(502, 503, 504, 509)) ) {
375
+ $warning_reason = sprintf(
376
+ 'HTTP error %d usually means that the site is down due to high server load or a configuration problem. '
377
+ . 'This error is often temporary and will go away after while.',
378
+ $http_code
379
+ );
380
+ } else {
381
+ $warning_reason = 'This HTTP error is often temporary.';
382
+ }
383
+ }
384
+
385
+ //----------------------------------------------------------------------
386
+
387
+ //Attempt to detect false positives.
388
+ $suspected_false_positive = false;
389
+
390
+ //A "403 Forbidden" error on an internal link usually means something on the site is blocking automated
391
+ //requests. Possible culprits include hotlink protection rules in .htaccess, badly configured IDS, and so on.
392
+ $is_internal_link = $this->is_internal_to_domain();
393
+ if ( $is_internal_link && ($http_code == 403) ) {
394
+ $suspected_false_positive = true;
395
+ $warning_reason = 'This might be a false positive. Make sure the link is not password-protected, '
396
+ . 'and that your server is not set up to block automated requests.';
397
+ }
398
+
399
+ //Some hosting providers turn off loopback connections. This causes all internal links to be reported as broken.
400
+ if ( $is_internal_link && in_array($error_code, array('connection_failed', 'couldnt_resolve_host')) ) {
401
+ $suspected_false_positive = true;
402
+ $warning_reason = 'This is probably a false positive. ';
403
+ if ( $error_code === 'connection_failed' ) {
404
+ $warning_reason .= 'The plugin could not connect to your site. That usually means that your '
405
+ . 'hosting provider has disabled loopback connections.';
406
+ } elseif ( $error_code === 'couldnt_resolve_host' ) {
407
+ $warning_reason .= 'The plugin could not connect to your site because DNS resolution failed. '
408
+ . 'This could mean DNS is configured incorrectly on your server.';
409
+ }
410
+ }
411
+
412
+ //----------------------------------------------------------------------
413
+
414
+ //Temporary problems and suspected false positives start out as warnings. False positives stay that way
415
+ //indefinitely because they are usually caused by bugs and server configuration issues, not temporary downtime.
416
+ if ( ($maybe_temporary_error && ($failure_count < $count_threshold)) || $suspected_false_positive ) {
417
+ $check_results['warning'] = true;
418
+ $check_results['broken'] = false;
419
+ }
420
+
421
+ //Upgrade temporary warnings to "broken" after X consecutive failures or Y hours, whichever comes first.
422
+ $threshold_reached = ($failure_count >= $count_threshold) || ($failure_duration >= $duration_threshold);
423
+ if ( $check_results['warning'] ) {
424
+ if ( ($maybe_temporary_error && $threshold_reached) && !$suspected_false_positive ) {
425
+ $check_results['warning'] = false;
426
+ $check_results['broken'] = true;
427
+ }
428
+ }
429
+
430
+ if ( !empty($warning_reason) && $check_results['warning'] ) {
431
+ $formatted_reason = "\n==========\n"
432
+ . 'Severity: Warning' . "\n"
433
+ . 'Reason: ' . trim($warning_reason)
434
+ . "\n==========\n";
435
+
436
+ $check_results['log'] .= $formatted_reason;
437
+ }
438
+
439
+ return $check_results;
440
+ }
441
 
442
  /**
443
  * A helper method used to update timestamps & other state-dependent fields
466
  //If the link has been marked as a (probable) false positive,
467
  //mark it as broken *only* if the new result is different from
468
  //the one that caused the user to mark it as a false positive.
469
+ if ( $broken || $this->warning ){
470
  if ( $this->result_hash == $new_result_hash ){
471
  //Got the same result as before, assume it's still incorrect and the link actually works.
472
+ $broken = false;
473
+ $this->warning = false;
474
  } else {
475
  //Got a new result. Assume (quite optimistically) that it's not a false positive.
476
  $this->false_positive = false;
487
 
488
  //Update timestamps
489
  $this->last_check = $this->last_check_attempt;
490
+ if ( $this->broken || $this->warning ){
491
  if ( empty($this->first_failure) ){
492
  $this->first_failure = $this->last_check;
493
  }
498
  }
499
 
500
  //Add a line indicating link status to the log
501
+ if ( $this->broken || $this->warning ) {
 
 
502
  $this->log .= "\n" . __("Link is broken.", 'broken-link-checker');
503
+ } else {
504
+ $this->log .= "\n" . __("Link is valid.", 'broken-link-checker');
505
  }
506
  }
507
 
515
  global $wpdb, $blclog; /** @var wpdb $wpdb */
516
 
517
  if ( !$this->valid() ) return false;
518
+
519
+ //A link can't be broken and treated as a warning at the same time.
520
+ if ( $this->broken && $this->warning ) {
521
+ $this->warning = false;
522
+ }
523
 
524
  //Make a list of fields to be saved and their values in DB format
525
  $values = array();
665
  function to_native_format($values){
666
 
667
  foreach($values as $name => $value){
668
+ //Don't process fields that don't exist in the blc_links table.
669
  if ( !isset($this->field_format[$name]) ){
670
  continue;
671
  }
1003
 
1004
  } else {
1005
 
1006
+ if ( $this->broken || $this->warning ){
 
1007
  $code = BLC_LINK_STATUS_WARNING;
1008
  $text = __('Unknown Error', 'link status', 'broken-link-checker');
1009
 
1054
  return blcUtility::idn_to_ascii($this->url);
1055
  }
1056
 
1057
+ /**
1058
+ * Check if this link points to a page on the same domain as the current site.
1059
+ *
1060
+ * Note: Only checks the domain name, not subdirectory. If there are two separate WP sites A and B installed
1061
+ * in two different subdirectories of the same domain, this method will treat a link from site A to B as internal.
1062
+ *
1063
+ * @return bool
1064
+ */
1065
+ public function is_internal_to_domain() {
1066
+ $host = @parse_url($this->url, PHP_URL_HOST);
1067
+ if ( empty($host) ) {
1068
+ return false;
1069
+ }
1070
+
1071
+ $site_host = @parse_url(get_site_url(), PHP_URL_HOST);
1072
+ if ( empty($site_host) ) {
1073
+ return false;
1074
+ }
1075
+
1076
+ //Some users are inconsistent with using/not using the www prefix, so get rid of it.
1077
+ $site_host = preg_replace('@^www\.@', '', $site_host, 1);
1078
+
1079
+ //Check if $host ends with $site_host. This means blah.example.com will match example.com.
1080
+ return (substr($host, -strlen($site_host)) === $site_host);
1081
+ }
1082
+
1083
  /**
1084
  * Remove the query string from an URL.
1085
  *
includes/parsers.php CHANGED
@@ -165,6 +165,10 @@ class blcParser extends blcModule {
165
 
166
  /**
167
  * Turn a relative URL into an absolute one.
 
 
 
 
168
  *
169
  * @param string $url Relative URL.
170
  * @param string $base_url Base URL. If omitted, the blog's root URL will be used.
165
 
166
  /**
167
  * Turn a relative URL into an absolute one.
168
+ *
169
+ * WordPress 3.4 has WP_Http::make_absolute_url() which is well-tested but not as comprehensive
170
+ * as this implementation. For example, WP_Http doesn't properly handle directory traversal with "..",
171
+ * and it removes #anchors for no good reason. The BLC implementation deals with both pretty well.
172
  *
173
  * @param string $url Relative URL.
174
  * @param string $base_url Base URL. If omitted, the blog's root URL will be used.
languages/broken-link-checker.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the Broken Link Checker package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Broken Link Checker 1.9.4\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/broken-link-checker\n"
7
- "POT-Creation-Date: 2014-08-19 14:12:36+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -12,247 +12,300 @@ msgstr ""
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
- #: core/core.php:153 includes/admin/links-page-js.php:44
16
  msgid "Loading..."
17
  msgstr ""
18
 
19
- #: core/core.php:177 includes/admin/options-page-js.php:18
20
  msgid "[ Network error ]"
21
  msgstr ""
22
 
23
- #: core/core.php:204
24
  msgid "Automatically expand the widget if broken links have been detected"
25
  msgstr ""
26
 
27
- #: core/core.php:295
28
  msgid "Link Checker Settings"
29
  msgstr ""
30
 
31
- #: core/core.php:296
32
  msgid "Link Checker"
33
  msgstr ""
34
 
35
- #: core/core.php:301 includes/link-query.php:27
36
  msgid "Broken Links"
37
  msgstr ""
38
 
39
- #: core/core.php:317
40
  msgid "View Broken Links"
41
  msgstr ""
42
 
43
- #: core/core.php:332
44
  msgid "Feedback"
45
  msgstr ""
46
 
47
- #: core/core.php:340
48
  msgid "Go to Broken Links"
49
  msgstr ""
50
 
51
- #: core/core.php:369
52
  msgid "Settings"
53
  msgstr ""
54
 
55
- #: core/core.php:585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  msgid "Settings saved."
57
  msgstr ""
58
 
59
- #: core/core.php:591
60
  msgid "Thank you for your donation!"
61
  msgstr ""
62
 
63
- #: core/core.php:599
64
  msgid "Complete site recheck started."
65
  msgstr ""
66
 
67
- #: core/core.php:608
68
- msgid "Details"
69
- msgstr ""
70
-
71
- #: core/core.php:622
72
  msgid "General"
73
  msgstr ""
74
 
75
- #: core/core.php:623
76
  msgid "Look For Links In"
77
  msgstr ""
78
 
79
- #: core/core.php:624
80
  msgid "Which Links To Check"
81
  msgstr ""
82
 
83
- #: core/core.php:625
84
  msgid "Protocols & APIs"
85
  msgstr ""
86
 
87
- #: core/core.php:626
88
  msgid "Advanced"
89
  msgstr ""
90
 
91
- #: core/core.php:641
92
  msgid "Broken Link Checker Options"
93
  msgstr ""
94
 
95
- #: core/core.php:683 includes/admin/table-printer.php:211
96
  msgid "Status"
97
  msgstr ""
98
 
99
- #: core/core.php:685 includes/admin/options-page-js.php:56
100
  msgid "Show debug info"
101
  msgstr ""
102
 
103
- #: core/core.php:713
104
  msgid "Check each link"
105
  msgstr ""
106
 
107
- #: core/core.php:718
108
  msgid "Every %s hours"
109
  msgstr ""
110
 
111
- #: core/core.php:727
112
  msgid ""
113
  "Existing links will be checked this often. New links will usually be checked "
114
  "ASAP."
115
  msgstr ""
116
 
117
- #: core/core.php:734
118
  msgid "E-mail notifications"
119
  msgstr ""
120
 
121
- #: core/core.php:740
122
  msgid "Send me e-mail notifications about newly detected broken links"
123
  msgstr ""
124
 
125
- #: core/core.php:748
126
  msgid "Send authors e-mail notifications about broken links in their posts"
127
  msgstr ""
128
 
129
- #: core/core.php:755
130
  msgid "Notification e-mail address"
131
  msgstr ""
132
 
133
- #: core/core.php:767
134
  msgid ""
135
  "Leave empty to use the e-mail address specified in Settings &rarr; General."
136
  msgstr ""
137
 
138
- #: core/core.php:774
139
  msgid "Link tweaks"
140
  msgstr ""
141
 
142
- #: core/core.php:780
143
  msgid "Apply custom formatting to broken links"
144
  msgstr ""
145
 
146
- #: core/core.php:784 core/core.php:815
147
  msgid "Edit CSS"
148
  msgstr ""
149
 
150
- #: core/core.php:800
151
  msgid "Example : Lorem ipsum <a %s>broken link</a>, dolor sit amet."
152
  msgstr ""
153
 
154
- #: core/core.php:803 core/core.php:834
155
  msgid "Click \"Save Changes\" to update example output."
156
  msgstr ""
157
 
158
- #: core/core.php:811
159
  msgid "Apply custom formatting to removed links"
160
  msgstr ""
161
 
162
- #: core/core.php:831
163
  msgid "Example : Lorem ipsum <span %s>removed link</span>, dolor sit amet."
164
  msgstr ""
165
 
166
- #: core/core.php:844
167
  msgid "Stop search engines from following broken links"
168
  msgstr ""
169
 
170
- #: core/core.php:852
 
 
 
 
 
 
 
171
  msgctxt "settings page"
172
  msgid "Suggestions"
173
  msgstr ""
174
 
175
- #: core/core.php:858
176
  msgid "Suggest alternatives to broken links"
177
  msgstr ""
178
 
179
- #: core/core.php:874
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  msgid "Look for links in"
181
  msgstr ""
182
 
183
- #: core/core.php:885
184
  msgid "Post statuses"
185
  msgstr ""
186
 
187
- #: core/core.php:918
188
  msgid "Link types"
189
  msgstr ""
190
 
191
- #: core/core.php:924
192
  msgid "Error : All link parsers missing!"
193
  msgstr ""
194
 
195
- #: core/core.php:931
196
  msgid "Exclusion list"
197
  msgstr ""
198
 
199
- #: core/core.php:932
200
  msgid ""
201
  "Don't check links where the URL contains any of these words (one per line) :"
202
  msgstr ""
203
 
204
- #: core/core.php:950
205
  msgid "Check links using"
206
  msgstr ""
207
 
208
- #: core/core.php:969 includes/links.php:867
209
  msgid "Timeout"
210
  msgstr ""
211
 
212
- #: core/core.php:975 core/core.php:1044 core/core.php:3097
213
  msgid "%s seconds"
214
  msgstr ""
215
 
216
- #: core/core.php:984
217
  msgid "Links that take longer than this to load will be marked as broken."
218
  msgstr ""
219
 
220
- #: core/core.php:991
221
  msgid "Link monitor"
222
  msgstr ""
223
 
224
- #: core/core.php:999
225
  msgid "Run continuously while the Dashboard is open"
226
  msgstr ""
227
 
228
- #: core/core.php:1007
229
  msgid "Run hourly in the background"
230
  msgstr ""
231
 
232
- #: core/core.php:1015
233
  msgid "Show the dashboard widget for"
234
  msgstr ""
235
 
236
- #: core/core.php:1020
237
  msgctxt "dashboard widget visibility"
238
  msgid "Administrator"
239
  msgstr ""
240
 
241
- #: core/core.php:1021
242
  msgctxt "dashboard widget visibility"
243
  msgid "Editor and above"
244
  msgstr ""
245
 
246
- #: core/core.php:1022
247
  msgctxt "dashboard widget visibility"
248
  msgid "Nobody (disables the widget)"
249
  msgstr ""
250
 
251
- #: core/core.php:1038
 
 
 
 
 
252
  msgid "Max. execution time"
253
  msgstr ""
254
 
255
- #: core/core.php:1055
256
  msgid ""
257
  "The plugin works by periodically launching a background job that parses your "
258
  "posts for links, checks the discovered URLs, and performs other time-"
@@ -260,150 +313,150 @@ msgid ""
260
  "may run each time before stopping."
261
  msgstr ""
262
 
263
- #: core/core.php:1064
264
  msgid "Server load limit"
265
  msgstr ""
266
 
267
- #: core/core.php:1079
268
  msgid "Current load : %s"
269
  msgstr ""
270
 
271
- #: core/core.php:1084
272
  msgid ""
273
  "Link checking will be suspended if the average <a href=\"%s\">server load</"
274
  "a> rises above this number. Leave this field blank to disable load limiting."
275
  msgstr ""
276
 
277
- #: core/core.php:1093
278
  msgid "Not available"
279
  msgstr ""
280
 
281
- #: core/core.php:1095
282
  msgid ""
283
  "Load limiting only works on Linux-like systems where <code>/proc/loadavg</"
284
  "code> is present and accessible."
285
  msgstr ""
286
 
287
- #: core/core.php:1103
288
  msgid "Target resource usage"
289
  msgstr ""
290
 
291
- #: core/core.php:1121
292
  msgid "Logging"
293
  msgstr ""
294
 
295
- #: core/core.php:1127
296
  msgid "Enable logging"
297
  msgstr ""
298
 
299
- #: core/core.php:1134
300
  msgid "Log file location"
301
  msgstr ""
302
 
303
- #: core/core.php:1143
304
  msgctxt "log file location"
305
  msgid "Default"
306
  msgstr ""
307
 
308
- #: core/core.php:1157
309
  msgctxt "log file location"
310
  msgid "Custom"
311
  msgstr ""
312
 
313
- #: core/core.php:1169
314
  msgid "Forced recheck"
315
  msgstr ""
316
 
317
- #: core/core.php:1172
318
  msgid "Re-check all pages"
319
  msgstr ""
320
 
321
- #: core/core.php:1176
322
  msgid ""
323
  "The \"Nuclear Option\". Click this button to make the plugin empty its link "
324
  "database and recheck the entire site from scratch."
325
  msgstr ""
326
 
327
- #: core/core.php:1187
328
  msgid "Save Changes"
329
  msgstr ""
330
 
331
- #: core/core.php:1238
332
  msgid "Configure"
333
  msgstr ""
334
 
335
- #: core/core.php:1320
336
  msgid ""
337
  "Enter the names of custom fields you want to check (one per line). If a "
338
  "field contains HTML code, prefix its name with <code>html:</code>. For "
339
  "example, <code>html:field_name</code>."
340
  msgstr ""
341
 
342
- #: core/core.php:1451 core/core.php:1534 core/core.php:1566
343
  msgid "Database error : %s"
344
  msgstr ""
345
 
346
- #: core/core.php:1516
347
  msgid "You must enter a filter name!"
348
  msgstr ""
349
 
350
- #: core/core.php:1520
351
  msgid "Invalid search query."
352
  msgstr ""
353
 
354
- #: core/core.php:1529
355
  msgid "Filter \"%s\" created"
356
  msgstr ""
357
 
358
- #: core/core.php:1556
359
  msgid "Filter ID not specified."
360
  msgstr ""
361
 
362
- #: core/core.php:1563
363
  msgid "Filter deleted"
364
  msgstr ""
365
 
366
- #: core/core.php:1610
367
  msgid "Replaced %d redirect with a direct link"
368
  msgid_plural "Replaced %d redirects with direct links"
369
  msgstr[0] ""
370
  msgstr[1] ""
371
 
372
- #: core/core.php:1621
373
  msgid "Failed to fix %d redirect"
374
  msgid_plural "Failed to fix %d redirects"
375
  msgstr[0] ""
376
  msgstr[1] ""
377
 
378
- #: core/core.php:1632
379
  msgid "None of the selected links are redirects!"
380
  msgstr ""
381
 
382
- #: core/core.php:1710
383
  msgid "%d link updated."
384
  msgid_plural "%d links updated."
385
  msgstr[0] ""
386
  msgstr[1] ""
387
 
388
- #: core/core.php:1721
389
  msgid "Failed to update %d link."
390
  msgid_plural "Failed to update %d links."
391
  msgstr[0] ""
392
  msgstr[1] ""
393
 
394
- #: core/core.php:1810
395
  msgid "%d link removed"
396
  msgid_plural "%d links removed"
397
  msgstr[0] ""
398
  msgstr[1] ""
399
 
400
- #: core/core.php:1821
401
  msgid "Failed to remove %d link"
402
  msgid_plural "Failed to remove %d links"
403
  msgstr[0] ""
404
  msgstr[1] ""
405
 
406
- #: core/core.php:1930
407
  msgid ""
408
  "%d item was skipped because it can't be moved to the Trash. You need to "
409
  "delete it manually."
@@ -413,282 +466,307 @@ msgid_plural ""
413
  msgstr[0] ""
414
  msgstr[1] ""
415
 
416
- #: core/core.php:1952
417
  msgid "Didn't find anything to delete!"
418
  msgstr ""
419
 
420
- #: core/core.php:1980
421
  msgid "%d link scheduled for rechecking"
422
  msgid_plural "%d links scheduled for rechecking"
423
  msgstr[0] ""
424
  msgstr[1] ""
425
 
426
- #: core/core.php:2026 core/core.php:2715
427
  msgid "This link was manually marked as working by the user."
428
  msgstr ""
429
 
430
- #: core/core.php:2033
431
  msgid "Couldn't modify link %d"
432
  msgstr ""
433
 
434
- #: core/core.php:2043
435
  msgid "%d link marked as not broken"
436
  msgid_plural "%d links marked as not broken"
437
  msgstr[0] ""
438
  msgstr[1] ""
439
 
440
- #: core/core.php:2083
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  msgid "Table columns"
442
  msgstr ""
443
 
444
- #: core/core.php:2102
445
  msgid "Show on screen"
446
  msgstr ""
447
 
448
- #: core/core.php:2109
449
  msgid "links"
450
  msgstr ""
451
 
452
- #: core/core.php:2110 includes/admin/table-printer.php:171
453
  msgid "Apply"
454
  msgstr ""
455
 
456
- #: core/core.php:2114
457
  msgid "Misc"
458
  msgstr ""
459
 
460
- #: core/core.php:2129
461
  msgid "Highlight links broken for at least %s days"
462
  msgstr ""
463
 
464
- #: core/core.php:2138
465
  msgid "Color-code status codes"
466
  msgstr ""
467
 
468
- #: core/core.php:2155 core/core.php:2700 core/core.php:2740 core/core.php:2773
469
- #: core/core.php:2860
470
  msgid "You're not allowed to do that!"
471
  msgstr ""
472
 
473
- #: core/core.php:2570
474
  msgid "View broken links"
475
  msgstr ""
476
 
477
- #: core/core.php:2571
478
  msgid "Found %d broken link"
479
  msgid_plural "Found %d broken links"
480
  msgstr[0] ""
481
  msgstr[1] ""
482
 
483
- #: core/core.php:2577
484
  msgid "No broken links found."
485
  msgstr ""
486
 
487
- #: core/core.php:2584
488
  msgid "%d URL in the work queue"
489
  msgid_plural "%d URLs in the work queue"
490
  msgstr[0] ""
491
  msgstr[1] ""
492
 
493
- #: core/core.php:2587
494
  msgid "No URLs in the work queue."
495
  msgstr ""
496
 
497
- #: core/core.php:2593
498
  msgctxt "for the \"Detected X unique URLs in Y links\" message"
499
  msgid "%d unique URL"
500
  msgid_plural "%d unique URLs"
501
  msgstr[0] ""
502
  msgstr[1] ""
503
 
504
- #: core/core.php:2597
505
  msgctxt "for the \"Detected X unique URLs in Y links\" message"
506
  msgid "%d link"
507
  msgid_plural "%d links"
508
  msgstr[0] ""
509
  msgstr[1] ""
510
 
511
- #: core/core.php:2603
512
  msgid "Detected %1$s in %2$s and still searching..."
513
  msgstr ""
514
 
515
- #: core/core.php:2609
516
  msgid "Detected %1$s in %2$s."
517
  msgstr ""
518
 
519
- #: core/core.php:2616
520
  msgid "Searching your blog for links..."
521
  msgstr ""
522
 
523
- #: core/core.php:2618
524
  msgid "No links detected."
525
  msgstr ""
526
 
527
- #: core/core.php:2644
528
  msgctxt "current load"
529
  msgid "Unknown"
530
  msgstr ""
531
 
532
- #: core/core.php:2708 core/core.php:2748 core/core.php:2788 core/core.php:2870
 
533
  msgid "Oops, I can't find the link %d"
534
  msgstr ""
535
 
536
- #: core/core.php:2721 core/core.php:2758
537
  msgid "Oops, couldn't modify the link!"
538
  msgstr ""
539
 
540
- #: core/core.php:2724 core/core.php:2761 core/core.php:2896
 
541
  msgid "Error : link_id not specified"
542
  msgstr ""
543
 
544
- #: core/core.php:2779
545
  msgid "Error : link_id or new_url not specified"
546
  msgstr ""
547
 
548
- #: core/core.php:2797
549
  msgid "Oops, the new URL is invalid!"
550
  msgstr ""
551
 
552
- #: core/core.php:2812
553
  msgid "An unexpected error occurred!"
554
  msgstr ""
555
 
556
- #: core/core.php:2879
557
  msgid "An unexpected error occured!"
558
  msgstr ""
559
 
560
- #: core/core.php:2905
561
  msgid "You don't have sufficient privileges to access this information!"
562
  msgstr ""
563
 
564
- #: core/core.php:2918
565
  msgid "Error : link ID not specified"
566
  msgstr ""
567
 
568
- #: core/core.php:2932
569
  msgid "Failed to load link details (%s)"
570
  msgstr ""
571
 
572
- #. #-#-#-#-# plugin.pot (Broken Link Checker 1.9.4) #-#-#-#-#
573
  #. Plugin Name of the plugin/theme
574
- #: core/core.php:2986
575
  msgid "Broken Link Checker"
576
  msgstr ""
577
 
578
- #: core/core.php:3006
579
  msgid "PHP version"
580
  msgstr ""
581
 
582
- #: core/core.php:3012
583
  msgid "MySQL version"
584
  msgstr ""
585
 
586
- #: core/core.php:3025
587
  msgid ""
588
  "You have an old version of CURL. Redirect detection may not work properly."
589
  msgstr ""
590
 
591
- #: core/core.php:3037 core/core.php:3053 core/core.php:3058
592
  msgid "Not installed"
593
  msgstr ""
594
 
595
- #: core/core.php:3040
596
  msgid "CURL version"
597
  msgstr ""
598
 
599
- #: core/core.php:3046
600
  msgid "Installed"
601
  msgstr ""
602
 
603
- #: core/core.php:3059
604
  msgid "You must have either CURL or Snoopy installed for the plugin to work!"
605
  msgstr ""
606
 
607
- #: core/core.php:3070
608
  msgid "On"
609
  msgstr ""
610
 
611
- #: core/core.php:3071
612
  msgid "Redirects may be detected as broken links when safe_mode is on."
613
  msgstr ""
614
 
615
- #: core/core.php:3076 core/core.php:3090
616
  msgid "Off"
617
  msgstr ""
618
 
619
- #: core/core.php:3084
620
  msgid "On ( %s )"
621
  msgstr ""
622
 
623
- #: core/core.php:3085
624
  msgid "Redirects may be detected as broken links when open_basedir is on."
625
  msgstr ""
626
 
627
- #: core/core.php:3114
628
  msgid ""
629
  "If this value is zero even after several page reloads you have probably "
630
  "encountered a bug."
631
  msgstr ""
632
 
633
- #: core/core.php:3237 core/core.php:3356
634
  msgid "[%s] Broken links detected"
635
  msgstr ""
636
 
637
- #: core/core.php:3242
638
  msgid "Broken Link Checker has detected %d new broken link on your site."
639
  msgid_plural ""
640
  "Broken Link Checker has detected %d new broken links on your site."
641
  msgstr[0] ""
642
  msgstr[1] ""
643
 
644
- #: core/core.php:3273
645
  msgid "Here's a list of the first %d broken links:"
646
  msgid_plural "Here's a list of the first %d broken links:"
647
  msgstr[0] ""
648
  msgstr[1] ""
649
 
650
- #: core/core.php:3282
651
  msgid "Here's a list of the new broken links: "
652
  msgstr ""
653
 
654
- #: core/core.php:3291
655
  msgid "Link text : %s"
656
  msgstr ""
657
 
658
- #: core/core.php:3292
659
  msgid "Link URL : <a href=\"%s\">%s</a>"
660
  msgstr ""
661
 
662
- #: core/core.php:3293
663
  msgid "Source : %s"
664
  msgstr ""
665
 
666
- #: core/core.php:3307
667
  msgid "You can see all broken links here:"
668
  msgstr ""
669
 
670
- #: core/core.php:3361
671
  msgid "Broken Link Checker has detected %d new broken link in your posts."
672
  msgid_plural ""
673
  "Broken Link Checker has detected %d new broken links in your posts."
674
  msgstr[0] ""
675
  msgstr[1] ""
676
 
677
- #: core/init.php:249
678
  msgid "Once Weekly"
679
  msgstr ""
680
 
681
- #: core/init.php:255
682
  msgid "Twice a Month"
683
  msgstr ""
684
 
685
- #: core/init.php:331
686
  msgid ""
687
  "Broken Link Checker installation failed. Try deactivating and then "
688
  "reactivating the plugin."
689
  msgstr ""
690
 
691
- #: core/init.php:335
692
  msgid ""
693
  "Please activate the plugin separately on each site. Network activation is "
694
  "not supported."
@@ -698,110 +776,101 @@ msgstr ""
698
  msgid "Failed to delete old DB tables. Database error : %s"
699
  msgstr ""
700
 
701
- #: includes/admin/links-page-js.php:62 includes/admin/links-page-js.php:525
702
  msgid "Wait..."
703
  msgstr ""
704
 
705
- #: includes/admin/links-page-js.php:107 includes/admin/table-printer.php:671
706
- msgid "Not broken"
707
- msgstr ""
708
-
709
- #: includes/admin/links-page-js.php:243
710
  msgctxt "link text"
711
  msgid "(None)"
712
  msgstr ""
713
 
714
- #: includes/admin/links-page-js.php:244
715
  msgctxt "link text"
716
  msgid "(Multiple links)"
717
  msgstr ""
718
 
719
- #: includes/admin/links-page-js.php:302
720
  msgctxt "link suggestions"
721
  msgid "Searching..."
722
  msgstr ""
723
 
724
- #: includes/admin/links-page-js.php:303
725
  msgctxt "link suggestions"
726
  msgid "No suggestions available."
727
  msgstr ""
728
 
729
- #: includes/admin/links-page-js.php:304
730
  msgctxt "link suggestions"
731
  msgid "Archived page from %s (via the Wayback Machine)"
732
  msgstr ""
733
 
734
- #: includes/admin/links-page-js.php:387
735
  msgid "%d instances of the link were successfully modified."
736
  msgstr ""
737
 
738
- #: includes/admin/links-page-js.php:393
739
  msgid ""
740
  "However, %d instances couldn't be edited and still point to the old URL."
741
  msgstr ""
742
 
743
- #: includes/admin/links-page-js.php:399
744
  msgid "The link could not be modified."
745
  msgstr ""
746
 
747
- #: includes/admin/links-page-js.php:402
748
  msgid "The following error(s) occurred :"
749
  msgstr ""
750
 
751
- #: includes/admin/links-page-js.php:488
752
  msgid "Error: Link URL must not be empty."
753
  msgstr ""
754
 
755
- #: includes/admin/links-page-js.php:563
756
  msgid "%d instances of the link were successfully unlinked."
757
  msgstr ""
758
 
759
- #: includes/admin/links-page-js.php:569
760
  msgid "However, %d instances couldn't be removed."
761
  msgstr ""
762
 
763
- #: includes/admin/links-page-js.php:574
764
  msgid "The plugin failed to remove the link."
765
  msgstr ""
766
 
767
- #: includes/admin/links-page-js.php:577
768
  msgid "The following error(s) occured :"
769
  msgstr ""
770
 
771
- #: includes/admin/links-page-js.php:585 includes/admin/table-printer.php:289
772
- #: includes/admin/table-printer.php:665
773
- msgid "Unlink"
774
- msgstr ""
775
-
776
- #: includes/admin/links-page-js.php:629
777
  msgid "Enter a name for the new custom filter"
778
  msgstr ""
779
 
780
- #: includes/admin/links-page-js.php:641
781
  msgid ""
782
  "You are about to delete the current filter.\n"
783
  "'Cancel' to stop, 'OK' to delete"
784
  msgstr ""
785
 
786
- #: includes/admin/links-page-js.php:665
787
  msgid ""
788
  "Are you sure you want to delete all posts, bookmarks or other items that "
789
  "contain any of the selected links? This action can't be undone.\n"
790
  "'Cancel' to stop, 'OK' to delete"
791
  msgstr ""
792
 
793
- #: includes/admin/links-page-js.php:679
794
  msgid ""
795
  "Are you sure you want to remove the selected links? This action can't be "
796
  "undone.\n"
797
  "'Cancel' to stop, 'OK' to remove"
798
  msgstr ""
799
 
800
- #: includes/admin/links-page-js.php:791
801
  msgid "Enter a search string first."
802
  msgstr ""
803
 
804
- #: includes/admin/links-page-js.php:798
805
  msgid "Select one or more links to edit."
806
  msgstr ""
807
 
@@ -817,7 +886,7 @@ msgstr ""
817
  msgid "Delete This Filter"
818
  msgstr ""
819
 
820
- #: includes/admin/search-form.php:32 includes/link-query.php:65
821
  msgid "Search"
822
  msgstr ""
823
 
@@ -829,7 +898,7 @@ msgstr ""
829
  msgid "URL"
830
  msgstr ""
831
 
832
- #: includes/admin/search-form.php:48 includes/admin/table-printer.php:535
833
  msgid "HTTP code"
834
  msgstr ""
835
 
@@ -853,8 +922,8 @@ msgstr ""
853
  msgid "Search Links"
854
  msgstr ""
855
 
856
- #: includes/admin/search-form.php:113 includes/admin/table-printer.php:365
857
- #: includes/admin/table-printer.php:695 includes/admin/table-printer.php:820
858
  msgid "Cancel"
859
  msgstr ""
860
 
@@ -896,286 +965,283 @@ msgstr ""
896
  msgid "Redirect URL"
897
  msgstr ""
898
 
899
- #: includes/admin/table-printer.php:284
900
- msgid "Bulk Actions"
901
- msgstr ""
902
-
903
- #: includes/admin/table-printer.php:285 includes/admin/table-printer.php:662
904
- msgid "Edit URL"
905
- msgstr ""
906
-
907
  #: includes/admin/table-printer.php:286
908
- msgid "Recheck"
909
  msgstr ""
910
 
911
- #: includes/admin/table-printer.php:287
912
  msgid "Fix redirects"
913
  msgstr ""
914
 
915
- #: includes/admin/table-printer.php:288
916
  msgid "Mark as not broken"
917
  msgstr ""
918
 
919
- #: includes/admin/table-printer.php:292
920
  msgid "Move sources to Trash"
921
  msgstr ""
922
 
923
- #: includes/admin/table-printer.php:294
924
  msgid "Delete sources"
925
  msgstr ""
926
 
927
- #: includes/admin/table-printer.php:309
928
  msgid "&laquo;"
929
  msgstr ""
930
 
931
- #: includes/admin/table-printer.php:310
932
  msgid "&raquo;"
933
  msgstr ""
934
 
935
- #: includes/admin/table-printer.php:318
936
  msgid "Displaying %s&#8211;%s of <span class=\"current-link-count\">%s</span>"
937
  msgstr ""
938
 
939
- #: includes/admin/table-printer.php:341
940
  msgid "Bulk Edit URLs"
941
  msgstr ""
942
 
943
- #: includes/admin/table-printer.php:343
944
  msgid "Find"
945
  msgstr ""
946
 
947
- #: includes/admin/table-printer.php:347
948
  msgid "Replace with"
949
  msgstr ""
950
 
951
- #: includes/admin/table-printer.php:355
952
  msgid "Case sensitive"
953
  msgstr ""
954
 
955
- #: includes/admin/table-printer.php:359
956
  msgid "Regular expression"
957
  msgstr ""
958
 
959
- #: includes/admin/table-printer.php:367 includes/admin/table-printer.php:821
960
  msgid "Update"
961
  msgstr ""
962
 
963
- #: includes/admin/table-printer.php:520
964
  msgid "Post published on"
965
  msgstr ""
966
 
967
- #: includes/admin/table-printer.php:525
968
  msgid "Link last checked"
969
  msgstr ""
970
 
971
- #: includes/admin/table-printer.php:529
972
  msgid "Never"
973
  msgstr ""
974
 
975
- #: includes/admin/table-printer.php:540
976
  msgid "Response time"
977
  msgstr ""
978
 
979
- #: includes/admin/table-printer.php:542
980
  msgid "%2.3f seconds"
981
  msgstr ""
982
 
983
- #: includes/admin/table-printer.php:545
984
  msgid "Final URL"
985
  msgstr ""
986
 
987
- #: includes/admin/table-printer.php:550
988
  msgid "Redirect count"
989
  msgstr ""
990
 
991
- #: includes/admin/table-printer.php:555
992
  msgid "Instance count"
993
  msgstr ""
994
 
995
- #: includes/admin/table-printer.php:564
996
  msgid "This link has failed %d time."
997
  msgid_plural "This link has failed %d times."
998
  msgstr[0] ""
999
  msgstr[1] ""
1000
 
1001
- #: includes/admin/table-printer.php:572
1002
  msgid "This link has been broken for %s."
1003
  msgstr ""
1004
 
1005
- #: includes/admin/table-printer.php:583
1006
  msgid "Log"
1007
  msgstr ""
1008
 
1009
- #: includes/admin/table-printer.php:608
1010
  msgid "Show more info about this link"
1011
  msgstr ""
1012
 
1013
- #: includes/admin/table-printer.php:626
1014
  msgctxt "checked how long ago"
1015
  msgid "Checked"
1016
  msgstr ""
1017
 
1018
- #: includes/admin/table-printer.php:642
1019
  msgid "Broken for"
1020
  msgstr ""
1021
 
1022
- #: includes/admin/table-printer.php:662
 
 
 
 
 
1023
  msgid "Edit this link"
1024
  msgstr ""
1025
 
1026
- #: includes/admin/table-printer.php:664
1027
  msgid "Remove this link from all posts"
1028
  msgstr ""
1029
 
1030
- #: includes/admin/table-printer.php:670
1031
  msgid "Remove this link from the list of broken links and mark it as valid"
1032
  msgstr ""
1033
 
1034
- #: includes/admin/table-printer.php:678
1035
  msgid "Hide this link and do not report it again unless its status changes"
1036
  msgstr ""
1037
 
1038
- #: includes/admin/table-printer.php:679
1039
- msgid "Dismiss"
1040
- msgstr ""
1041
-
1042
- #: includes/admin/table-printer.php:684
1043
  msgid "Undismiss this link"
1044
  msgstr ""
1045
 
1046
- #: includes/admin/table-printer.php:685
1047
  msgid "Undismiss"
1048
  msgstr ""
1049
 
1050
- #: includes/admin/table-printer.php:696
 
 
 
 
1051
  msgid "Update URL"
1052
  msgstr ""
1053
 
1054
- #: includes/admin/table-printer.php:723
1055
  msgid "[An orphaned link! This is a bug.]"
1056
  msgstr ""
1057
 
1058
- #: includes/admin/table-printer.php:800
1059
  msgctxt "inline editor title"
1060
  msgid "Edit Link"
1061
  msgstr ""
1062
 
1063
- #: includes/admin/table-printer.php:803
1064
  msgctxt "inline link editor"
1065
  msgid "Text"
1066
  msgstr ""
1067
 
1068
- #: includes/admin/table-printer.php:808
1069
  msgctxt "inline link editor"
1070
  msgid "URL"
1071
  msgstr ""
1072
 
1073
- #: includes/admin/table-printer.php:813
1074
  msgctxt "inline link editor"
1075
  msgid "Suggestions"
1076
  msgstr ""
1077
 
1078
- #: includes/admin/table-printer.php:833
1079
  msgid "Use this URL"
1080
  msgstr ""
1081
 
1082
- #: includes/any-post.php:407 modules/containers/blogroll.php:46
1083
- #: modules/containers/comment.php:153 modules/containers/custom_field.php:207
1084
  msgid "Edit"
1085
  msgstr ""
1086
 
1087
- #: includes/any-post.php:415 modules/containers/custom_field.php:213
1088
  msgid "Move this item to the Trash"
1089
  msgstr ""
1090
 
1091
- #: includes/any-post.php:417 modules/containers/custom_field.php:215
1092
  msgid "Trash"
1093
  msgstr ""
1094
 
1095
- #: includes/any-post.php:422 modules/containers/custom_field.php:220
1096
  msgid "Delete this item permanently"
1097
  msgstr ""
1098
 
1099
- #: includes/any-post.php:424 modules/containers/blogroll.php:47
1100
- #: modules/containers/custom_field.php:222
1101
  msgid "Delete"
1102
  msgstr ""
1103
 
1104
- #: includes/any-post.php:437
1105
  msgid "Preview &#8220;%s&#8221;"
1106
  msgstr ""
1107
 
1108
- #: includes/any-post.php:438
1109
  msgid "Preview"
1110
  msgstr ""
1111
 
1112
- #: includes/any-post.php:445
1113
  msgid "View &#8220;%s&#8221;"
1114
  msgstr ""
1115
 
1116
- #: includes/any-post.php:446 modules/containers/comment.php:166
1117
- #: modules/containers/custom_field.php:227
1118
  msgid "View"
1119
  msgstr ""
1120
 
1121
- #: includes/any-post.php:465 modules/containers/custom_field.php:207
1122
  msgid "Edit this item"
1123
  msgstr ""
1124
 
1125
- #: includes/any-post.php:529 modules/containers/blogroll.php:83
1126
  #: modules/containers/comment.php:43
1127
  msgid "Nothing to update"
1128
  msgstr ""
1129
 
1130
- #: includes/any-post.php:539
1131
  msgid "Updating post %d failed"
1132
  msgstr ""
1133
 
1134
- #: includes/any-post.php:576 modules/containers/custom_field.php:294
1135
  msgid "Failed to delete post \"%s\" (%d)"
1136
  msgstr ""
1137
 
1138
- #: includes/any-post.php:595 modules/containers/custom_field.php:313
1139
  msgid ""
1140
  "Can't move post \"%s\" (%d) to the trash because the trash feature is "
1141
  "disabled"
1142
  msgstr ""
1143
 
1144
- #: includes/any-post.php:615 modules/containers/custom_field.php:332
1145
  msgid "Failed to move post \"%s\" (%d) to the trash"
1146
  msgstr ""
1147
 
1148
- #: includes/any-post.php:723
1149
  msgid "%d post deleted."
1150
  msgid_plural "%d posts deleted."
1151
  msgstr[0] ""
1152
  msgstr[1] ""
1153
 
1154
- #: includes/any-post.php:725
1155
  msgid "%d page deleted."
1156
  msgid_plural "%d pages deleted."
1157
  msgstr[0] ""
1158
  msgstr[1] ""
1159
 
1160
- #: includes/any-post.php:727
1161
  msgid "%d \"%s\" deleted."
1162
  msgid_plural "%d \"%s\" deleted."
1163
  msgstr[0] ""
1164
  msgstr[1] ""
1165
 
1166
- #: includes/any-post.php:746
1167
  msgid "%d post moved to the Trash."
1168
  msgid_plural "%d posts moved to the Trash."
1169
  msgstr[0] ""
1170
  msgstr[1] ""
1171
 
1172
- #: includes/any-post.php:748
1173
  msgid "%d page moved to the Trash."
1174
  msgid_plural "%d pages moved to the Trash."
1175
  msgstr[0] ""
1176
  msgstr[1] ""
1177
 
1178
- #: includes/any-post.php:750
1179
  msgid "%d \"%s\" moved to the Trash."
1180
  msgid_plural "%d \"%s\" moved to the Trash."
1181
  msgstr[0] ""
@@ -1294,114 +1360,127 @@ msgstr ""
1294
  msgid "Parser '%s' not found."
1295
  msgstr ""
1296
 
1297
- #: includes/link-query.php:26
1298
- msgid "Broken"
1299
  msgstr ""
1300
 
1301
- #: includes/link-query.php:28
1302
- msgid "No broken links found"
1303
  msgstr ""
1304
 
1305
- #: includes/link-query.php:36
1306
- msgid "Redirects"
1307
  msgstr ""
1308
 
1309
- #: includes/link-query.php:37
1310
- msgid "Redirected Links"
1311
  msgstr ""
1312
 
1313
  #: includes/link-query.php:38
1314
- msgid "No redirects found"
1315
  msgstr ""
1316
 
1317
  #: includes/link-query.php:46
1318
- msgid "Dismissed"
 
1319
  msgstr ""
1320
 
1321
  #: includes/link-query.php:47
1322
- msgid "Dismissed Links"
1323
  msgstr ""
1324
 
1325
  #: includes/link-query.php:48
1326
- msgid "No dismissed links found"
1327
  msgstr ""
1328
 
1329
  #: includes/link-query.php:56
1330
- msgid "All"
1331
  msgstr ""
1332
 
1333
  #: includes/link-query.php:57
1334
- msgid "Detected Links"
1335
  msgstr ""
1336
 
1337
  #: includes/link-query.php:58
1338
- msgid "No links found (yet)"
1339
  msgstr ""
1340
 
1341
  #: includes/link-query.php:66
 
 
 
 
 
 
 
 
 
 
 
 
1342
  msgid "Search Results"
1343
  msgstr ""
1344
 
1345
- #: includes/link-query.php:67 includes/link-query.php:114
1346
  msgid "No links found for your query"
1347
  msgstr ""
1348
 
1349
- #: includes/links.php:222
1350
  msgid "The plugin script was terminated while trying to check the link."
1351
  msgstr ""
1352
 
1353
- #: includes/links.php:268
1354
  msgid "The plugin doesn't know how to check this type of link."
1355
  msgstr ""
1356
 
1357
- #: includes/links.php:361
1358
- msgid "Link is valid."
1359
  msgstr ""
1360
 
1361
- #: includes/links.php:363
1362
- msgid "Link is broken."
1363
  msgstr ""
1364
 
1365
- #: includes/links.php:582 includes/links.php:684 includes/links.php:711
1366
  msgid "Link is not valid"
1367
  msgstr ""
1368
 
1369
- #: includes/links.php:599
1370
  msgid ""
1371
  "This link can not be edited because it is not used anywhere on this site."
1372
  msgstr ""
1373
 
1374
- #: includes/links.php:625
1375
  msgid "Failed to create a DB entry for the new URL."
1376
  msgstr ""
1377
 
1378
- #: includes/links.php:691
1379
  msgid "This link is not a redirect"
1380
  msgstr ""
1381
 
1382
- #: includes/links.php:738 includes/links.php:775
1383
  msgid "Couldn't delete the link's database record"
1384
  msgstr ""
1385
 
1386
- #: includes/links.php:849
1387
  msgctxt "link status"
1388
  msgid "Unknown"
1389
  msgstr ""
1390
 
1391
- #: includes/links.php:863 modules/checkers/http.php:304
1392
- #: modules/extras/mediafire.php:101
1393
  msgid "Unknown Error"
1394
  msgstr ""
1395
 
1396
- #: includes/links.php:887
1397
  msgid "Not checked"
1398
  msgstr ""
1399
 
1400
- #: includes/links.php:890
1401
  msgid "False positive"
1402
  msgstr ""
1403
 
1404
- #: includes/links.php:893 modules/extras/rapidshare.php:145
1405
  #: modules/extras/rapidshare.php:151 modules/extras/rapidshare.php:178
1406
  msgctxt "link status"
1407
  msgid "OK"
@@ -1475,31 +1554,31 @@ msgid_plural "%d months ago"
1475
  msgstr[0] ""
1476
  msgstr[1] ""
1477
 
1478
- #: modules/checkers/http.php:283
1479
  msgid "Server Not Found"
1480
  msgstr ""
1481
 
1482
- #: modules/checkers/http.php:298
1483
  msgid "Connection Failed"
1484
  msgstr ""
1485
 
1486
- #: modules/checkers/http.php:340 modules/checkers/http.php:410
1487
  msgid "HTTP code : %d"
1488
  msgstr ""
1489
 
1490
- #: modules/checkers/http.php:342 modules/checkers/http.php:412
1491
  msgid "(No response)"
1492
  msgstr ""
1493
 
1494
- #: modules/checkers/http.php:348
1495
  msgid "Most likely the connection timed out or the domain doesn't exist."
1496
  msgstr ""
1497
 
1498
- #: modules/checkers/http.php:419
1499
  msgid "Request timed out."
1500
  msgstr ""
1501
 
1502
- #: modules/checkers/http.php:437
1503
  msgid "Using Snoopy"
1504
  msgstr ""
1505
 
@@ -1543,38 +1622,38 @@ msgstr ""
1543
  msgid "Can't move comment %d to the trash"
1544
  msgstr ""
1545
 
1546
- #: modules/containers/comment.php:153 modules/containers/comment.php:195
1547
  msgid "Edit comment"
1548
  msgstr ""
1549
 
1550
- #: modules/containers/comment.php:160
1551
  msgid "Delete Permanently"
1552
  msgstr ""
1553
 
1554
- #: modules/containers/comment.php:162
1555
  msgid "Move this comment to the trash"
1556
  msgstr ""
1557
 
1558
- #: modules/containers/comment.php:162
1559
  msgctxt "verb"
1560
  msgid "Trash"
1561
  msgstr ""
1562
 
1563
- #: modules/containers/comment.php:166
1564
  msgid "View comment"
1565
  msgstr ""
1566
 
1567
- #: modules/containers/comment.php:183
1568
  msgid "Comment"
1569
  msgstr ""
1570
 
1571
- #: modules/containers/comment.php:358
1572
  msgid "%d comment has been deleted."
1573
  msgid_plural "%d comments have been deleted."
1574
  msgstr[0] ""
1575
  msgstr[1] ""
1576
 
1577
- #: modules/containers/comment.php:377
1578
  msgid "%d comment moved to the Trash."
1579
  msgid_plural "%d comments moved to the Trash."
1580
  msgstr[0] ""
@@ -1588,11 +1667,11 @@ msgstr ""
1588
  msgid "Failed to delete the meta field '%s' on %s [%d]"
1589
  msgstr ""
1590
 
1591
- #: modules/containers/custom_field.php:197
1592
  msgid "Edit this post"
1593
  msgstr ""
1594
 
1595
- #: modules/containers/custom_field.php:227
1596
  msgid "View \"%s\""
1597
  msgstr ""
1598
 
@@ -1622,11 +1701,15 @@ msgstr ""
1622
  msgid "Embedded GoogleVideo video"
1623
  msgstr ""
1624
 
1625
- #: modules/extras/mediafire.php:91 modules/extras/mediafire.php:96
1626
  #: modules/extras/rapidshare.php:139
1627
  msgid "Not Found"
1628
  msgstr ""
1629
 
 
 
 
 
1630
  #: modules/extras/rapidshare.php:51
1631
  msgid "Using RapidShare API"
1632
  msgstr ""
2
  # This file is distributed under the same license as the Broken Link Checker package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Broken Link Checker 1.9.5\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/broken-link-checker\n"
7
+ "POT-Creation-Date: 2014-11-25 11:57:14+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #: core/core.php:156 includes/admin/links-page-js.php:44
16
  msgid "Loading..."
17
  msgstr ""
18
 
19
+ #: core/core.php:180 includes/admin/options-page-js.php:18
20
  msgid "[ Network error ]"
21
  msgstr ""
22
 
23
+ #: core/core.php:207
24
  msgid "Automatically expand the widget if broken links have been detected"
25
  msgstr ""
26
 
27
+ #: core/core.php:298
28
  msgid "Link Checker Settings"
29
  msgstr ""
30
 
31
+ #: core/core.php:299
32
  msgid "Link Checker"
33
  msgstr ""
34
 
35
+ #: core/core.php:304 includes/link-query.php:37
36
  msgid "Broken Links"
37
  msgstr ""
38
 
39
+ #: core/core.php:320
40
  msgid "View Broken Links"
41
  msgstr ""
42
 
43
+ #: core/core.php:335
44
  msgid "Feedback"
45
  msgstr ""
46
 
47
+ #: core/core.php:343
48
  msgid "Go to Broken Links"
49
  msgstr ""
50
 
51
+ #: core/core.php:372
52
  msgid "Settings"
53
  msgstr ""
54
 
55
+ #: core/core.php:401 includes/admin/table-printer.php:287
56
+ #: includes/admin/table-printer.php:678
57
+ msgid "Edit URL"
58
+ msgstr ""
59
+
60
+ #: core/core.php:402 includes/admin/links-page-js.php:699
61
+ #: includes/admin/table-printer.php:292 includes/admin/table-printer.php:681
62
+ msgid "Unlink"
63
+ msgstr ""
64
+
65
+ #: core/core.php:403 includes/admin/links-page-js.php:110
66
+ #: includes/admin/table-printer.php:687
67
+ msgid "Not broken"
68
+ msgstr ""
69
+
70
+ #: core/core.php:404 includes/admin/table-printer.php:291
71
+ #: includes/admin/table-printer.php:695
72
+ msgid "Dismiss"
73
+ msgstr ""
74
+
75
+ #: core/core.php:405 includes/admin/table-printer.php:288
76
+ #: includes/admin/table-printer.php:707
77
+ msgid "Recheck"
78
+ msgstr ""
79
+
80
+ #: core/core.php:406 includes/admin/table-printer.php:715
81
+ msgctxt "link action; replace one redirect with a direct link"
82
+ msgid "Fix redirect"
83
+ msgstr ""
84
+
85
+ #: core/core.php:626
86
  msgid "Settings saved."
87
  msgstr ""
88
 
89
+ #: core/core.php:632
90
  msgid "Thank you for your donation!"
91
  msgstr ""
92
 
93
+ #: core/core.php:640
94
  msgid "Complete site recheck started."
95
  msgstr ""
96
 
97
+ #: core/core.php:662
 
 
 
 
98
  msgid "General"
99
  msgstr ""
100
 
101
+ #: core/core.php:663
102
  msgid "Look For Links In"
103
  msgstr ""
104
 
105
+ #: core/core.php:664
106
  msgid "Which Links To Check"
107
  msgstr ""
108
 
109
+ #: core/core.php:665
110
  msgid "Protocols & APIs"
111
  msgstr ""
112
 
113
+ #: core/core.php:666
114
  msgid "Advanced"
115
  msgstr ""
116
 
117
+ #: core/core.php:681
118
  msgid "Broken Link Checker Options"
119
  msgstr ""
120
 
121
+ #: core/core.php:723 includes/admin/table-printer.php:211
122
  msgid "Status"
123
  msgstr ""
124
 
125
+ #: core/core.php:725 includes/admin/options-page-js.php:56
126
  msgid "Show debug info"
127
  msgstr ""
128
 
129
+ #: core/core.php:753
130
  msgid "Check each link"
131
  msgstr ""
132
 
133
+ #: core/core.php:758
134
  msgid "Every %s hours"
135
  msgstr ""
136
 
137
+ #: core/core.php:767
138
  msgid ""
139
  "Existing links will be checked this often. New links will usually be checked "
140
  "ASAP."
141
  msgstr ""
142
 
143
+ #: core/core.php:774
144
  msgid "E-mail notifications"
145
  msgstr ""
146
 
147
+ #: core/core.php:780
148
  msgid "Send me e-mail notifications about newly detected broken links"
149
  msgstr ""
150
 
151
+ #: core/core.php:788
152
  msgid "Send authors e-mail notifications about broken links in their posts"
153
  msgstr ""
154
 
155
+ #: core/core.php:795
156
  msgid "Notification e-mail address"
157
  msgstr ""
158
 
159
+ #: core/core.php:807
160
  msgid ""
161
  "Leave empty to use the e-mail address specified in Settings &rarr; General."
162
  msgstr ""
163
 
164
+ #: core/core.php:814
165
  msgid "Link tweaks"
166
  msgstr ""
167
 
168
+ #: core/core.php:820
169
  msgid "Apply custom formatting to broken links"
170
  msgstr ""
171
 
172
+ #: core/core.php:824 core/core.php:855
173
  msgid "Edit CSS"
174
  msgstr ""
175
 
176
+ #: core/core.php:840
177
  msgid "Example : Lorem ipsum <a %s>broken link</a>, dolor sit amet."
178
  msgstr ""
179
 
180
+ #: core/core.php:843 core/core.php:874
181
  msgid "Click \"Save Changes\" to update example output."
182
  msgstr ""
183
 
184
+ #: core/core.php:851
185
  msgid "Apply custom formatting to removed links"
186
  msgstr ""
187
 
188
+ #: core/core.php:871
189
  msgid "Example : Lorem ipsum <span %s>removed link</span>, dolor sit amet."
190
  msgstr ""
191
 
192
+ #: core/core.php:884
193
  msgid "Stop search engines from following broken links"
194
  msgstr ""
195
 
196
+ #: core/core.php:890
197
+ msgctxt "\"Link tweaks\" settings"
198
+ msgid ""
199
+ "These settings only apply to the content of posts, not comments or custom "
200
+ "fields."
201
+ msgstr ""
202
+
203
+ #: core/core.php:901
204
  msgctxt "settings page"
205
  msgid "Suggestions"
206
  msgstr ""
207
 
208
+ #: core/core.php:906
209
  msgid "Suggest alternatives to broken links"
210
  msgstr ""
211
 
212
+ #: core/core.php:912
213
+ msgctxt "settings page"
214
+ msgid "Warnings"
215
+ msgstr ""
216
+
217
+ #: core/core.php:917
218
+ msgid "Show uncertain or minor problems as \"warnings\" instead of \"broken\""
219
+ msgstr ""
220
+
221
+ #: core/core.php:920
222
+ msgid ""
223
+ "Turning off this option will make the plugin report all problems as broken "
224
+ "links."
225
+ msgstr ""
226
+
227
+ #: core/core.php:935
228
  msgid "Look for links in"
229
  msgstr ""
230
 
231
+ #: core/core.php:946
232
  msgid "Post statuses"
233
  msgstr ""
234
 
235
+ #: core/core.php:979
236
  msgid "Link types"
237
  msgstr ""
238
 
239
+ #: core/core.php:985
240
  msgid "Error : All link parsers missing!"
241
  msgstr ""
242
 
243
+ #: core/core.php:992
244
  msgid "Exclusion list"
245
  msgstr ""
246
 
247
+ #: core/core.php:993
248
  msgid ""
249
  "Don't check links where the URL contains any of these words (one per line) :"
250
  msgstr ""
251
 
252
+ #: core/core.php:1011
253
  msgid "Check links using"
254
  msgstr ""
255
 
256
+ #: core/core.php:1030 includes/links.php:1012
257
  msgid "Timeout"
258
  msgstr ""
259
 
260
+ #: core/core.php:1036 core/core.php:1123 core/core.php:3409
261
  msgid "%s seconds"
262
  msgstr ""
263
 
264
+ #: core/core.php:1045
265
  msgid "Links that take longer than this to load will be marked as broken."
266
  msgstr ""
267
 
268
+ #: core/core.php:1052
269
  msgid "Link monitor"
270
  msgstr ""
271
 
272
+ #: core/core.php:1060
273
  msgid "Run continuously while the Dashboard is open"
274
  msgstr ""
275
 
276
+ #: core/core.php:1068
277
  msgid "Run hourly in the background"
278
  msgstr ""
279
 
280
+ #: core/core.php:1076
281
  msgid "Show the dashboard widget for"
282
  msgstr ""
283
 
284
+ #: core/core.php:1081
285
  msgctxt "dashboard widget visibility"
286
  msgid "Administrator"
287
  msgstr ""
288
 
289
+ #: core/core.php:1082
290
  msgctxt "dashboard widget visibility"
291
  msgid "Editor and above"
292
  msgstr ""
293
 
294
+ #: core/core.php:1083
295
  msgctxt "dashboard widget visibility"
296
  msgid "Nobody (disables the widget)"
297
  msgstr ""
298
 
299
+ #: core/core.php:1099
300
+ msgctxt "settings page"
301
+ msgid "Show link actions"
302
+ msgstr ""
303
+
304
+ #: core/core.php:1117
305
  msgid "Max. execution time"
306
  msgstr ""
307
 
308
+ #: core/core.php:1134
309
  msgid ""
310
  "The plugin works by periodically launching a background job that parses your "
311
  "posts for links, checks the discovered URLs, and performs other time-"
313
  "may run each time before stopping."
314
  msgstr ""
315
 
316
+ #: core/core.php:1143
317
  msgid "Server load limit"
318
  msgstr ""
319
 
320
+ #: core/core.php:1158
321
  msgid "Current load : %s"
322
  msgstr ""
323
 
324
+ #: core/core.php:1163
325
  msgid ""
326
  "Link checking will be suspended if the average <a href=\"%s\">server load</"
327
  "a> rises above this number. Leave this field blank to disable load limiting."
328
  msgstr ""
329
 
330
+ #: core/core.php:1172
331
  msgid "Not available"
332
  msgstr ""
333
 
334
+ #: core/core.php:1174
335
  msgid ""
336
  "Load limiting only works on Linux-like systems where <code>/proc/loadavg</"
337
  "code> is present and accessible."
338
  msgstr ""
339
 
340
+ #: core/core.php:1182
341
  msgid "Target resource usage"
342
  msgstr ""
343
 
344
+ #: core/core.php:1200
345
  msgid "Logging"
346
  msgstr ""
347
 
348
+ #: core/core.php:1206
349
  msgid "Enable logging"
350
  msgstr ""
351
 
352
+ #: core/core.php:1213
353
  msgid "Log file location"
354
  msgstr ""
355
 
356
+ #: core/core.php:1222
357
  msgctxt "log file location"
358
  msgid "Default"
359
  msgstr ""
360
 
361
+ #: core/core.php:1236
362
  msgctxt "log file location"
363
  msgid "Custom"
364
  msgstr ""
365
 
366
+ #: core/core.php:1248
367
  msgid "Forced recheck"
368
  msgstr ""
369
 
370
+ #: core/core.php:1251
371
  msgid "Re-check all pages"
372
  msgstr ""
373
 
374
+ #: core/core.php:1255
375
  msgid ""
376
  "The \"Nuclear Option\". Click this button to make the plugin empty its link "
377
  "database and recheck the entire site from scratch."
378
  msgstr ""
379
 
380
+ #: core/core.php:1266
381
  msgid "Save Changes"
382
  msgstr ""
383
 
384
+ #: core/core.php:1317
385
  msgid "Configure"
386
  msgstr ""
387
 
388
+ #: core/core.php:1399
389
  msgid ""
390
  "Enter the names of custom fields you want to check (one per line). If a "
391
  "field contains HTML code, prefix its name with <code>html:</code>. For "
392
  "example, <code>html:field_name</code>."
393
  msgstr ""
394
 
395
+ #: core/core.php:1534 core/core.php:1617 core/core.php:1649
396
  msgid "Database error : %s"
397
  msgstr ""
398
 
399
+ #: core/core.php:1599
400
  msgid "You must enter a filter name!"
401
  msgstr ""
402
 
403
+ #: core/core.php:1603
404
  msgid "Invalid search query."
405
  msgstr ""
406
 
407
+ #: core/core.php:1612
408
  msgid "Filter \"%s\" created"
409
  msgstr ""
410
 
411
+ #: core/core.php:1639
412
  msgid "Filter ID not specified."
413
  msgstr ""
414
 
415
+ #: core/core.php:1646
416
  msgid "Filter deleted"
417
  msgstr ""
418
 
419
+ #: core/core.php:1693
420
  msgid "Replaced %d redirect with a direct link"
421
  msgid_plural "Replaced %d redirects with direct links"
422
  msgstr[0] ""
423
  msgstr[1] ""
424
 
425
+ #: core/core.php:1704
426
  msgid "Failed to fix %d redirect"
427
  msgid_plural "Failed to fix %d redirects"
428
  msgstr[0] ""
429
  msgstr[1] ""
430
 
431
+ #: core/core.php:1715
432
  msgid "None of the selected links are redirects!"
433
  msgstr ""
434
 
435
+ #: core/core.php:1793
436
  msgid "%d link updated."
437
  msgid_plural "%d links updated."
438
  msgstr[0] ""
439
  msgstr[1] ""
440
 
441
+ #: core/core.php:1804
442
  msgid "Failed to update %d link."
443
  msgid_plural "Failed to update %d links."
444
  msgstr[0] ""
445
  msgstr[1] ""
446
 
447
+ #: core/core.php:1893
448
  msgid "%d link removed"
449
  msgid_plural "%d links removed"
450
  msgstr[0] ""
451
  msgstr[1] ""
452
 
453
+ #: core/core.php:1904
454
  msgid "Failed to remove %d link"
455
  msgid_plural "Failed to remove %d links"
456
  msgstr[0] ""
457
  msgstr[1] ""
458
 
459
+ #: core/core.php:2013
460
  msgid ""
461
  "%d item was skipped because it can't be moved to the Trash. You need to "
462
  "delete it manually."
466
  msgstr[0] ""
467
  msgstr[1] ""
468
 
469
+ #: core/core.php:2035
470
  msgid "Didn't find anything to delete!"
471
  msgstr ""
472
 
473
+ #: core/core.php:2063
474
  msgid "%d link scheduled for rechecking"
475
  msgid_plural "%d links scheduled for rechecking"
476
  msgstr[0] ""
477
  msgstr[1] ""
478
 
479
+ #: core/core.php:2110 core/core.php:2923
480
  msgid "This link was manually marked as working by the user."
481
  msgstr ""
482
 
483
+ #: core/core.php:2117 core/core.php:2175
484
  msgid "Couldn't modify link %d"
485
  msgstr ""
486
 
487
+ #: core/core.php:2127
488
  msgid "%d link marked as not broken"
489
  msgid_plural "%d links marked as not broken"
490
  msgstr[0] ""
491
  msgstr[1] ""
492
 
493
+ #: core/core.php:2185
494
+ msgid "%d link dismissed"
495
+ msgid_plural "%d links dismissed"
496
+ msgstr[0] ""
497
+ msgstr[1] ""
498
+
499
+ #: core/core.php:2242
500
+ msgid ""
501
+ "The \"Warnings\" page lists problems that are probably temporary or "
502
+ "suspected to be false positives.<br> Warnings that persist for a long time "
503
+ "will usually be reclassified as broken links."
504
+ msgstr ""
505
+
506
+ #: core/core.php:2247
507
+ msgctxt "admin notice under Tools - Broken links - Warnings"
508
+ msgid "Hide notice"
509
+ msgstr ""
510
+
511
+ #: core/core.php:2253
512
+ msgctxt "a link from the admin notice under Tools - Broken links - Warnings"
513
+ msgid "Change warning settings"
514
+ msgstr ""
515
+
516
+ #: core/core.php:2278
517
  msgid "Table columns"
518
  msgstr ""
519
 
520
+ #: core/core.php:2297
521
  msgid "Show on screen"
522
  msgstr ""
523
 
524
+ #: core/core.php:2304
525
  msgid "links"
526
  msgstr ""
527
 
528
+ #: core/core.php:2305 includes/admin/table-printer.php:171
529
  msgid "Apply"
530
  msgstr ""
531
 
532
+ #: core/core.php:2309
533
  msgid "Misc"
534
  msgstr ""
535
 
536
+ #: core/core.php:2324
537
  msgid "Highlight links broken for at least %s days"
538
  msgstr ""
539
 
540
+ #: core/core.php:2333
541
  msgid "Color-code status codes"
542
  msgstr ""
543
 
544
+ #: core/core.php:2350 core/core.php:2907 core/core.php:2948 core/core.php:2981
545
+ #: core/core.php:3070 core/core.php:3114 core/core.php:3175
546
  msgid "You're not allowed to do that!"
547
  msgstr ""
548
 
549
+ #: core/core.php:2778
550
  msgid "View broken links"
551
  msgstr ""
552
 
553
+ #: core/core.php:2779
554
  msgid "Found %d broken link"
555
  msgid_plural "Found %d broken links"
556
  msgstr[0] ""
557
  msgstr[1] ""
558
 
559
+ #: core/core.php:2785
560
  msgid "No broken links found."
561
  msgstr ""
562
 
563
+ #: core/core.php:2792
564
  msgid "%d URL in the work queue"
565
  msgid_plural "%d URLs in the work queue"
566
  msgstr[0] ""
567
  msgstr[1] ""
568
 
569
+ #: core/core.php:2795
570
  msgid "No URLs in the work queue."
571
  msgstr ""
572
 
573
+ #: core/core.php:2801
574
  msgctxt "for the \"Detected X unique URLs in Y links\" message"
575
  msgid "%d unique URL"
576
  msgid_plural "%d unique URLs"
577
  msgstr[0] ""
578
  msgstr[1] ""
579
 
580
+ #: core/core.php:2805
581
  msgctxt "for the \"Detected X unique URLs in Y links\" message"
582
  msgid "%d link"
583
  msgid_plural "%d links"
584
  msgstr[0] ""
585
  msgstr[1] ""
586
 
587
+ #: core/core.php:2811
588
  msgid "Detected %1$s in %2$s and still searching..."
589
  msgstr ""
590
 
591
+ #: core/core.php:2817
592
  msgid "Detected %1$s in %2$s."
593
  msgstr ""
594
 
595
+ #: core/core.php:2824
596
  msgid "Searching your blog for links..."
597
  msgstr ""
598
 
599
+ #: core/core.php:2826
600
  msgid "No links detected."
601
  msgstr ""
602
 
603
+ #: core/core.php:2852
604
  msgctxt "current load"
605
  msgid "Unknown"
606
  msgstr ""
607
 
608
+ #: core/core.php:2915 core/core.php:2956 core/core.php:2996 core/core.php:3080
609
+ #: core/core.php:3129 core/core.php:3190
610
  msgid "Oops, I can't find the link %d"
611
  msgstr ""
612
 
613
+ #: core/core.php:2929 core/core.php:2966
614
  msgid "Oops, couldn't modify the link!"
615
  msgstr ""
616
 
617
+ #: core/core.php:2932 core/core.php:2969 core/core.php:3106 core/core.php:3120
618
+ #: core/core.php:3181
619
  msgid "Error : link_id not specified"
620
  msgstr ""
621
 
622
+ #: core/core.php:2987
623
  msgid "Error : link_id or new_url not specified"
624
  msgstr ""
625
 
626
+ #: core/core.php:3005
627
  msgid "Oops, the new URL is invalid!"
628
  msgstr ""
629
 
630
+ #: core/core.php:3020
631
  msgid "An unexpected error occurred!"
632
  msgstr ""
633
 
634
+ #: core/core.php:3089
635
  msgid "An unexpected error occured!"
636
  msgstr ""
637
 
638
+ #: core/core.php:3217
639
  msgid "You don't have sufficient privileges to access this information!"
640
  msgstr ""
641
 
642
+ #: core/core.php:3230
643
  msgid "Error : link ID not specified"
644
  msgstr ""
645
 
646
+ #: core/core.php:3244
647
  msgid "Failed to load link details (%s)"
648
  msgstr ""
649
 
650
+ #. #-#-#-#-# plugin.pot (Broken Link Checker 1.9.5) #-#-#-#-#
651
  #. Plugin Name of the plugin/theme
652
+ #: core/core.php:3298
653
  msgid "Broken Link Checker"
654
  msgstr ""
655
 
656
+ #: core/core.php:3318
657
  msgid "PHP version"
658
  msgstr ""
659
 
660
+ #: core/core.php:3324
661
  msgid "MySQL version"
662
  msgstr ""
663
 
664
+ #: core/core.php:3337
665
  msgid ""
666
  "You have an old version of CURL. Redirect detection may not work properly."
667
  msgstr ""
668
 
669
+ #: core/core.php:3349 core/core.php:3365 core/core.php:3370
670
  msgid "Not installed"
671
  msgstr ""
672
 
673
+ #: core/core.php:3352
674
  msgid "CURL version"
675
  msgstr ""
676
 
677
+ #: core/core.php:3358
678
  msgid "Installed"
679
  msgstr ""
680
 
681
+ #: core/core.php:3371
682
  msgid "You must have either CURL or Snoopy installed for the plugin to work!"
683
  msgstr ""
684
 
685
+ #: core/core.php:3382
686
  msgid "On"
687
  msgstr ""
688
 
689
+ #: core/core.php:3383
690
  msgid "Redirects may be detected as broken links when safe_mode is on."
691
  msgstr ""
692
 
693
+ #: core/core.php:3388 core/core.php:3402
694
  msgid "Off"
695
  msgstr ""
696
 
697
+ #: core/core.php:3396
698
  msgid "On ( %s )"
699
  msgstr ""
700
 
701
+ #: core/core.php:3397
702
  msgid "Redirects may be detected as broken links when open_basedir is on."
703
  msgstr ""
704
 
705
+ #: core/core.php:3426
706
  msgid ""
707
  "If this value is zero even after several page reloads you have probably "
708
  "encountered a bug."
709
  msgstr ""
710
 
711
+ #: core/core.php:3549 core/core.php:3668
712
  msgid "[%s] Broken links detected"
713
  msgstr ""
714
 
715
+ #: core/core.php:3554
716
  msgid "Broken Link Checker has detected %d new broken link on your site."
717
  msgid_plural ""
718
  "Broken Link Checker has detected %d new broken links on your site."
719
  msgstr[0] ""
720
  msgstr[1] ""
721
 
722
+ #: core/core.php:3585
723
  msgid "Here's a list of the first %d broken links:"
724
  msgid_plural "Here's a list of the first %d broken links:"
725
  msgstr[0] ""
726
  msgstr[1] ""
727
 
728
+ #: core/core.php:3594
729
  msgid "Here's a list of the new broken links: "
730
  msgstr ""
731
 
732
+ #: core/core.php:3603
733
  msgid "Link text : %s"
734
  msgstr ""
735
 
736
+ #: core/core.php:3604
737
  msgid "Link URL : <a href=\"%s\">%s</a>"
738
  msgstr ""
739
 
740
+ #: core/core.php:3605
741
  msgid "Source : %s"
742
  msgstr ""
743
 
744
+ #: core/core.php:3619
745
  msgid "You can see all broken links here:"
746
  msgstr ""
747
 
748
+ #: core/core.php:3673
749
  msgid "Broken Link Checker has detected %d new broken link in your posts."
750
  msgid_plural ""
751
  "Broken Link Checker has detected %d new broken links in your posts."
752
  msgstr[0] ""
753
  msgstr[1] ""
754
 
755
+ #: core/init.php:255
756
  msgid "Once Weekly"
757
  msgstr ""
758
 
759
+ #: core/init.php:261
760
  msgid "Twice a Month"
761
  msgstr ""
762
 
763
+ #: core/init.php:337
764
  msgid ""
765
  "Broken Link Checker installation failed. Try deactivating and then "
766
  "reactivating the plugin."
767
  msgstr ""
768
 
769
+ #: core/init.php:341
770
  msgid ""
771
  "Please activate the plugin separately on each site. Network activation is "
772
  "not supported."
776
  msgid "Failed to delete old DB tables. Database error : %s"
777
  msgstr ""
778
 
779
+ #: includes/admin/links-page-js.php:63 includes/admin/links-page-js.php:639
780
  msgid "Wait..."
781
  msgstr ""
782
 
783
+ #: includes/admin/links-page-js.php:368
 
 
 
 
784
  msgctxt "link text"
785
  msgid "(None)"
786
  msgstr ""
787
 
788
+ #: includes/admin/links-page-js.php:369
789
  msgctxt "link text"
790
  msgid "(Multiple links)"
791
  msgstr ""
792
 
793
+ #: includes/admin/links-page-js.php:427
794
  msgctxt "link suggestions"
795
  msgid "Searching..."
796
  msgstr ""
797
 
798
+ #: includes/admin/links-page-js.php:428
799
  msgctxt "link suggestions"
800
  msgid "No suggestions available."
801
  msgstr ""
802
 
803
+ #: includes/admin/links-page-js.php:429
804
  msgctxt "link suggestions"
805
  msgid "Archived page from %s (via the Wayback Machine)"
806
  msgstr ""
807
 
808
+ #: includes/admin/links-page-js.php:523
809
  msgid "%d instances of the link were successfully modified."
810
  msgstr ""
811
 
812
+ #: includes/admin/links-page-js.php:529
813
  msgid ""
814
  "However, %d instances couldn't be edited and still point to the old URL."
815
  msgstr ""
816
 
817
+ #: includes/admin/links-page-js.php:535
818
  msgid "The link could not be modified."
819
  msgstr ""
820
 
821
+ #: includes/admin/links-page-js.php:538
822
  msgid "The following error(s) occurred :"
823
  msgstr ""
824
 
825
+ #: includes/admin/links-page-js.php:602
826
  msgid "Error: Link URL must not be empty."
827
  msgstr ""
828
 
829
+ #: includes/admin/links-page-js.php:677
830
  msgid "%d instances of the link were successfully unlinked."
831
  msgstr ""
832
 
833
+ #: includes/admin/links-page-js.php:683
834
  msgid "However, %d instances couldn't be removed."
835
  msgstr ""
836
 
837
+ #: includes/admin/links-page-js.php:688
838
  msgid "The plugin failed to remove the link."
839
  msgstr ""
840
 
841
+ #: includes/admin/links-page-js.php:691
842
  msgid "The following error(s) occured :"
843
  msgstr ""
844
 
845
+ #: includes/admin/links-page-js.php:737
 
 
 
 
 
846
  msgid "Enter a name for the new custom filter"
847
  msgstr ""
848
 
849
+ #: includes/admin/links-page-js.php:749
850
  msgid ""
851
  "You are about to delete the current filter.\n"
852
  "'Cancel' to stop, 'OK' to delete"
853
  msgstr ""
854
 
855
+ #: includes/admin/links-page-js.php:773
856
  msgid ""
857
  "Are you sure you want to delete all posts, bookmarks or other items that "
858
  "contain any of the selected links? This action can't be undone.\n"
859
  "'Cancel' to stop, 'OK' to delete"
860
  msgstr ""
861
 
862
+ #: includes/admin/links-page-js.php:787
863
  msgid ""
864
  "Are you sure you want to remove the selected links? This action can't be "
865
  "undone.\n"
866
  "'Cancel' to stop, 'OK' to remove"
867
  msgstr ""
868
 
869
+ #: includes/admin/links-page-js.php:899
870
  msgid "Enter a search string first."
871
  msgstr ""
872
 
873
+ #: includes/admin/links-page-js.php:906
874
  msgid "Select one or more links to edit."
875
  msgstr ""
876
 
886
  msgid "Delete This Filter"
887
  msgstr ""
888
 
889
+ #: includes/admin/search-form.php:32 includes/link-query.php:81
890
  msgid "Search"
891
  msgstr ""
892
 
898
  msgid "URL"
899
  msgstr ""
900
 
901
+ #: includes/admin/search-form.php:48 includes/admin/table-printer.php:542
902
  msgid "HTTP code"
903
  msgstr ""
904
 
922
  msgid "Search Links"
923
  msgstr ""
924
 
925
+ #: includes/admin/search-form.php:113 includes/admin/table-printer.php:368
926
+ #: includes/admin/table-printer.php:747 includes/admin/table-printer.php:872
927
  msgid "Cancel"
928
  msgstr ""
929
 
965
  msgid "Redirect URL"
966
  msgstr ""
967
 
 
 
 
 
 
 
 
 
968
  #: includes/admin/table-printer.php:286
969
+ msgid "Bulk Actions"
970
  msgstr ""
971
 
972
+ #: includes/admin/table-printer.php:289
973
  msgid "Fix redirects"
974
  msgstr ""
975
 
976
+ #: includes/admin/table-printer.php:290
977
  msgid "Mark as not broken"
978
  msgstr ""
979
 
980
+ #: includes/admin/table-printer.php:295
981
  msgid "Move sources to Trash"
982
  msgstr ""
983
 
984
+ #: includes/admin/table-printer.php:297
985
  msgid "Delete sources"
986
  msgstr ""
987
 
988
+ #: includes/admin/table-printer.php:312
989
  msgid "&laquo;"
990
  msgstr ""
991
 
992
+ #: includes/admin/table-printer.php:313
993
  msgid "&raquo;"
994
  msgstr ""
995
 
996
+ #: includes/admin/table-printer.php:321
997
  msgid "Displaying %s&#8211;%s of <span class=\"current-link-count\">%s</span>"
998
  msgstr ""
999
 
1000
+ #: includes/admin/table-printer.php:344
1001
  msgid "Bulk Edit URLs"
1002
  msgstr ""
1003
 
1004
+ #: includes/admin/table-printer.php:346
1005
  msgid "Find"
1006
  msgstr ""
1007
 
1008
+ #: includes/admin/table-printer.php:350
1009
  msgid "Replace with"
1010
  msgstr ""
1011
 
1012
+ #: includes/admin/table-printer.php:358
1013
  msgid "Case sensitive"
1014
  msgstr ""
1015
 
1016
+ #: includes/admin/table-printer.php:362
1017
  msgid "Regular expression"
1018
  msgstr ""
1019
 
1020
+ #: includes/admin/table-printer.php:370 includes/admin/table-printer.php:873
1021
  msgid "Update"
1022
  msgstr ""
1023
 
1024
+ #: includes/admin/table-printer.php:523
1025
  msgid "Post published on"
1026
  msgstr ""
1027
 
1028
+ #: includes/admin/table-printer.php:528
1029
  msgid "Link last checked"
1030
  msgstr ""
1031
 
1032
+ #: includes/admin/table-printer.php:532
1033
  msgid "Never"
1034
  msgstr ""
1035
 
1036
+ #: includes/admin/table-printer.php:547
1037
  msgid "Response time"
1038
  msgstr ""
1039
 
1040
+ #: includes/admin/table-printer.php:549
1041
  msgid "%2.3f seconds"
1042
  msgstr ""
1043
 
1044
+ #: includes/admin/table-printer.php:552
1045
  msgid "Final URL"
1046
  msgstr ""
1047
 
1048
+ #: includes/admin/table-printer.php:557
1049
  msgid "Redirect count"
1050
  msgstr ""
1051
 
1052
+ #: includes/admin/table-printer.php:562
1053
  msgid "Instance count"
1054
  msgstr ""
1055
 
1056
+ #: includes/admin/table-printer.php:571
1057
  msgid "This link has failed %d time."
1058
  msgid_plural "This link has failed %d times."
1059
  msgstr[0] ""
1060
  msgstr[1] ""
1061
 
1062
+ #: includes/admin/table-printer.php:579
1063
  msgid "This link has been broken for %s."
1064
  msgstr ""
1065
 
1066
+ #: includes/admin/table-printer.php:590
1067
  msgid "Log"
1068
  msgstr ""
1069
 
1070
+ #: includes/admin/table-printer.php:615 includes/admin/table-printer.php:660
1071
  msgid "Show more info about this link"
1072
  msgstr ""
1073
 
1074
+ #: includes/admin/table-printer.php:633
1075
  msgctxt "checked how long ago"
1076
  msgid "Checked"
1077
  msgstr ""
1078
 
1079
+ #: includes/admin/table-printer.php:649
1080
  msgid "Broken for"
1081
  msgstr ""
1082
 
1083
+ #: includes/admin/table-printer.php:661
1084
+ msgctxt "link in the \"Status\" column"
1085
+ msgid "Details"
1086
+ msgstr ""
1087
+
1088
+ #: includes/admin/table-printer.php:678
1089
  msgid "Edit this link"
1090
  msgstr ""
1091
 
1092
+ #: includes/admin/table-printer.php:680
1093
  msgid "Remove this link from all posts"
1094
  msgstr ""
1095
 
1096
+ #: includes/admin/table-printer.php:686
1097
  msgid "Remove this link from the list of broken links and mark it as valid"
1098
  msgstr ""
1099
 
1100
+ #: includes/admin/table-printer.php:694
1101
  msgid "Hide this link and do not report it again unless its status changes"
1102
  msgstr ""
1103
 
1104
+ #: includes/admin/table-printer.php:700
 
 
 
 
1105
  msgid "Undismiss this link"
1106
  msgstr ""
1107
 
1108
+ #: includes/admin/table-printer.php:701
1109
  msgid "Undismiss"
1110
  msgstr ""
1111
 
1112
+ #: includes/admin/table-printer.php:714
1113
+ msgid "Replace this redirect with a direct link"
1114
+ msgstr ""
1115
+
1116
+ #: includes/admin/table-printer.php:748
1117
  msgid "Update URL"
1118
  msgstr ""
1119
 
1120
+ #: includes/admin/table-printer.php:775
1121
  msgid "[An orphaned link! This is a bug.]"
1122
  msgstr ""
1123
 
1124
+ #: includes/admin/table-printer.php:852
1125
  msgctxt "inline editor title"
1126
  msgid "Edit Link"
1127
  msgstr ""
1128
 
1129
+ #: includes/admin/table-printer.php:855
1130
  msgctxt "inline link editor"
1131
  msgid "Text"
1132
  msgstr ""
1133
 
1134
+ #: includes/admin/table-printer.php:860
1135
  msgctxt "inline link editor"
1136
  msgid "URL"
1137
  msgstr ""
1138
 
1139
+ #: includes/admin/table-printer.php:865
1140
  msgctxt "inline link editor"
1141
  msgid "Suggestions"
1142
  msgstr ""
1143
 
1144
+ #: includes/admin/table-printer.php:885
1145
  msgid "Use this URL"
1146
  msgstr ""
1147
 
1148
+ #: includes/any-post.php:426 modules/containers/blogroll.php:46
1149
+ #: modules/containers/comment.php:159 modules/containers/custom_field.php:230
1150
  msgid "Edit"
1151
  msgstr ""
1152
 
1153
+ #: includes/any-post.php:434 modules/containers/custom_field.php:236
1154
  msgid "Move this item to the Trash"
1155
  msgstr ""
1156
 
1157
+ #: includes/any-post.php:436 modules/containers/custom_field.php:238
1158
  msgid "Trash"
1159
  msgstr ""
1160
 
1161
+ #: includes/any-post.php:441 modules/containers/custom_field.php:243
1162
  msgid "Delete this item permanently"
1163
  msgstr ""
1164
 
1165
+ #: includes/any-post.php:443 modules/containers/blogroll.php:47
1166
+ #: modules/containers/custom_field.php:245
1167
  msgid "Delete"
1168
  msgstr ""
1169
 
1170
+ #: includes/any-post.php:456
1171
  msgid "Preview &#8220;%s&#8221;"
1172
  msgstr ""
1173
 
1174
+ #: includes/any-post.php:457
1175
  msgid "Preview"
1176
  msgstr ""
1177
 
1178
+ #: includes/any-post.php:464
1179
  msgid "View &#8220;%s&#8221;"
1180
  msgstr ""
1181
 
1182
+ #: includes/any-post.php:465 modules/containers/comment.php:172
1183
+ #: modules/containers/custom_field.php:250
1184
  msgid "View"
1185
  msgstr ""
1186
 
1187
+ #: includes/any-post.php:484 modules/containers/custom_field.php:230
1188
  msgid "Edit this item"
1189
  msgstr ""
1190
 
1191
+ #: includes/any-post.php:548 modules/containers/blogroll.php:83
1192
  #: modules/containers/comment.php:43
1193
  msgid "Nothing to update"
1194
  msgstr ""
1195
 
1196
+ #: includes/any-post.php:558
1197
  msgid "Updating post %d failed"
1198
  msgstr ""
1199
 
1200
+ #: includes/any-post.php:595 modules/containers/custom_field.php:317
1201
  msgid "Failed to delete post \"%s\" (%d)"
1202
  msgstr ""
1203
 
1204
+ #: includes/any-post.php:614 modules/containers/custom_field.php:336
1205
  msgid ""
1206
  "Can't move post \"%s\" (%d) to the trash because the trash feature is "
1207
  "disabled"
1208
  msgstr ""
1209
 
1210
+ #: includes/any-post.php:634 modules/containers/custom_field.php:355
1211
  msgid "Failed to move post \"%s\" (%d) to the trash"
1212
  msgstr ""
1213
 
1214
+ #: includes/any-post.php:742
1215
  msgid "%d post deleted."
1216
  msgid_plural "%d posts deleted."
1217
  msgstr[0] ""
1218
  msgstr[1] ""
1219
 
1220
+ #: includes/any-post.php:744
1221
  msgid "%d page deleted."
1222
  msgid_plural "%d pages deleted."
1223
  msgstr[0] ""
1224
  msgstr[1] ""
1225
 
1226
+ #: includes/any-post.php:746
1227
  msgid "%d \"%s\" deleted."
1228
  msgid_plural "%d \"%s\" deleted."
1229
  msgstr[0] ""
1230
  msgstr[1] ""
1231
 
1232
+ #: includes/any-post.php:765
1233
  msgid "%d post moved to the Trash."
1234
  msgid_plural "%d posts moved to the Trash."
1235
  msgstr[0] ""
1236
  msgstr[1] ""
1237
 
1238
+ #: includes/any-post.php:767
1239
  msgid "%d page moved to the Trash."
1240
  msgid_plural "%d pages moved to the Trash."
1241
  msgstr[0] ""
1242
  msgstr[1] ""
1243
 
1244
+ #: includes/any-post.php:769
1245
  msgid "%d \"%s\" moved to the Trash."
1246
  msgid_plural "%d \"%s\" moved to the Trash."
1247
  msgstr[0] ""
1360
  msgid "Parser '%s' not found."
1361
  msgstr ""
1362
 
1363
+ #: includes/link-query.php:25
1364
+ msgid "All"
1365
  msgstr ""
1366
 
1367
+ #: includes/link-query.php:26
1368
+ msgid "Detected Links"
1369
  msgstr ""
1370
 
1371
+ #: includes/link-query.php:27
1372
+ msgid "No links found (yet)"
1373
  msgstr ""
1374
 
1375
+ #: includes/link-query.php:36
1376
+ msgid "Broken"
1377
  msgstr ""
1378
 
1379
  #: includes/link-query.php:38
1380
+ msgid "No broken links found"
1381
  msgstr ""
1382
 
1383
  #: includes/link-query.php:46
1384
+ msgctxt "filter name"
1385
+ msgid "Warnings"
1386
  msgstr ""
1387
 
1388
  #: includes/link-query.php:47
1389
+ msgid "Warnings"
1390
  msgstr ""
1391
 
1392
  #: includes/link-query.php:48
1393
+ msgid "No warnings found"
1394
  msgstr ""
1395
 
1396
  #: includes/link-query.php:56
1397
+ msgid "Redirects"
1398
  msgstr ""
1399
 
1400
  #: includes/link-query.php:57
1401
+ msgid "Redirected Links"
1402
  msgstr ""
1403
 
1404
  #: includes/link-query.php:58
1405
+ msgid "No redirects found"
1406
  msgstr ""
1407
 
1408
  #: includes/link-query.php:66
1409
+ msgid "Dismissed"
1410
+ msgstr ""
1411
+
1412
+ #: includes/link-query.php:67
1413
+ msgid "Dismissed Links"
1414
+ msgstr ""
1415
+
1416
+ #: includes/link-query.php:68
1417
+ msgid "No dismissed links found"
1418
+ msgstr ""
1419
+
1420
+ #: includes/link-query.php:82
1421
  msgid "Search Results"
1422
  msgstr ""
1423
 
1424
+ #: includes/link-query.php:83 includes/link-query.php:130
1425
  msgid "No links found for your query"
1426
  msgstr ""
1427
 
1428
+ #: includes/links.php:224
1429
  msgid "The plugin script was terminated while trying to check the link."
1430
  msgstr ""
1431
 
1432
+ #: includes/links.php:271
1433
  msgid "The plugin doesn't know how to check this type of link."
1434
  msgstr ""
1435
 
1436
+ #: includes/links.php:502
1437
+ msgid "Link is broken."
1438
  msgstr ""
1439
 
1440
+ #: includes/links.php:504
1441
+ msgid "Link is valid."
1442
  msgstr ""
1443
 
1444
+ #: includes/links.php:728 includes/links.php:830 includes/links.php:857
1445
  msgid "Link is not valid"
1446
  msgstr ""
1447
 
1448
+ #: includes/links.php:745
1449
  msgid ""
1450
  "This link can not be edited because it is not used anywhere on this site."
1451
  msgstr ""
1452
 
1453
+ #: includes/links.php:771
1454
  msgid "Failed to create a DB entry for the new URL."
1455
  msgstr ""
1456
 
1457
+ #: includes/links.php:837
1458
  msgid "This link is not a redirect"
1459
  msgstr ""
1460
 
1461
+ #: includes/links.php:884 includes/links.php:921
1462
  msgid "Couldn't delete the link's database record"
1463
  msgstr ""
1464
 
1465
+ #: includes/links.php:995
1466
  msgctxt "link status"
1467
  msgid "Unknown"
1468
  msgstr ""
1469
 
1470
+ #: includes/links.php:1008 modules/checkers/http.php:308
1471
+ #: modules/extras/mediafire.php:115
1472
  msgid "Unknown Error"
1473
  msgstr ""
1474
 
1475
+ #: includes/links.php:1032
1476
  msgid "Not checked"
1477
  msgstr ""
1478
 
1479
+ #: includes/links.php:1035
1480
  msgid "False positive"
1481
  msgstr ""
1482
 
1483
+ #: includes/links.php:1038 modules/extras/rapidshare.php:145
1484
  #: modules/extras/rapidshare.php:151 modules/extras/rapidshare.php:178
1485
  msgctxt "link status"
1486
  msgid "OK"
1554
  msgstr[0] ""
1555
  msgstr[1] ""
1556
 
1557
+ #: modules/checkers/http.php:285
1558
  msgid "Server Not Found"
1559
  msgstr ""
1560
 
1561
+ #: modules/checkers/http.php:301
1562
  msgid "Connection Failed"
1563
  msgstr ""
1564
 
1565
+ #: modules/checkers/http.php:344 modules/checkers/http.php:414
1566
  msgid "HTTP code : %d"
1567
  msgstr ""
1568
 
1569
+ #: modules/checkers/http.php:346 modules/checkers/http.php:416
1570
  msgid "(No response)"
1571
  msgstr ""
1572
 
1573
+ #: modules/checkers/http.php:352
1574
  msgid "Most likely the connection timed out or the domain doesn't exist."
1575
  msgstr ""
1576
 
1577
+ #: modules/checkers/http.php:423
1578
  msgid "Request timed out."
1579
  msgstr ""
1580
 
1581
+ #: modules/checkers/http.php:441
1582
  msgid "Using Snoopy"
1583
  msgstr ""
1584
 
1622
  msgid "Can't move comment %d to the trash"
1623
  msgstr ""
1624
 
1625
+ #: modules/containers/comment.php:159 modules/containers/comment.php:201
1626
  msgid "Edit comment"
1627
  msgstr ""
1628
 
1629
+ #: modules/containers/comment.php:166
1630
  msgid "Delete Permanently"
1631
  msgstr ""
1632
 
1633
+ #: modules/containers/comment.php:168
1634
  msgid "Move this comment to the trash"
1635
  msgstr ""
1636
 
1637
+ #: modules/containers/comment.php:168
1638
  msgctxt "verb"
1639
  msgid "Trash"
1640
  msgstr ""
1641
 
1642
+ #: modules/containers/comment.php:172
1643
  msgid "View comment"
1644
  msgstr ""
1645
 
1646
+ #: modules/containers/comment.php:189
1647
  msgid "Comment"
1648
  msgstr ""
1649
 
1650
+ #: modules/containers/comment.php:364
1651
  msgid "%d comment has been deleted."
1652
  msgid_plural "%d comments have been deleted."
1653
  msgstr[0] ""
1654
  msgstr[1] ""
1655
 
1656
+ #: modules/containers/comment.php:383
1657
  msgid "%d comment moved to the Trash."
1658
  msgid_plural "%d comments moved to the Trash."
1659
  msgstr[0] ""
1667
  msgid "Failed to delete the meta field '%s' on %s [%d]"
1668
  msgstr ""
1669
 
1670
+ #: modules/containers/custom_field.php:216
1671
  msgid "Edit this post"
1672
  msgstr ""
1673
 
1674
+ #: modules/containers/custom_field.php:250
1675
  msgid "View \"%s\""
1676
  msgstr ""
1677
 
1701
  msgid "Embedded GoogleVideo video"
1702
  msgstr ""
1703
 
1704
+ #: modules/extras/mediafire.php:97 modules/extras/mediafire.php:103
1705
  #: modules/extras/rapidshare.php:139
1706
  msgid "Not Found"
1707
  msgstr ""
1708
 
1709
+ #: modules/extras/mediafire.php:109
1710
+ msgid "Permission Denied"
1711
+ msgstr ""
1712
+
1713
  #: modules/extras/rapidshare.php:51
1714
  msgid "Using RapidShare API"
1715
  msgstr ""
modules/checkers/http.php CHANGED
@@ -166,6 +166,8 @@ class blcCurlHttp extends blcHttpCheckerBase {
166
 
167
  $result = array(
168
  'broken' => false,
 
 
169
  );
170
  $log = '';
171
 
@@ -281,6 +283,7 @@ class blcCurlHttp extends blcHttpCheckerBase {
281
  case 6: //CURLE_COULDNT_RESOLVE_HOST
282
  $result['status_code'] = BLC_LINK_STATUS_WARNING;
283
  $result['status_text'] = __('Server Not Found', 'broken-link-checker');
 
284
  break;
285
 
286
  case 28: //CURLE_OPERATION_TIMEDOUT
@@ -296,6 +299,7 @@ class blcCurlHttp extends blcHttpCheckerBase {
296
  } else {
297
  $result['status_code'] = BLC_LINK_STATUS_WARNING;
298
  $result['status_text'] = __('Connection Failed', 'broken-link-checker');
 
299
  }
300
  break;
301
 
166
 
167
  $result = array(
168
  'broken' => false,
169
+ 'timeout' => false,
170
+ 'warning' => false,
171
  );
172
  $log = '';
173
 
283
  case 6: //CURLE_COULDNT_RESOLVE_HOST
284
  $result['status_code'] = BLC_LINK_STATUS_WARNING;
285
  $result['status_text'] = __('Server Not Found', 'broken-link-checker');
286
+ $result['error_code'] = 'couldnt_resolve_host';
287
  break;
288
 
289
  case 28: //CURLE_OPERATION_TIMEDOUT
299
  } else {
300
  $result['status_code'] = BLC_LINK_STATUS_WARNING;
301
  $result['status_text'] = __('Connection Failed', 'broken-link-checker');
302
+ $result['error_code'] = 'connection_failed';
303
  }
304
  break;
305
 
modules/containers/blogroll.php CHANGED
@@ -37,7 +37,7 @@ class blcBookmark extends blcContainer{
37
 
38
  function ui_get_action_links($container_field){
39
  //Inline action links for bookmarks
40
- $bookmark = &$this->get_wrapped_object();
41
 
42
  $delete_url = admin_url( wp_nonce_url("link.php?action=delete&link_id={$this->container_id}", 'delete-bookmark_' . $this->container_id) );
43
 
37
 
38
  function ui_get_action_links($container_field){
39
  //Inline action links for bookmarks
40
+ $bookmark = $this->get_wrapped_object();
41
 
42
  $delete_url = admin_url( wp_nonce_url("link.php?action=delete&link_id={$this->container_id}", 'delete-bookmark_' . $this->container_id) );
43
 
modules/containers/comment.php CHANGED
@@ -24,7 +24,7 @@ class blcComment extends blcContainer{
24
  */
25
  function get_wrapped_object($ensure_consistency = false){
26
  if( $ensure_consistency || is_null($this->wrapped_object) ){
27
- $this->wrapped_object = &get_comment($this->container_id);
28
  }
29
  return $this->wrapped_object;
30
  }
@@ -106,7 +106,7 @@ class blcComment extends blcContainer{
106
  */
107
  function current_user_can_delete(){
108
  //TODO: Fix for custom post types? WP itself doesn't care, at least in 3.0.
109
- $comment = &$this->get_wrapped_object();
110
  return current_user_can('edit_post', $comment->comment_post_ID);
111
  }
112
 
@@ -146,9 +146,15 @@ class blcComment extends blcContainer{
146
 
147
  $comment = $this->get_wrapped_object();
148
  $post = get_post($comment->comment_post_ID); /* @var StdClass $post */
149
-
 
 
 
 
 
 
150
  //Display Edit & Delete/Trash links only if the user has the right caps.
151
- $user_can = current_user_can('edit_post', $comment->comment_post_ID);
152
  if ( $user_can ){
153
  $actions['edit'] = "<a href='". $this->get_edit_url() ."' title='" . esc_attr__('Edit comment') . "'>". __('Edit') . '</a>';
154
 
@@ -226,12 +232,12 @@ class blcCommentManager extends blcContainerManager {
226
  function init(){
227
  parent::init();
228
 
229
- add_action('post_comment', array(&$this, 'hook_post_comment'), 10, 2);
230
- add_action('edit_comment', array(&$this, 'hook_edit_comment'));
231
- add_action('transition_comment_status', array(&$this, 'hook_comment_status'), 10, 3);
232
 
233
- add_action('trashed_post_comments', array(&$this, 'hook_trashed_post_comments'), 10, 2);
234
- add_action('untrash_post_comments', array(&$this, 'hook_untrash_post_comments'));
235
  }
236
 
237
  function hook_post_comment($comment_id, $comment_status){
@@ -261,7 +267,7 @@ class blcCommentManager extends blcContainerManager {
261
  }
262
  }
263
 
264
- function hook_trashed_post_comments($post_id, $statuses){
265
  foreach($statuses as $comment_id => $comment_status){
266
  if ( $comment_status == '1' ){
267
  $container = blcContainerHelper::get_container(array($this->container_type, $comment_id));
24
  */
25
  function get_wrapped_object($ensure_consistency = false){
26
  if( $ensure_consistency || is_null($this->wrapped_object) ){
27
+ $this->wrapped_object = get_comment($this->container_id);
28
  }
29
  return $this->wrapped_object;
30
  }
106
  */
107
  function current_user_can_delete(){
108
  //TODO: Fix for custom post types? WP itself doesn't care, at least in 3.0.
109
+ $comment = $this->get_wrapped_object();
110
  return current_user_can('edit_post', $comment->comment_post_ID);
111
  }
112
 
146
 
147
  $comment = $this->get_wrapped_object();
148
  $post = get_post($comment->comment_post_ID); /* @var StdClass $post */
149
+
150
+ //If the post type no longer exists, we can't really do anything with this comment.
151
+ //WordPress will just throw errors if we try.
152
+ if ( !post_type_exists(get_post_type($post)) ) {
153
+ return $actions;
154
+ }
155
+
156
  //Display Edit & Delete/Trash links only if the user has the right caps.
157
+ $user_can = current_user_can('edit_post', $comment->comment_post_ID);
158
  if ( $user_can ){
159
  $actions['edit'] = "<a href='". $this->get_edit_url() ."' title='" . esc_attr__('Edit comment') . "'>". __('Edit') . '</a>';
160
 
232
  function init(){
233
  parent::init();
234
 
235
+ add_action('post_comment', array($this, 'hook_post_comment'), 10, 2);
236
+ add_action('edit_comment', array($this, 'hook_edit_comment'));
237
+ add_action('transition_comment_status', array($this, 'hook_comment_status'), 10, 3);
238
 
239
+ add_action('trashed_post_comments', array($this, 'hook_trashed_post_comments'), 10, 2);
240
+ add_action('untrash_post_comments', array($this, 'hook_untrash_post_comments'));
241
  }
242
 
243
  function hook_post_comment($comment_id, $comment_status){
267
  }
268
  }
269
 
270
+ function hook_trashed_post_comments(/** @noinspection PhpUnusedParameterInspection */$post_id, $statuses){
271
  foreach($statuses as $comment_id => $comment_status){
272
  if ( $comment_status == '1' ){
273
  $container = blcContainerHelper::get_container(array($this->container_type, $comment_id));
modules/containers/custom_field.php CHANGED
@@ -191,6 +191,25 @@ class blcPostMeta extends blcContainer {
191
  }
192
 
193
  function ui_get_source($container_field = '', $context = 'display'){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  $post_html = sprintf(
195
  '<a class="row-title" href="%s" title="%s">%s</a>',
196
  esc_url($this->get_edit_url()),
@@ -203,6 +222,10 @@ class blcPostMeta extends blcContainer {
203
 
204
  function ui_get_action_links($container_field){
205
  $actions = array();
 
 
 
 
206
  if ( current_user_can('edit_post', $this->container_id) ) {
207
  $actions['edit'] = '<span class="edit"><a href="' . $this->get_edit_url() . '" title="' . esc_attr(__('Edit this item')) . '">' . __('Edit') . '</a>';
208
 
191
  }
192
 
193
  function ui_get_source($container_field = '', $context = 'display'){
194
+ if ( !post_type_exists(get_post_type($this->container_id)) ) {
195
+ //Error: Invalid post type. The user probably removed a CPT without removing the actual posts.
196
+ $post_html = '';
197
+
198
+ $post = get_post($this->container_id);
199
+ if ( $post ) {
200
+ $post_html .= sprintf(
201
+ '<span class="row-title">%s</span><br>',
202
+ get_the_title($post)
203
+ );
204
+ }
205
+ $post_html .= sprintf(
206
+ 'Invalid post type "%s"',
207
+ htmlentities($this->container_type)
208
+ );
209
+
210
+ return $post_html;
211
+ }
212
+
213
  $post_html = sprintf(
214
  '<a class="row-title" href="%s" title="%s">%s</a>',
215
  esc_url($this->get_edit_url()),
222
 
223
  function ui_get_action_links($container_field){
224
  $actions = array();
225
+ if ( !post_type_exists(get_post_type($this->container_id)) ) {
226
+ return $actions;
227
+ }
228
+
229
  if ( current_user_can('edit_post', $this->container_id) ) {
230
  $actions['edit'] = '<span class="edit"><a href="' . $this->get_edit_url() . '" title="' . esc_attr(__('Edit this item')) . '">' . __('Edit') . '</a>';
231
 
modules/extras/mediafire.php CHANGED
@@ -12,7 +12,7 @@ ModuleLazyInit: true
12
  ModuleClassName: blcMediaFireChecker
13
  ModulePriority: 100
14
 
15
- ModuleCheckerUrlPattern: @^http://(?:www\.)?mediafire\.com/(?:download\.php)?\?([0-9a-zA-Z]{11})(?:$|[^0-9a-zA-Z])@
16
  */
17
 
18
  /**
@@ -81,29 +81,44 @@ class blcMediaFireChecker extends blcChecker {
81
  $result['broken'] = false;
82
  $result['log'] .= "File OK";
83
  } elseif ( isset($rez['headers']['location']) ) {
84
- //Redirect = some kind of error. Redirects to an error page with an explanatory message.
85
- //The redirect URL is structured like this : '/error.php?errno=320'. The 'errno' argument
86
- //contains an (undocumented) error code. The only known value is 'errno=320', which
87
- //indicates that the file is invalid or has been deleted.
88
  $result['broken'] = true;
89
- if ( strpos($rez['headers']['location'], 'errno=320') !== false ){
 
 
 
 
 
 
 
90
  $result['status_code'] = BLC_LINK_STATUS_ERROR;
91
  $result['status_text'] = __('Not Found', 'broken-link-checker');
92
  $result['http_code'] = 0;
93
  $result['log'] .= "The file is invalid or has been removed.";
94
- } else if ( strpos($rez['headers']['location'], 'errno=378') !== false ){
 
95
  $result['status_code'] = BLC_LINK_STATUS_ERROR;
96
  $result['status_text'] = __('Not Found', 'broken-link-checker');
97
  $result['http_code'] = 0;
98
  $result['log'] .= "The file has been removed due to a violation of MediaFire ToS.";
 
 
 
 
 
 
 
99
  } else {
100
  $result['status_code'] = BLC_LINK_STATUS_INFO;
101
  $result['status_text'] = __('Unknown Error', 'broken-link-checker');
102
  $result['log'] .= "Unknown error.\n\n";
103
  foreach($rez['headers'] as $name => $value){
104
- $result['log'] .= printf("%s: %s\n", $name, $value);
105
  }
106
  }
 
107
  } else {
108
  $result['log'] .= "Unknown error.\n\n" . implode("\n",$rez['headers']);
109
  }
@@ -138,28 +153,14 @@ class blcMediaFireChecker extends blcChecker {
138
  * @return array|WP_Error
139
  */
140
  function head($url){
141
- //Only consider transports that allow redirection to be disabled.
142
- $args = array();
143
- if ( class_exists('WP_Http_ExtHttp') && (true === WP_Http_ExtHttp::test($args)) ) {
144
- $transport = new WP_Http_ExtHttp();
145
- } else if ( class_exists('WP_Http_Curl') && (true === WP_Http_Curl::test($args)) ) {
146
- $transport = new WP_Http_Curl();
147
- } else if ( class_exists('WP_Http_Curl') && (true === WP_Http_Fsockopen::test($args)) ) {
148
- $transport = new WP_Http_Fsockopen();
149
- } else {
150
- return new WP_Error(
151
- 'no_suitable_transport',
152
- "No suitable HTTP transport found. Please upgrade to a more recent version of PHP or install the CURL extension."
153
- );
154
- }
155
-
156
  $conf = blc_get_configuration();
157
  $args = array(
158
  'timeout' => $conf->options['timeout'],
159
  'redirection' => 0,
160
- 'method' => 'HEAD',
161
  );
162
- return $transport->request($url, $args);
 
163
  }
164
 
165
  }
12
  ModuleClassName: blcMediaFireChecker
13
  ModulePriority: 100
14
 
15
+ ModuleCheckerUrlPattern: @^http://(?:www\.)?mediafire\.com/(?:(?:download\.php)?\?|download/)([0-9a-zA-Z]{11,20})(?:$|[^0-9a-zA-Z])@
16
  */
17
 
18
  /**
81
  $result['broken'] = false;
82
  $result['log'] .= "File OK";
83
  } elseif ( isset($rez['headers']['location']) ) {
84
+ //Redirect = either an error or a redirect to the full file URL.
85
+ //For errors, the redirect URL is structured like this : '/error.php?errno=320'.
86
+ //The 'errno' argument contains an (undocumented) error code.
 
87
  $result['broken'] = true;
88
+
89
+ if ( strpos($rez['headers']['location'], '/download/') !== false ) {
90
+ $result['broken'] = false;
91
+ $result['http_code'] = 200;
92
+ $result['log'] .= "File OK";
93
+ $result['log'] .= "\nFull URL: " . $rez['headers']['location'];
94
+
95
+ } elseif ( strpos($rez['headers']['location'], 'errno=320') !== false ){
96
  $result['status_code'] = BLC_LINK_STATUS_ERROR;
97
  $result['status_text'] = __('Not Found', 'broken-link-checker');
98
  $result['http_code'] = 0;
99
  $result['log'] .= "The file is invalid or has been removed.";
100
+
101
+ } elseif ( strpos($rez['headers']['location'], 'errno=378') !== false ) {
102
  $result['status_code'] = BLC_LINK_STATUS_ERROR;
103
  $result['status_text'] = __('Not Found', 'broken-link-checker');
104
  $result['http_code'] = 0;
105
  $result['log'] .= "The file has been removed due to a violation of MediaFire ToS.";
106
+
107
+ } elseif ( strpos($rez['headers']['location'], 'errno=388') !== false ) {
108
+ $result['status_code'] = BLC_LINK_STATUS_WARNING;
109
+ $result['status_text'] = __('Permission Denied', 'broken-link-checker');
110
+ $result['http_code'] = 0;
111
+ $result['log'] .= "Permission denied. Most likely the plugin sent too many requests too quickly. Try again later.";
112
+
113
  } else {
114
  $result['status_code'] = BLC_LINK_STATUS_INFO;
115
  $result['status_text'] = __('Unknown Error', 'broken-link-checker');
116
  $result['log'] .= "Unknown error.\n\n";
117
  foreach($rez['headers'] as $name => $value){
118
+ $result['log'] .= sprintf("%s: %s\n", $name, $value);
119
  }
120
  }
121
+
122
  } else {
123
  $result['log'] .= "Unknown error.\n\n" . implode("\n",$rez['headers']);
124
  }
153
  * @return array|WP_Error
154
  */
155
  function head($url){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  $conf = blc_get_configuration();
157
  $args = array(
158
  'timeout' => $conf->options['timeout'],
159
  'redirection' => 0,
160
+ '_redirection' => 0, //Internal flag that turns off redirect handling. See WP_Http::handle_redirects()
161
  );
162
+
163
+ return wp_remote_head($url, $args);
164
  }
165
 
166
  }
modules/parsers/image.php CHANGED
@@ -60,7 +60,7 @@ class blcHTMLImage extends blcParser {
60
  };
61
 
62
  if ( !isset($parts['scheme']) ){
63
- //No sheme - likely a relative URL. Turn it into an absolute one.
64
  $url = $this->relative2absolute($url, $base_url);
65
  }
66
 
60
  };
61
 
62
  if ( !isset($parts['scheme']) ){
63
+ //No scheme - likely a relative URL. Turn it into an absolute one.
64
  $url = $this->relative2absolute($url, $base_url);
65
  }
66
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: whiteshadow
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6P9S6CE3SRSW
4
  Tags: links, broken, maintenance, blogroll, custom fields, admin, comments, posts
5
  Requires at least: 3.2
6
- Tested up to: 4.0
7
- Stable tag: 1.9.5
8
 
9
  This plugin will check your posts, comments and other content for broken links and missing images, and notify you if any are found.
10
 
@@ -98,6 +98,24 @@ To upgrade your installation
98
 
99
  == Changelog ==
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  = 1.9.5 =
102
  * Fixed missing YouTube videos not being detected when the video URL starts with https instead of http.
103
  * Enabled the YouTube video checker by default on new installations.
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6P9S6CE3SRSW
4
  Tags: links, broken, maintenance, blogroll, custom fields, admin, comments, posts
5
  Requires at least: 3.2
6
+ Tested up to: 4.0.1
7
+ Stable tag: 1.10
8
 
9
  This plugin will check your posts, comments and other content for broken links and missing images, and notify you if any are found.
10
 
98
 
99
  == Changelog ==
100
 
101
+ = 1.10 =
102
+ * Added a way to hide individual link actions like "Dismiss" and "Unlink".
103
+ * Added a "Fix redirect" link action. It replaces a redirect with a direct link. It is hidden by default and can be enabled through the settings page.
104
+ * Added a "Recheck" link action. Unlike the bulk action by the same name, it checks a link immediately and displays the results without having to refresh the page.
105
+ * Added a "Dismiss" bulk action.
106
+ * Added a note below the "link tweaks" settings explaining that they only apply to the contents of posts (and pages, and CPTs), not comments or custom fields.
107
+ * Made the "Redirect URL" column sortable.
108
+ * Added a "Details" link to the "Status" column.
109
+ * Added a "Warnings" section to Tools -> Broken Links. It shows problems that might be temporary or false positives. Warnings can be disabled through the settings page.
110
+ * Fixed a conflict with plugins that use PHP sessions.
111
+ * Fixed the "post statuses" option. Now disabling a post status (e.g. "Draft") should take effect immediately.
112
+ * Fixed the Mediafire link checker.
113
+ * Fixed the text in the "Status" column being slightly offset vertically when compared to other columns.
114
+ * Fixed search box position in WP 4.1-alpha.
115
+ * Added a few workarounds for situations where a custom post type is removed without first removing the posts.
116
+ * Removed the screen icon. WordPress has deprecated it.
117
+ * Other minor fixes.
118
+
119
  = 1.9.5 =
120
  * Fixed missing YouTube videos not being detected when the video URL starts with https instead of http.
121
  * Enabled the YouTube video checker by default on new installations.