Broken Link Checker - Version 1.11.17

Version Description

  • Fix security vulnerability
Download this release

Release Info

Developer vanyukov
Plugin Icon 128x128 Broken Link Checker
Version 1.11.17
Comparing to
See all releases

Code changes from version 1.11.15 to 1.11.17

broken-link-checker.php CHANGED
@@ -10,7 +10,7 @@
10
  * Plugin Name: Broken Link Checker
11
  * Plugin URI: https://wordpress.org/plugins/broken-link-checker/
12
  * Description: Checks your blog for broken links and missing images and notifies you on the dashboard if any are found.
13
- * Version: 1.11.15
14
  * Author: WPMU DEV
15
  * Author URI: https://wpmudev.com/
16
  * Text Domain: broken-link-checker
10
  * Plugin Name: Broken Link Checker
11
  * Plugin URI: https://wordpress.org/plugins/broken-link-checker/
12
  * Description: Checks your blog for broken links and missing images and notifies you on the dashboard if any are found.
13
+ * Version: 1.11.17
14
  * Author: WPMU DEV
15
  * Author URI: https://wpmudev.com/
16
  * Text Domain: broken-link-checker
core/core.php CHANGED
@@ -430,7 +430,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
430
  * Handler for the 'plugin_action_links' hook. Adds a "Settings" link to this plugin's entry
431
  * on the plugin list.
432
  *
433
- * @param array $links
434
  * @param string $file
435
  * @return array
436
  */
@@ -447,16 +447,6 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
447
  public function options_page() {
448
  $moduleManager = blcModuleManager::getInstance();
449
 
450
- // Prior to 1.5.2 (released 2012-05-27), there was a bug that would cause the donation flag to be
451
- // set incorrectly. So we'll unset the flag in that case.
452
- $reset_donation_flag = ( $this->conf->get( 'first_installation_timestamp', 0 ) < strtotime( '2012-05-27 00:00' ) ) && ! $this->conf->get( 'donation_flag_fixed', false );
453
-
454
- if ( $reset_donation_flag ) {
455
- $this->conf->set( 'user_has_donated', false );
456
- $this->conf->set( 'donation_flag_fixed', true );
457
- $this->conf->save_options();
458
- }
459
-
460
  if ( isset( $_POST['recheck'] ) && ! empty( $_POST['recheck'] ) ) {
461
  $this->initiate_recheck();
462
 
@@ -503,25 +493,25 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
503
  } else {
504
  $enabled_post_statuses = array();
505
  }
506
- //At least one status must be enabled; defaults to "Published".
507
  if ( empty( $enabled_post_statuses ) ) {
508
  $enabled_post_statuses = array( 'publish' );
509
  }
510
 
511
- //Did the user add/remove any post statuses?
512
  $same_statuses = array_intersect( $enabled_post_statuses, $this->conf->options['enabled_post_statuses'] );
513
  $post_statuses_changed = ( count( $same_statuses ) != count( $enabled_post_statuses ) )
514
  || ( count( $same_statuses ) !== count( $this->conf->options['enabled_post_statuses'] ) );
515
 
516
  $this->conf->options['enabled_post_statuses'] = $enabled_post_statuses;
517
 
518
- //The execution time limit must be above zero
519
  $new_execution_time = intval( $_POST['max_execution_time'] );
520
  if ( $new_execution_time > 0 ) {
521
  $this->conf->options['max_execution_time'] = $new_execution_time;
522
  }
523
 
524
- //The check threshold also must be > 0
525
  $new_check_threshold = intval( $_POST['check_threshold'] );
526
 
527
  if ( $new_check_threshold > 0 ) {
@@ -542,14 +532,14 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
542
 
543
  $this->conf->options['exclusion_list'] = array_filter(
544
  preg_split(
545
- '/[\s\r\n]+/', //split on newlines and whitespace
546
  $cleanPost['exclusion_list'],
547
  -1,
548
- PREG_SPLIT_NO_EMPTY //skip empty values
549
  )
550
  );
551
 
552
- //Parse the custom field list
553
  $new_custom_fields = array_filter(
554
  preg_split(
555
  '/[\r\n]+/',
@@ -559,36 +549,36 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
559
  )
560
  );
561
 
562
- //Calculate the difference between the old custom field list and the new one (used later)
563
  $diff1 = array_diff( $new_custom_fields, $this->conf->options['custom_fields'] );
564
  $diff2 = array_diff( $this->conf->options['custom_fields'], $new_custom_fields );
565
  $this->conf->options['custom_fields'] = $new_custom_fields;
566
 
567
- //Parse the custom field list
568
  $new_acf_fields = array_filter( preg_split( '/[\r\n]+/', $cleanPost['blc_acf_fields'], -1, PREG_SPLIT_NO_EMPTY ) );
569
 
570
- //Calculate the difference between the old custom field list and the new one (used later)
571
  $acf_fields_diff1 = array_diff( $new_acf_fields, $this->conf->options['acf_fields'] );
572
  $acf_fields_diff2 = array_diff( $this->conf->options['acf_fields'], $new_acf_fields );
573
  $this->conf->options['acf_fields'] = $new_acf_fields;
574
 
575
- //Turning off warnings turns existing warnings into "broken" links.
576
  $this->conf->options['blc_post_modified'] = ! empty( $_POST['blc_post_modified'] );
577
 
578
- //Turning off warnings turns existing warnings into "broken" links.
579
  $warnings_enabled = ! empty( $_POST['warnings_enabled'] );
580
  if ( $this->conf->get( 'warnings_enabled' ) && ! $warnings_enabled ) {
581
  $this->promote_warnings_to_broken();
582
  }
583
  $this->conf->options['warnings_enabled'] = $warnings_enabled;
584
 
585
- //HTTP timeout
586
  $new_timeout = intval( $_POST['timeout'] );
587
  if ( $new_timeout > 0 ) {
588
  $this->conf->options['timeout'] = $new_timeout;
589
  }
590
 
591
- //Server load limit
592
  if ( isset( $_POST['server_load_limit'] ) ) {
593
  $this->conf->options['server_load_limit'] = floatval( $_POST['server_load_limit'] );
594
  if ( $this->conf->options['server_load_limit'] < 0 ) {
@@ -597,21 +587,21 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
597
  $this->conf->options['enable_load_limit'] = $this->conf->options['server_load_limit'] > 0;
598
  }
599
 
600
- //Target resource usage (1% to 100%)
601
  if ( isset( $_POST['target_resource_usage'] ) ) {
602
  $usage = floatval( $_POST['target_resource_usage'] );
603
  $usage = max( min( $usage / 100, 1 ), 0.01 );
604
  $this->conf->options['target_resource_usage'] = $usage;
605
  }
606
 
607
- //When to run the checker
608
  $this->conf->options['run_in_dashboard'] = ! empty( $_POST['run_in_dashboard'] );
609
  $this->conf->options['run_via_cron'] = ! empty( $_POST['run_via_cron'] );
610
 
611
- //youtube api
612
  $this->conf->options['youtube_api_key'] = ! empty( $_POST['youtube_api_key'] ) ? $_POST['youtube_api_key'] : '';
613
 
614
- //Email notifications on/off
615
  $email_notifications = ! empty( $_POST['send_email_notifications'] );
616
  $send_authors_email_notifications = ! empty( $_POST['send_authors_email_notifications'] );
617
 
@@ -640,53 +630,60 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
640
  $this->conf->options['dashboard_widget_capability'] = $widget_cap;
641
  }
642
 
643
- //Link actions. The user can hide some of them to reduce UI clutter.
644
  $show_link_actions = array();
645
  foreach ( array_keys( $available_link_actions ) as $action ) {
646
  $show_link_actions[ $action ] = isset( $_POST['show_link_actions'] ) && ! empty( $_POST['show_link_actions'][ $action ] );
647
  }
648
  $this->conf->set( 'show_link_actions', $show_link_actions );
649
 
650
- //Logging. The plugin can log various events and results for debugging purposes.
651
  $this->conf->options['logging_enabled'] = ! empty( $_POST['logging_enabled'] );
652
  $this->conf->options['custom_log_file_enabled'] = ! empty( $_POST['custom_log_file_enabled'] );
653
 
654
  if ( $this->conf->options['logging_enabled'] ) {
655
  if ( $this->conf->options['custom_log_file_enabled'] ) {
656
 
657
- $log_file = strval( $cleanPost['log_file'] );
658
- if ( ! file_exists( $log_file ) ) {
 
 
 
 
 
 
659
  if ( ! file_exists( dirname( $log_file ) ) ) {
660
  mkdir( dirname( $log_file ), 0750, true );
661
  }
662
  // Attempt to create the log file if not already there.
663
  if ( ! is_file( $log_file ) ) {
664
- //Add a .htaccess to hide the log file from site visitors.
665
  file_put_contents( dirname( $log_file ) . '/.htaccess', 'Deny from all' );
666
  file_put_contents( $log_file, '' );
667
  }
668
  }
669
- //revert to default
 
670
  if ( ! is_writable( $log_file ) || ! is_file( $log_file ) ) {
671
  $this->conf->options['custom_log_file_enabled'] = '';
672
- $log_directory = self::get_default_log_directory();
673
- $log_file = $log_directory . '/' . self::get_default_log_basename();
674
  }
675
  } else {
676
- //Default log file is /wp-content/uploads/broken-link-checker/blc-log.txt
677
  $log_directory = self::get_default_log_directory();
678
  $log_file = $log_directory . '/' . self::get_default_log_basename();
679
 
680
- //Attempt to create the log directory.
681
  if ( ! is_dir( $log_directory ) ) {
682
  if ( mkdir( $log_directory, 0750 ) ) {
683
- //Add a .htaccess to hide the log file from site visitors.
684
  file_put_contents( $log_directory . '/.htaccess', 'Deny from all' );
685
  }
686
  }
687
  }
688
 
689
- $this->conf->options['log_file'] = $log_file;
690
  $this->conf->options['clear_log_on'] = strval( $cleanPost['clear_log_on'] );
691
 
692
  // Attempt to create the log file if not already there.
@@ -694,13 +691,13 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
694
  file_put_contents( $log_file, '' );
695
  }
696
 
697
- //The log file must be writable.
698
  if ( ! is_writable( $log_file ) || ! is_file( $log_file ) ) {
699
  $this->conf->options['logging_enabled'] = false;
700
  }
701
  }
702
 
703
- //Make settings that affect our Cron events take effect immediately
704
  $this->setup_cron_events();
705
  $this->conf->save_options();
706
 
@@ -730,7 +727,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
730
  }
731
  }
732
 
733
- //Resynchronize posts when the user enables or disables post statuses.
734
  if ( $post_statuses_changed ) {
735
  $overlord = blcPostTypeOverlord::getInstance();
736
  $overlord->enabled_post_statuses = $this->conf->get( 'enabled_post_statuses', array() );
@@ -741,7 +738,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
741
  blc_cleanup_links();
742
  }
743
 
744
- //Redirect back to the settings page
745
  $base_url = remove_query_arg( array( '_wpnonce', 'noheader', 'updated', 'error', 'action', 'message' ) );
746
  wp_redirect(
747
  add_query_arg(
@@ -753,27 +750,20 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
753
  );
754
  }
755
 
756
- //Show a confirmation message when settings are saved.
757
  if ( ! empty( $_GET['settings-updated'] ) ) {
758
  echo '<div id="message" class="updated fade"><p><strong>',__( 'Settings saved.', 'broken-link-checker' ), '</strong></p></div>';
759
 
760
  }
761
 
762
- //Show a thank-you message when a donation is made.
763
- if ( ! empty( $_GET['donated'] ) ) {
764
- echo '<div id="message" class="updated fade"><p><strong>',__( 'Thank you for your donation!', 'broken-link-checker' ), '</strong></p></div>';
765
- $this->conf->set( 'user_has_donated', true );
766
- $this->conf->save_options();
767
- }
768
-
769
- //Show one when recheck is started, too.
770
  if ( ! empty( $_GET['recheck-initiated'] ) ) {
771
  echo '<div id="message" class="updated fade"><p><strong>',
772
  __( 'Complete site recheck started.', 'broken-link-checker' ), // -- Yoda
773
  '</strong></p></div>';
774
  }
775
 
776
- //Cull invalid and missing modules
777
  $moduleManager->validate_active_modules();
778
 
779
  $debug = $this->get_debug_info();
@@ -781,10 +771,10 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
781
  add_filter( 'blc-module-settings-custom_field', array( $this, 'make_custom_field_input' ), 10, 2 );
782
  add_filter( 'blc-module-settings-acf_field', array( $this, 'make_acf_field_input' ), 10, 2 );
783
 
784
- //Translate and markup-ify module headers for display
785
  $modules = $moduleManager->get_modules_by_category( '', true, true );
786
 
787
- //Output the custom broken link/removed link styles for example links
788
  printf(
789
  '<style type="text/css">%s %s</style>',
790
  $this->conf->options['broken_link_css'],
@@ -813,14 +803,6 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
813
  <div class="wrap" id="blc-settings-wrap">
814
  <h2><?php _e( 'Broken Link Checker Options', 'broken-link-checker' ); ?></h2>
815
 
816
-
817
- <div id="blc-sidebar">
818
- <div class="metabox-holder">
819
- <?php include BLC_DIRECTORY . '/includes/admin/sidebar.php'; ?>
820
- </div>
821
- </div>
822
-
823
-
824
  <div id="blc-admin-content">
825
 
826
  <form name="link_checker_options" id="link_checker_options" method="post" action="
@@ -868,7 +850,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
868
  <table id="blc-debug-info">
869
  <?php
870
 
871
- //Output the debug info in a table
872
  foreach ( $debug as $key => $value ) {
873
  printf(
874
  '<tr valign="top" class="blc-debug-item-%s"><th scope="row">%s</th><td>%s<div class="blc-debug-message">%s</div></td></tr>',
@@ -963,7 +945,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
963
  if ( defined( 'TEST_WPEL_PLUGIN_FILE' ) ) {
964
  printf(
965
  __( 'Configure <a target="_blank" href="%s">External Links</a> settings.', 'broken-link-checker' ),
966
- admin_url('admin.php?page=wpel-settings-page' )
967
  );
968
  } else {
969
  printf(
@@ -1129,7 +1111,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1129
  type="text"
1130
  name="youtube_api_key"
1131
  id="youtube_api_key"
1132
- value="<?php echo $this->conf->options[ 'youtube_api_key' ]; ?>"
1133
  class="regular-text ltr">
1134
  </label><br>
1135
  <span class="description">
@@ -1547,7 +1529,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1547
  </div>
1548
 
1549
  <?php
1550
- //The various JS for this page is stored in a separate file for the purposes readability.
1551
  include dirname( $this->loader ) . '/includes/admin/options-page-js.php';
1552
  }
1553
 
@@ -1592,7 +1574,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1592
  __( 'Configure', 'broken-link-checker' )
1593
  );
1594
 
1595
- //The plugin remembers the last open/closed state of module configuration boxes
1596
  $box_id = 'module-extra-settings-' . $module_id;
1597
  $show = blcUtility::get_cookie(
1598
  $box_id,
@@ -1620,8 +1602,8 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1620
  * form submissions work correctly.
1621
  *
1622
  * @param string $module_id Module ID.
1623
- * @param array $module_data Associative array of module data.
1624
- * @param bool $active If true, the newly created checkbox will start out checked.
1625
  * @return void
1626
  */
1627
  function print_module_checkbox( $module_id, $module_data, $active = false ) {
@@ -1666,7 +1648,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1666
  * Callback for the 'blc-module-settings-custom_field' filter.
1667
  *
1668
  * @param string $html Current extra HTML
1669
- * @param array $current_settings The current plugin configuration.
1670
  * @return string New extra HTML.
1671
  */
1672
  function make_custom_field_input( $html, $current_settings ) {
@@ -1704,8 +1686,8 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1704
 
1705
  wp_enqueue_style( 'dashboard' );
1706
 
1707
- wp_enqueue_style('plugin-install');
1708
- wp_enqueue_script('plugin-install');
1709
 
1710
  add_thickbox();
1711
  }
@@ -1721,36 +1703,36 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1721
 
1722
  $blc_link_query = blcLinkQuery::getInstance();
1723
 
1724
- //Cull invalid and missing modules so that we don't get dummy links/instances showing up.
1725
  $moduleManager = blcModuleManager::getInstance();
1726
  $moduleManager->validate_active_modules();
1727
 
1728
  if ( defined( 'BLC_DEBUG' ) && constant( 'BLC_DEBUG' ) ) {
1729
- //Make module headers translatable. They need to be formatted corrrectly and
1730
- //placed in a .php file to be visible to the script(s) that generate .pot files.
1731
  $code = $moduleManager->_build_header_translation_code();
1732
  file_put_contents( dirname( $this->loader ) . '/includes/extra-strings.php', $code );
1733
  }
1734
 
1735
  $action = ! empty( $_POST['action'] ) ? $_POST['action'] : '';
1736
  if ( intval( $action ) == -1 ) {
1737
- //Try the second bulk actions box
1738
  $action = ! empty( $_POST['action2'] ) ? $_POST['action2'] : '';
1739
  }
1740
 
1741
- //Get the list of link IDs selected via checkboxes
1742
  $selected_links = array();
1743
  if ( isset( $_POST['selected_links'] ) && is_array( $_POST['selected_links'] ) ) {
1744
- //Convert all link IDs to integers (non-numeric entries are converted to zero)
1745
  $selected_links = array_map( 'intval', $_POST['selected_links'] );
1746
- //Remove all zeroes
1747
  $selected_links = array_filter( $selected_links );
1748
  }
1749
 
1750
  $message = '';
1751
  $msg_class = 'updated';
1752
 
1753
- //Run the selected bulk action, if any
1754
  $force_delete = false;
1755
  switch ( $action ) {
1756
  case 'create-custom-filter':
@@ -1764,7 +1746,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1764
  // @noinspection PhpMissingBreakStatementInspection Deliberate fall-through.
1765
  case 'bulk-delete-sources':
1766
  $force_delete = true;
1767
- //intentional fall through
1768
  case 'bulk-trash-sources':
1769
  list($message, $msg_class) = $this->do_bulk_delete_sources( $selected_links, $force_delete );
1770
  break;
@@ -1800,13 +1782,13 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1800
 
1801
  $start_time = microtime_float();
1802
 
1803
- //Load custom filters, if any
1804
  $blc_link_query->load_custom_filters();
1805
 
1806
- //Calculate the number of links matching each filter
1807
  $blc_link_query->count_filter_results();
1808
 
1809
- //Run the selected filter (defaults to displaying broken links)
1810
  $selected_filter_id = isset( $_GET['filter_id'] ) ? $_GET['filter_id'] : 'broken';
1811
  $current_filter = $blc_link_query->exec_filter(
1812
  $selected_filter_id,
@@ -1817,10 +1799,10 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1817
  isset( $_GET['order'] ) ? $_GET['order'] : ''
1818
  );
1819
 
1820
- //exec_filter() returns an array with filter data, including the actual filter ID that was used.
1821
  $filter_id = $current_filter['filter_id'];
1822
 
1823
- //Error?
1824
  if ( empty( $current_filter['links'] ) && ! empty( $wpdb->last_error ) ) {
1825
  printf( __( 'Database error : %s', 'broken-link-checker' ), $wpdb->last_error );
1826
  }
@@ -1838,18 +1820,18 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1838
  $blc_link_query->print_filter_heading( $current_filter );
1839
  $blc_link_query->print_filter_menu( $filter_id );
1840
 
1841
- //Display the "Search" form and associated buttons.
1842
- //The form requires the $filter_id and $current_filter variables to be set.
1843
  include dirname( $this->loader ) . '/includes/admin/search-form.php';
1844
 
1845
- //If the user has decided to switch the table to a different mode (compact/full),
1846
- //save the new setting.
1847
  if ( isset( $_GET['compact'] ) ) {
1848
  $this->conf->options['table_compact'] = (bool) $_GET['compact'];
1849
  $this->conf->save_options();
1850
  }
1851
 
1852
- //Display the links, if any
1853
  if ( $current_filter['links'] && ( count( $current_filter['links'] ) > 0 ) ) {
1854
 
1855
  include dirname( $this->loader ) . '/includes/admin/table-printer.php';
@@ -1864,7 +1846,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1864
  };
1865
  printf( '<!-- Total elapsed : %.4f seconds -->', microtime_float() - $start_time );
1866
 
1867
- //Load assorted JS event handlers and other shinies
1868
  include dirname( $this->loader ) . '/includes/admin/links-page-js.php';
1869
 
1870
  ?>
@@ -1883,31 +1865,31 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1883
  function do_create_custom_filter() {
1884
  global $wpdb;
1885
 
1886
- //Create a custom filter!
1887
  check_admin_referer( 'create-custom-filter' );
1888
  $msg_class = 'updated';
1889
 
1890
- //Filter name must be set
1891
  if ( empty( $_POST['name'] ) ) {
1892
  $message = __( 'You must enter a filter name!', 'broken-link-checker' );
1893
  $msg_class = 'error';
1894
- //Filter parameters (a search query) must also be set
1895
  } elseif ( empty( $_POST['params'] ) ) {
1896
  $message = __( 'Invalid search query.', 'broken-link-checker' );
1897
  $msg_class = 'error';
1898
  } else {
1899
- //Save the new filter
1900
  $name = strip_tags( strval( $_POST['name'] ) );
1901
  $blc_link_query = blcLinkQuery::getInstance();
1902
  $filter_id = $blc_link_query->create_custom_filter( $name, $_POST['params'] );
1903
 
1904
  if ( $filter_id ) {
1905
- //Saved
1906
  $message = sprintf( __( 'Filter "%s" created', 'broken-link-checker' ), $name );
1907
- //A little hack to make the filter active immediately
1908
  $_GET['filter_id'] = $filter_id;
1909
  } else {
1910
- //Error
1911
  $message = sprintf( __( 'Database error : %s', 'broken-link-checker' ), $wpdb->last_error );
1912
  $msg_class = 'error';
1913
  }
@@ -1924,22 +1906,22 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1924
  * @return array Message and a CSS class to apply to the message.
1925
  */
1926
  function do_delete_custom_filter() {
1927
- //Delete an existing custom filter!
1928
  check_admin_referer( 'delete-custom-filter' );
1929
  $msg_class = 'updated';
1930
 
1931
- //Filter ID must be set
1932
  if ( empty( $_POST['filter_id'] ) ) {
1933
  $message = __( 'Filter ID not specified.', 'broken-link-checker' );
1934
  $msg_class = 'error';
1935
  } else {
1936
- //Try to delete the filter
1937
  $blc_link_query = blcLinkQuery::getInstance();
1938
  if ( $blc_link_query->delete_custom_filter( $_POST['filter_id'] ) ) {
1939
- //Success
1940
  $message = __( 'Filter deleted', 'broken-link-checker' );
1941
  } else {
1942
- //Either the ID is wrong or there was some other error
1943
  $message = __( 'Database error : %s', 'broken-link-checker' );
1944
  $msg_class = 'error';
1945
  }
@@ -1955,7 +1937,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1955
  * @return array The message to display and its CSS class.
1956
  */
1957
  function do_bulk_deredirect( $selected_links ) {
1958
- //For all selected links, replace the URL with the final URL that it redirects to.
1959
 
1960
  $message = '';
1961
  $msg_class = 'updated';
@@ -1963,7 +1945,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1963
  check_admin_referer( 'bulk-action' );
1964
 
1965
  if ( count( $selected_links ) > 0 ) {
1966
- //Fetch all the selected links
1967
  $links = blc_get_links(
1968
  array(
1969
  'link_ids' => $selected_links,
@@ -1975,7 +1957,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
1975
  $processed_links = 0;
1976
  $failed_links = 0;
1977
 
1978
- //Deredirect all selected links
1979
  foreach ( $links as $link ) {
1980
  $rez = $link->deredirect();
1981
  if ( ! is_wp_error( $rez ) && empty( $rez['errors'] ) ) {
@@ -2029,7 +2011,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2029
 
2030
  $post = $_POST;
2031
  if ( function_exists( 'wp_magic_quotes' ) ) {
2032
- $post = stripslashes_deep( $post ); //Ceterum censeo, WP shouldn't mangle superglobals.
2033
  }
2034
 
2035
  $search = isset( $post['search'] ) ? esc_attr( $post['search'] ) : '';
@@ -2037,23 +2019,23 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2037
  $use_regex = ! empty( $post['regex'] );
2038
  $case_sensitive = ! empty( $post['case_sensitive'] );
2039
 
2040
- $delimiter = '`'; //Pick a char that's uncommon in URLs so that escaping won't usually be a problem
2041
  if ( $use_regex ) {
2042
  $search = $delimiter . $this->escape_regex_delimiter( $search, $delimiter ) . $delimiter;
2043
  if ( ! $case_sensitive ) {
2044
  $search .= 'i';
2045
  }
2046
  } elseif ( ! $case_sensitive ) {
2047
- //str_ireplace() would be more appropriate for case-insensitive, non-regexp replacement,
2048
- //but that's only available in PHP5.
2049
  $search = $delimiter . preg_quote( $search, $delimiter ) . $delimiter . 'i';
2050
  $use_regex = true;
2051
  }
2052
 
2053
  if ( count( $selected_links ) > 0 ) {
2054
- set_time_limit( 300 ); //In case the user decides to edit hundreds of links at once
2055
 
2056
- //Fetch all the selected links
2057
  $links = blc_get_links(
2058
  array(
2059
  'link_ids' => $selected_links,
@@ -2066,7 +2048,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2066
  $failed_links = 0;
2067
  $skipped_links = 0;
2068
 
2069
- //Edit the links
2070
  foreach ( $links as $link ) {
2071
  if ( $use_regex ) {
2072
  $new_url = preg_replace( $search, $replace, $link->url );
@@ -2157,7 +2139,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2157
  * @return array Message and a CSS classname.
2158
  */
2159
  function do_bulk_unlink( $selected_links ) {
2160
- //Unlink all selected links.
2161
  $message = '';
2162
  $msg_class = 'updated';
2163
 
@@ -2165,7 +2147,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2165
 
2166
  if ( count( $selected_links ) > 0 ) {
2167
 
2168
- //Fetch all the selected links
2169
  $links = blc_get_links(
2170
  array(
2171
  'link_ids' => $selected_links,
@@ -2177,7 +2159,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2177
  $processed_links = 0;
2178
  $failed_links = 0;
2179
 
2180
- //Unlink (delete) each one
2181
  foreach ( $links as $link ) {
2182
  $rez = $link->unlink();
2183
  if ( ( false == $rez ) || is_wp_error( $rez ) ) {
@@ -2187,8 +2169,8 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2187
  }
2188
  }
2189
 
2190
- //This message is slightly misleading - it doesn't account for the fact that
2191
- //a link can be present in more than one post.
2192
  $message = sprintf(
2193
  _n(
2194
  '%d link removed',
@@ -2224,26 +2206,26 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2224
  * can't be moved to the trash, it will skip that item by default.
2225
  *
2226
  * @param array $selected_links An array of link IDs
2227
- * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
2228
  * @return array Confirmation message and its CSS class.
2229
  */
2230
  function do_bulk_delete_sources( $selected_links, $force_delete = false ) {
2231
  $message = '';
2232
  $msg_class = 'updated';
2233
 
2234
- //Delete posts, blogroll entries and any other link containers that contain any of the selected links.
2235
  //
2236
- //Note that once all containers containing a particular link have been deleted,
2237
- //there is no need to explicitly delete the link record itself. The hooks attached to
2238
- //the actions that execute when something is deleted (e.g. "post_deleted") will
2239
- //take care of that.
2240
 
2241
  check_admin_referer( 'bulk-action' );
2242
 
2243
  if ( count( $selected_links ) > 0 ) {
2244
  $messages = array();
2245
 
2246
- //Fetch all the selected links
2247
  $links = blc_get_links(
2248
  array(
2249
  'link_ids' => $selected_links,
@@ -2251,8 +2233,8 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2251
  )
2252
  );
2253
 
2254
- //Make a list of all containers associated with these links, with each container
2255
- //listed only once.
2256
  $containers = array();
2257
  foreach ( $links as $link ) { /* @var blcLink $link */
2258
  $instances = $link->get_instances();
@@ -2262,10 +2244,10 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2262
  }
2263
  }
2264
 
2265
- //Instantiate the containers
2266
  $containers = blcContainerHelper::get_containers( $containers );
2267
 
2268
- //Delete/trash their associated entities
2269
  $deleted = array();
2270
  $skipped = array();
2271
  foreach ( $containers as $container ) { /* @var blcContainer $container */
@@ -2284,12 +2266,13 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2284
  }
2285
  }
2286
 
2287
- if ( is_wp_error( $rez ) ) { /* @var WP_Error $rez */
2288
- //Record error messages for later display
 
2289
  $messages[] = $rez->get_error_message();
2290
  $msg_class = 'error';
2291
  } else {
2292
- //Keep track of how many of each type were deleted.
2293
  $container_type = $container->container_type;
2294
  if ( isset( $deleted[ $container_type ] ) ) {
2295
  $deleted[ $container_type ]++;
@@ -2299,7 +2282,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2299
  }
2300
  }
2301
 
2302
- //Generate delete confirmation messages
2303
  foreach ( $deleted as $container_type => $number ) {
2304
  if ( $force_delete ) {
2305
  $messages[] = blcContainerHelper::ui_bulk_delete_message( $container_type, $number );
@@ -2308,7 +2291,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2308
  }
2309
  }
2310
 
2311
- //If some items couldn't be trashed, let the user know
2312
  if ( count( $skipped ) > 0 ) {
2313
  $message = sprintf(
2314
  _n(
@@ -2351,15 +2334,15 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2351
  /** @var wpdb $wpdb */
2352
  global $wpdb;
2353
 
2354
- $message = '';
2355
- $msg_class = 'updated';
2356
  $total_links = count( $selected_links );
2357
  check_admin_referer( 'bulk-action' );
2358
 
2359
  if ( $total_links > 0 ) {
2360
  $placeholders = array_fill( 0, $total_links, '%d' );
2361
- $format = implode( ', ', $placeholders );
2362
- $query = "UPDATE {$wpdb->prefix}blc_links
2363
  SET last_check_attempt = '0000-00-00 00:00:00'
2364
  WHERE link_id IN ( $format )";
2365
 
@@ -2402,20 +2385,20 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2402
  $transactionManager = TransactionManager::getInstance();
2403
  $transactionManager->start();
2404
  foreach ( $selected_links as $link_id ) {
2405
- //Load the link
2406
  $link = new blcLink( intval( $link_id ) );
2407
 
2408
- //Skip links that don't actually exist
2409
  if ( ! $link->valid() ) {
2410
  continue;
2411
  }
2412
 
2413
- //Skip links that weren't actually detected as broken
2414
  if ( ! $link->broken && ! $link->warning ) {
2415
  continue;
2416
  }
2417
 
2418
- //Make it appear "not broken"
2419
  $link->broken = false;
2420
  $link->warning = false;
2421
  $link->false_positive = true;
@@ -2423,7 +2406,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2423
  $link->log = __( 'This link was manually marked as working by the user.', 'broken-link-checker' );
2424
 
2425
  $link->isOptionLinkChanged = true;
2426
- //Save the changes
2427
  if ( $link->save() ) {
2428
  $processed_links++;
2429
  } else {
@@ -2469,15 +2452,15 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2469
  $transactionManager = TransactionManager::getInstance();
2470
  $transactionManager->start();
2471
  foreach ( $selected_links as $link_id ) {
2472
- //Load the link
2473
  $link = new blcLink( intval( $link_id ) );
2474
 
2475
- //Skip links that don't actually exist
2476
  if ( ! $link->valid() ) {
2477
  continue;
2478
  }
2479
 
2480
- //We can only dismiss broken links and redirects.
2481
  if ( ! ( $link->broken || $link->warning || ( $link->redirect_count > 0 ) ) ) {
2482
  continue;
2483
  }
@@ -2486,7 +2469,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2486
 
2487
  $link->isOptionLinkChanged = true;
2488
 
2489
- //Save the changes
2490
  if ( $link->save() ) {
2491
  $processed_links++;
2492
  } else {
@@ -2539,7 +2522,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2539
  return;
2540
  }
2541
 
2542
- //Let the user hide the notice.
2543
  $conf = blc_get_configuration();
2544
  $notice_name = 'show_warnings_section_hint';
2545
 
@@ -2584,7 +2567,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2584
  * @return string
2585
  */
2586
  function screen_options_html() {
2587
- //Update the links-per-page setting when "Apply" is clicked
2588
  if ( isset( $_POST['per_page'] ) && is_numeric( $_POST['per_page'] ) ) {
2589
  check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' );
2590
  $per_page = intval( $_POST['per_page'] );
@@ -2594,7 +2577,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2594
  }
2595
  }
2596
 
2597
- //Let the user show/hide individual table columns
2598
  $html = '<h5>' . __( 'Table columns', 'broken-link-checker' ) . '</h5>';
2599
 
2600
  include dirname( $this->loader ) . '/includes/admin/table-printer.php';
@@ -2646,7 +2629,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2646
  );
2647
  $html .= '</label>';
2648
 
2649
- //Display a checkbox for turning colourful link status messages on/off
2650
  $html .= sprintf(
2651
  '<br/><label><input type="checkbox" id="table_color_code_status" name="table_color_code_status"%s> %s</label>',
2652
  $this->conf->options['table_color_code_status'] ? ' checked="checked"' : '',
@@ -2707,23 +2690,23 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2707
  function work() {
2708
  global $blclog;
2709
 
2710
- //Close the session to prevent lock-ups.
2711
- //PHP sessions are blocking. session_start() will wait until all other scripts that are using the same session
2712
- //are finished. As a result, a long-running script that unintentionally keeps the session open can cause
2713
- //the entire site to "lock up" for the current user/browser. WordPress itself doesn't use sessions, but some
2714
- //plugins do, so we should explicitly close the session (if any) before starting the worker.
2715
  if ( session_id() != '' ) {
2716
  session_write_close();
2717
  }
2718
 
2719
  if ( ! $this->acquire_lock() ) {
2720
- //FB::warn("Another instance of BLC is already working. Stop.");
2721
  $blclog->info( 'Another instance of BLC is already working. Stop.' );
2722
  return;
2723
  }
2724
 
2725
  if ( $this->server_too_busy() ) {
2726
- //FB::warn("Server is too busy. Stop.");
2727
  $blclog->warn( 'Server load is too high, stopping.' );
2728
  return;
2729
  }
@@ -2735,7 +2718,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2735
 
2736
  /*****************************************
2737
  Preparation
2738
- ******************************************/
2739
  // Check for safe mode
2740
  if ( blcUtility::is_safe_mode() ) {
2741
  // Do it the safe mode way - obey the existing max_execution_time setting
@@ -2745,48 +2728,48 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2745
  }
2746
  } else {
2747
  // Do it the regular way
2748
- @set_time_limit( $max_execution_time * 2 ); //x2 should be plenty, running any longer would mean a glitch.
2749
  }
2750
 
2751
- //Don't stop the script when the connection is closed
2752
  ignore_user_abort( true );
2753
 
2754
- //Close the connection as per http://www.php.net/manual/en/features.connection-handling.php#71172
2755
- //This reduces resource usage.
2756
- //(Disable when debugging or you won't get the FirePHP output)
2757
  if (
2758
  ! headers_sent()
2759
  && ( defined( 'DOING_AJAX' ) && constant( 'DOING_AJAX' ) )
2760
  && ( ! defined( 'BLC_DEBUG' ) || ! constant( 'BLC_DEBUG' ) )
2761
  ) {
2762
- @ob_end_clean(); //Discard the existing buffer, if any
2763
  header( 'Connection: close' );
2764
  ob_start();
2765
- echo ( 'Connection closed' ); //This could be anything
2766
  $size = ob_get_length();
2767
  header( "Content-Length: $size" );
2768
  ob_end_flush(); // Strange behaviour, will not work
2769
  flush(); // Unless both are called !
2770
  }
2771
 
2772
- //Load modules for this context
2773
  $moduleManager = blcModuleManager::getInstance();
2774
  $moduleManager->load_modules( 'work' );
2775
 
2776
  $target_usage_fraction = $this->conf->get( 'target_resource_usage', 0.25 );
2777
- //Target usage must be between 1% and 100%.
2778
  $target_usage_fraction = max( min( $target_usage_fraction, 1 ), 0.01 );
2779
 
2780
  /*****************************************
2781
  Parse posts and bookmarks
2782
- ******************************************/
2783
 
2784
  $orphans_possible = false;
2785
  $still_need_resynch = $this->conf->options['need_resynch'];
2786
 
2787
  if ( $still_need_resynch ) {
2788
 
2789
- //FB::log("Looking for containers that need parsing...");
2790
  $max_containers_per_query = 50;
2791
 
2792
  $start = microtime( true );
@@ -2794,13 +2777,13 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2794
  $get_containers_time = microtime( true ) - $start;
2795
 
2796
  while ( ! empty( $containers ) ) {
2797
- //FB::log($containers, 'Found containers');
2798
  $this->sleep_to_maintain_ratio( $get_containers_time, $target_usage_fraction );
2799
 
2800
  foreach ( $containers as $container ) {
2801
  $synch_start_time = microtime( true );
2802
 
2803
- //FB::log($container, "Parsing container");
2804
  $container->synch();
2805
 
2806
  $synch_elapsed_time = microtime( true ) - $synch_start_time;
@@ -2813,24 +2796,24 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2813
  )
2814
  );
2815
 
2816
- //Check if we still have some execution time left
2817
  if ( $this->execution_time() > $max_execution_time ) {
2818
- //FB::log('The allotted execution time has run out');
2819
  blc_cleanup_links();
2820
  $this->release_lock();
2821
  return;
2822
  }
2823
 
2824
- //Check if the server isn't overloaded
2825
  if ( $this->server_too_busy() ) {
2826
- //FB::log('Server overloaded, bailing out.');
2827
  blc_cleanup_links();
2828
  $this->release_lock();
2829
  return;
2830
  }
2831
 
2832
- //Intentionally slow down parsing to reduce the load on the server. Basically,
2833
- //we work $target_usage_fraction of the time and sleep the rest of the time.
2834
  $this->sleep_to_maintain_ratio( $synch_elapsed_time, $target_usage_fraction );
2835
  }
2836
  $orphans_possible = true;
@@ -2840,16 +2823,16 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2840
  $get_containers_time = microtime( true ) - $start;
2841
  }
2842
 
2843
- //FB::log('No unparsed items found.');
2844
  $still_need_resynch = false;
2845
 
2846
  } else {
2847
- //FB::log('Resynch not required.');
2848
  }
2849
 
2850
  /******************************************
2851
  Resynch done?
2852
- *******************************************/
2853
  if ( $this->conf->options['need_resynch'] && ! $still_need_resynch ) {
2854
  $this->conf->options['need_resynch'] = $still_need_resynch;
2855
  $this->conf->save_options();
@@ -2857,7 +2840,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2857
 
2858
  /******************************************
2859
  Remove orphaned links
2860
- *******************************************/
2861
 
2862
  if ( $orphans_possible ) {
2863
  $start = microtime( true );
@@ -2869,16 +2852,16 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2869
  $this->sleep_to_maintain_ratio( $get_links_time, $target_usage_fraction );
2870
  }
2871
 
2872
- //Check if we still have some execution time left
2873
  if ( $this->execution_time() > $max_execution_time ) {
2874
- //FB::log('The allotted execution time has run out');
2875
  $blclog->info( 'The allotted execution time has run out.' );
2876
  $this->release_lock();
2877
  return;
2878
  }
2879
 
2880
  if ( $this->server_too_busy() ) {
2881
- //FB::log('Server overloaded, bailing out.');
2882
  $blclog->info( 'Server load too high, stopping.' );
2883
  $this->release_lock();
2884
  return;
@@ -2886,7 +2869,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2886
 
2887
  /*****************************************
2888
  Check links
2889
- ******************************************/
2890
  $max_links_per_query = 30;
2891
 
2892
  $start = microtime( true );
@@ -2896,42 +2879,42 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2896
  while ( $links ) {
2897
  $this->sleep_to_maintain_ratio( $get_links_time, $target_usage_fraction );
2898
 
2899
- //Some unchecked links found
2900
- //FB::log("Checking ".count($links)." link(s)");
2901
  $blclog->info( 'Checking ' . count( $links ) . ' link(s)' );
2902
 
2903
- //Randomizing the array reduces the chances that we'll get several links to the same domain in a row.
2904
  shuffle( $links );
2905
 
2906
  $transactionManager = TransactionManager::getInstance();
2907
  $transactionManager->start();
2908
 
2909
  foreach ( $links as $link ) {
2910
- //Does this link need to be checked? Excluded links aren't checked, but their URLs are still
2911
- //tested periodically to see if they're still on the exclusion list.
2912
  if ( ! $this->is_excluded( $link->url ) ) {
2913
- //Check the link.
2914
- //FB::log($link->url, "Checking link {$link->link_id}");
2915
  $link->check( true );
2916
  } else {
2917
- //FB::info("The URL {$link->url} is excluded, skipping link {$link->link_id}.");
2918
  $link->last_check_attempt = time();
2919
  $link->save();
2920
  }
2921
 
2922
- //Check if we still have some execution time left
2923
  if ( $this->execution_time() > $max_execution_time ) {
2924
  $transactionManager->commit();
2925
- //FB::log('The allotted execution time has run out');
2926
  $blclog->info( 'The allotted execution time has run out.' );
2927
  $this->release_lock();
2928
  return;
2929
  }
2930
 
2931
- //Check if the server isn't overloaded
2932
  if ( $this->server_too_busy() ) {
2933
  $transactionManager->commit();
2934
- //FB::log('Server overloaded, bailing out.');
2935
  $blclog->info( 'Server load too high, stopping.' );
2936
  $this->release_lock();
2937
  return;
@@ -2943,11 +2926,11 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2943
  $links = $this->get_links_to_check( $max_links_per_query );
2944
  $get_links_time = microtime( true ) - $start;
2945
  }
2946
- //FB::log('No links need to be checked right now.');
2947
 
2948
  $this->release_lock();
2949
  $blclog->info( 'work(): All done.' );
2950
- //FB::log('All done.');
2951
  }
2952
 
2953
  /**
@@ -2965,7 +2948,8 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2965
  }
2966
  $sleep_time = $elapsed_time * ( ( 1 / $ratio ) - 1 );
2967
  if ( $sleep_time > 0.0001 ) {
2968
- /*global $blclog;
 
2969
  $blclog->debug(sprintf(
2970
  'Task took %.2f ms, sleeping for %.2f ms',
2971
  $elapsed_time * 1000,
@@ -2991,7 +2975,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
2991
  * Retrieve links that need to be checked or re-checked.
2992
  *
2993
  * @param integer $max_results The maximum number of links to return. Defaults to 0 = no limit.
2994
- * @param bool $count_only If true, only the number of found links will be returned, not the links themselves.
2995
  * @return int|blcLink[]
2996
  */
2997
  function get_links_to_check( $max_results = 0, $count_only = false ) {
@@ -3000,23 +2984,23 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3000
  $check_threshold = date( 'Y-m-d H:i:s', strtotime( '-' . $this->conf->options['check_threshold'] . ' hours' ) );//phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
3001
  $recheck_threshold = date( 'Y-m-d H:i:s', time() - $this->conf->options['recheck_threshold'] );//phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
3002
 
3003
- //FB::log('Looking for links to check (threshold : '.$check_threshold.', recheck_threshold : '.$recheck_threshold.')...');
3004
 
3005
- //Select some links that haven't been checked for a long time or
3006
- //that are broken and need to be re-checked again. Links that are
3007
- //marked as "being checked" and have been that way for several minutes
3008
- //can also be considered broken/buggy, so those will be selected
3009
- //as well.
3010
 
3011
- //Only check links that have at least one valid instance (i.e. an instance exists and
3012
- //it corresponds to one of the currently loaded container/parser types).
3013
  $manager = blcModuleManager::getInstance();
3014
  $loaded_containers = $manager->get_escaped_ids( 'container' );
3015
  $loaded_parsers = $manager->get_escaped_ids( 'parser' );
3016
 
3017
- //Note : This is a slow query, but AFAIK there is no way to speed it up.
3018
- //I could put an index on last_check_attempt, but that value is almost
3019
- //certainly unique for each row so it wouldn't be much better than a full table scan.
3020
  if ( $count_only ) {
3021
  $q = "SELECT COUNT(DISTINCT links.link_id)\n";
3022
  } else {
@@ -3055,21 +3039,21 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3055
  $recheck_threshold
3056
  );
3057
 
3058
- //FB::log($link_q, "Find links to check");
3059
- //$blclog->debug("Find links to check: \n" . $link_q);
3060
 
3061
- //If we just need the number of links, retrieve it and return
3062
  if ( $count_only ) {
3063
  return $wpdb->get_var( $link_q );//phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
3064
  }
3065
 
3066
- //Fetch the link data
3067
  $link_data = $wpdb->get_results( $link_q, ARRAY_A ); //phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
3068
  if ( empty( $link_data ) ) {
3069
  return array();
3070
  }
3071
 
3072
- //Instantiate blcLink objects for all fetched links
3073
  $links = array();
3074
  foreach ( $link_data as $data ) {
3075
  $links[] = new blcLink( $data );
@@ -3171,7 +3155,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3171
  * @return void
3172
  */
3173
  function ajax_dashboard_status() {
3174
- //Just display the full status.
3175
  $this->ajax_full_status();
3176
  }
3177
 
@@ -3195,14 +3179,14 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3195
  /**
3196
  * Returns an array with various status information about the plugin. Array key reference:
3197
  * check_threshold - date/time; links checked before this threshold should be checked again.
3198
- * recheck_threshold - date/time; broken links checked before this threshold should be re-checked.
3199
- * known_links - the number of detected unique URLs (a misleading name, yes).
3200
- * known_instances - the number of detected link instances, i.e. actual link elements in posts and other places.
3201
- * broken_links - the number of detected broken links.
3202
- * unchecked_links - the number of URLs that need to be checked ASAP; based on check_threshold and recheck_threshold.
3203
- *
3204
- * @return array
3205
- */
3206
  function get_status() {
3207
  $blc_link_query = blcLinkQuery::getInstance();
3208
 
@@ -3229,7 +3213,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3229
  function ajax_work() {
3230
  check_ajax_referer( 'blc_work' );
3231
 
3232
- //Run the worker function
3233
  $this->work();
3234
  die();
3235
  }
@@ -3245,14 +3229,14 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3245
  }
3246
 
3247
  if ( isset( $_POST['link_id'] ) ) {
3248
- //Load the link
3249
  $link = new blcLink( intval( $_POST['link_id'] ) );
3250
 
3251
  if ( ! $link->valid() ) {
3252
  printf( __( "Oops, I can't find the link %d", 'broken-link-checker' ), intval( $_POST['link_id'] ) );
3253
  die();
3254
  }
3255
- //Make it appear "not broken"
3256
  $link->broken = false;
3257
  $link->warning = false;
3258
  $link->false_positive = true;
@@ -3264,7 +3248,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3264
  $transactionManager = TransactionManager::getInstance();
3265
  $transactionManager->start();
3266
 
3267
- //Save the changes
3268
  if ( $link->save() ) {
3269
  $transactionManager->commit();
3270
  die( 'OK' );
@@ -3292,7 +3276,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3292
  }
3293
 
3294
  if ( isset( $_POST['link_id'] ) ) {
3295
- //Load the link
3296
  $link = new blcLink( intval( $_POST['link_id'] ) );
3297
 
3298
  if ( ! $link->valid() ) {
@@ -3302,7 +3286,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3302
 
3303
  $link->dismissed = $dismiss;
3304
 
3305
- //Save the changes
3306
  $link->isOptionLinkChanged = true;
3307
  $transactionManager = TransactionManager::getInstance();
3308
  $transactionManager->start();
@@ -3343,7 +3327,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3343
  );
3344
  }
3345
 
3346
- //Load the link
3347
  $link = new blcLink( intval( $_POST['link_id'] ) );
3348
 
3349
  if ( ! $link->valid() ) {
@@ -3356,7 +3340,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3356
  );
3357
  }
3358
 
3359
- //Validate the new URL.
3360
  $new_url = stripslashes( $_POST['new_url'] );
3361
  $parsed = @parse_url( $new_url );
3362
  if ( ! $parsed ) {
@@ -3370,7 +3354,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3370
  }
3371
 
3372
  if ( ! current_user_can( 'unfiltered_html' ) ) {
3373
- //Disallow potentially dangerous URLs like "javascript:...".
3374
  $protocols = wp_allowed_protocols();
3375
  $good_protocol_url = wp_kses_bad_protocol( $new_url, $protocols );
3376
  if ( $new_url != $good_protocol_url ) {
@@ -3389,7 +3373,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3389
  $new_text = null;
3390
  }
3391
  if ( ! empty( $new_text ) && ! current_user_can( 'unfiltered_html' ) ) {
3392
- $new_text = stripslashes( wp_filter_post_kses( addslashes( $new_text ) ) ); //wp_filter_post_kses expects slashed data.
3393
  }
3394
 
3395
  $rez = $link->edit( $new_url, $new_text );
@@ -3431,7 +3415,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3431
 
3432
  'errors' => array(),
3433
  );
3434
- //url, status text, status code, link text, editable link text
3435
 
3436
  foreach ( $rez['errors'] as $error ) { /** @var $error WP_Error */
3437
  array_push( $response['errors'], implode( ', ', $error->get_error_messages() ) );
@@ -3458,7 +3442,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3458
  }
3459
 
3460
  if ( isset( $_POST['link_id'] ) ) {
3461
- //Load the link
3462
  $link = new blcLink( intval( $_POST['link_id'] ) );
3463
 
3464
  if ( ! $link->valid() ) {
@@ -3471,7 +3455,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3471
  );
3472
  }
3473
 
3474
- //Try and unlink it
3475
  $rez = $link->unlink();
3476
 
3477
  if ( false === $rez ) {
@@ -3539,7 +3523,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3539
  );
3540
  }
3541
 
3542
- //The actual task is simple; it's error handling that's complicated.
3543
  $result = $link->deredirect();
3544
  if ( is_wp_error( $result ) ) {
3545
  die(
@@ -3570,7 +3554,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3570
  'errors' => array(),
3571
  );
3572
 
3573
- //Convert WP_Error's to simple strings.
3574
  if ( ! empty( $result['errors'] ) ) {
3575
  foreach ( $result['errors'] as $error ) { /** @var WP_Error $error */
3576
  $response['errors'][] = $error->get_error_message();
@@ -3620,12 +3604,12 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3620
  $transactionManager = TransactionManager::getInstance();
3621
  $transactionManager->start();
3622
 
3623
- //In case the immediate check fails, this will ensure the link is checked during the next work() run.
3624
  $link->last_check_attempt = 0;
3625
  $link->isOptionLinkChanged = true;
3626
  $link->save();
3627
 
3628
- //Check the link and save the results.
3629
  $link->check( true );
3630
 
3631
  $transactionManager->commit();
@@ -3649,24 +3633,24 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3649
  die( __( "You don't have sufficient privileges to access this information!", 'broken-link-checker' ) );
3650
  }
3651
 
3652
- //FB::log("Loading link details via AJAX");
3653
 
3654
  if ( isset( $_GET['link_id'] ) ) {
3655
- //FB::info("Link ID found in GET");
3656
  $link_id = intval( $_GET['link_id'] );
3657
  } elseif ( isset( $_POST['link_id'] ) ) {
3658
- //FB::info("Link ID found in POST");
3659
  $link_id = intval( $_POST['link_id'] );
3660
  } else {
3661
- //FB::error('Link ID not specified, you hacking bastard.');
3662
  die( __( 'Error : link ID not specified', 'broken-link-checker' ) );
3663
  }
3664
 
3665
- //Load the link.
3666
  $link = new blcLink( $link_id );
3667
 
3668
  if ( ! $link->is_new ) {
3669
- //FB::info($link, 'Link loaded');
3670
  if ( ! class_exists( 'blcTablePrinter' ) ) {
3671
  require dirname( $this->loader ) . '/includes/admin/table-printer.php';
3672
  }
@@ -3743,22 +3727,22 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3743
  /** @var wpdb $wpdb */
3744
  global $wpdb;
3745
 
3746
- //Collect some information that's useful for debugging
3747
  $debug = array();
3748
 
3749
- //PHP version. Any one is fine as long as WP supports it.
3750
  $debug[ __( 'PHP version', 'broken-link-checker' ) ] = array(
3751
  'state' => 'ok',
3752
  'value' => phpversion(),
3753
  );
3754
 
3755
- //MySQL version
3756
  $debug[ __( 'MySQL version', 'broken-link-checker' ) ] = array(
3757
  'state' => 'ok',
3758
  'value' => $wpdb->db_version(),
3759
  );
3760
 
3761
- //CURL presence and version
3762
  if ( function_exists( 'curl_version' ) ) {
3763
  $version = curl_version();
3764
 
@@ -3782,14 +3766,14 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3782
  }
3783
  $debug[ __( 'CURL version', 'broken-link-checker' ) ] = $data;
3784
 
3785
- //Snoopy presence
3786
  if ( class_exists( 'WP_Http' ) || file_exists( ABSPATH . WPINC . '/class-http.php' ) ) {
3787
  $data = array(
3788
  'state' => 'ok',
3789
  'value' => __( 'Installed', 'broken-link-checker' ),
3790
  );
3791
  } else {
3792
- //No Snoopy? This should never happen, but if it does we *must* have CURL.
3793
  if ( function_exists( 'curl_init' ) ) {
3794
  $data = array(
3795
  'state' => 'ok',
@@ -3805,7 +3789,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3805
  }
3806
  $debug['Snoopy'] = $data;
3807
 
3808
- //Safe_mode status
3809
  if ( blcUtility::is_safe_mode() ) {
3810
  $debug['Safe mode'] = array(
3811
  'state' => 'warning',
@@ -3819,7 +3803,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3819
  );
3820
  }
3821
 
3822
- //Open_basedir status
3823
  if ( blcUtility::is_open_basedir() ) {
3824
  $debug['open_basedir'] = array(
3825
  'state' => 'warning',
@@ -3833,27 +3817,27 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3833
  );
3834
  }
3835
 
3836
- //Default PHP execution time limit
3837
  $debug['Default PHP execution time limit'] = array(
3838
  'state' => 'ok',
3839
  'value' => sprintf( __( '%s seconds' ), ini_get( 'max_execution_time' ) ),
3840
  );
3841
 
3842
- //Database character set. Usually it's UTF-8. Setting it to something else can cause problems
3843
- //unless the site owner really knows what they're doing.
3844
  $charset = $wpdb->get_charset_collate();
3845
  $debug[ __( 'Database character set', 'broken-link-checker' ) ] = array(
3846
  'state' => 'ok',
3847
  'value' => ! empty( $charset ) ? $charset : '-',
3848
  );
3849
 
3850
- //Resynch flag.
3851
  $debug['Resynch. flag'] = array(
3852
  'state' => 'ok',
3853
  'value' => sprintf( '%d', $this->conf->options['need_resynch'] ? '1 (resynch. required)' : '0 (resynch. not required)' ),
3854
  );
3855
 
3856
- //Synch records
3857
  $synch_records = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}blc_synch" ) );
3858
  $data = array(
3859
  'state' => 'ok',
@@ -3865,12 +3849,12 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3865
  }
3866
  $debug['Synch. records'] = $data;
3867
 
3868
- //Total links and instances (including invalid ones)
3869
  $all_links = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}blc_links" ) );
3870
  $all_instances = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}blc_instances" ) );
3871
 
3872
- //Show the number of unparsed containers. Useful for debugging. For performance,
3873
- //this is only shown when we have no links/instances yet.
3874
  if ( ( 0 == $all_links ) && ( 0 == $all_instances ) ) {
3875
  $unparsed_items = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}blc_synch WHERE synched=0" ) );
3876
  $debug['Unparsed items'] = array(
@@ -3879,7 +3863,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3879
  );
3880
  }
3881
 
3882
- //Links & instances
3883
  if ( ( $all_links > 0 ) && ( $all_instances > 0 ) ) {
3884
  $debug['Link records'] = array(
3885
  'state' => 'ok',
@@ -3892,7 +3876,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3892
  );
3893
  }
3894
 
3895
- //Email notifications.
3896
  if ( $this->conf->options['last_notification_sent'] ) {
3897
  $notificationDebug = array(
3898
  'value' => date( 'Y-m-d H:i:s T', $this->conf->options['last_notification_sent'] ), //phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
@@ -3919,7 +3903,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3919
  );
3920
  }
3921
 
3922
- //Installation log
3923
  $logger = new blcCachedOptionLogger( 'blc_installation_log' );
3924
  $installation_log = $logger->get_messages();
3925
  if ( ! empty( $installation_log ) ) {
@@ -3945,11 +3929,11 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3945
 
3946
  $send_authors_notifications = apply_filters( 'blc_allow_send_author_email_notification', $this->conf->options['send_authors_email_notifications'] );
3947
 
3948
- if ( ! ( $send_notification || $send_authors_notifications ) ) {
3949
  return;
3950
  }
3951
 
3952
- //Find links that have been detected as broken since the last sent notification.
3953
  $last_notification = date( 'Y-m-d H:i:s', $this->conf->options['last_notification_sent'] );//phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
3954
  $where = $wpdb->prepare( '( first_failure >= %s )', $last_notification );
3955
 
@@ -3968,17 +3952,17 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3968
  return;
3969
  }
3970
 
3971
- //Send the admin/maintainer an email notification.
3972
  $email = $this->conf->get( 'notification_email_address' );
3973
  if ( empty( $email ) ) {
3974
- //Default to the admin email.
3975
  $email = get_option( 'admin_email' );
3976
  }
3977
  if ( $this->conf->options['send_email_notifications'] && ! empty( $email ) ) {
3978
  $this->send_admin_notification( $links, $email );
3979
  }
3980
 
3981
- //Send notifications to post authors
3982
  if ( $this->conf->options['send_authors_email_notifications'] ) {
3983
  $this->send_authors_notifications( $links );
3984
  }
@@ -3988,7 +3972,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
3988
  }
3989
 
3990
  function send_admin_notification( $links, $email ) {
3991
- //Prepare email message
3992
  $subject = sprintf(
3993
  __( '[%s] Broken links detected', 'broken-link-checker' ),
3994
  html_entity_decode( get_option( 'blogname' ), ENT_QUOTES )
@@ -4040,7 +4024,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4040
 
4041
  $result .= "<p>$line</p>";
4042
 
4043
- //Show up to $max_displayed_links broken link instances right in the email.
4044
  $displayed = 0;
4045
  foreach ( $instances as $instance ) { /* @var blcLinkInstance $instance */
4046
  $pieces = array(
@@ -4058,7 +4042,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4058
  }
4059
  }
4060
 
4061
- //Add a link to the "Broken Links" tab.
4062
  if ( $add_admin_link ) {
4063
  $result .= __( 'You can see all broken links here:', 'broken-link-checker' ) . '<br>';
4064
  $result .= sprintf( '<a href="%1$s">%1$s</a>', admin_url( 'tools.php?page=view-broken-links' ) );
@@ -4068,17 +4052,17 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4068
  }
4069
 
4070
  function send_html_email( $email_address, $subject, $body ) {
4071
- //Need to override the default 'text/plain' content type to send a HTML email.
4072
  add_filter( 'wp_mail_content_type', array( $this, 'override_mail_content_type' ) );
4073
 
4074
- //Let auto-responders and similar software know this is an auto-generated email
4075
- //that they shouldn't respond to.
4076
  $headers = array( 'Auto-Submitted: auto-generated' );
4077
 
4078
  $success = wp_mail( $email_address, $subject, $body, $headers );
4079
 
4080
- //Remove the override so that it doesn't interfere with other plugins that might
4081
- //want to send normal plaintext emails.
4082
  remove_filter( 'wp_mail_content_type', array( $this, 'override_mail_content_type' ) );
4083
 
4084
  $this->conf->options['last_email'] = array(
@@ -4166,7 +4150,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4166
  */
4167
  function setup_cron_events() {
4168
 
4169
- //Link monitor
4170
  if ( $this->conf->options['run_via_cron'] ) {
4171
  if ( ! wp_next_scheduled( 'blc_cron_check_links' ) ) {
4172
  wp_schedule_event( time(), '10min', 'blc_cron_check_links' );
@@ -4175,7 +4159,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4175
  wp_clear_scheduled_hook( 'blc_cron_check_links' );
4176
  }
4177
 
4178
- //Email notifications about broken links
4179
  if ( $this->conf->options['send_email_notifications'] || $this->conf->options['send_authors_email_notifications'] ) {
4180
  if ( ! wp_next_scheduled( 'blc_cron_email_notifications' ) ) {
4181
  wp_schedule_event( time(), $this->conf->options['notification_schedule'], 'blc_cron_email_notifications' );
@@ -4184,7 +4168,7 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4184
  wp_clear_scheduled_hook( 'blc_cron_email_notifications' );
4185
  }
4186
 
4187
- //Run database maintenance every two weeks or so
4188
  if ( ! wp_next_scheduled( 'blc_cron_database_maintenance' ) ) {
4189
  wp_schedule_event( time(), 'daily', 'blc_cron_database_maintenance' );
4190
  }
@@ -4201,12 +4185,13 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4201
 
4202
  /**
4203
  * Clear blc log file
 
4204
  * @return void
4205
  */
4206
  function clear_log_file() {
4207
  $log_file = $this->conf->options['log_file'];
4208
 
4209
- //clear log file
4210
  if ( is_writable( $log_file ) && is_file( $log_file ) ) {
4211
  $handle = fopen( $log_file, 'w' );
4212
  fclose( $handle );
@@ -4226,15 +4211,13 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4226
 
4227
  $last_modified_gmt = isset( $postarr['blc_post_modified_gmt'] ) ? $postarr['blc_post_modified_gmt'] : '';
4228
 
4229
-
4230
  // if is not enabled bail!
4231
- if( ! $this->conf->options['blc_post_modified'] ) {
4232
  return $data;
4233
  }
4234
 
4235
-
4236
  // only restore the post modified for BLC links
4237
- if( empty( $last_modified ) || empty( $last_modified_gmt ) ) {
4238
  return $data;
4239
  }
4240
 
@@ -4267,6 +4250,6 @@ if ( ! class_exists( 'wsBrokenLinkChecker' ) ) {
4267
  return 'blc-log.txt';
4268
  }
4269
 
4270
- }//class ends here
4271
 
4272
  } // if class_exists...
430
  * Handler for the 'plugin_action_links' hook. Adds a "Settings" link to this plugin's entry
431
  * on the plugin list.
432
  *
433
+ * @param array $links
434
  * @param string $file
435
  * @return array
436
  */
447
  public function options_page() {
448
  $moduleManager = blcModuleManager::getInstance();
449
 
 
 
 
 
 
 
 
 
 
 
450
  if ( isset( $_POST['recheck'] ) && ! empty( $_POST['recheck'] ) ) {
451
  $this->initiate_recheck();
452
 
493
  } else {
494
  $enabled_post_statuses = array();
495
  }
496
+ // At least one status must be enabled; defaults to "Published".
497
  if ( empty( $enabled_post_statuses ) ) {
498
  $enabled_post_statuses = array( 'publish' );
499
  }
500
 
501
+ // Did the user add/remove any post statuses?
502
  $same_statuses = array_intersect( $enabled_post_statuses, $this->conf->options['enabled_post_statuses'] );
503
  $post_statuses_changed = ( count( $same_statuses ) != count( $enabled_post_statuses ) )
504
  || ( count( $same_statuses ) !== count( $this->conf->options['enabled_post_statuses'] ) );
505
 
506
  $this->conf->options['enabled_post_statuses'] = $enabled_post_statuses;
507
 
508
+ // The execution time limit must be above zero
509
  $new_execution_time = intval( $_POST['max_execution_time'] );
510
  if ( $new_execution_time > 0 ) {
511
  $this->conf->options['max_execution_time'] = $new_execution_time;
512
  }
513
 
514
+ // The check threshold also must be > 0
515
  $new_check_threshold = intval( $_POST['check_threshold'] );
516
 
517
  if ( $new_check_threshold > 0 ) {
532
 
533
  $this->conf->options['exclusion_list'] = array_filter(
534
  preg_split(
535
+ '/[\s\r\n]+/', // split on newlines and whitespace
536
  $cleanPost['exclusion_list'],
537
  -1,
538
+ PREG_SPLIT_NO_EMPTY // skip empty values
539
  )
540
  );
541
 
542
+ // Parse the custom field list
543
  $new_custom_fields = array_filter(
544
  preg_split(
545
  '/[\r\n]+/',
549
  )
550
  );
551
 
552
+ // Calculate the difference between the old custom field list and the new one (used later)
553
  $diff1 = array_diff( $new_custom_fields, $this->conf->options['custom_fields'] );
554
  $diff2 = array_diff( $this->conf->options['custom_fields'], $new_custom_fields );
555
  $this->conf->options['custom_fields'] = $new_custom_fields;
556
 
557
+ // Parse the custom field list
558
  $new_acf_fields = array_filter( preg_split( '/[\r\n]+/', $cleanPost['blc_acf_fields'], -1, PREG_SPLIT_NO_EMPTY ) );
559
 
560
+ // Calculate the difference between the old custom field list and the new one (used later)
561
  $acf_fields_diff1 = array_diff( $new_acf_fields, $this->conf->options['acf_fields'] );
562
  $acf_fields_diff2 = array_diff( $this->conf->options['acf_fields'], $new_acf_fields );
563
  $this->conf->options['acf_fields'] = $new_acf_fields;
564
 
565
+ // Turning off warnings turns existing warnings into "broken" links.
566
  $this->conf->options['blc_post_modified'] = ! empty( $_POST['blc_post_modified'] );
567
 
568
+ // Turning off warnings turns existing warnings into "broken" links.
569
  $warnings_enabled = ! empty( $_POST['warnings_enabled'] );
570
  if ( $this->conf->get( 'warnings_enabled' ) && ! $warnings_enabled ) {
571
  $this->promote_warnings_to_broken();
572
  }
573
  $this->conf->options['warnings_enabled'] = $warnings_enabled;
574
 
575
+ // HTTP timeout
576
  $new_timeout = intval( $_POST['timeout'] );
577
  if ( $new_timeout > 0 ) {
578
  $this->conf->options['timeout'] = $new_timeout;
579
  }
580
 
581
+ // Server load limit
582
  if ( isset( $_POST['server_load_limit'] ) ) {
583
  $this->conf->options['server_load_limit'] = floatval( $_POST['server_load_limit'] );
584
  if ( $this->conf->options['server_load_limit'] < 0 ) {
587
  $this->conf->options['enable_load_limit'] = $this->conf->options['server_load_limit'] > 0;
588
  }
589
 
590
+ // Target resource usage (1% to 100%)
591
  if ( isset( $_POST['target_resource_usage'] ) ) {
592
  $usage = floatval( $_POST['target_resource_usage'] );
593
  $usage = max( min( $usage / 100, 1 ), 0.01 );
594
  $this->conf->options['target_resource_usage'] = $usage;
595
  }
596
 
597
+ // When to run the checker
598
  $this->conf->options['run_in_dashboard'] = ! empty( $_POST['run_in_dashboard'] );
599
  $this->conf->options['run_via_cron'] = ! empty( $_POST['run_via_cron'] );
600
 
601
+ // youtube api
602
  $this->conf->options['youtube_api_key'] = ! empty( $_POST['youtube_api_key'] ) ? $_POST['youtube_api_key'] : '';
603
 
604
+ // Email notifications on/off
605
  $email_notifications = ! empty( $_POST['send_email_notifications'] );
606
  $send_authors_email_notifications = ! empty( $_POST['send_authors_email_notifications'] );
607
 
630
  $this->conf->options['dashboard_widget_capability'] = $widget_cap;
631
  }
632
 
633
+ // Link actions. The user can hide some of them to reduce UI clutter.
634
  $show_link_actions = array();
635
  foreach ( array_keys( $available_link_actions ) as $action ) {
636
  $show_link_actions[ $action ] = isset( $_POST['show_link_actions'] ) && ! empty( $_POST['show_link_actions'][ $action ] );
637
  }
638
  $this->conf->set( 'show_link_actions', $show_link_actions );
639
 
640
+ // Logging. The plugin can log various events and results for debugging purposes.
641
  $this->conf->options['logging_enabled'] = ! empty( $_POST['logging_enabled'] );
642
  $this->conf->options['custom_log_file_enabled'] = ! empty( $_POST['custom_log_file_enabled'] );
643
 
644
  if ( $this->conf->options['logging_enabled'] ) {
645
  if ( $this->conf->options['custom_log_file_enabled'] ) {
646
 
647
+ $log_file = esc_url_raw( strval( $cleanPost['log_file'] ) );
648
+ $file_type_data = wp_check_filetype( $log_file );
649
+
650
+ if ( substr( $log_file, 0, 7 ) === 'phar://' || ! isset( $file_type_data['type'] ) || empty( $file_type_data['type'] ) ) {
651
+ $log_file = '';
652
+ }
653
+
654
+ if ( ! empty( $log_file ) && ! file_exists( $log_file ) ) {
655
  if ( ! file_exists( dirname( $log_file ) ) ) {
656
  mkdir( dirname( $log_file ), 0750, true );
657
  }
658
  // Attempt to create the log file if not already there.
659
  if ( ! is_file( $log_file ) ) {
660
+ // Add a .htaccess to hide the log file from site visitors.
661
  file_put_contents( dirname( $log_file ) . '/.htaccess', 'Deny from all' );
662
  file_put_contents( $log_file, '' );
663
  }
664
  }
665
+
666
+ // Revert to default.
667
  if ( ! is_writable( $log_file ) || ! is_file( $log_file ) ) {
668
  $this->conf->options['custom_log_file_enabled'] = '';
669
+ $log_directory = self::get_default_log_directory();
670
+ $log_file = $log_directory . '/' . self::get_default_log_basename();
671
  }
672
  } else {
673
+ // Default log file is /wp-content/uploads/broken-link-checker/blc-log.txt
674
  $log_directory = self::get_default_log_directory();
675
  $log_file = $log_directory . '/' . self::get_default_log_basename();
676
 
677
+ // Attempt to create the log directory.
678
  if ( ! is_dir( $log_directory ) ) {
679
  if ( mkdir( $log_directory, 0750 ) ) {
680
+ // Add a .htaccess to hide the log file from site visitors.
681
  file_put_contents( $log_directory . '/.htaccess', 'Deny from all' );
682
  }
683
  }
684
  }
685
 
686
+ $this->conf->options['log_file'] = $log_file;
687
  $this->conf->options['clear_log_on'] = strval( $cleanPost['clear_log_on'] );
688
 
689
  // Attempt to create the log file if not already there.
691
  file_put_contents( $log_file, '' );
692
  }
693
 
694
+ // The log file must be writable.
695
  if ( ! is_writable( $log_file ) || ! is_file( $log_file ) ) {
696
  $this->conf->options['logging_enabled'] = false;
697
  }
698
  }
699
 
700
+ // Make settings that affect our Cron events take effect immediately
701
  $this->setup_cron_events();
702
  $this->conf->save_options();
703
 
727
  }
728
  }
729
 
730
+ // Resynchronize posts when the user enables or disables post statuses.
731
  if ( $post_statuses_changed ) {
732
  $overlord = blcPostTypeOverlord::getInstance();
733
  $overlord->enabled_post_statuses = $this->conf->get( 'enabled_post_statuses', array() );
738
  blc_cleanup_links();
739
  }
740
 
741
+ // Redirect back to the settings page
742
  $base_url = remove_query_arg( array( '_wpnonce', 'noheader', 'updated', 'error', 'action', 'message' ) );
743
  wp_redirect(
744
  add_query_arg(
750
  );
751
  }
752
 
753
+ // Show a confirmation message when settings are saved.
754
  if ( ! empty( $_GET['settings-updated'] ) ) {
755
  echo '<div id="message" class="updated fade"><p><strong>',__( 'Settings saved.', 'broken-link-checker' ), '</strong></p></div>';
756
 
757
  }
758
 
759
+ // Show one when recheck is started, too.
 
 
 
 
 
 
 
760
  if ( ! empty( $_GET['recheck-initiated'] ) ) {
761
  echo '<div id="message" class="updated fade"><p><strong>',
762
  __( 'Complete site recheck started.', 'broken-link-checker' ), // -- Yoda
763
  '</strong></p></div>';
764
  }
765
 
766
+ // Cull invalid and missing modules
767
  $moduleManager->validate_active_modules();
768
 
769
  $debug = $this->get_debug_info();
771
  add_filter( 'blc-module-settings-custom_field', array( $this, 'make_custom_field_input' ), 10, 2 );
772
  add_filter( 'blc-module-settings-acf_field', array( $this, 'make_acf_field_input' ), 10, 2 );
773
 
774
+ // Translate and markup-ify module headers for display
775
  $modules = $moduleManager->get_modules_by_category( '', true, true );
776
 
777
+ // Output the custom broken link/removed link styles for example links
778
  printf(
779
  '<style type="text/css">%s %s</style>',
780
  $this->conf->options['broken_link_css'],
803
  <div class="wrap" id="blc-settings-wrap">
804
  <h2><?php _e( 'Broken Link Checker Options', 'broken-link-checker' ); ?></h2>
805
 
 
 
 
 
 
 
 
 
806
  <div id="blc-admin-content">
807
 
808
  <form name="link_checker_options" id="link_checker_options" method="post" action="
850
  <table id="blc-debug-info">
851
  <?php
852
 
853
+ // Output the debug info in a table
854
  foreach ( $debug as $key => $value ) {
855
  printf(
856
  '<tr valign="top" class="blc-debug-item-%s"><th scope="row">%s</th><td>%s<div class="blc-debug-message">%s</div></td></tr>',
945
  if ( defined( 'TEST_WPEL_PLUGIN_FILE' ) ) {
946
  printf(
947
  __( 'Configure <a target="_blank" href="%s">External Links</a> settings.', 'broken-link-checker' ),
948
+ admin_url( 'admin.php?page=wpel-settings-page' )
949
  );
950
  } else {
951
  printf(
1111
  type="text"
1112
  name="youtube_api_key"
1113
  id="youtube_api_key"
1114
+ value="<?php echo $this->conf->options['youtube_api_key']; ?>"
1115
  class="regular-text ltr">
1116
  </label><br>
1117
  <span class="description">
1529
  </div>
1530
 
1531
  <?php
1532
+ // The various JS for this page is stored in a separate file for the purposes readability.
1533
  include dirname( $this->loader ) . '/includes/admin/options-page-js.php';
1534
  }
1535
 
1574
  __( 'Configure', 'broken-link-checker' )
1575
  );
1576
 
1577
+ // The plugin remembers the last open/closed state of module configuration boxes
1578
  $box_id = 'module-extra-settings-' . $module_id;
1579
  $show = blcUtility::get_cookie(
1580
  $box_id,
1602
  * form submissions work correctly.
1603
  *
1604
  * @param string $module_id Module ID.
1605
+ * @param array $module_data Associative array of module data.
1606
+ * @param bool $active If true, the newly created checkbox will start out checked.
1607
  * @return void
1608
  */
1609
  function print_module_checkbox( $module_id, $module_data, $active = false ) {
1648
  * Callback for the 'blc-module-settings-custom_field' filter.
1649
  *
1650
  * @param string $html Current extra HTML
1651
+ * @param array $current_settings The current plugin configuration.
1652
  * @return string New extra HTML.
1653
  */
1654
  function make_custom_field_input( $html, $current_settings ) {
1686
 
1687
  wp_enqueue_style( 'dashboard' );
1688
 
1689
+ wp_enqueue_style( 'plugin-install' );
1690
+ wp_enqueue_script( 'plugin-install' );
1691
 
1692
  add_thickbox();
1693
  }
1703
 
1704
  $blc_link_query = blcLinkQuery::getInstance();
1705
 
1706
+ // Cull invalid and missing modules so that we don't get dummy links/instances showing up.
1707
  $moduleManager = blcModuleManager::getInstance();
1708
  $moduleManager->validate_active_modules();
1709
 
1710
  if ( defined( 'BLC_DEBUG' ) && constant( 'BLC_DEBUG' ) ) {
1711
+ // Make module headers translatable. They need to be formatted corrrectly and
1712
+ // placed in a .php file to be visible to the script(s) that generate .pot files.
1713
  $code = $moduleManager->_build_header_translation_code();
1714
  file_put_contents( dirname( $this->loader ) . '/includes/extra-strings.php', $code );
1715
  }
1716
 
1717
  $action = ! empty( $_POST['action'] ) ? $_POST['action'] : '';
1718
  if ( intval( $action ) == -1 ) {
1719
+ // Try the second bulk actions box
1720
  $action = ! empty( $_POST['action2'] ) ? $_POST['action2'] : '';
1721
  }
1722
 
1723
+ // Get the list of link IDs selected via checkboxes
1724
  $selected_links = array();
1725
  if ( isset( $_POST['selected_links'] ) && is_array( $_POST['selected_links'] ) ) {
1726
+ // Convert all link IDs to integers (non-numeric entries are converted to zero)
1727
  $selected_links = array_map( 'intval', $_POST['selected_links'] );
1728
+ // Remove all zeroes
1729
  $selected_links = array_filter( $selected_links );
1730
  }
1731
 
1732
  $message = '';
1733
  $msg_class = 'updated';
1734
 
1735
+ // Run the selected bulk action, if any
1736
  $force_delete = false;
1737
  switch ( $action ) {
1738
  case 'create-custom-filter':
1746
  // @noinspection PhpMissingBreakStatementInspection Deliberate fall-through.
1747
  case 'bulk-delete-sources':
1748
  $force_delete = true;
1749
+ // intentional fall through
1750
  case 'bulk-trash-sources':
1751
  list($message, $msg_class) = $this->do_bulk_delete_sources( $selected_links, $force_delete );
1752
  break;
1782
 
1783
  $start_time = microtime_float();
1784
 
1785
+ // Load custom filters, if any
1786
  $blc_link_query->load_custom_filters();
1787
 
1788
+ // Calculate the number of links matching each filter
1789
  $blc_link_query->count_filter_results();
1790
 
1791
+ // Run the selected filter (defaults to displaying broken links)
1792
  $selected_filter_id = isset( $_GET['filter_id'] ) ? $_GET['filter_id'] : 'broken';
1793
  $current_filter = $blc_link_query->exec_filter(
1794
  $selected_filter_id,
1799
  isset( $_GET['order'] ) ? $_GET['order'] : ''
1800
  );
1801
 
1802
+ // exec_filter() returns an array with filter data, including the actual filter ID that was used.
1803
  $filter_id = $current_filter['filter_id'];
1804
 
1805
+ // Error?
1806
  if ( empty( $current_filter['links'] ) && ! empty( $wpdb->last_error ) ) {
1807
  printf( __( 'Database error : %s', 'broken-link-checker' ), $wpdb->last_error );
1808
  }
1820
  $blc_link_query->print_filter_heading( $current_filter );
1821
  $blc_link_query->print_filter_menu( $filter_id );
1822
 
1823
+ // Display the "Search" form and associated buttons.
1824
+ // The form requires the $filter_id and $current_filter variables to be set.
1825
  include dirname( $this->loader ) . '/includes/admin/search-form.php';
1826
 
1827
+ // If the user has decided to switch the table to a different mode (compact/full),
1828
+ // save the new setting.
1829
  if ( isset( $_GET['compact'] ) ) {
1830
  $this->conf->options['table_compact'] = (bool) $_GET['compact'];
1831
  $this->conf->save_options();
1832
  }
1833
 
1834
+ // Display the links, if any
1835
  if ( $current_filter['links'] && ( count( $current_filter['links'] ) > 0 ) ) {
1836
 
1837
  include dirname( $this->loader ) . '/includes/admin/table-printer.php';
1846
  };
1847
  printf( '<!-- Total elapsed : %.4f seconds -->', microtime_float() - $start_time );
1848
 
1849
+ // Load assorted JS event handlers and other shinies
1850
  include dirname( $this->loader ) . '/includes/admin/links-page-js.php';
1851
 
1852
  ?>
1865
  function do_create_custom_filter() {
1866
  global $wpdb;
1867
 
1868
+ // Create a custom filter!
1869
  check_admin_referer( 'create-custom-filter' );
1870
  $msg_class = 'updated';
1871
 
1872
+ // Filter name must be set
1873
  if ( empty( $_POST['name'] ) ) {
1874
  $message = __( 'You must enter a filter name!', 'broken-link-checker' );
1875
  $msg_class = 'error';
1876
+ // Filter parameters (a search query) must also be set
1877
  } elseif ( empty( $_POST['params'] ) ) {
1878
  $message = __( 'Invalid search query.', 'broken-link-checker' );
1879
  $msg_class = 'error';
1880
  } else {
1881
+ // Save the new filter
1882
  $name = strip_tags( strval( $_POST['name'] ) );
1883
  $blc_link_query = blcLinkQuery::getInstance();
1884
  $filter_id = $blc_link_query->create_custom_filter( $name, $_POST['params'] );
1885
 
1886
  if ( $filter_id ) {
1887
+ // Saved
1888
  $message = sprintf( __( 'Filter "%s" created', 'broken-link-checker' ), $name );
1889
+ // A little hack to make the filter active immediately
1890
  $_GET['filter_id'] = $filter_id;
1891
  } else {
1892
+ // Error
1893
  $message = sprintf( __( 'Database error : %s', 'broken-link-checker' ), $wpdb->last_error );
1894
  $msg_class = 'error';
1895
  }
1906
  * @return array Message and a CSS class to apply to the message.
1907
  */
1908
  function do_delete_custom_filter() {
1909
+ // Delete an existing custom filter!
1910
  check_admin_referer( 'delete-custom-filter' );
1911
  $msg_class = 'updated';
1912
 
1913
+ // Filter ID must be set
1914
  if ( empty( $_POST['filter_id'] ) ) {
1915
  $message = __( 'Filter ID not specified.', 'broken-link-checker' );
1916
  $msg_class = 'error';
1917
  } else {
1918
+ // Try to delete the filter
1919
  $blc_link_query = blcLinkQuery::getInstance();
1920
  if ( $blc_link_query->delete_custom_filter( $_POST['filter_id'] ) ) {
1921
+ // Success
1922
  $message = __( 'Filter deleted', 'broken-link-checker' );
1923
  } else {
1924
+ // Either the ID is wrong or there was some other error
1925
  $message = __( 'Database error : %s', 'broken-link-checker' );
1926
  $msg_class = 'error';
1927
  }
1937
  * @return array The message to display and its CSS class.
1938
  */
1939
  function do_bulk_deredirect( $selected_links ) {
1940
+ // For all selected links, replace the URL with the final URL that it redirects to.
1941
 
1942
  $message = '';
1943
  $msg_class = 'updated';
1945
  check_admin_referer( 'bulk-action' );
1946
 
1947
  if ( count( $selected_links ) > 0 ) {
1948
+ // Fetch all the selected links
1949
  $links = blc_get_links(
1950
  array(
1951
  'link_ids' => $selected_links,
1957
  $processed_links = 0;
1958
  $failed_links = 0;
1959
 
1960
+ // Deredirect all selected links
1961
  foreach ( $links as $link ) {
1962
  $rez = $link->deredirect();
1963
  if ( ! is_wp_error( $rez ) && empty( $rez['errors'] ) ) {
2011
 
2012
  $post = $_POST;
2013
  if ( function_exists( 'wp_magic_quotes' ) ) {
2014
+ $post = stripslashes_deep( $post ); // Ceterum censeo, WP shouldn't mangle superglobals.
2015
  }
2016
 
2017
  $search = isset( $post['search'] ) ? esc_attr( $post['search'] ) : '';
2019
  $use_regex = ! empty( $post['regex'] );
2020
  $case_sensitive = ! empty( $post['case_sensitive'] );
2021
 
2022
+ $delimiter = '`'; // Pick a char that's uncommon in URLs so that escaping won't usually be a problem
2023
  if ( $use_regex ) {
2024
  $search = $delimiter . $this->escape_regex_delimiter( $search, $delimiter ) . $delimiter;
2025
  if ( ! $case_sensitive ) {
2026
  $search .= 'i';
2027
  }
2028
  } elseif ( ! $case_sensitive ) {
2029
+ // str_ireplace() would be more appropriate for case-insensitive, non-regexp replacement,
2030
+ // but that's only available in PHP5.
2031
  $search = $delimiter . preg_quote( $search, $delimiter ) . $delimiter . 'i';
2032
  $use_regex = true;
2033
  }
2034
 
2035
  if ( count( $selected_links ) > 0 ) {
2036
+ set_time_limit( 300 ); // In case the user decides to edit hundreds of links at once
2037
 
2038
+ // Fetch all the selected links
2039
  $links = blc_get_links(
2040
  array(
2041
  'link_ids' => $selected_links,
2048
  $failed_links = 0;
2049
  $skipped_links = 0;
2050
 
2051
+ // Edit the links
2052
  foreach ( $links as $link ) {
2053
  if ( $use_regex ) {
2054
  $new_url = preg_replace( $search, $replace, $link->url );
2139
  * @return array Message and a CSS classname.
2140
  */
2141
  function do_bulk_unlink( $selected_links ) {
2142
+ // Unlink all selected links.
2143
  $message = '';
2144
  $msg_class = 'updated';
2145
 
2147
 
2148
  if ( count( $selected_links ) > 0 ) {
2149
 
2150
+ // Fetch all the selected links
2151
  $links = blc_get_links(
2152
  array(
2153
  'link_ids' => $selected_links,
2159
  $processed_links = 0;
2160
  $failed_links = 0;
2161
 
2162
+ // Unlink (delete) each one
2163
  foreach ( $links as $link ) {
2164
  $rez = $link->unlink();
2165
  if ( ( false == $rez ) || is_wp_error( $rez ) ) {
2169
  }
2170
  }
2171
 
2172
+ // This message is slightly misleading - it doesn't account for the fact that
2173
+ // a link can be present in more than one post.
2174
  $message = sprintf(
2175
  _n(
2176
  '%d link removed',
2206
  * can't be moved to the trash, it will skip that item by default.
2207
  *
2208
  * @param array $selected_links An array of link IDs
2209
+ * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
2210
  * @return array Confirmation message and its CSS class.
2211
  */
2212
  function do_bulk_delete_sources( $selected_links, $force_delete = false ) {
2213
  $message = '';
2214
  $msg_class = 'updated';
2215
 
2216
+ // Delete posts, blogroll entries and any other link containers that contain any of the selected links.
2217
  //
2218
+ // Note that once all containers containing a particular link have been deleted,
2219
+ // there is no need to explicitly delete the link record itself. The hooks attached to
2220
+ // the actions that execute when something is deleted (e.g. "post_deleted") will
2221
+ // take care of that.
2222
 
2223
  check_admin_referer( 'bulk-action' );
2224
 
2225
  if ( count( $selected_links ) > 0 ) {
2226
  $messages = array();
2227
 
2228
+ // Fetch all the selected links
2229
  $links = blc_get_links(
2230
  array(
2231
  'link_ids' => $selected_links,
2233
  )
2234
  );
2235
 
2236
+ // Make a list of all containers associated with these links, with each container
2237
+ // listed only once.
2238
  $containers = array();
2239
  foreach ( $links as $link ) { /* @var blcLink $link */
2240
  $instances = $link->get_instances();
2244
  }
2245
  }
2246
 
2247
+ // Instantiate the containers
2248
  $containers = blcContainerHelper::get_containers( $containers );
2249
 
2250
+ // Delete/trash their associated entities
2251
  $deleted = array();
2252
  $skipped = array();
2253
  foreach ( $containers as $container ) { /* @var blcContainer $container */
2266
  }
2267
  }
2268
 
2269
+ if ( is_wp_error( $rez ) ) { /*
2270
+ @var WP_Error $rez */
2271
+ // Record error messages for later display
2272
  $messages[] = $rez->get_error_message();
2273
  $msg_class = 'error';
2274
  } else {
2275
+ // Keep track of how many of each type were deleted.
2276
  $container_type = $container->container_type;
2277
  if ( isset( $deleted[ $container_type ] ) ) {
2278
  $deleted[ $container_type ]++;
2282
  }
2283
  }
2284
 
2285
+ // Generate delete confirmation messages
2286
  foreach ( $deleted as $container_type => $number ) {
2287
  if ( $force_delete ) {
2288
  $messages[] = blcContainerHelper::ui_bulk_delete_message( $container_type, $number );
2291
  }
2292
  }
2293
 
2294
+ // If some items couldn't be trashed, let the user know
2295
  if ( count( $skipped ) > 0 ) {
2296
  $message = sprintf(
2297
  _n(
2334
  /** @var wpdb $wpdb */
2335
  global $wpdb;
2336
 
2337
+ $message = '';
2338
+ $msg_class = 'updated';
2339
  $total_links = count( $selected_links );
2340
  check_admin_referer( 'bulk-action' );
2341
 
2342
  if ( $total_links > 0 ) {
2343
  $placeholders = array_fill( 0, $total_links, '%d' );
2344
+ $format = implode( ', ', $placeholders );
2345
+ $query = "UPDATE {$wpdb->prefix}blc_links
2346
  SET last_check_attempt = '0000-00-00 00:00:00'
2347
  WHERE link_id IN ( $format )";
2348
 
2385
  $transactionManager = TransactionManager::getInstance();
2386
  $transactionManager->start();
2387
  foreach ( $selected_links as $link_id ) {
2388
+ // Load the link
2389
  $link = new blcLink( intval( $link_id ) );
2390
 
2391
+ // Skip links that don't actually exist
2392
  if ( ! $link->valid() ) {
2393
  continue;
2394
  }
2395
 
2396
+ // Skip links that weren't actually detected as broken
2397
  if ( ! $link->broken && ! $link->warning ) {
2398
  continue;
2399
  }
2400
 
2401
+ // Make it appear "not broken"
2402
  $link->broken = false;
2403
  $link->warning = false;
2404
  $link->false_positive = true;
2406
  $link->log = __( 'This link was manually marked as working by the user.', 'broken-link-checker' );
2407
 
2408
  $link->isOptionLinkChanged = true;
2409
+ // Save the changes
2410
  if ( $link->save() ) {
2411
  $processed_links++;
2412
  } else {
2452
  $transactionManager = TransactionManager::getInstance();
2453
  $transactionManager->start();
2454
  foreach ( $selected_links as $link_id ) {
2455
+ // Load the link
2456
  $link = new blcLink( intval( $link_id ) );
2457
 
2458
+ // Skip links that don't actually exist
2459
  if ( ! $link->valid() ) {
2460
  continue;
2461
  }
2462
 
2463
+ // We can only dismiss broken links and redirects.
2464
  if ( ! ( $link->broken || $link->warning || ( $link->redirect_count > 0 ) ) ) {
2465
  continue;
2466
  }
2469
 
2470
  $link->isOptionLinkChanged = true;
2471
 
2472
+ // Save the changes
2473
  if ( $link->save() ) {
2474
  $processed_links++;
2475
  } else {
2522
  return;
2523
  }
2524
 
2525
+ // Let the user hide the notice.
2526
  $conf = blc_get_configuration();
2527
  $notice_name = 'show_warnings_section_hint';
2528
 
2567
  * @return string
2568
  */
2569
  function screen_options_html() {
2570
+ // Update the links-per-page setting when "Apply" is clicked
2571
  if ( isset( $_POST['per_page'] ) && is_numeric( $_POST['per_page'] ) ) {
2572
  check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' );
2573
  $per_page = intval( $_POST['per_page'] );
2577
  }
2578
  }
2579
 
2580
+ // Let the user show/hide individual table columns
2581
  $html = '<h5>' . __( 'Table columns', 'broken-link-checker' ) . '</h5>';
2582
 
2583
  include dirname( $this->loader ) . '/includes/admin/table-printer.php';
2629
  );
2630
  $html .= '</label>';
2631
 
2632
+ // Display a checkbox for turning colourful link status messages on/off
2633
  $html .= sprintf(
2634
  '<br/><label><input type="checkbox" id="table_color_code_status" name="table_color_code_status"%s> %s</label>',
2635
  $this->conf->options['table_color_code_status'] ? ' checked="checked"' : '',
2690
  function work() {
2691
  global $blclog;
2692
 
2693
+ // Close the session to prevent lock-ups.
2694
+ // PHP sessions are blocking. session_start() will wait until all other scripts that are using the same session
2695
+ // are finished. As a result, a long-running script that unintentionally keeps the session open can cause
2696
+ // the entire site to "lock up" for the current user/browser. WordPress itself doesn't use sessions, but some
2697
+ // plugins do, so we should explicitly close the session (if any) before starting the worker.
2698
  if ( session_id() != '' ) {
2699
  session_write_close();
2700
  }
2701
 
2702
  if ( ! $this->acquire_lock() ) {
2703
+ // FB::warn("Another instance of BLC is already working. Stop.");
2704
  $blclog->info( 'Another instance of BLC is already working. Stop.' );
2705
  return;
2706
  }
2707
 
2708
  if ( $this->server_too_busy() ) {
2709
+ // FB::warn("Server is too busy. Stop.");
2710
  $blclog->warn( 'Server load is too high, stopping.' );
2711
  return;
2712
  }
2718
 
2719
  /*****************************************
2720
  Preparation
2721
+ */
2722
  // Check for safe mode
2723
  if ( blcUtility::is_safe_mode() ) {
2724
  // Do it the safe mode way - obey the existing max_execution_time setting
2728
  }
2729
  } else {
2730
  // Do it the regular way
2731
+ @set_time_limit( $max_execution_time * 2 ); // x2 should be plenty, running any longer would mean a glitch.
2732
  }
2733
 
2734
+ // Don't stop the script when the connection is closed
2735
  ignore_user_abort( true );
2736
 
2737
+ // Close the connection as per http://www.php.net/manual/en/features.connection-handling.php#71172
2738
+ // This reduces resource usage.
2739
+ // (Disable when debugging or you won't get the FirePHP output)
2740
  if (
2741
  ! headers_sent()
2742
  && ( defined( 'DOING_AJAX' ) && constant( 'DOING_AJAX' ) )
2743
  && ( ! defined( 'BLC_DEBUG' ) || ! constant( 'BLC_DEBUG' ) )
2744
  ) {
2745
+ @ob_end_clean(); // Discard the existing buffer, if any
2746
  header( 'Connection: close' );
2747
  ob_start();
2748
+ echo ( 'Connection closed' ); // This could be anything
2749
  $size = ob_get_length();
2750
  header( "Content-Length: $size" );
2751
  ob_end_flush(); // Strange behaviour, will not work
2752
  flush(); // Unless both are called !
2753
  }
2754
 
2755
+ // Load modules for this context
2756
  $moduleManager = blcModuleManager::getInstance();
2757
  $moduleManager->load_modules( 'work' );
2758
 
2759
  $target_usage_fraction = $this->conf->get( 'target_resource_usage', 0.25 );
2760
+ // Target usage must be between 1% and 100%.
2761
  $target_usage_fraction = max( min( $target_usage_fraction, 1 ), 0.01 );
2762
 
2763
  /*****************************************
2764
  Parse posts and bookmarks
2765
+ */
2766
 
2767
  $orphans_possible = false;
2768
  $still_need_resynch = $this->conf->options['need_resynch'];
2769
 
2770
  if ( $still_need_resynch ) {
2771
 
2772
+ // FB::log("Looking for containers that need parsing...");
2773
  $max_containers_per_query = 50;
2774
 
2775
  $start = microtime( true );
2777
  $get_containers_time = microtime( true ) - $start;
2778
 
2779
  while ( ! empty( $containers ) ) {
2780
+ // FB::log($containers, 'Found containers');
2781
  $this->sleep_to_maintain_ratio( $get_containers_time, $target_usage_fraction );
2782
 
2783
  foreach ( $containers as $container ) {
2784
  $synch_start_time = microtime( true );
2785
 
2786
+ // FB::log($container, "Parsing container");
2787
  $container->synch();
2788
 
2789
  $synch_elapsed_time = microtime( true ) - $synch_start_time;
2796
  )
2797
  );
2798
 
2799
+ // Check if we still have some execution time left
2800
  if ( $this->execution_time() > $max_execution_time ) {
2801
+ // FB::log('The allotted execution time has run out');
2802
  blc_cleanup_links();
2803
  $this->release_lock();
2804
  return;
2805
  }
2806
 
2807
+ // Check if the server isn't overloaded
2808
  if ( $this->server_too_busy() ) {
2809
+ // FB::log('Server overloaded, bailing out.');
2810
  blc_cleanup_links();
2811
  $this->release_lock();
2812
  return;
2813
  }
2814
 
2815
+ // Intentionally slow down parsing to reduce the load on the server. Basically,
2816
+ // we work $target_usage_fraction of the time and sleep the rest of the time.
2817
  $this->sleep_to_maintain_ratio( $synch_elapsed_time, $target_usage_fraction );
2818
  }
2819
  $orphans_possible = true;
2823
  $get_containers_time = microtime( true ) - $start;
2824
  }
2825
 
2826
+ // FB::log('No unparsed items found.');
2827
  $still_need_resynch = false;
2828
 
2829
  } else {
2830
+ // FB::log('Resynch not required.');
2831
  }
2832
 
2833
  /******************************************
2834
  Resynch done?
2835
+ */
2836
  if ( $this->conf->options['need_resynch'] && ! $still_need_resynch ) {
2837
  $this->conf->options['need_resynch'] = $still_need_resynch;
2838
  $this->conf->save_options();
2840
 
2841
  /******************************************
2842
  Remove orphaned links
2843
+ */
2844
 
2845
  if ( $orphans_possible ) {
2846
  $start = microtime( true );
2852
  $this->sleep_to_maintain_ratio( $get_links_time, $target_usage_fraction );
2853
  }
2854
 
2855
+ // Check if we still have some execution time left
2856
  if ( $this->execution_time() > $max_execution_time ) {
2857
+ // FB::log('The allotted execution time has run out');
2858
  $blclog->info( 'The allotted execution time has run out.' );
2859
  $this->release_lock();
2860
  return;
2861
  }
2862
 
2863
  if ( $this->server_too_busy() ) {
2864
+ // FB::log('Server overloaded, bailing out.');
2865
  $blclog->info( 'Server load too high, stopping.' );
2866
  $this->release_lock();
2867
  return;
2869
 
2870
  /*****************************************
2871
  Check links
2872
+ */
2873
  $max_links_per_query = 30;
2874
 
2875
  $start = microtime( true );
2879
  while ( $links ) {
2880
  $this->sleep_to_maintain_ratio( $get_links_time, $target_usage_fraction );
2881
 
2882
+ // Some unchecked links found
2883
+ // FB::log("Checking ".count($links)." link(s)");
2884
  $blclog->info( 'Checking ' . count( $links ) . ' link(s)' );
2885
 
2886
+ // Randomizing the array reduces the chances that we'll get several links to the same domain in a row.
2887
  shuffle( $links );
2888
 
2889
  $transactionManager = TransactionManager::getInstance();
2890
  $transactionManager->start();
2891
 
2892
  foreach ( $links as $link ) {
2893
+ // Does this link need to be checked? Excluded links aren't checked, but their URLs are still
2894
+ // tested periodically to see if they're still on the exclusion list.
2895
  if ( ! $this->is_excluded( $link->url ) ) {
2896
+ // Check the link.
2897
+ // FB::log($link->url, "Checking link {$link->link_id}");
2898
  $link->check( true );
2899
  } else {
2900
+ // FB::info("The URL {$link->url} is excluded, skipping link {$link->link_id}.");
2901
  $link->last_check_attempt = time();
2902
  $link->save();
2903
  }
2904
 
2905
+ // Check if we still have some execution time left
2906
  if ( $this->execution_time() > $max_execution_time ) {
2907
  $transactionManager->commit();
2908
+ // FB::log('The allotted execution time has run out');
2909
  $blclog->info( 'The allotted execution time has run out.' );
2910
  $this->release_lock();
2911
  return;
2912
  }
2913
 
2914
+ // Check if the server isn't overloaded
2915
  if ( $this->server_too_busy() ) {
2916
  $transactionManager->commit();
2917
+ // FB::log('Server overloaded, bailing out.');
2918
  $blclog->info( 'Server load too high, stopping.' );
2919
  $this->release_lock();
2920
  return;
2926
  $links = $this->get_links_to_check( $max_links_per_query );
2927
  $get_links_time = microtime( true ) - $start;
2928
  }
2929
+ // FB::log('No links need to be checked right now.');
2930
 
2931
  $this->release_lock();
2932
  $blclog->info( 'work(): All done.' );
2933
+ // FB::log('All done.');
2934
  }
2935
 
2936
  /**
2948
  }
2949
  $sleep_time = $elapsed_time * ( ( 1 / $ratio ) - 1 );
2950
  if ( $sleep_time > 0.0001 ) {
2951
+ /*
2952
+ global $blclog;
2953
  $blclog->debug(sprintf(
2954
  'Task took %.2f ms, sleeping for %.2f ms',
2955
  $elapsed_time * 1000,
2975
  * Retrieve links that need to be checked or re-checked.
2976
  *
2977
  * @param integer $max_results The maximum number of links to return. Defaults to 0 = no limit.
2978
+ * @param bool $count_only If true, only the number of found links will be returned, not the links themselves.
2979
  * @return int|blcLink[]
2980
  */
2981
  function get_links_to_check( $max_results = 0, $count_only = false ) {
2984
  $check_threshold = date( 'Y-m-d H:i:s', strtotime( '-' . $this->conf->options['check_threshold'] . ' hours' ) );//phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
2985
  $recheck_threshold = date( 'Y-m-d H:i:s', time() - $this->conf->options['recheck_threshold'] );//phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
2986
 
2987
+ // FB::log('Looking for links to check (threshold : '.$check_threshold.', recheck_threshold : '.$recheck_threshold.')...');
2988
 
2989
+ // Select some links that haven't been checked for a long time or
2990
+ // that are broken and need to be re-checked again. Links that are
2991
+ // marked as "being checked" and have been that way for several minutes
2992
+ // can also be considered broken/buggy, so those will be selected
2993
+ // as well.
2994
 
2995
+ // Only check links that have at least one valid instance (i.e. an instance exists and
2996
+ // it corresponds to one of the currently loaded container/parser types).
2997
  $manager = blcModuleManager::getInstance();
2998
  $loaded_containers = $manager->get_escaped_ids( 'container' );
2999
  $loaded_parsers = $manager->get_escaped_ids( 'parser' );
3000
 
3001
+ // Note : This is a slow query, but AFAIK there is no way to speed it up.
3002
+ // I could put an index on last_check_attempt, but that value is almost
3003
+ // certainly unique for each row so it wouldn't be much better than a full table scan.
3004
  if ( $count_only ) {
3005
  $q = "SELECT COUNT(DISTINCT links.link_id)\n";
3006
  } else {
3039
  $recheck_threshold
3040
  );
3041
 
3042
+ // FB::log($link_q, "Find links to check");
3043
+ // $blclog->debug("Find links to check: \n" . $link_q);
3044
 
3045
+ // If we just need the number of links, retrieve it and return
3046
  if ( $count_only ) {
3047
  return $wpdb->get_var( $link_q );//phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
3048
  }
3049
 
3050
+ // Fetch the link data
3051
  $link_data = $wpdb->get_results( $link_q, ARRAY_A ); //phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
3052
  if ( empty( $link_data ) ) {
3053
  return array();
3054
  }
3055
 
3056
+ // Instantiate blcLink objects for all fetched links
3057
  $links = array();
3058
  foreach ( $link_data as $data ) {
3059
  $links[] = new blcLink( $data );
3155
  * @return void
3156
  */
3157
  function ajax_dashboard_status() {
3158
+ // Just display the full status.
3159
  $this->ajax_full_status();
3160
  }
3161
 
3179
  /**
3180
  * Returns an array with various status information about the plugin. Array key reference:
3181
  * check_threshold - date/time; links checked before this threshold should be checked again.
3182
+ * recheck_threshold - date/time; broken links checked before this threshold should be re-checked.
3183
+ * known_links - the number of detected unique URLs (a misleading name, yes).
3184
+ * known_instances - the number of detected link instances, i.e. actual link elements in posts and other places.
3185
+ * broken_links - the number of detected broken links.
3186
+ * unchecked_links - the number of URLs that need to be checked ASAP; based on check_threshold and recheck_threshold.
3187
+ *
3188
+ * @return array
3189
+ */
3190
  function get_status() {
3191
  $blc_link_query = blcLinkQuery::getInstance();
3192
 
3213
  function ajax_work() {
3214
  check_ajax_referer( 'blc_work' );
3215
 
3216
+ // Run the worker function
3217
  $this->work();
3218
  die();
3219
  }
3229
  }
3230
 
3231
  if ( isset( $_POST['link_id'] ) ) {
3232
+ // Load the link
3233
  $link = new blcLink( intval( $_POST['link_id'] ) );
3234
 
3235
  if ( ! $link->valid() ) {
3236
  printf( __( "Oops, I can't find the link %d", 'broken-link-checker' ), intval( $_POST['link_id'] ) );
3237
  die();
3238
  }
3239
+ // Make it appear "not broken"
3240
  $link->broken = false;
3241
  $link->warning = false;
3242
  $link->false_positive = true;
3248
  $transactionManager = TransactionManager::getInstance();
3249
  $transactionManager->start();
3250
 
3251
+ // Save the changes
3252
  if ( $link->save() ) {
3253
  $transactionManager->commit();
3254
  die( 'OK' );
3276
  }
3277
 
3278
  if ( isset( $_POST['link_id'] ) ) {
3279
+ // Load the link
3280
  $link = new blcLink( intval( $_POST['link_id'] ) );
3281
 
3282
  if ( ! $link->valid() ) {
3286
 
3287
  $link->dismissed = $dismiss;
3288
 
3289
+ // Save the changes
3290
  $link->isOptionLinkChanged = true;
3291
  $transactionManager = TransactionManager::getInstance();
3292
  $transactionManager->start();
3327
  );
3328
  }
3329
 
3330
+ // Load the link
3331
  $link = new blcLink( intval( $_POST['link_id'] ) );
3332
 
3333
  if ( ! $link->valid() ) {
3340
  );
3341
  }
3342
 
3343
+ // Validate the new URL.
3344
  $new_url = stripslashes( $_POST['new_url'] );
3345
  $parsed = @parse_url( $new_url );
3346
  if ( ! $parsed ) {
3354
  }
3355
 
3356
  if ( ! current_user_can( 'unfiltered_html' ) ) {
3357
+ // Disallow potentially dangerous URLs like "javascript:...".
3358
  $protocols = wp_allowed_protocols();
3359
  $good_protocol_url = wp_kses_bad_protocol( $new_url, $protocols );
3360
  if ( $new_url != $good_protocol_url ) {
3373
  $new_text = null;
3374
  }
3375
  if ( ! empty( $new_text ) && ! current_user_can( 'unfiltered_html' ) ) {
3376
+ $new_text = stripslashes( wp_filter_post_kses( addslashes( $new_text ) ) ); // wp_filter_post_kses expects slashed data.
3377
  }
3378
 
3379
  $rez = $link->edit( $new_url, $new_text );
3415
 
3416
  'errors' => array(),
3417
  );
3418
+ // url, status text, status code, link text, editable link text
3419
 
3420
  foreach ( $rez['errors'] as $error ) { /** @var $error WP_Error */
3421
  array_push( $response['errors'], implode( ', ', $error->get_error_messages() ) );
3442
  }
3443
 
3444
  if ( isset( $_POST['link_id'] ) ) {
3445
+ // Load the link
3446
  $link = new blcLink( intval( $_POST['link_id'] ) );
3447
 
3448
  if ( ! $link->valid() ) {
3455
  );
3456
  }
3457
 
3458
+ // Try and unlink it
3459
  $rez = $link->unlink();
3460
 
3461
  if ( false === $rez ) {
3523
  );
3524
  }
3525
 
3526
+ // The actual task is simple; it's error handling that's complicated.
3527
  $result = $link->deredirect();
3528
  if ( is_wp_error( $result ) ) {
3529
  die(
3554
  'errors' => array(),
3555
  );
3556
 
3557
+ // Convert WP_Error's to simple strings.
3558
  if ( ! empty( $result['errors'] ) ) {
3559
  foreach ( $result['errors'] as $error ) { /** @var WP_Error $error */
3560
  $response['errors'][] = $error->get_error_message();
3604
  $transactionManager = TransactionManager::getInstance();
3605
  $transactionManager->start();
3606
 
3607
+ // In case the immediate check fails, this will ensure the link is checked during the next work() run.
3608
  $link->last_check_attempt = 0;
3609
  $link->isOptionLinkChanged = true;
3610
  $link->save();
3611
 
3612
+ // Check the link and save the results.
3613
  $link->check( true );
3614
 
3615
  $transactionManager->commit();
3633
  die( __( "You don't have sufficient privileges to access this information!", 'broken-link-checker' ) );
3634
  }
3635
 
3636
+ // FB::log("Loading link details via AJAX");
3637
 
3638
  if ( isset( $_GET['link_id'] ) ) {
3639
+ // FB::info("Link ID found in GET");
3640
  $link_id = intval( $_GET['link_id'] );
3641
  } elseif ( isset( $_POST['link_id'] ) ) {
3642
+ // FB::info("Link ID found in POST");
3643
  $link_id = intval( $_POST['link_id'] );
3644
  } else {
3645
+ // FB::error('Link ID not specified, you hacking bastard.');
3646
  die( __( 'Error : link ID not specified', 'broken-link-checker' ) );
3647
  }
3648
 
3649
+ // Load the link.
3650
  $link = new blcLink( $link_id );
3651
 
3652
  if ( ! $link->is_new ) {
3653
+ // FB::info($link, 'Link loaded');
3654
  if ( ! class_exists( 'blcTablePrinter' ) ) {
3655
  require dirname( $this->loader ) . '/includes/admin/table-printer.php';
3656
  }
3727
  /** @var wpdb $wpdb */
3728
  global $wpdb;
3729
 
3730
+ // Collect some information that's useful for debugging
3731
  $debug = array();
3732
 
3733
+ // PHP version. Any one is fine as long as WP supports it.
3734
  $debug[ __( 'PHP version', 'broken-link-checker' ) ] = array(
3735
  'state' => 'ok',
3736
  'value' => phpversion(),
3737
  );
3738
 
3739
+ // MySQL version
3740
  $debug[ __( 'MySQL version', 'broken-link-checker' ) ] = array(
3741
  'state' => 'ok',
3742
  'value' => $wpdb->db_version(),
3743
  );
3744
 
3745
+ // CURL presence and version
3746
  if ( function_exists( 'curl_version' ) ) {
3747
  $version = curl_version();
3748
 
3766
  }
3767
  $debug[ __( 'CURL version', 'broken-link-checker' ) ] = $data;
3768
 
3769
+ // Snoopy presence
3770
  if ( class_exists( 'WP_Http' ) || file_exists( ABSPATH . WPINC . '/class-http.php' ) ) {
3771
  $data = array(
3772
  'state' => 'ok',
3773
  'value' => __( 'Installed', 'broken-link-checker' ),
3774
  );
3775
  } else {
3776
+ // No Snoopy? This should never happen, but if it does we *must* have CURL.
3777
  if ( function_exists( 'curl_init' ) ) {
3778
  $data = array(
3779
  'state' => 'ok',
3789
  }
3790
  $debug['Snoopy'] = $data;
3791
 
3792
+ // Safe_mode status
3793
  if ( blcUtility::is_safe_mode() ) {
3794
  $debug['Safe mode'] = array(
3795
  'state' => 'warning',
3803
  );
3804
  }
3805
 
3806
+ // Open_basedir status
3807
  if ( blcUtility::is_open_basedir() ) {
3808
  $debug['open_basedir'] = array(
3809
  'state' => 'warning',
3817
  );
3818
  }
3819
 
3820
+ // Default PHP execution time limit
3821
  $debug['Default PHP execution time limit'] = array(
3822
  'state' => 'ok',
3823
  'value' => sprintf( __( '%s seconds' ), ini_get( 'max_execution_time' ) ),
3824
  );
3825
 
3826
+ // Database character set. Usually it's UTF-8. Setting it to something else can cause problems
3827
+ // unless the site owner really knows what they're doing.
3828
  $charset = $wpdb->get_charset_collate();
3829
  $debug[ __( 'Database character set', 'broken-link-checker' ) ] = array(
3830
  'state' => 'ok',
3831
  'value' => ! empty( $charset ) ? $charset : '-',
3832
  );
3833
 
3834
+ // Resynch flag.
3835
  $debug['Resynch. flag'] = array(
3836
  'state' => 'ok',
3837
  'value' => sprintf( '%d', $this->conf->options['need_resynch'] ? '1 (resynch. required)' : '0 (resynch. not required)' ),
3838
  );
3839
 
3840
+ // Synch records
3841
  $synch_records = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}blc_synch" ) );
3842
  $data = array(
3843
  'state' => 'ok',
3849
  }
3850
  $debug['Synch. records'] = $data;
3851
 
3852
+ // Total links and instances (including invalid ones)
3853
  $all_links = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}blc_links" ) );
3854
  $all_instances = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}blc_instances" ) );
3855
 
3856
+ // Show the number of unparsed containers. Useful for debugging. For performance,
3857
+ // this is only shown when we have no links/instances yet.
3858
  if ( ( 0 == $all_links ) && ( 0 == $all_instances ) ) {
3859
  $unparsed_items = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}blc_synch WHERE synched=0" ) );
3860
  $debug['Unparsed items'] = array(
3863
  );
3864
  }
3865
 
3866
+ // Links & instances
3867
  if ( ( $all_links > 0 ) && ( $all_instances > 0 ) ) {
3868
  $debug['Link records'] = array(
3869
  'state' => 'ok',
3876
  );
3877
  }
3878
 
3879
+ // Email notifications.
3880
  if ( $this->conf->options['last_notification_sent'] ) {
3881
  $notificationDebug = array(
3882
  'value' => date( 'Y-m-d H:i:s T', $this->conf->options['last_notification_sent'] ), //phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
3903
  );
3904
  }
3905
 
3906
+ // Installation log
3907
  $logger = new blcCachedOptionLogger( 'blc_installation_log' );
3908
  $installation_log = $logger->get_messages();
3909
  if ( ! empty( $installation_log ) ) {
3929
 
3930
  $send_authors_notifications = apply_filters( 'blc_allow_send_author_email_notification', $this->conf->options['send_authors_email_notifications'] );
3931
 
3932
+ if ( ! ( $send_notification || $send_authors_notifications ) ) {
3933
  return;
3934
  }
3935
 
3936
+ // Find links that have been detected as broken since the last sent notification.
3937
  $last_notification = date( 'Y-m-d H:i:s', $this->conf->options['last_notification_sent'] );//phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
3938
  $where = $wpdb->prepare( '( first_failure >= %s )', $last_notification );
3939
 
3952
  return;
3953
  }
3954
 
3955
+ // Send the admin/maintainer an email notification.
3956
  $email = $this->conf->get( 'notification_email_address' );
3957
  if ( empty( $email ) ) {
3958
+ // Default to the admin email.
3959
  $email = get_option( 'admin_email' );
3960
  }
3961
  if ( $this->conf->options['send_email_notifications'] && ! empty( $email ) ) {
3962
  $this->send_admin_notification( $links, $email );
3963
  }
3964
 
3965
+ // Send notifications to post authors
3966
  if ( $this->conf->options['send_authors_email_notifications'] ) {
3967
  $this->send_authors_notifications( $links );
3968
  }
3972
  }
3973
 
3974
  function send_admin_notification( $links, $email ) {
3975
+ // Prepare email message
3976
  $subject = sprintf(
3977
  __( '[%s] Broken links detected', 'broken-link-checker' ),
3978
  html_entity_decode( get_option( 'blogname' ), ENT_QUOTES )
4024
 
4025
  $result .= "<p>$line</p>";
4026
 
4027
+ // Show up to $max_displayed_links broken link instances right in the email.
4028
  $displayed = 0;
4029
  foreach ( $instances as $instance ) { /* @var blcLinkInstance $instance */
4030
  $pieces = array(
4042
  }
4043
  }
4044
 
4045
+ // Add a link to the "Broken Links" tab.
4046
  if ( $add_admin_link ) {
4047
  $result .= __( 'You can see all broken links here:', 'broken-link-checker' ) . '<br>';
4048
  $result .= sprintf( '<a href="%1$s">%1$s</a>', admin_url( 'tools.php?page=view-broken-links' ) );
4052
  }
4053
 
4054
  function send_html_email( $email_address, $subject, $body ) {
4055
+ // Need to override the default 'text/plain' content type to send a HTML email.
4056
  add_filter( 'wp_mail_content_type', array( $this, 'override_mail_content_type' ) );
4057
 
4058
+ // Let auto-responders and similar software know this is an auto-generated email
4059
+ // that they shouldn't respond to.
4060
  $headers = array( 'Auto-Submitted: auto-generated' );
4061
 
4062
  $success = wp_mail( $email_address, $subject, $body, $headers );
4063
 
4064
+ // Remove the override so that it doesn't interfere with other plugins that might
4065
+ // want to send normal plaintext emails.
4066
  remove_filter( 'wp_mail_content_type', array( $this, 'override_mail_content_type' ) );
4067
 
4068
  $this->conf->options['last_email'] = array(
4150
  */
4151
  function setup_cron_events() {
4152
 
4153
+ // Link monitor
4154
  if ( $this->conf->options['run_via_cron'] ) {
4155
  if ( ! wp_next_scheduled( 'blc_cron_check_links' ) ) {
4156
  wp_schedule_event( time(), '10min', 'blc_cron_check_links' );
4159
  wp_clear_scheduled_hook( 'blc_cron_check_links' );
4160
  }
4161
 
4162
+ // Email notifications about broken links
4163
  if ( $this->conf->options['send_email_notifications'] || $this->conf->options['send_authors_email_notifications'] ) {
4164
  if ( ! wp_next_scheduled( 'blc_cron_email_notifications' ) ) {
4165
  wp_schedule_event( time(), $this->conf->options['notification_schedule'], 'blc_cron_email_notifications' );
4168
  wp_clear_scheduled_hook( 'blc_cron_email_notifications' );
4169
  }
4170
 
4171
+ // Run database maintenance every two weeks or so
4172
  if ( ! wp_next_scheduled( 'blc_cron_database_maintenance' ) ) {
4173
  wp_schedule_event( time(), 'daily', 'blc_cron_database_maintenance' );
4174
  }
4185
 
4186
  /**
4187
  * Clear blc log file
4188
+ *
4189
  * @return void
4190
  */
4191
  function clear_log_file() {
4192
  $log_file = $this->conf->options['log_file'];
4193
 
4194
+ // clear log file
4195
  if ( is_writable( $log_file ) && is_file( $log_file ) ) {
4196
  $handle = fopen( $log_file, 'w' );
4197
  fclose( $handle );
4211
 
4212
  $last_modified_gmt = isset( $postarr['blc_post_modified_gmt'] ) ? $postarr['blc_post_modified_gmt'] : '';
4213
 
 
4214
  // if is not enabled bail!
4215
+ if ( ! $this->conf->options['blc_post_modified'] ) {
4216
  return $data;
4217
  }
4218
 
 
4219
  // only restore the post modified for BLC links
4220
+ if ( empty( $last_modified ) || empty( $last_modified_gmt ) ) {
4221
  return $data;
4222
  }
4223
 
4250
  return 'blc-log.txt';
4251
  }
4252
 
4253
+ }//end class
4254
 
4255
  } // if class_exists...
core/init.php CHANGED
@@ -102,8 +102,6 @@ if ( defined( 'BLC_ACTIVE' ) ) {
102
  'installation_complete' => false,
103
  'installation_flag_cleared_on' => 0,
104
  'installation_flag_set_on' => 0,
105
- 'user_has_donated' => false, // Whether the user has donated to the plugin.
106
- 'donation_flag_fixed' => false,
107
  'show_link_actions' => array( 'blc-deredirect-action' => false ), //Visible link actions.
108
  'youtube_api_key' => '',
109
  'blc_post_modified' => '',
102
  'installation_complete' => false,
103
  'installation_flag_cleared_on' => 0,
104
  'installation_flag_set_on' => 0,
 
 
105
  'show_link_actions' => array( 'blc-deredirect-action' => false ), //Visible link actions.
106
  'youtube_api_key' => '',
107
  'blc_post_modified' => '',
css/options-page.css CHANGED
@@ -1,243 +1,234 @@
1
- /*
2
- Sidebar
3
- */
4
-
5
- #blc-sidebar {
6
- clear: right;
7
- float: right;
8
- position: relative;
9
- width: 255px;
10
- }
11
-
12
- #blc-admin-content {
13
- clear: left;
14
- float: left;
15
- margin-right: -275px;
16
- width: 100%;
17
- }
18
-
19
- #blc-admin-content > * {
20
- margin-right: 267px;
21
- }
22
-
23
- #advertising {
24
- border-color: green !important;
25
- border-width: 2px;
26
- }
27
-
28
- #advertising h3 {
29
- color: green;
30
- }
31
-
32
- #advertising .inside {
33
- text-align: left;
34
- }
35
-
36
- .ws-ame-ad-copy {
37
- font-size: 1.2em;
38
- font-style: italic;
39
- }
40
- .ws-ame-ad-link {
41
- font-size: 1.1em;
42
- font-weight: bold;
43
- }
44
-
45
- #themefuse-ad .inside,
46
- #managewp-ad .inside,
47
- #embedplus-ad .inside
48
- {
49
- padding: 2px 0 0 0;
50
- margin: 0;
51
- text-align: center;
52
- }
53
-
54
- #embedplus-ad .inside {
55
- padding-top: 0;
56
- }
57
-
58
- #embedplus-ad {
59
- border-style: none;
60
- background-color: transparent;
61
- box-shadow: none;
62
- }
63
-
64
-
65
- #link_checker_options .form-table th {
66
- width: 25%;
67
- min-width: 110px;
68
- max-width: 200px;
69
- }
70
-
71
- #blc-debug-info-toggle {
72
- font-size: smaller;
73
- }
74
-
75
- .blc-debug-item-ok {
76
- background-color: #d7ffa2;
77
- }
78
- .blc-debug-item-warning {
79
- background-color: #fcffa2;
80
- }
81
- .blc-debug-item-error {
82
- background-color: #ffc4c4;
83
- }
84
-
85
- #blc-debug-info {
86
- display: none;
87
-
88
- text-align: left;
89
-
90
- border-width: 1px;
91
- border-color: gray;
92
- border-style: solid;
93
-
94
- border-spacing: 0;
95
- border-collapse: collapse;
96
- }
97
-
98
- #blc-debug-info th, #blc-debug-info td {
99
- padding: 6px;
100
- font-weight: normal;
101
- text-shadow: none;
102
-
103
- border-width: 1px ;
104
- border-color: silver;
105
- border-style: solid;
106
-
107
- border-collapse: collapse;
108
- }
109
-
110
- .blc-toggle-link {
111
- /*padding-left: 20px; */
112
- }
113
-
114
- .module-container {
115
- margin: 1em 0;
116
- font-size: 12px;
117
- line-height: 140%;
118
- }
119
-
120
- .module-extra-settings {
121
- margin-top: 0.5em;
122
- }
123
-
124
- .form-table td p:first-child, .form-table td .module-container:first-child {
125
- margin-top: 0.2em;
126
- }
127
-
128
- .module-requires-pro {
129
- color: gray;
130
- }
131
-
132
- #blc-tabs {
133
- margin-top: 0.5em;
134
- }
135
-
136
- /* Tab navigation */
137
- ul.ui-tabs-nav {
138
- margin-bottom: -1px;
139
- height: 31px;
140
- padding-left: 1.5em;
141
-
142
- overflow: hidden;
143
- white-space: nowrap;
144
- padding-right: 3.5em;
145
- }
146
-
147
- ul.ui-tabs-nav li {
148
- display: inline-block;
149
- height: 29px;
150
- margin: 0 0.5em 0 0;
151
-
152
- border: 1px solid #DFDFDF;
153
-
154
- background: none repeat scroll 0 0 #F4F4F4;
155
-
156
- border-top-right-radius: 6px;
157
- border-top-left-radius: 6px;
158
-
159
- -moz-border-radius-topright: 6px;
160
- -moz-border-radius-topleft: 6px;
161
-
162
- -webkit-border-top-right-radius: 6px;
163
- -webkit-border-top-left-radius: 6px;
164
-
165
- font-weight: bold;
166
- text-shadow: 0 1px 0 #FFFFFF;
167
-
168
- max-width: 20%;
169
- overflow: hidden;
170
- text-align: center;
171
- }
172
-
173
- #tab-button-which {
174
- max-width: 25%;
175
- }
176
-
177
- ul.ui-tabs-nav li.ui-tabs-selected,
178
- ul.ui-tabs-nav li.ui-tabs-active
179
- {
180
- background: white;
181
- color: black;
182
- border-bottom-color: white;
183
- }
184
-
185
- ul.ui-tabs-nav li a {
186
- display: inline-block;
187
- height: 17px;
188
- text-decoration: none;
189
- color: #C1C1C1;
190
- padding: 0.5em 1em 0.6em 1em;
191
- }
192
-
193
- ul.ui-tabs-nav li a:focus {
194
- outline: none;
195
- }
196
-
197
- ul.ui-tabs-nav li.ui-tabs-selected a,
198
- ul.ui-tabs-nav li.ui-tabs-active a {
199
- color: black;
200
- outline: none;
201
- }
202
-
203
- /* Tab panels */
204
-
205
- .ui-tabs .blc-section {
206
- border: 1px solid #DFDFDF;
207
- border-top-width: 1px;
208
-
209
- padding-bottom: 1em;
210
-
211
- background: white;
212
-
213
- border-radius: 6px;
214
- -moz-border-radius: 6px;
215
- -webkit-border-radius: 6px;
216
-
217
- border-top-right-radius: 6px;
218
- border-bottom-right-radius: 6px;
219
- border-bottom-left-radius: 6px;
220
-
221
- -moz-border-radius-topright: 6px;
222
- -moz-border-radius-bottomright: 6px;
223
- -moz-border-radius-bottomleft: 6px;
224
-
225
- -webkit-border-top-right-radius: 6px;
226
- -webkit-border-bottom-right-radius: 6px;
227
- -webkit-border-bottom-left-radius: 6px;
228
- }
229
-
230
- .blc-section table.form-table th {
231
- padding-left: 10px;
232
- }
233
-
234
- /* Right sidebar */
235
-
236
- #blc-settings-wrap .hndle {
237
- cursor: default;
238
- }
239
-
240
- /* Miscellaneous */
241
- td:target, label:target {
242
- background: #ffffaa;
243
- }
1
+ /*
2
+ Sidebar
3
+ */
4
+ #blc-admin-content {
5
+ clear: left;
6
+ float: left;
7
+ margin-right: -275px;
8
+ width: 100%;
9
+ }
10
+
11
+ #blc-admin-content > * {
12
+ margin-right: 267px;
13
+ }
14
+
15
+ #advertising {
16
+ border-color: green !important;
17
+ border-width: 2px;
18
+ }
19
+
20
+ #advertising h3 {
21
+ color: green;
22
+ }
23
+
24
+ #advertising .inside {
25
+ text-align: left;
26
+ }
27
+
28
+ .ws-ame-ad-copy {
29
+ font-size: 1.2em;
30
+ font-style: italic;
31
+ }
32
+ .ws-ame-ad-link {
33
+ font-size: 1.1em;
34
+ font-weight: bold;
35
+ }
36
+
37
+ #themefuse-ad .inside,
38
+ #embedplus-ad .inside
39
+ {
40
+ padding: 2px 0 0 0;
41
+ margin: 0;
42
+ text-align: center;
43
+ }
44
+
45
+ #embedplus-ad .inside {
46
+ padding-top: 0;
47
+ }
48
+
49
+ #embedplus-ad {
50
+ border-style: none;
51
+ background-color: transparent;
52
+ box-shadow: none;
53
+ }
54
+
55
+
56
+ #link_checker_options .form-table th {
57
+ width: 25%;
58
+ min-width: 110px;
59
+ max-width: 200px;
60
+ }
61
+
62
+ #blc-debug-info-toggle {
63
+ font-size: smaller;
64
+ }
65
+
66
+ .blc-debug-item-ok {
67
+ background-color: #d7ffa2;
68
+ }
69
+ .blc-debug-item-warning {
70
+ background-color: #fcffa2;
71
+ }
72
+ .blc-debug-item-error {
73
+ background-color: #ffc4c4;
74
+ }
75
+
76
+ #blc-debug-info {
77
+ display: none;
78
+
79
+ text-align: left;
80
+
81
+ border-width: 1px;
82
+ border-color: gray;
83
+ border-style: solid;
84
+
85
+ border-spacing: 0;
86
+ border-collapse: collapse;
87
+ }
88
+
89
+ #blc-debug-info th, #blc-debug-info td {
90
+ padding: 6px;
91
+ font-weight: normal;
92
+ text-shadow: none;
93
+
94
+ border-width: 1px ;
95
+ border-color: silver;
96
+ border-style: solid;
97
+
98
+ border-collapse: collapse;
99
+ }
100
+
101
+ .blc-toggle-link {
102
+ /*padding-left: 20px; */
103
+ }
104
+
105
+ .module-container {
106
+ margin: 1em 0;
107
+ font-size: 12px;
108
+ line-height: 140%;
109
+ }
110
+
111
+ .module-extra-settings {
112
+ margin-top: 0.5em;
113
+ }
114
+
115
+ .form-table td p:first-child, .form-table td .module-container:first-child {
116
+ margin-top: 0.2em;
117
+ }
118
+
119
+ .module-requires-pro {
120
+ color: gray;
121
+ }
122
+
123
+ #blc-tabs {
124
+ margin-top: 0.5em;
125
+ }
126
+
127
+ /* Tab navigation */
128
+ ul.ui-tabs-nav {
129
+ margin-bottom: -1px;
130
+ height: 31px;
131
+ padding-left: 1.5em;
132
+
133
+ overflow: hidden;
134
+ white-space: nowrap;
135
+ padding-right: 3.5em;
136
+ }
137
+
138
+ ul.ui-tabs-nav li {
139
+ display: inline-block;
140
+ height: 29px;
141
+ margin: 0 0.5em 0 0;
142
+
143
+ border: 1px solid #DFDFDF;
144
+
145
+ background: none repeat scroll 0 0 #F4F4F4;
146
+
147
+ border-top-right-radius: 6px;
148
+ border-top-left-radius: 6px;
149
+
150
+ -moz-border-radius-topright: 6px;
151
+ -moz-border-radius-topleft: 6px;
152
+
153
+ -webkit-border-top-right-radius: 6px;
154
+ -webkit-border-top-left-radius: 6px;
155
+
156
+ font-weight: bold;
157
+ text-shadow: 0 1px 0 #FFFFFF;
158
+
159
+ max-width: 20%;
160
+ overflow: hidden;
161
+ text-align: center;
162
+ }
163
+
164
+ #tab-button-which {
165
+ max-width: 25%;
166
+ }
167
+
168
+ ul.ui-tabs-nav li.ui-tabs-selected,
169
+ ul.ui-tabs-nav li.ui-tabs-active
170
+ {
171
+ background: white;
172
+ color: black;
173
+ border-bottom-color: white;
174
+ }
175
+
176
+ ul.ui-tabs-nav li a {
177
+ display: inline-block;
178
+ height: 17px;
179
+ text-decoration: none;
180
+ color: #C1C1C1;
181
+ padding: 0.5em 1em 0.6em 1em;
182
+ }
183
+
184
+ ul.ui-tabs-nav li a:focus {
185
+ outline: none;
186
+ }
187
+
188
+ ul.ui-tabs-nav li.ui-tabs-selected a,
189
+ ul.ui-tabs-nav li.ui-tabs-active a {
190
+ color: black;
191
+ outline: none;
192
+ }
193
+
194
+ /* Tab panels */
195
+
196
+ .ui-tabs .blc-section {
197
+ border: 1px solid #DFDFDF;
198
+ border-top-width: 1px;
199
+
200
+ padding-bottom: 1em;
201
+
202
+ background: white;
203
+
204
+ border-radius: 6px;
205
+ -moz-border-radius: 6px;
206
+ -webkit-border-radius: 6px;
207
+
208
+ border-top-right-radius: 6px;
209
+ border-bottom-right-radius: 6px;
210
+ border-bottom-left-radius: 6px;
211
+
212
+ -moz-border-radius-topright: 6px;
213
+ -moz-border-radius-bottomright: 6px;
214
+ -moz-border-radius-bottomleft: 6px;
215
+
216
+ -webkit-border-top-right-radius: 6px;
217
+ -webkit-border-bottom-right-radius: 6px;
218
+ -webkit-border-bottom-left-radius: 6px;
219
+ }
220
+
221
+ .blc-section table.form-table th {
222
+ padding-left: 10px;
223
+ }
224
+
225
+ /* Right sidebar */
226
+
227
+ #blc-settings-wrap .hndle {
228
+ cursor: default;
229
+ }
230
+
231
+ /* Miscellaneous */
232
+ td:target, label:target {
233
+ background: #ffffaa;
234
+ }
 
 
 
 
 
 
 
 
 
images/mwp250_2.png DELETED
Binary file
includes/admin/sidebar.php DELETED
@@ -1,14 +0,0 @@
1
- <!-- Advertising -->
2
- <?php
3
- $configuration = blc_get_configuration();
4
- if ( ! $configuration->get( 'user_has_donated' ) ) :
5
- ?>
6
- <div id="managewp-ad" class="postbox">
7
- <div class="inside">
8
- <a href="http://managewp.com/?utm_source=broken_link_checker&utm_medium=Banner&utm_content=mwp250_2&utm_campaign=Plugins" title="ManageWP">
9
- <img src="<?php echo plugins_url( 'images/mwp250_2.png', BLC_PLUGIN_FILE ); ?>" width="250" height="250" alt="ManageWP">
10
- </a>
11
- </div>
12
- </div>
13
- <?php
14
- endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/broken-link-checker.pot CHANGED
@@ -1,11 +1,12 @@
1
- # Copyright (C) 2020 Broken Link Checker 1.11.14
2
- # This file is distributed under the same license as the Broken Link Checker 1.11.14 package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Broken Link Checker 1.11.14\n"
6
  "MIME-Version: 1.0\n"
7
  "Content-Type: text/plain; charset=UTF-8\n"
8
  "Content-Transfer-Encoding: 8bit\n"
 
9
  "X-Poedit-Basepath: ..\n"
10
  "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n"
11
  "X-Poedit-SearchPath-0: .\n"
@@ -13,728 +14,741 @@ msgstr ""
13
  "X-Poedit-SourceCharset: UTF-8\n"
14
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
 
16
- #: core/core.php:211, includes/admin/links-page-js.php:45
17
  msgid "Loading..."
18
  msgstr ""
19
 
20
- #: core/core.php:235, includes/admin/options-page-js.php:18
21
  msgid "[ Network error ]"
22
  msgstr ""
23
 
24
- #: core/core.php:278
25
  msgid "Automatically expand the widget if broken links have been detected"
26
  msgstr ""
27
 
28
- #: core/core.php:374
29
  msgid "Link Checker Settings"
30
  msgstr ""
31
 
32
- #: core/core.php:375
33
  msgid "Link Checker"
34
  msgstr ""
35
 
36
- #: core/core.php:381, includes/link-query.php:37
37
  msgid "Broken Links"
38
  msgstr ""
39
 
40
- #: core/core.php:397
41
  msgid "View Broken Links"
42
  msgstr ""
43
 
44
- #: core/core.php:413
45
  msgid "Go to Broken Links"
46
  msgstr ""
47
 
48
- #: core/core.php:431
49
  msgid "Settings"
50
  msgstr ""
51
 
52
- #: core/core.php:469, includes/admin/table-printer.php:292, includes/admin/table-printer.php:710
53
  msgid "Edit URL"
54
  msgstr ""
55
 
56
- #: core/core.php:470, includes/admin/links-page-js.php:716, includes/admin/table-printer.php:297, includes/admin/table-printer.php:713
57
  msgid "Unlink"
58
  msgstr ""
59
 
60
- #: core/core.php:471, includes/admin/links-page-js.php:111, includes/admin/table-printer.php:719
61
  msgid "Not broken"
62
  msgstr ""
63
 
64
- #: core/core.php:472, includes/admin/table-printer.php:296, includes/admin/table-printer.php:727
65
  msgid "Dismiss"
66
  msgstr ""
67
 
68
- #: core/core.php:473, includes/admin/table-printer.php:293, includes/admin/table-printer.php:739
69
  msgid "Recheck"
70
  msgstr ""
71
 
72
- #: core/core.php:474, includes/admin/table-printer.php:747
73
  msgctxt "link action; replace one redirect with a direct link"
74
  msgid "Fix redirect"
75
  msgstr ""
76
 
77
- #: core/core.php:750
78
  msgid "Settings saved."
79
  msgstr ""
80
 
81
- #: core/core.php:756
82
- msgid "Thank you for your donation!"
83
- msgstr ""
84
-
85
- #: core/core.php:764
86
  msgid "Complete site recheck started."
87
  msgstr ""
88
 
89
- #: core/core.php:787
90
  msgid "General"
91
  msgstr ""
92
 
93
- #: core/core.php:788
94
  msgid "Look For Links In"
95
  msgstr ""
96
 
97
- #: core/core.php:789
98
  msgid "Which Links To Check"
99
  msgstr ""
100
 
101
- #: core/core.php:790
102
  msgid "Protocols & APIs"
103
  msgstr ""
104
 
105
- #: core/core.php:791
106
  msgid "Advanced"
107
  msgstr ""
108
 
109
- #: core/core.php:806
110
  msgid "Broken Link Checker Options"
111
  msgstr ""
112
 
113
- #: core/core.php:850, includes/admin/table-printer.php:215
114
  msgid "Status"
115
  msgstr ""
116
 
117
- #: core/core.php:852, includes/admin/options-page-js.php:56
118
  msgid "Show debug info"
119
  msgstr ""
120
 
121
- #: core/core.php:880
122
  msgid "Check each link"
123
  msgstr ""
124
 
125
- #: core/core.php:885
126
  msgid "Every %s hours"
127
  msgstr ""
128
 
129
- #: core/core.php:894
130
  msgid "Existing links will be checked this often. New links will usually be checked ASAP."
131
  msgstr ""
132
 
133
- #: core/core.php:901
134
  msgid "E-mail notifications"
135
  msgstr ""
136
 
137
- #: core/core.php:911
138
  msgid "Send me e-mail notifications about newly detected broken links"
139
  msgstr ""
140
 
141
- #: core/core.php:923
142
  msgid "Send authors e-mail notifications about broken links in their posts"
143
  msgstr ""
144
 
145
- #: core/core.php:930
146
  msgid "Notification e-mail address"
147
  msgstr ""
148
 
149
- #: core/core.php:942
150
  msgid "Leave empty to use the e-mail address specified in Settings &rarr; General."
151
  msgstr ""
152
 
153
- #: core/core.php:949
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  msgid "Link tweaks"
155
  msgstr ""
156
 
157
- #: core/core.php:959
158
  msgid "Apply custom formatting to broken links"
159
  msgstr ""
160
 
161
- #: core/core.php:964, core/core.php:1007
162
  msgid "Edit CSS"
163
  msgstr ""
164
 
165
- #: core/core.php:986
166
  msgid "Example : Lorem ipsum <a %s>broken link</a>, dolor sit amet."
167
  msgstr ""
168
 
169
- #: core/core.php:989, core/core.php:1033
170
  msgid "Click \"Save Changes\" to update example output."
171
  msgstr ""
172
 
173
- #: core/core.php:1002
174
  msgid "Apply custom formatting to removed links"
175
  msgstr ""
176
 
177
- #: core/core.php:1030
178
  msgid "Example : Lorem ipsum <span %s>removed link</span>, dolor sit amet."
179
  msgstr ""
180
 
181
- #: core/core.php:1047
182
  msgid "Stop search engines from following broken links"
183
  msgstr ""
184
 
185
- #: core/core.php:1053
186
  msgctxt "\"Link tweaks\" settings"
187
  msgid "These settings only apply to the content of posts, not comments or custom fields."
188
  msgstr ""
189
 
190
- #: core/core.php:1064
191
  msgctxt "settings page"
192
  msgid "Suggestions"
193
  msgstr ""
194
 
195
- #: core/core.php:1069
196
  msgid "Suggest alternatives to broken links"
197
  msgstr ""
198
 
199
- #: core/core.php:1075
200
  msgctxt "settings page"
201
  msgid "Warnings"
202
  msgstr ""
203
 
204
- #: core/core.php:1080
205
  msgid "Show uncertain or minor problems as \"warnings\" instead of \"broken\""
206
  msgstr ""
207
 
208
- #: core/core.php:1084
209
  msgid "Turning off this option will make the plugin report all problems as broken links."
210
  msgstr ""
211
 
212
- #: core/core.php:1091
213
  msgid "YouTube API Key"
214
  msgstr ""
215
 
216
- #: core/core.php:1103
217
  msgid "Use your own %1$sapi key%2$s for checking youtube links."
218
  msgstr ""
219
 
220
- #: core/core.php:1110
221
  msgid "Post Modified Date"
222
  msgstr ""
223
 
224
- #: core/core.php:1115
225
  msgid "Disable post modified date change when link is edited"
226
  msgstr ""
227
 
228
- #: core/core.php:1130
229
  msgid "Look for links in"
230
  msgstr ""
231
 
232
- #: core/core.php:1146
233
  msgid "Post statuses"
234
  msgstr ""
235
 
236
- #: core/core.php:1179
237
  msgid "Link types"
238
  msgstr ""
239
 
240
- #: core/core.php:1185
241
  msgid "Error : All link parsers missing!"
242
  msgstr ""
243
 
244
- #: core/core.php:1192
245
  msgid "Exclusion list"
246
  msgstr ""
247
 
248
- #: core/core.php:1193
249
  msgid "Don't check links where the URL contains any of these words (one per line) :"
250
  msgstr ""
251
 
252
- #: core/core.php:1214
253
  msgid "Check links using"
254
  msgstr ""
255
 
256
- #: core/core.php:1233, includes/links.php:1033
257
  msgid "Timeout"
258
  msgstr ""
259
 
260
- #: core/core.php:1239, core/core.php:1334, core/core.php:3800
261
  msgid "%s seconds"
262
  msgstr ""
263
 
264
- #: core/core.php:1248
265
  msgid "Links that take longer than this to load will be marked as broken."
266
  msgstr ""
267
 
268
- #: core/core.php:1255
269
  msgid "Link monitor"
270
  msgstr ""
271
 
272
- #: core/core.php:1267
273
  msgid "Run continuously while the Dashboard is open"
274
  msgstr ""
275
 
276
- #: core/core.php:1279
277
  msgid "Run hourly in the background"
278
  msgstr ""
279
 
280
- #: core/core.php:1287
281
  msgid "Show the dashboard widget for"
282
  msgstr ""
283
 
284
- #: core/core.php:1292
285
  msgctxt "dashboard widget visibility"
286
  msgid "Administrator"
287
  msgstr ""
288
 
289
- #: core/core.php:1293
290
  msgctxt "dashboard widget visibility"
291
  msgid "Editor and above"
292
  msgstr ""
293
 
294
- #: core/core.php:1294
295
  msgctxt "dashboard widget visibility"
296
  msgid "Nobody (disables the widget)"
297
  msgstr ""
298
 
299
- #: core/core.php:1310
300
  msgctxt "settings page"
301
  msgid "Show link actions"
302
  msgstr ""
303
 
304
- #: core/core.php:1328
305
  msgid "Max. execution time"
306
  msgstr ""
307
 
308
- #: core/core.php:1345
309
  msgid "The plugin works by periodically launching a background job that parses your posts for links, checks the discovered URLs, and performs other time-consuming tasks. Here you can set for how long, at most, the link monitor may run each time before stopping."
310
  msgstr ""
311
 
312
- #: core/core.php:1354
313
  msgid "Server load limit"
314
  msgstr ""
315
 
316
- #: core/core.php:1369
317
- msgid "Current load : %s"
318
  msgstr ""
319
 
320
- #: core/core.php:1374
321
- msgid "Link checking will be suspended if the average <a href=\"%s\">server load</a> rises above this number. Leave this field blank to disable load limiting."
322
  msgstr ""
323
 
324
- #: core/core.php:1383
325
- msgid "Not available"
326
  msgstr ""
327
 
328
- #: core/core.php:1385
329
- msgid "Load limiting only works on Linux-like systems where <code>/proc/loadavg</code> is present and accessible."
330
  msgstr ""
331
 
332
- #: core/core.php:1393
333
  msgid "Target resource usage"
334
  msgstr ""
335
 
336
- #: core/core.php:1413
337
  msgid "Logging"
338
  msgstr ""
339
 
340
- #: core/core.php:1419
341
  msgid "Enable logging"
342
  msgstr ""
343
 
344
- #: core/core.php:1426
345
  msgid "Log file location"
346
  msgstr ""
347
 
348
- #: core/core.php:1435
349
  msgctxt "log file location"
350
  msgid "Default"
351
  msgstr ""
352
 
353
- #: core/core.php:1451
354
  msgctxt "log file location"
355
  msgid "Custom"
356
  msgstr ""
357
 
358
- #: core/core.php:1461
359
  msgid "Log file clear schedule"
360
  msgstr ""
361
 
362
- #: core/core.php:1467, includes/admin/table-printer.php:548
363
  msgid "Never"
364
  msgstr ""
365
 
366
- #: core/core.php:1488
367
  msgid "Forced recheck"
368
  msgstr ""
369
 
370
- #: core/core.php:1491
371
  msgid "Re-check all pages"
372
  msgstr ""
373
 
374
- #: core/core.php:1496
375
  msgid "The \"Nuclear Option\". Click this button to make the plugin empty its link database and recheck the entire site from scratch."
376
  msgstr ""
377
 
378
- #: core/core.php:1508
379
  msgid "Save Changes"
380
  msgstr ""
381
 
382
- #: core/core.php:1559
383
  msgid "Configure"
384
  msgstr ""
385
 
386
- #: core/core.php:1641
387
  msgid "Enter the names of custom fields you want to check (one per line). If a field contains HTML code, prefix its name with <code>html:</code>. For example, <code>html:field_name</code>."
388
  msgstr ""
389
 
390
- #: core/core.php:1655
391
  msgid "Enter the keys of acf fields you want to check (one per line). If a field contains HTML code, prefix its name with <code>html:</code>. For example, <code>html:field_586a3eaa4091b</code>."
392
  msgstr ""
393
 
394
- #: core/core.php:1786, core/core.php:1872, core/core.php:1904
395
  msgid "Database error : %s"
396
  msgstr ""
397
 
398
- #: core/core.php:1853
399
- msgid "You must enter a filter name!"
400
  msgstr ""
401
 
402
- #: core/core.php:1857
403
  msgid "Invalid search query."
404
  msgstr ""
405
 
406
- #: core/core.php:1867
407
- msgid "Filter \"%s\" created"
 
 
 
 
408
  msgstr ""
409
 
410
- #: core/core.php:1894
411
  msgid "Filter ID not specified."
412
  msgstr ""
413
 
414
- #: core/core.php:1901
415
- msgid "Filter deleted"
416
  msgstr ""
417
 
418
- #: core/core.php:1950
419
  msgid "Replaced %d redirect with a direct link"
420
  msgid_plural "Replaced %d redirects with direct links"
421
  msgstr[0] ""
422
  msgstr[1] ""
423
 
424
- #: core/core.php:1961
425
  msgid "Failed to fix %d redirect"
426
  msgid_plural "Failed to fix %d redirects"
427
  msgstr[0] ""
428
  msgstr[1] ""
429
 
430
- #: core/core.php:1972
431
- msgid "None of the selected links are redirects!"
432
- msgstr ""
433
-
434
- #: core/core.php:2052
435
  msgid "%d link updated."
436
  msgid_plural "%d links updated."
437
  msgstr[0] ""
438
  msgstr[1] ""
439
 
440
- #: core/core.php:2063
441
  msgid "Failed to update %d link."
442
  msgid_plural "Failed to update %d links."
443
  msgstr[0] ""
444
  msgstr[1] ""
445
 
446
- #: core/core.php:2154
447
  msgid "%d link removed"
448
  msgid_plural "%d links removed"
449
  msgstr[0] ""
450
  msgstr[1] ""
451
 
452
- #: core/core.php:2165
453
  msgid "Failed to remove %d link"
454
  msgid_plural "Failed to remove %d links"
455
  msgstr[0] ""
456
  msgstr[1] ""
457
 
458
- #: core/core.php:2275
459
  msgid "%d item was skipped because it can't be moved to the Trash. You need to delete it manually."
460
  msgid_plural "%d items were skipped because they can't be moved to the Trash. You need to delete them manually."
461
  msgstr[0] ""
462
  msgstr[1] ""
463
 
464
- #: core/core.php:2297
465
  msgid "Didn't find anything to delete!"
466
  msgstr ""
467
 
468
- #: core/core.php:2335
469
  msgid "%d link scheduled for rechecking"
470
  msgid_plural "%d links scheduled for rechecking"
471
  msgstr[0] ""
472
  msgstr[1] ""
473
 
474
- #: core/core.php:2384, core/core.php:3221
475
  msgid "This link was manually marked as working by the user."
476
  msgstr ""
477
 
478
- #: core/core.php:2392, core/core.php:2455
479
  msgid "Couldn't modify link %d"
480
  msgstr ""
481
 
482
- #: core/core.php:2403
483
  msgid "%d link marked as not broken"
484
  msgid_plural "%d links marked as not broken"
485
  msgstr[0] ""
486
  msgstr[1] ""
487
 
488
- #: core/core.php:2466
489
  msgid "%d link dismissed"
490
  msgid_plural "%d links dismissed"
491
  msgstr[0] ""
492
  msgstr[1] ""
493
 
494
- #: core/core.php:2523
495
  msgid "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."
496
  msgstr ""
497
 
498
- #: core/core.php:2528
499
  msgctxt "admin notice under Tools - Broken links - Warnings"
500
  msgid "Hide notice"
501
  msgstr ""
502
 
503
- #: core/core.php:2534
504
  msgctxt "a link from the admin notice under Tools - Broken links - Warnings"
505
  msgid "Change warning settings"
506
  msgstr ""
507
 
508
- #: core/core.php:2559
509
  msgid "Table columns"
510
  msgstr ""
511
 
512
- #: core/core.php:2578
513
  msgid "Show on screen"
514
  msgstr ""
515
 
516
- #: core/core.php:2585
517
  msgid "links"
518
  msgstr ""
519
 
520
- #: core/core.php:2586, includes/admin/table-printer.php:175
521
  msgid "Apply"
522
  msgstr ""
523
 
524
- #: core/core.php:2590
525
  msgid "Misc"
526
  msgstr ""
527
 
528
- #: core/core.php:2605
529
  msgid "Highlight links broken for at least %s days"
530
  msgstr ""
531
 
532
- #: core/core.php:2614
533
  msgid "Color-code status codes"
534
  msgstr ""
535
 
536
- #: core/core.php:2633, core/core.php:3205, core/core.php:3252, core/core.php:3291, core/core.php:3415, core/core.php:3474, core/core.php:3552
537
  msgid "You're not allowed to do that!"
538
  msgstr ""
539
 
540
- #: core/core.php:3073
 
 
 
 
541
  msgid "View broken links"
542
  msgstr ""
543
 
544
- #: core/core.php:3074
545
  msgid "Found %d broken link"
546
  msgid_plural "Found %d broken links"
547
  msgstr[0] ""
548
  msgstr[1] ""
549
 
550
- #: core/core.php:3080
551
- msgid "No broken links found."
552
  msgstr ""
553
 
554
- #: core/core.php:3087
555
  msgid "%d URL in the work queue"
556
  msgid_plural "%d URLs in the work queue"
557
  msgstr[0] ""
558
  msgstr[1] ""
559
 
560
- #: core/core.php:3091
561
- msgid "No URLs in the work queue."
562
  msgstr ""
563
 
564
- #: core/core.php:3097
 
 
 
 
565
  msgctxt "for the \"Detected X unique URLs in Y links\" message"
566
  msgid "%d unique URL"
567
  msgid_plural "%d unique URLs"
568
  msgstr[0] ""
569
  msgstr[1] ""
570
 
571
- #: core/core.php:3101
572
  msgctxt "for the \"Detected X unique URLs in Y links\" message"
573
  msgid "%d link"
574
  msgid_plural "%d links"
575
  msgstr[0] ""
576
  msgstr[1] ""
577
 
578
- #: core/core.php:3107
579
- msgid "Detected %1$s in %2$s and still searching..."
580
- msgstr ""
581
-
582
- #: core/core.php:3113
583
  msgid "Detected %1$s in %2$s."
584
  msgstr ""
585
 
586
- #: core/core.php:3120
587
- msgid "Searching your blog for links..."
588
- msgstr ""
589
-
590
- #: core/core.php:3122
591
- msgid "No links detected."
592
  msgstr ""
593
 
594
- #: core/core.php:3148
595
  msgctxt "current load"
596
  msgid "Unknown"
597
  msgstr ""
598
 
599
- #: core/core.php:3213, core/core.php:3260, core/core.php:3314, core/core.php:3429, core/core.php:3497, core/core.php:3575
600
- msgid "Oops, I can't find the link %d"
601
  msgstr ""
602
 
603
- #: core/core.php:3233, core/core.php:3274
604
- msgid "Oops, couldn't modify the link!"
605
  msgstr ""
606
 
607
- #: core/core.php:3236, core/core.php:3277, core/core.php:3462, core/core.php:3484, core/core.php:3562
608
- msgid "Error : link_id not specified"
609
  msgstr ""
610
 
611
- #: core/core.php:3301
612
  msgid "Error : link_id or new_url not specified"
613
  msgstr ""
614
 
615
- #: core/core.php:3327, core/core.php:3341
616
  msgid "Oops, the new URL is invalid!"
617
  msgstr ""
618
 
619
- #: core/core.php:3361
620
  msgid "An unexpected error occurred!"
621
  msgstr ""
622
 
623
- #: core/core.php:3442
624
  msgid "An unexpected error occured!"
625
  msgstr ""
626
 
627
- #: core/core.php:3610
628
  msgid "You don't have sufficient privileges to access this information!"
629
  msgstr ""
630
 
631
- #: core/core.php:3623
632
  msgid "Error : link ID not specified"
633
  msgstr ""
634
 
635
- #: core/core.php:3637
636
  msgid "Failed to load link details (%s)"
637
  msgstr ""
638
 
639
- #: core/core.php:3691
640
  msgid "Broken Link Checker"
641
  msgstr ""
642
 
643
- #: core/core.php:3730
 
 
 
 
644
  msgid "You have an old version of CURL. Redirect detection may not work properly."
645
  msgstr ""
646
 
647
- #: core/core.php:3741, core/core.php:3757, core/core.php:3762
648
- msgid "Not installed"
649
  msgstr ""
650
 
651
- #: core/core.php:3750
652
  msgid "Installed"
653
  msgstr ""
654
 
655
- #: core/core.php:3763
656
- msgid "You must have either CURL or Snoopy installed for the plugin to work!"
657
  msgstr ""
658
 
659
- #: core/core.php:3773
660
  msgid "On"
661
  msgstr ""
662
 
663
- #: core/core.php:3774
664
  msgid "Redirects may be detected as broken links when safe_mode is on."
665
  msgstr ""
666
 
667
- #: core/core.php:3779, core/core.php:3793
668
- msgid "Off"
669
- msgstr ""
670
-
671
- #: core/core.php:3787
672
  msgid "On ( %s )"
673
  msgstr ""
674
 
675
- #: core/core.php:3788
676
  msgid "Redirects may be detected as broken links when open_basedir is on."
677
  msgstr ""
678
 
679
- #: core/core.php:3825
680
  msgid "If this value is zero even after several page reloads you have probably encountered a bug."
681
  msgstr ""
682
 
683
- #: core/core.php:3954, core/core.php:4073
684
  msgid "[%s] Broken links detected"
685
  msgstr ""
686
 
687
- #: core/core.php:3959
688
  msgid "Broken Link Checker has detected %d new broken link on your site."
689
  msgid_plural "Broken Link Checker has detected %d new broken links on your site."
690
  msgstr[0] ""
691
  msgstr[1] ""
692
 
693
- #: core/core.php:3990
 
 
 
 
694
  msgid "Here's a list of the first %d broken links:"
695
  msgid_plural "Here's a list of the first %d broken links:"
696
  msgstr[0] ""
697
  msgstr[1] ""
698
 
699
- #: core/core.php:3999
700
- msgid "Here's a list of the new broken links: "
701
- msgstr ""
702
-
703
- #: core/core.php:4008
704
  msgid "Link text : %s"
705
  msgstr ""
706
 
707
- #: core/core.php:4009
708
  msgid "Link URL : <a href=\"%1$s\">%2$s</a>"
709
  msgstr ""
710
 
711
- #: core/core.php:4010
712
  msgid "Source : %s"
713
  msgstr ""
714
 
715
- #: core/core.php:4024
716
  msgid "You can see all broken links here:"
717
  msgstr ""
718
 
719
- #: core/core.php:4078
720
  msgid "Broken Link Checker has detected %d new broken link in your posts."
721
  msgid_plural "Broken Link Checker has detected %d new broken links in your posts."
722
  msgstr[0] ""
723
  msgstr[1] ""
724
 
725
- #: core/init.php:237
726
  msgid "Every 10 minutes"
727
  msgstr ""
728
 
729
- #: core/init.php:244
730
  msgid "Once Weekly"
731
  msgstr ""
732
 
733
- #: core/init.php:250
734
  msgid "Twice a Month"
735
  msgstr ""
736
 
737
- #: core/init.php:323
738
  msgid "Broken Link Checker installation failed. Try deactivating and then reactivating the plugin."
739
  msgstr ""
740
 
@@ -742,14 +756,6 @@ msgstr ""
742
  msgid "Edit"
743
  msgstr ""
744
 
745
- #: includes/any-post.php:485, modules/containers/acf_field.php:252, modules/containers/custom_field.php:258
746
- msgid "Move this item to the Trash"
747
- msgstr ""
748
-
749
- #: includes/any-post.php:487, modules/containers/acf_field.php:252, modules/containers/custom_field.php:260
750
- msgid "Trash"
751
- msgstr ""
752
-
753
  #: includes/any-post.php:492, modules/containers/acf_field.php:254, modules/containers/custom_field.php:265
754
  msgid "Delete this item permanently"
755
  msgstr ""
@@ -758,12 +764,12 @@ msgstr ""
758
  msgid "Delete"
759
  msgstr ""
760
 
761
- #: includes/any-post.php:507
762
- msgid "Preview &#8220;%s&#8221;"
763
  msgstr ""
764
 
765
- #: includes/any-post.php:508
766
- msgid "Preview"
767
  msgstr ""
768
 
769
  #: includes/any-post.php:515
@@ -774,6 +780,14 @@ msgstr ""
774
  msgid "View"
775
  msgstr ""
776
 
 
 
 
 
 
 
 
 
777
  #: includes/any-post.php:535, modules/containers/acf_field.php:248, modules/containers/custom_field.php:252
778
  msgid "Edit this item"
779
  msgstr ""
@@ -798,9 +812,9 @@ msgstr ""
798
  msgid "Failed to move post \"%1$s\" (%2$d) to the trash"
799
  msgstr ""
800
 
801
- #: includes/any-post.php:820
802
- msgid "%d post deleted."
803
- msgid_plural "%d posts deleted."
804
  msgstr[0] ""
805
  msgstr[1] ""
806
 
@@ -810,15 +824,15 @@ msgid_plural "%d pages deleted."
810
  msgstr[0] ""
811
  msgstr[1] ""
812
 
813
- #: includes/any-post.php:824
814
- msgid "%1$d \"%2$s\" deleted."
815
- msgid_plural "%1$d \"%2$s\" deleted."
816
  msgstr[0] ""
817
  msgstr[1] ""
818
 
819
- #: includes/any-post.php:843
820
- msgid "%d post moved to the Trash."
821
- msgid_plural "%d posts moved to the Trash."
822
  msgstr[0] ""
823
  msgstr[1] ""
824
 
@@ -828,9 +842,9 @@ msgid_plural "%d pages moved to the Trash."
828
  msgstr[0] ""
829
  msgstr[1] ""
830
 
831
- #: includes/any-post.php:847
832
- msgid "%1$d \"%2$s\" moved to the Trash."
833
- msgid_plural "%1$d \"%2$s\" moved to the Trash."
834
  msgstr[0] ""
835
  msgstr[1] ""
836
 
@@ -1025,14 +1039,14 @@ msgstr ""
1025
  msgid "The plugin doesn't know how to check this type of link."
1026
  msgstr ""
1027
 
1028
- #: includes/links.php:503
1029
- msgid "Link is broken."
1030
- msgstr ""
1031
-
1032
  #: includes/links.php:505
1033
  msgid "Link is valid."
1034
  msgstr ""
1035
 
 
 
 
 
1036
  #: includes/links.php:738, includes/links.php:841, includes/links.php:875
1037
  msgid "Link is not valid"
1038
  msgstr ""
@@ -1058,21 +1072,21 @@ msgctxt "link status"
1058
  msgid "Unknown"
1059
  msgstr ""
1060
 
1061
- #: includes/links.php:1029, modules/checkers/http.php:312, modules/checkers/http.php:316, modules/extras/mediafire.php:115, modules/extras/youtube.php:135, modules/extras/youtube.php:230
1062
- msgid "Unknown Error"
1063
- msgstr ""
1064
-
1065
- #: includes/links.php:1052
1066
- msgid "Not checked"
1067
  msgstr ""
1068
 
1069
  #: includes/links.php:1055
1070
  msgid "False positive"
1071
  msgstr ""
1072
 
1073
- #: includes/links.php:1058, modules/extras/rapidshare.php:145, modules/extras/rapidshare.php:151, modules/extras/rapidshare.php:178, modules/extras/youtube.php:141, modules/extras/youtube.php:217
1074
- msgctxt "link status"
1075
- msgid "OK"
 
 
 
1076
  msgstr ""
1077
 
1078
  #: includes/parsers.php:117
@@ -1250,14 +1264,14 @@ msgstr ""
1250
  msgid "Hide debug info"
1251
  msgstr ""
1252
 
1253
- #: includes/admin/search-form.php:16
1254
- msgid "Save This Search As a Filter"
1255
- msgstr ""
1256
-
1257
  #: includes/admin/search-form.php:26
1258
  msgid "Delete This Filter"
1259
  msgstr ""
1260
 
 
 
 
 
1261
  #: includes/admin/search-form.php:42
1262
  msgid "Link text"
1263
  msgstr ""
@@ -1326,14 +1340,14 @@ msgstr ""
1326
  msgid "Mark as not broken"
1327
  msgstr ""
1328
 
1329
- #: includes/admin/table-printer.php:300
1330
- msgid "Move sources to Trash"
1331
- msgstr ""
1332
-
1333
  #: includes/admin/table-printer.php:302
1334
  msgid "Delete sources"
1335
  msgstr ""
1336
 
 
 
 
 
1337
  #: includes/admin/table-printer.php:318
1338
  msgid "&laquo;"
1339
  msgstr ""
@@ -1442,10 +1456,6 @@ msgstr ""
1442
  msgid "Remove this link from the list of broken links and mark it as valid"
1443
  msgstr ""
1444
 
1445
- #: includes/admin/table-printer.php:726
1446
- msgid "Hide this link and do not report it again unless its status changes"
1447
- msgstr ""
1448
-
1449
  #: includes/admin/table-printer.php:732
1450
  msgid "Undismiss this link"
1451
  msgstr ""
@@ -1454,6 +1464,10 @@ msgstr ""
1454
  msgid "Undismiss"
1455
  msgstr ""
1456
 
 
 
 
 
1457
  #: includes/admin/table-printer.php:746
1458
  msgid "Replace this redirect with a direct link"
1459
  msgstr ""
@@ -1498,14 +1512,14 @@ msgstr ""
1498
  msgid "Connection Failed"
1499
  msgstr ""
1500
 
1501
- #: modules/checkers/http.php:359, modules/checkers/http.php:448
1502
- msgid "HTTP code : %d"
1503
- msgstr ""
1504
-
1505
  #: modules/checkers/http.php:361, modules/checkers/http.php:450
1506
  msgid "(No response)"
1507
  msgstr ""
1508
 
 
 
 
 
1509
  #: modules/checkers/http.php:379
1510
  msgid "Most likely the connection timed out or the domain doesn't exist."
1511
  msgstr ""
@@ -1578,10 +1592,6 @@ msgstr ""
1578
  msgid "Edit comment"
1579
  msgstr ""
1580
 
1581
- #: modules/containers/comment.php:166
1582
- msgid "Delete Permanently"
1583
- msgstr ""
1584
-
1585
  #: modules/containers/comment.php:168
1586
  msgid "Move this comment to the trash"
1587
  msgstr ""
@@ -1591,6 +1601,10 @@ msgctxt "verb"
1591
  msgid "Trash"
1592
  msgstr ""
1593
 
 
 
 
 
1594
  #: modules/containers/comment.php:172
1595
  msgid "View comment"
1596
  msgstr ""
@@ -1635,18 +1649,22 @@ msgstr ""
1635
  msgid "Embedded GoogleVideo video"
1636
  msgstr ""
1637
 
1638
- #: modules/extras/mediafire.php:97, modules/extras/mediafire.php:103, modules/extras/rapidshare.php:139
1639
- msgid "Not Found"
1640
- msgstr ""
1641
-
1642
  #: modules/extras/mediafire.php:109
1643
  msgid "Permission Denied"
1644
  msgstr ""
1645
 
 
 
 
 
1646
  #: modules/extras/rapidshare.php:51
1647
  msgid "Using RapidShare API"
1648
  msgstr ""
1649
 
 
 
 
 
1650
  #: modules/extras/rapidshare.php:158
1651
  msgid "RS Server Down"
1652
  msgstr ""
@@ -1663,10 +1681,6 @@ msgstr ""
1663
  msgid "RapidShare : %s"
1664
  msgstr ""
1665
 
1666
- #: modules/extras/rapidshare.php:189
1667
- msgid "RapidShare API error: %s"
1668
- msgstr ""
1669
-
1670
  #: modules/extras/vimeo-embed.php:24
1671
  msgid "Vimeo Video"
1672
  msgstr ""
@@ -1691,20 +1705,24 @@ msgstr ""
1691
  msgid "Embedded YouTube playlist"
1692
  msgstr ""
1693
 
 
 
 
 
1694
  #: modules/extras/youtube.php:140
1695
  msgid "Video OK"
1696
  msgstr ""
1697
 
1698
- #: modules/extras/youtube.php:151, modules/extras/youtube.php:154
1699
- msgid "Video Not Found"
1700
  msgstr ""
1701
 
1702
- #: modules/extras/youtube.php:173, modules/extras/youtube.php:176
1703
- msgid "Playlist Not Found"
1704
  msgstr ""
1705
 
1706
- #: modules/extras/youtube.php:183
1707
- msgid "Playlist Restricted"
1708
  msgstr ""
1709
 
1710
  #: modules/extras/youtube.php:190
@@ -1716,16 +1734,12 @@ msgctxt "link status"
1716
  msgid "Empty Playlist"
1717
  msgstr ""
1718
 
1719
- #: modules/extras/youtube.php:201
1720
- msgid "Video status : %1$s%2$s"
1721
- msgstr ""
1722
-
1723
- #: modules/extras/youtube.php:207
1724
- msgid "Video Restricted"
1725
  msgstr ""
1726
 
1727
- #: modules/extras/youtube.php:216
1728
- msgid "Playlist OK"
1729
  msgstr ""
1730
 
1731
  #: modules/extras/youtube.php:264
1
+ # Copyright (C) 2022 Broken Link Checker 1.11.17
2
+ # This file is distributed under the same license as the Broken Link Checker 1.11.17 package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Broken Link Checker 1.11.17\n"
6
  "MIME-Version: 1.0\n"
7
  "Content-Type: text/plain; charset=UTF-8\n"
8
  "Content-Transfer-Encoding: 8bit\n"
9
+ "POT-Creation-Date: 2022-07-18 07:30+0000\n"
10
  "X-Poedit-Basepath: ..\n"
11
  "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n"
12
  "X-Poedit-SearchPath-0: .\n"
14
  "X-Poedit-SourceCharset: UTF-8\n"
15
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
 
17
+ #: core/core.php:219, includes/admin/links-page-js.php:45
18
  msgid "Loading..."
19
  msgstr ""
20
 
21
+ #: core/core.php:243, includes/admin/options-page-js.php:18
22
  msgid "[ Network error ]"
23
  msgstr ""
24
 
25
+ #: core/core.php:286
26
  msgid "Automatically expand the widget if broken links have been detected"
27
  msgstr ""
28
 
29
+ #: core/core.php:382
30
  msgid "Link Checker Settings"
31
  msgstr ""
32
 
33
+ #: core/core.php:383
34
  msgid "Link Checker"
35
  msgstr ""
36
 
37
+ #: core/core.php:389, includes/link-query.php:37
38
  msgid "Broken Links"
39
  msgstr ""
40
 
41
+ #: core/core.php:405
42
  msgid "View Broken Links"
43
  msgstr ""
44
 
45
+ #: core/core.php:421
46
  msgid "Go to Broken Links"
47
  msgstr ""
48
 
49
+ #: core/core.php:439
50
  msgid "Settings"
51
  msgstr ""
52
 
53
+ #: core/core.php:467, includes/admin/table-printer.php:292, includes/admin/table-printer.php:710
54
  msgid "Edit URL"
55
  msgstr ""
56
 
57
+ #: core/core.php:468, includes/admin/links-page-js.php:716, includes/admin/table-printer.php:297, includes/admin/table-printer.php:713
58
  msgid "Unlink"
59
  msgstr ""
60
 
61
+ #: core/core.php:469, includes/admin/links-page-js.php:111, includes/admin/table-printer.php:719
62
  msgid "Not broken"
63
  msgstr ""
64
 
65
+ #: core/core.php:470, includes/admin/table-printer.php:296, includes/admin/table-printer.php:727
66
  msgid "Dismiss"
67
  msgstr ""
68
 
69
+ #: core/core.php:471, includes/admin/table-printer.php:293, includes/admin/table-printer.php:739
70
  msgid "Recheck"
71
  msgstr ""
72
 
73
+ #: core/core.php:472, includes/admin/table-printer.php:747
74
  msgctxt "link action; replace one redirect with a direct link"
75
  msgid "Fix redirect"
76
  msgstr ""
77
 
78
+ #: core/core.php:755
79
  msgid "Settings saved."
80
  msgstr ""
81
 
82
+ #: core/core.php:762
 
 
 
 
83
  msgid "Complete site recheck started."
84
  msgstr ""
85
 
86
+ #: core/core.php:785
87
  msgid "General"
88
  msgstr ""
89
 
90
+ #: core/core.php:786
91
  msgid "Look For Links In"
92
  msgstr ""
93
 
94
+ #: core/core.php:787
95
  msgid "Which Links To Check"
96
  msgstr ""
97
 
98
+ #: core/core.php:788
99
  msgid "Protocols & APIs"
100
  msgstr ""
101
 
102
+ #: core/core.php:789
103
  msgid "Advanced"
104
  msgstr ""
105
 
106
+ #: core/core.php:804
107
  msgid "Broken Link Checker Options"
108
  msgstr ""
109
 
110
+ #: core/core.php:840, includes/admin/table-printer.php:215
111
  msgid "Status"
112
  msgstr ""
113
 
114
+ #: core/core.php:842, includes/admin/options-page-js.php:56
115
  msgid "Show debug info"
116
  msgstr ""
117
 
118
+ #: core/core.php:870
119
  msgid "Check each link"
120
  msgstr ""
121
 
122
+ #: core/core.php:875
123
  msgid "Every %s hours"
124
  msgstr ""
125
 
126
+ #: core/core.php:884
127
  msgid "Existing links will be checked this often. New links will usually be checked ASAP."
128
  msgstr ""
129
 
130
+ #: core/core.php:891
131
  msgid "E-mail notifications"
132
  msgstr ""
133
 
134
+ #: core/core.php:901
135
  msgid "Send me e-mail notifications about newly detected broken links"
136
  msgstr ""
137
 
138
+ #: core/core.php:913
139
  msgid "Send authors e-mail notifications about broken links in their posts"
140
  msgstr ""
141
 
142
+ #: core/core.php:920
143
  msgid "Notification e-mail address"
144
  msgstr ""
145
 
146
+ #: core/core.php:932
147
  msgid "Leave empty to use the e-mail address specified in Settings &rarr; General."
148
  msgstr ""
149
 
150
+ #: core/core.php:940
151
+ msgctxt "settings page"
152
+ msgid "Control external links"
153
+ msgstr ""
154
+
155
+ #: core/core.php:952
156
+ msgid "Install the free <a href=\"%s\" class=\"thickbox open-plugin-details-modal\">External Links plugin</a> to control if external links open in a new tab, and their nofollow, noopener and UGC options."
157
+ msgstr ""
158
+
159
+ #: core/core.php:956
160
+ msgid "It's used on over 80,000 sites just like yours."
161
+ msgstr ""
162
+
163
+ #: core/core.php:947
164
+ msgid "Configure <a target=\"_blank\" href=\"%s\">External Links</a> settings."
165
+ msgstr ""
166
+
167
+ #: core/core.php:964
168
  msgid "Link tweaks"
169
  msgstr ""
170
 
171
+ #: core/core.php:974
172
  msgid "Apply custom formatting to broken links"
173
  msgstr ""
174
 
175
+ #: core/core.php:979, core/core.php:1022
176
  msgid "Edit CSS"
177
  msgstr ""
178
 
179
+ #: core/core.php:1001
180
  msgid "Example : Lorem ipsum <a %s>broken link</a>, dolor sit amet."
181
  msgstr ""
182
 
183
+ #: core/core.php:1004, core/core.php:1048
184
  msgid "Click \"Save Changes\" to update example output."
185
  msgstr ""
186
 
187
+ #: core/core.php:1017
188
  msgid "Apply custom formatting to removed links"
189
  msgstr ""
190
 
191
+ #: core/core.php:1045
192
  msgid "Example : Lorem ipsum <span %s>removed link</span>, dolor sit amet."
193
  msgstr ""
194
 
195
+ #: core/core.php:1062
196
  msgid "Stop search engines from following broken links"
197
  msgstr ""
198
 
199
+ #: core/core.php:1068
200
  msgctxt "\"Link tweaks\" settings"
201
  msgid "These settings only apply to the content of posts, not comments or custom fields."
202
  msgstr ""
203
 
204
+ #: core/core.php:1079
205
  msgctxt "settings page"
206
  msgid "Suggestions"
207
  msgstr ""
208
 
209
+ #: core/core.php:1084
210
  msgid "Suggest alternatives to broken links"
211
  msgstr ""
212
 
213
+ #: core/core.php:1090
214
  msgctxt "settings page"
215
  msgid "Warnings"
216
  msgstr ""
217
 
218
+ #: core/core.php:1095
219
  msgid "Show uncertain or minor problems as \"warnings\" instead of \"broken\""
220
  msgstr ""
221
 
222
+ #: core/core.php:1099
223
  msgid "Turning off this option will make the plugin report all problems as broken links."
224
  msgstr ""
225
 
226
+ #: core/core.php:1106
227
  msgid "YouTube API Key"
228
  msgstr ""
229
 
230
+ #: core/core.php:1118
231
  msgid "Use your own %1$sapi key%2$s for checking youtube links."
232
  msgstr ""
233
 
234
+ #: core/core.php:1125
235
  msgid "Post Modified Date"
236
  msgstr ""
237
 
238
+ #: core/core.php:1130
239
  msgid "Disable post modified date change when link is edited"
240
  msgstr ""
241
 
242
+ #: core/core.php:1145
243
  msgid "Look for links in"
244
  msgstr ""
245
 
246
+ #: core/core.php:1161
247
  msgid "Post statuses"
248
  msgstr ""
249
 
250
+ #: core/core.php:1194
251
  msgid "Link types"
252
  msgstr ""
253
 
254
+ #: core/core.php:1200
255
  msgid "Error : All link parsers missing!"
256
  msgstr ""
257
 
258
+ #: core/core.php:1207
259
  msgid "Exclusion list"
260
  msgstr ""
261
 
262
+ #: core/core.php:1208
263
  msgid "Don't check links where the URL contains any of these words (one per line) :"
264
  msgstr ""
265
 
266
+ #: core/core.php:1229
267
  msgid "Check links using"
268
  msgstr ""
269
 
270
+ #: core/core.php:1248, includes/links.php:1033
271
  msgid "Timeout"
272
  msgstr ""
273
 
274
+ #: core/core.php:1254, core/core.php:1349, core/core.php:3823
275
  msgid "%s seconds"
276
  msgstr ""
277
 
278
+ #: core/core.php:1263
279
  msgid "Links that take longer than this to load will be marked as broken."
280
  msgstr ""
281
 
282
+ #: core/core.php:1270
283
  msgid "Link monitor"
284
  msgstr ""
285
 
286
+ #: core/core.php:1282
287
  msgid "Run continuously while the Dashboard is open"
288
  msgstr ""
289
 
290
+ #: core/core.php:1294
291
  msgid "Run hourly in the background"
292
  msgstr ""
293
 
294
+ #: core/core.php:1302
295
  msgid "Show the dashboard widget for"
296
  msgstr ""
297
 
298
+ #: core/core.php:1307
299
  msgctxt "dashboard widget visibility"
300
  msgid "Administrator"
301
  msgstr ""
302
 
303
+ #: core/core.php:1308
304
  msgctxt "dashboard widget visibility"
305
  msgid "Editor and above"
306
  msgstr ""
307
 
308
+ #: core/core.php:1309
309
  msgctxt "dashboard widget visibility"
310
  msgid "Nobody (disables the widget)"
311
  msgstr ""
312
 
313
+ #: core/core.php:1325
314
  msgctxt "settings page"
315
  msgid "Show link actions"
316
  msgstr ""
317
 
318
+ #: core/core.php:1343
319
  msgid "Max. execution time"
320
  msgstr ""
321
 
322
+ #: core/core.php:1360
323
  msgid "The plugin works by periodically launching a background job that parses your posts for links, checks the discovered URLs, and performs other time-consuming tasks. Here you can set for how long, at most, the link monitor may run each time before stopping."
324
  msgstr ""
325
 
326
+ #: core/core.php:1369
327
  msgid "Server load limit"
328
  msgstr ""
329
 
330
+ #: core/core.php:1398
331
+ msgid "Not available"
332
  msgstr ""
333
 
334
+ #: core/core.php:1400
335
+ msgid "Load limiting only works on Linux-like systems where <code>/proc/loadavg</code> is present and accessible."
336
  msgstr ""
337
 
338
+ #: core/core.php:1384
339
+ msgid "Current load : %s"
340
  msgstr ""
341
 
342
+ #: core/core.php:1389
343
+ msgid "Link checking will be suspended if the average <a href=\"%s\">server load</a> rises above this number. Leave this field blank to disable load limiting."
344
  msgstr ""
345
 
346
+ #: core/core.php:1408
347
  msgid "Target resource usage"
348
  msgstr ""
349
 
350
+ #: core/core.php:1428
351
  msgid "Logging"
352
  msgstr ""
353
 
354
+ #: core/core.php:1434
355
  msgid "Enable logging"
356
  msgstr ""
357
 
358
+ #: core/core.php:1441
359
  msgid "Log file location"
360
  msgstr ""
361
 
362
+ #: core/core.php:1450
363
  msgctxt "log file location"
364
  msgid "Default"
365
  msgstr ""
366
 
367
+ #: core/core.php:1466
368
  msgctxt "log file location"
369
  msgid "Custom"
370
  msgstr ""
371
 
372
+ #: core/core.php:1476
373
  msgid "Log file clear schedule"
374
  msgstr ""
375
 
376
+ #: core/core.php:1482, includes/admin/table-printer.php:548
377
  msgid "Never"
378
  msgstr ""
379
 
380
+ #: core/core.php:1503
381
  msgid "Forced recheck"
382
  msgstr ""
383
 
384
+ #: core/core.php:1506
385
  msgid "Re-check all pages"
386
  msgstr ""
387
 
388
+ #: core/core.php:1511
389
  msgid "The \"Nuclear Option\". Click this button to make the plugin empty its link database and recheck the entire site from scratch."
390
  msgstr ""
391
 
392
+ #: core/core.php:1523
393
  msgid "Save Changes"
394
  msgstr ""
395
 
396
+ #: core/core.php:1574
397
  msgid "Configure"
398
  msgstr ""
399
 
400
+ #: core/core.php:1656
401
  msgid "Enter the names of custom fields you want to check (one per line). If a field contains HTML code, prefix its name with <code>html:</code>. For example, <code>html:field_name</code>."
402
  msgstr ""
403
 
404
+ #: core/core.php:1670
405
  msgid "Enter the keys of acf fields you want to check (one per line). If a field contains HTML code, prefix its name with <code>html:</code>. For example, <code>html:field_586a3eaa4091b</code>."
406
  msgstr ""
407
 
408
+ #: core/core.php:1807, core/core.php:1893, core/core.php:1925
409
  msgid "Database error : %s"
410
  msgstr ""
411
 
412
+ #: core/core.php:1888
413
+ msgid "Filter \"%s\" created"
414
  msgstr ""
415
 
416
+ #: core/core.php:1878
417
  msgid "Invalid search query."
418
  msgstr ""
419
 
420
+ #: core/core.php:1874
421
+ msgid "You must enter a filter name!"
422
+ msgstr ""
423
+
424
+ #: core/core.php:1922
425
+ msgid "Filter deleted"
426
  msgstr ""
427
 
428
+ #: core/core.php:1915
429
  msgid "Filter ID not specified."
430
  msgstr ""
431
 
432
+ #: core/core.php:1993
433
+ msgid "None of the selected links are redirects!"
434
  msgstr ""
435
 
436
+ #: core/core.php:1971
437
  msgid "Replaced %d redirect with a direct link"
438
  msgid_plural "Replaced %d redirects with direct links"
439
  msgstr[0] ""
440
  msgstr[1] ""
441
 
442
+ #: core/core.php:1982
443
  msgid "Failed to fix %d redirect"
444
  msgid_plural "Failed to fix %d redirects"
445
  msgstr[0] ""
446
  msgstr[1] ""
447
 
448
+ #: core/core.php:2073
 
 
 
 
449
  msgid "%d link updated."
450
  msgid_plural "%d links updated."
451
  msgstr[0] ""
452
  msgstr[1] ""
453
 
454
+ #: core/core.php:2084
455
  msgid "Failed to update %d link."
456
  msgid_plural "Failed to update %d links."
457
  msgstr[0] ""
458
  msgstr[1] ""
459
 
460
+ #: core/core.php:2175
461
  msgid "%d link removed"
462
  msgid_plural "%d links removed"
463
  msgstr[0] ""
464
  msgstr[1] ""
465
 
466
+ #: core/core.php:2186
467
  msgid "Failed to remove %d link"
468
  msgid_plural "Failed to remove %d links"
469
  msgstr[0] ""
470
  msgstr[1] ""
471
 
472
+ #: core/core.php:2297
473
  msgid "%d item was skipped because it can't be moved to the Trash. You need to delete it manually."
474
  msgid_plural "%d items were skipped because they can't be moved to the Trash. You need to delete them manually."
475
  msgstr[0] ""
476
  msgstr[1] ""
477
 
478
+ #: core/core.php:2319
479
  msgid "Didn't find anything to delete!"
480
  msgstr ""
481
 
482
+ #: core/core.php:2357
483
  msgid "%d link scheduled for rechecking"
484
  msgid_plural "%d links scheduled for rechecking"
485
  msgstr[0] ""
486
  msgstr[1] ""
487
 
488
+ #: core/core.php:2406, core/core.php:3244
489
  msgid "This link was manually marked as working by the user."
490
  msgstr ""
491
 
492
+ #: core/core.php:2414, core/core.php:2477
493
  msgid "Couldn't modify link %d"
494
  msgstr ""
495
 
496
+ #: core/core.php:2425
497
  msgid "%d link marked as not broken"
498
  msgid_plural "%d links marked as not broken"
499
  msgstr[0] ""
500
  msgstr[1] ""
501
 
502
+ #: core/core.php:2488
503
  msgid "%d link dismissed"
504
  msgid_plural "%d links dismissed"
505
  msgstr[0] ""
506
  msgstr[1] ""
507
 
508
+ #: core/core.php:2545
509
  msgid "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."
510
  msgstr ""
511
 
512
+ #: core/core.php:2550
513
  msgctxt "admin notice under Tools - Broken links - Warnings"
514
  msgid "Hide notice"
515
  msgstr ""
516
 
517
+ #: core/core.php:2556
518
  msgctxt "a link from the admin notice under Tools - Broken links - Warnings"
519
  msgid "Change warning settings"
520
  msgstr ""
521
 
522
+ #: core/core.php:2581
523
  msgid "Table columns"
524
  msgstr ""
525
 
526
+ #: core/core.php:2600
527
  msgid "Show on screen"
528
  msgstr ""
529
 
530
+ #: core/core.php:2607
531
  msgid "links"
532
  msgstr ""
533
 
534
+ #: core/core.php:2608, includes/admin/table-printer.php:175
535
  msgid "Apply"
536
  msgstr ""
537
 
538
+ #: core/core.php:2612
539
  msgid "Misc"
540
  msgstr ""
541
 
542
+ #: core/core.php:2627
543
  msgid "Highlight links broken for at least %s days"
544
  msgstr ""
545
 
546
+ #: core/core.php:2636
547
  msgid "Color-code status codes"
548
  msgstr ""
549
 
550
+ #: core/core.php:2655, core/core.php:3228, core/core.php:3275, core/core.php:3314, core/core.php:3438, core/core.php:3497, core/core.php:3575
551
  msgid "You're not allowed to do that!"
552
  msgstr ""
553
 
554
+ #: core/core.php:3103
555
+ msgid "No broken links found."
556
+ msgstr ""
557
+
558
+ #: core/core.php:3096
559
  msgid "View broken links"
560
  msgstr ""
561
 
562
+ #: core/core.php:3097
563
  msgid "Found %d broken link"
564
  msgid_plural "Found %d broken links"
565
  msgstr[0] ""
566
  msgstr[1] ""
567
 
568
+ #: core/core.php:3114
569
+ msgid "No URLs in the work queue."
570
  msgstr ""
571
 
572
+ #: core/core.php:3110
573
  msgid "%d URL in the work queue"
574
  msgid_plural "%d URLs in the work queue"
575
  msgstr[0] ""
576
  msgstr[1] ""
577
 
578
+ #: core/core.php:3145
579
+ msgid "No links detected."
580
  msgstr ""
581
 
582
+ #: core/core.php:3143
583
+ msgid "Searching your blog for links..."
584
+ msgstr ""
585
+
586
+ #: core/core.php:3120
587
  msgctxt "for the \"Detected X unique URLs in Y links\" message"
588
  msgid "%d unique URL"
589
  msgid_plural "%d unique URLs"
590
  msgstr[0] ""
591
  msgstr[1] ""
592
 
593
+ #: core/core.php:3124
594
  msgctxt "for the \"Detected X unique URLs in Y links\" message"
595
  msgid "%d link"
596
  msgid_plural "%d links"
597
  msgstr[0] ""
598
  msgstr[1] ""
599
 
600
+ #: core/core.php:3136
 
 
 
 
601
  msgid "Detected %1$s in %2$s."
602
  msgstr ""
603
 
604
+ #: core/core.php:3130
605
+ msgid "Detected %1$s in %2$s and still searching..."
 
 
 
 
606
  msgstr ""
607
 
608
+ #: core/core.php:3171
609
  msgctxt "current load"
610
  msgid "Unknown"
611
  msgstr ""
612
 
613
+ #: core/core.php:3259, core/core.php:3300, core/core.php:3485, core/core.php:3507, core/core.php:3585
614
+ msgid "Error : link_id not specified"
615
  msgstr ""
616
 
617
+ #: core/core.php:3236, core/core.php:3283, core/core.php:3337, core/core.php:3452, core/core.php:3520, core/core.php:3598
618
+ msgid "Oops, I can't find the link %d"
619
  msgstr ""
620
 
621
+ #: core/core.php:3256, core/core.php:3297
622
+ msgid "Oops, couldn't modify the link!"
623
  msgstr ""
624
 
625
+ #: core/core.php:3324
626
  msgid "Error : link_id or new_url not specified"
627
  msgstr ""
628
 
629
+ #: core/core.php:3350, core/core.php:3364
630
  msgid "Oops, the new URL is invalid!"
631
  msgstr ""
632
 
633
+ #: core/core.php:3384
634
  msgid "An unexpected error occurred!"
635
  msgstr ""
636
 
637
+ #: core/core.php:3465
638
  msgid "An unexpected error occured!"
639
  msgstr ""
640
 
641
+ #: core/core.php:3633
642
  msgid "You don't have sufficient privileges to access this information!"
643
  msgstr ""
644
 
645
+ #: core/core.php:3646
646
  msgid "Error : link ID not specified"
647
  msgstr ""
648
 
649
+ #: core/core.php:3660
650
  msgid "Failed to load link details (%s)"
651
  msgstr ""
652
 
653
+ #: core/core.php:3714
654
  msgid "Broken Link Checker"
655
  msgstr ""
656
 
657
+ #: core/core.php:3764, core/core.php:3785, core/core.php:3780
658
+ msgid "Not installed"
659
+ msgstr ""
660
+
661
+ #: core/core.php:3753
662
  msgid "You have an old version of CURL. Redirect detection may not work properly."
663
  msgstr ""
664
 
665
+ #: core/core.php:3786
666
+ msgid "You must have either CURL or Snoopy installed for the plugin to work!"
667
  msgstr ""
668
 
669
+ #: core/core.php:3773
670
  msgid "Installed"
671
  msgstr ""
672
 
673
+ #: core/core.php:3802, core/core.php:3816
674
+ msgid "Off"
675
  msgstr ""
676
 
677
+ #: core/core.php:3796
678
  msgid "On"
679
  msgstr ""
680
 
681
+ #: core/core.php:3797
682
  msgid "Redirects may be detected as broken links when safe_mode is on."
683
  msgstr ""
684
 
685
+ #: core/core.php:3810
 
 
 
 
686
  msgid "On ( %s )"
687
  msgstr ""
688
 
689
+ #: core/core.php:3811
690
  msgid "Redirects may be detected as broken links when open_basedir is on."
691
  msgstr ""
692
 
693
+ #: core/core.php:3848
694
  msgid "If this value is zero even after several page reloads you have probably encountered a bug."
695
  msgstr ""
696
 
697
+ #: core/core.php:3977, core/core.php:4096
698
  msgid "[%s] Broken links detected"
699
  msgstr ""
700
 
701
+ #: core/core.php:3982
702
  msgid "Broken Link Checker has detected %d new broken link on your site."
703
  msgid_plural "Broken Link Checker has detected %d new broken links on your site."
704
  msgstr[0] ""
705
  msgstr[1] ""
706
 
707
+ #: core/core.php:4022
708
+ msgid "Here's a list of the new broken links: "
709
+ msgstr ""
710
+
711
+ #: core/core.php:4013
712
  msgid "Here's a list of the first %d broken links:"
713
  msgid_plural "Here's a list of the first %d broken links:"
714
  msgstr[0] ""
715
  msgstr[1] ""
716
 
717
+ #: core/core.php:4031
 
 
 
 
718
  msgid "Link text : %s"
719
  msgstr ""
720
 
721
+ #: core/core.php:4032
722
  msgid "Link URL : <a href=\"%1$s\">%2$s</a>"
723
  msgstr ""
724
 
725
+ #: core/core.php:4033
726
  msgid "Source : %s"
727
  msgstr ""
728
 
729
+ #: core/core.php:4047
730
  msgid "You can see all broken links here:"
731
  msgstr ""
732
 
733
+ #: core/core.php:4101
734
  msgid "Broken Link Checker has detected %d new broken link in your posts."
735
  msgid_plural "Broken Link Checker has detected %d new broken links in your posts."
736
  msgstr[0] ""
737
  msgstr[1] ""
738
 
739
+ #: core/init.php:235
740
  msgid "Every 10 minutes"
741
  msgstr ""
742
 
743
+ #: core/init.php:242
744
  msgid "Once Weekly"
745
  msgstr ""
746
 
747
+ #: core/init.php:248
748
  msgid "Twice a Month"
749
  msgstr ""
750
 
751
+ #: core/init.php:321
752
  msgid "Broken Link Checker installation failed. Try deactivating and then reactivating the plugin."
753
  msgstr ""
754
 
756
  msgid "Edit"
757
  msgstr ""
758
 
 
 
 
 
 
 
 
 
759
  #: includes/any-post.php:492, modules/containers/acf_field.php:254, modules/containers/custom_field.php:265
760
  msgid "Delete this item permanently"
761
  msgstr ""
764
  msgid "Delete"
765
  msgstr ""
766
 
767
+ #: includes/any-post.php:485, modules/containers/acf_field.php:252, modules/containers/custom_field.php:258
768
+ msgid "Move this item to the Trash"
769
  msgstr ""
770
 
771
+ #: includes/any-post.php:487, modules/containers/acf_field.php:252, modules/containers/custom_field.php:260
772
+ msgid "Trash"
773
  msgstr ""
774
 
775
  #: includes/any-post.php:515
780
  msgid "View"
781
  msgstr ""
782
 
783
+ #: includes/any-post.php:507
784
+ msgid "Preview &#8220;%s&#8221;"
785
+ msgstr ""
786
+
787
+ #: includes/any-post.php:508
788
+ msgid "Preview"
789
+ msgstr ""
790
+
791
  #: includes/any-post.php:535, modules/containers/acf_field.php:248, modules/containers/custom_field.php:252
792
  msgid "Edit this item"
793
  msgstr ""
812
  msgid "Failed to move post \"%1$s\" (%2$d) to the trash"
813
  msgstr ""
814
 
815
+ #: includes/any-post.php:824
816
+ msgid "%1$d \"%2$s\" deleted."
817
+ msgid_plural "%1$d \"%2$s\" deleted."
818
  msgstr[0] ""
819
  msgstr[1] ""
820
 
824
  msgstr[0] ""
825
  msgstr[1] ""
826
 
827
+ #: includes/any-post.php:820
828
+ msgid "%d post deleted."
829
+ msgid_plural "%d posts deleted."
830
  msgstr[0] ""
831
  msgstr[1] ""
832
 
833
+ #: includes/any-post.php:847
834
+ msgid "%1$d \"%2$s\" moved to the Trash."
835
+ msgid_plural "%1$d \"%2$s\" moved to the Trash."
836
  msgstr[0] ""
837
  msgstr[1] ""
838
 
842
  msgstr[0] ""
843
  msgstr[1] ""
844
 
845
+ #: includes/any-post.php:843
846
+ msgid "%d post moved to the Trash."
847
+ msgid_plural "%d posts moved to the Trash."
848
  msgstr[0] ""
849
  msgstr[1] ""
850
 
1039
  msgid "The plugin doesn't know how to check this type of link."
1040
  msgstr ""
1041
 
 
 
 
 
1042
  #: includes/links.php:505
1043
  msgid "Link is valid."
1044
  msgstr ""
1045
 
1046
+ #: includes/links.php:503
1047
+ msgid "Link is broken."
1048
+ msgstr ""
1049
+
1050
  #: includes/links.php:738, includes/links.php:841, includes/links.php:875
1051
  msgid "Link is not valid"
1052
  msgstr ""
1072
  msgid "Unknown"
1073
  msgstr ""
1074
 
1075
+ #: includes/links.php:1058, modules/extras/rapidshare.php:145, modules/extras/rapidshare.php:151, modules/extras/rapidshare.php:178, modules/extras/youtube.php:141, modules/extras/youtube.php:217
1076
+ msgctxt "link status"
1077
+ msgid "OK"
 
 
 
1078
  msgstr ""
1079
 
1080
  #: includes/links.php:1055
1081
  msgid "False positive"
1082
  msgstr ""
1083
 
1084
+ #: includes/links.php:1052
1085
+ msgid "Not checked"
1086
+ msgstr ""
1087
+
1088
+ #: includes/links.php:1029, modules/checkers/http.php:316, modules/checkers/http.php:312, modules/extras/mediafire.php:115, modules/extras/youtube.php:135, modules/extras/youtube.php:230
1089
+ msgid "Unknown Error"
1090
  msgstr ""
1091
 
1092
  #: includes/parsers.php:117
1264
  msgid "Hide debug info"
1265
  msgstr ""
1266
 
 
 
 
 
1267
  #: includes/admin/search-form.php:26
1268
  msgid "Delete This Filter"
1269
  msgstr ""
1270
 
1271
+ #: includes/admin/search-form.php:16
1272
+ msgid "Save This Search As a Filter"
1273
+ msgstr ""
1274
+
1275
  #: includes/admin/search-form.php:42
1276
  msgid "Link text"
1277
  msgstr ""
1340
  msgid "Mark as not broken"
1341
  msgstr ""
1342
 
 
 
 
 
1343
  #: includes/admin/table-printer.php:302
1344
  msgid "Delete sources"
1345
  msgstr ""
1346
 
1347
+ #: includes/admin/table-printer.php:300
1348
+ msgid "Move sources to Trash"
1349
+ msgstr ""
1350
+
1351
  #: includes/admin/table-printer.php:318
1352
  msgid "&laquo;"
1353
  msgstr ""
1456
  msgid "Remove this link from the list of broken links and mark it as valid"
1457
  msgstr ""
1458
 
 
 
 
 
1459
  #: includes/admin/table-printer.php:732
1460
  msgid "Undismiss this link"
1461
  msgstr ""
1464
  msgid "Undismiss"
1465
  msgstr ""
1466
 
1467
+ #: includes/admin/table-printer.php:726
1468
+ msgid "Hide this link and do not report it again unless its status changes"
1469
+ msgstr ""
1470
+
1471
  #: includes/admin/table-printer.php:746
1472
  msgid "Replace this redirect with a direct link"
1473
  msgstr ""
1512
  msgid "Connection Failed"
1513
  msgstr ""
1514
 
 
 
 
 
1515
  #: modules/checkers/http.php:361, modules/checkers/http.php:450
1516
  msgid "(No response)"
1517
  msgstr ""
1518
 
1519
+ #: modules/checkers/http.php:359, modules/checkers/http.php:448
1520
+ msgid "HTTP code : %d"
1521
+ msgstr ""
1522
+
1523
  #: modules/checkers/http.php:379
1524
  msgid "Most likely the connection timed out or the domain doesn't exist."
1525
  msgstr ""
1592
  msgid "Edit comment"
1593
  msgstr ""
1594
 
 
 
 
 
1595
  #: modules/containers/comment.php:168
1596
  msgid "Move this comment to the trash"
1597
  msgstr ""
1601
  msgid "Trash"
1602
  msgstr ""
1603
 
1604
+ #: modules/containers/comment.php:166
1605
+ msgid "Delete Permanently"
1606
+ msgstr ""
1607
+
1608
  #: modules/containers/comment.php:172
1609
  msgid "View comment"
1610
  msgstr ""
1649
  msgid "Embedded GoogleVideo video"
1650
  msgstr ""
1651
 
 
 
 
 
1652
  #: modules/extras/mediafire.php:109
1653
  msgid "Permission Denied"
1654
  msgstr ""
1655
 
1656
+ #: modules/extras/mediafire.php:103, modules/extras/mediafire.php:97, modules/extras/rapidshare.php:139
1657
+ msgid "Not Found"
1658
+ msgstr ""
1659
+
1660
  #: modules/extras/rapidshare.php:51
1661
  msgid "Using RapidShare API"
1662
  msgstr ""
1663
 
1664
+ #: modules/extras/rapidshare.php:189
1665
+ msgid "RapidShare API error: %s"
1666
+ msgstr ""
1667
+
1668
  #: modules/extras/rapidshare.php:158
1669
  msgid "RS Server Down"
1670
  msgstr ""
1681
  msgid "RapidShare : %s"
1682
  msgstr ""
1683
 
 
 
 
 
1684
  #: modules/extras/vimeo-embed.php:24
1685
  msgid "Vimeo Video"
1686
  msgstr ""
1705
  msgid "Embedded YouTube playlist"
1706
  msgstr ""
1707
 
1708
+ #: modules/extras/youtube.php:151, modules/extras/youtube.php:154
1709
+ msgid "Video Not Found"
1710
+ msgstr ""
1711
+
1712
  #: modules/extras/youtube.php:140
1713
  msgid "Video OK"
1714
  msgstr ""
1715
 
1716
+ #: modules/extras/youtube.php:201
1717
+ msgid "Video status : %1$s%2$s"
1718
  msgstr ""
1719
 
1720
+ #: modules/extras/youtube.php:207
1721
+ msgid "Video Restricted"
1722
  msgstr ""
1723
 
1724
+ #: modules/extras/youtube.php:216
1725
+ msgid "Playlist OK"
1726
  msgstr ""
1727
 
1728
  #: modules/extras/youtube.php:190
1734
  msgid "Empty Playlist"
1735
  msgstr ""
1736
 
1737
+ #: modules/extras/youtube.php:183
1738
+ msgid "Playlist Restricted"
 
 
 
 
1739
  msgstr ""
1740
 
1741
+ #: modules/extras/youtube.php:173, modules/extras/youtube.php:176
1742
+ msgid "Playlist Not Found"
1743
  msgstr ""
1744
 
1745
  #: modules/extras/youtube.php:264
modules/parsers/metadata.php CHANGED
@@ -57,7 +57,7 @@ class blcMetadataParser extends blcParser {
57
  * @param string $default_link_text
58
  * @return array An array of new blcLinkInstance objects.
59
  */
60
- function parse_metafield( $metaurl = '', $base_url, $default_link_text = '' ) {
61
  //The complete contents of the meta field are stored in raw_url.
62
  //This is useful for editing/unlinking, when one may need to
63
  //distinguish between multiple fields with the same name.
57
  * @param string $default_link_text
58
  * @return array An array of new blcLinkInstance objects.
59
  */
60
+ function parse_metafield( $metaurl = '', $base_url = '', $default_link_text = '' ) {
61
  //The complete contents of the meta field are stored in raw_url.
62
  //This is useful for editing/unlinking, when one may need to
63
  //distinguish between multiple fields with the same name.
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Broken Link Checker ===
2
  Contributors: managewp, wpmudev
3
  Tags: links, broken links, internal link, external link, broken images, seo, test links, check links, bad links
4
- Requires at least: 4.6
5
- Tested up to: 5.5
6
- Stable tag: 1.11.15
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -66,6 +66,15 @@ To upgrade your installation
66
  1. Reactivate the plugin. Your settings will be retained from the previous version.
67
 
68
  == Changelog ==
 
 
 
 
 
 
 
 
 
69
  = 1.11.15 =
70
  * Added integration with WP External Links plugin
71
 
1
  === Broken Link Checker ===
2
  Contributors: managewp, wpmudev
3
  Tags: links, broken links, internal link, external link, broken images, seo, test links, check links, bad links
4
+ Requires at least: 5.2
5
+ Tested up to: 5.8
6
+ Stable tag: 1.11.16
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
66
  1. Reactivate the plugin. Your settings will be retained from the previous version.
67
 
68
  == Changelog ==
69
+
70
+ = 1.11.17 =
71
+ * Fix security vulnerability
72
+
73
+ = 1.11.16 =
74
+ * Enhance compatibility with PHP 8
75
+ * Enhance compatibility with WordPress 5.8
76
+ * Remove donation links and adds
77
+
78
  = 1.11.15 =
79
  * Added integration with WP External Links plugin
80