Broken Link Checker - Version 1.11.1

Version Description

  • Major performance improvement. Database queries reduced up to 10x in some cases.
  • Feel free to contribute to the plugin on GitHub. Pull requests welcome!
Download this release

Release Info

Developer freediver
Plugin Icon 128x128 Broken Link Checker
Version 1.11.1
Comparing to
See all releases

Code changes from version 1.10.11 to 1.11.1

broken-link-checker.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Broken Link Checker
4
  Plugin URI: http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/
5
  Description: Checks your blog for broken links and missing images and notifies you on the dashboard if any are found.
6
- Version: 1.10.11
7
  Author: Janis Elsts, Vladimir Prelovac
8
  Author URI: http://w-shadow.com/
9
  Text Domain: broken-link-checker
3
  Plugin Name: Broken Link Checker
4
  Plugin URI: http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/
5
  Description: Checks your blog for broken links and missing images and notifies you on the dashboard if any are found.
6
+ Version: 1.11.1
7
  Author: Janis Elsts, Vladimir Prelovac
8
  Author URI: http://w-shadow.com/
9
  Text Domain: broken-link-checker
core/core.php CHANGED
@@ -14,6 +14,7 @@ if ( !function_exists( 'microtime_float' ) ) {
14
  require BLC_DIRECTORY . '/includes/screen-options/screen-options.php';
15
  require BLC_DIRECTORY . '/includes/screen-meta-links.php';
16
  require BLC_DIRECTORY . '/includes/wp-mutex.php';
 
17
 
18
  if (!class_exists('wsBrokenLinkChecker')) {
19
 
@@ -37,7 +38,7 @@ class wsBrokenLinkChecker {
37
  * @param blcConfigurationManager $conf An instance of the configuration manager
38
  * @return void
39
  */
40
- function __construct ( $loader, $conf ) {
41
  $this->db_version = BLC_DATABASE_VERSION;
42
 
43
  $this->conf = $conf;
@@ -81,8 +82,7 @@ class wsBrokenLinkChecker {
81
  add_action('blc_cron_email_notifications', array( $this, 'maybe_send_email_notifications' ));
82
  add_action('blc_cron_check_links', array($this, 'cron_check_links'));
83
  add_action('blc_cron_database_maintenance', array($this, 'database_maintenance'));
84
- add_action('blc_cron_check_news', array($this, 'check_news'));
85
-
86
  //Set the footer hook that will call the worker function via AJAX.
87
  add_action('admin_footer', array($this,'admin_footer'));
88
 
@@ -259,7 +259,7 @@ class wsBrokenLinkChecker {
259
  wp_clear_scheduled_hook('blc_cron_check_links');
260
  wp_clear_scheduled_hook('blc_cron_email_notifications');
261
  wp_clear_scheduled_hook('blc_cron_database_maintenance');
262
- wp_clear_scheduled_hook('blc_cron_check_news');
263
  //Note the deactivation time for each module. This will help them
264
  //synch up propely if/when the plugin is reactivated.
265
  $moduleManager = blcModuleManager::getInstance();
@@ -331,14 +331,6 @@ class wsBrokenLinkChecker {
331
  add_action( 'admin_print_scripts-' . $options_page_hook, array($this, 'enqueue_settings_scripts') );
332
  add_action( 'admin_print_scripts-' . $links_page_hook, array($this, 'enqueue_link_page_scripts') );
333
 
334
- //Add a "Feedback" button that links to the plugin's UserVoice forum
335
- add_screen_meta_link(
336
- 'blc-feedback-widget',
337
- __('Feedback', 'broken-link-checker'),
338
- 'http://whiteshadow.uservoice.com/forums/58400-broken-link-checker',
339
- array($options_page_hook, $links_page_hook)
340
- );
341
-
342
  //Make the Settings page link to the link list
343
  add_screen_meta_link(
344
  'blc-links-page-link',
@@ -347,17 +339,6 @@ class wsBrokenLinkChecker {
347
  $options_page_hook,
348
  array('style' => 'font-weight: bold;')
349
  );
350
-
351
- //Add a link to the latest blog post/whatever about this plugin, if any.
352
- if ( !$this->conf->get('user_has_donated') && isset($this->conf->options['plugin_news']) && !empty($this->conf->options['plugin_news']) ){
353
- $news = $this->conf->options['plugin_news'];
354
- add_screen_meta_link(
355
- 'blc-plugin-news-link',
356
- $news[0],
357
- $news[1],
358
- array($options_page_hook, $links_page_hook)
359
- );
360
- }
361
  }
362
 
363
  /**
@@ -2113,7 +2094,8 @@ class wsBrokenLinkChecker {
2113
  $link->false_positive = true;
2114
  $link->last_check_attempt = time();
2115
  $link->log = __("This link was manually marked as working by the user.", 'broken-link-checker');
2116
-
 
2117
  //Save the changes
2118
  if ( $link->save() ){
2119
  $processed_links++;
@@ -2172,6 +2154,7 @@ class wsBrokenLinkChecker {
2172
 
2173
  $link->dismissed = true;
2174
 
 
2175
  //Save the changes
2176
  if ( $link->save() ){
2177
  $processed_links++;
@@ -2581,7 +2564,10 @@ class wsBrokenLinkChecker {
2581
 
2582
  //Randomizing the array reduces the chances that we'll get several links to the same domain in a row.
2583
  shuffle($links);
2584
-
 
 
 
2585
  foreach ($links as $link) {
2586
  //Does this link need to be checked? Excluded links aren't checked, but their URLs are still
2587
  //tested periodically to see if they're still on the exclusion list.
@@ -2611,6 +2597,7 @@ class wsBrokenLinkChecker {
2611
  return;
2612
  }
2613
  }
 
2614
 
2615
  $start = microtime(true);
2616
  $links = $this->get_links_to_check($max_links_per_query);
@@ -2691,30 +2678,29 @@ class wsBrokenLinkChecker {
2691
  //I could put an index on last_check_attempt, but that value is almost
2692
  //certainly unique for each row so it wouldn't be much better than a full table scan.
2693
  if ( $count_only ){
2694
- $q = "SELECT COUNT(links.link_id)\n";
2695
  } else {
2696
- $q = "SELECT links.*\n";
2697
  }
2698
  $q .= "FROM {$wpdb->prefix}blc_links AS links
2699
- WHERE
2700
- (
2701
- ( last_check_attempt < %s )
2702
- OR
2703
- (
2704
- (broken = 1 OR being_checked = 1)
2705
- AND may_recheck = 1
2706
- AND check_count < %d
2707
- AND last_check_attempt < %s
2708
- )
2709
- )
2710
- AND EXISTS (
2711
- SELECT 1 FROM {$wpdb->prefix}blc_instances AS instances
2712
- WHERE
2713
- instances.link_id = links.link_id
2714
- AND ( instances.container_type IN ({$loaded_containers}) )
2715
- AND ( instances.parser_type IN ({$loaded_parsers}) )
2716
- )
2717
- ";
2718
  if ( !$count_only ){
2719
  $q .= "\nORDER BY last_check_attempt ASC\n";
2720
  if ( !empty($max_results) ){
@@ -2928,7 +2914,8 @@ class wsBrokenLinkChecker {
2928
  $link->false_positive = true;
2929
  $link->last_check_attempt = time();
2930
  $link->log = __("This link was manually marked as working by the user.", 'broken-link-checker');
2931
-
 
2932
  //Save the changes
2933
  if ( $link->save() ){
2934
  die( "OK" );
@@ -2967,6 +2954,7 @@ class wsBrokenLinkChecker {
2967
  $link->dismissed = $dismiss;
2968
 
2969
  //Save the changes
 
2970
  if ( $link->save() ){
2971
  die( "OK" );
2972
  } else {
@@ -3213,6 +3201,7 @@ class wsBrokenLinkChecker {
3213
 
3214
  //In case the immediate check fails, this will ensure the link is checked during the next work() run.
3215
  $link->last_check_attempt = 0;
 
3216
  $link->save();
3217
 
3218
  //Check the link and save the results.
@@ -3771,12 +3760,7 @@ class wsBrokenLinkChecker {
3771
  if ( !wp_next_scheduled('blc_cron_database_maintenance') ){
3772
  wp_schedule_event(time(), 'bimonthly', 'blc_cron_database_maintenance');
3773
  }
3774
-
3775
- //Check for news notices related to this plugin
3776
- if ( !wp_next_scheduled('blc_cron_check_news') ){
3777
- wp_schedule_event(time(), 'daily', 'blc_cron_check_news');
3778
- }
3779
- }
3780
 
3781
  /**
3782
  * Load the plugin's textdomain.
@@ -3787,34 +3771,6 @@ class wsBrokenLinkChecker {
3787
  $this->is_textdomain_loaded = load_plugin_textdomain( 'broken-link-checker', false, basename(dirname($this->loader)) . '/languages' );
3788
  }
3789
 
3790
- /**
3791
- * Check if there's a "news" link to display on the plugin's pages.
3792
- *
3793
- * @return void
3794
- */
3795
- function check_news(){
3796
- $url = 'http://w-shadow.com/plugin-news/broken-link-checker-news.txt';
3797
-
3798
- //Retrieve the appropriate "news" file
3799
- $res = wp_remote_get($url);
3800
- if ( is_wp_error($res) ){
3801
- return;
3802
- }
3803
-
3804
- //Anything there?
3805
- if ( isset($res['response']['code']) && ($res['response']['code'] == 200) && isset($res['body']) ) {
3806
- //The file should contain two lines - a title and an URL
3807
- $news = explode("\n", trim($res['body']));
3808
- if ( count($news) == 2 ){
3809
- //Save for later.
3810
- $this->conf->options['plugin_news'] = $news;
3811
- } else {
3812
- $this->conf->options['plugin_news'] = null;
3813
- }
3814
- $this->conf->save_options();
3815
- }
3816
- }
3817
-
3818
  protected static function get_default_log_directory() {
3819
  $uploads = wp_upload_dir();
3820
  return $uploads['basedir'] . '/broken-link-checker';
14
  require BLC_DIRECTORY . '/includes/screen-options/screen-options.php';
15
  require BLC_DIRECTORY . '/includes/screen-meta-links.php';
16
  require BLC_DIRECTORY . '/includes/wp-mutex.php';
17
+ require BLC_DIRECTORY . '/includes/transactions-manager.php';
18
 
19
  if (!class_exists('wsBrokenLinkChecker')) {
20
 
38
  * @param blcConfigurationManager $conf An instance of the configuration manager
39
  * @return void
40
  */
41
+ function __construct ( $loader, $conf ) {
42
  $this->db_version = BLC_DATABASE_VERSION;
43
 
44
  $this->conf = $conf;
82
  add_action('blc_cron_email_notifications', array( $this, 'maybe_send_email_notifications' ));
83
  add_action('blc_cron_check_links', array($this, 'cron_check_links'));
84
  add_action('blc_cron_database_maintenance', array($this, 'database_maintenance'));
85
+
 
86
  //Set the footer hook that will call the worker function via AJAX.
87
  add_action('admin_footer', array($this,'admin_footer'));
88
 
259
  wp_clear_scheduled_hook('blc_cron_check_links');
260
  wp_clear_scheduled_hook('blc_cron_email_notifications');
261
  wp_clear_scheduled_hook('blc_cron_database_maintenance');
262
+ wp_clear_scheduled_hook('blc_cron_check_news'); //Unused event.
263
  //Note the deactivation time for each module. This will help them
264
  //synch up propely if/when the plugin is reactivated.
265
  $moduleManager = blcModuleManager::getInstance();
331
  add_action( 'admin_print_scripts-' . $options_page_hook, array($this, 'enqueue_settings_scripts') );
332
  add_action( 'admin_print_scripts-' . $links_page_hook, array($this, 'enqueue_link_page_scripts') );
333
 
 
 
 
 
 
 
 
 
334
  //Make the Settings page link to the link list
335
  add_screen_meta_link(
336
  'blc-links-page-link',
339
  $options_page_hook,
340
  array('style' => 'font-weight: bold;')
341
  );
 
 
 
 
 
 
 
 
 
 
 
342
  }
343
 
344
  /**
2094
  $link->false_positive = true;
2095
  $link->last_check_attempt = time();
2096
  $link->log = __("This link was manually marked as working by the user.", 'broken-link-checker');
2097
+
2098
+ $link->isOptionLinkChanged = true;
2099
  //Save the changes
2100
  if ( $link->save() ){
2101
  $processed_links++;
2154
 
2155
  $link->dismissed = true;
2156
 
2157
+ $link->isOptionLinkChanged = true;
2158
  //Save the changes
2159
  if ( $link->save() ){
2160
  $processed_links++;
2564
 
2565
  //Randomizing the array reduces the chances that we'll get several links to the same domain in a row.
2566
  shuffle($links);
2567
+
2568
+ $transactionManager = TransactionManager::getInstance();
2569
+ $transactionManager->start();
2570
+
2571
  foreach ($links as $link) {
2572
  //Does this link need to be checked? Excluded links aren't checked, but their URLs are still
2573
  //tested periodically to see if they're still on the exclusion list.
2597
  return;
2598
  }
2599
  }
2600
+ $transactionManager->commit();
2601
 
2602
  $start = microtime(true);
2603
  $links = $this->get_links_to_check($max_links_per_query);
2678
  //I could put an index on last_check_attempt, but that value is almost
2679
  //certainly unique for each row so it wouldn't be much better than a full table scan.
2680
  if ( $count_only ){
2681
+ $q = "SELECT COUNT(DISTINCT links.link_id)\n";
2682
  } else {
2683
+ $q = "SELECT DISTINCT links.*\n";
2684
  }
2685
  $q .= "FROM {$wpdb->prefix}blc_links AS links
2686
+ INNER JOIN {$wpdb->prefix}blc_instances AS instances USING(link_id)
2687
+ WHERE
2688
+ (
2689
+ ( last_check_attempt < %s )
2690
+ OR
2691
+ (
2692
+ (broken = 1 OR being_checked = 1)
2693
+ AND may_recheck = 1
2694
+ AND check_count < %d
2695
+ AND last_check_attempt < %s
2696
+ )
2697
+ )
2698
+
2699
+ AND
2700
+ ( instances.container_type IN ({$loaded_containers}) )
2701
+ AND ( instances.parser_type IN ({$loaded_parsers}) )
2702
+ ";
2703
+
 
2704
  if ( !$count_only ){
2705
  $q .= "\nORDER BY last_check_attempt ASC\n";
2706
  if ( !empty($max_results) ){
2914
  $link->false_positive = true;
2915
  $link->last_check_attempt = time();
2916
  $link->log = __("This link was manually marked as working by the user.", 'broken-link-checker');
2917
+
2918
+ $link->isOptionLinkChanged = true;
2919
  //Save the changes
2920
  if ( $link->save() ){
2921
  die( "OK" );
2954
  $link->dismissed = $dismiss;
2955
 
2956
  //Save the changes
2957
+ $link->isOptionLinkChanged = true;
2958
  if ( $link->save() ){
2959
  die( "OK" );
2960
  } else {
3201
 
3202
  //In case the immediate check fails, this will ensure the link is checked during the next work() run.
3203
  $link->last_check_attempt = 0;
3204
+ $link->isOptionLinkChanged = true;
3205
  $link->save();
3206
 
3207
  //Check the link and save the results.
3760
  if ( !wp_next_scheduled('blc_cron_database_maintenance') ){
3761
  wp_schedule_event(time(), 'bimonthly', 'blc_cron_database_maintenance');
3762
  }
3763
+ }
 
 
 
 
 
3764
 
3765
  /**
3766
  * Load the plugin's textdomain.
3771
  $this->is_textdomain_loaded = load_plugin_textdomain( 'broken-link-checker', false, basename(dirname($this->loader)) . '/languages' );
3772
  }
3773
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3774
  protected static function get_default_log_directory() {
3775
  $uploads = wp_upload_dir();
3776
  return $uploads['basedir'] . '/broken-link-checker';
images/embedplus_banner.jpg DELETED
Binary file
images/mwp250_2.jpg DELETED
Binary file
images/mwp250_2.png CHANGED
Binary file
includes/admin/sidebar.php CHANGED
@@ -1,84 +1,6 @@
 
1
  <?php
2
  $configuration = blc_get_configuration();
3
-
4
- if ( !function_exists('fetch_feed') ){
5
- include_once(ABSPATH . WPINC . '/feed.php');
6
- }
7
-
8
- $show_plugin_feed = false;
9
- if ( !$configuration->get('user_has_donated', false) ) {
10
- $show_plugin_feed = true;
11
- }
12
- $show_plugin_feed = false; //Disabled for now to make room for the EmbedPlus banner.
13
- ?>
14
-
15
- <!-- "More plugins" RSS feed -->
16
- <?php
17
- if ( $show_plugin_feed ):
18
- $feed_url = 'http://w-shadow.com/files/blc-plugin-links.rss';
19
- $num_items = 3;
20
-
21
- $feed = fetch_feed($feed_url);
22
- if ( !is_wp_error($feed) ):
23
- ?>
24
- <div id="advertising" class="postbox">
25
- <h3 class="hndle"><?php _e('More plugins by Janis Elsts', 'broken-link-checker'); ?></h3>
26
- <div class="inside">
27
- <ul>
28
- <?php
29
- foreach($feed->get_items(0, $num_items) as $item) { /** @var SimplePie_Item $item */
30
- printf(
31
- '<li><a href="%1$s" title="%2$s">%3$s</a></li>',
32
- esc_url( $item->get_link() ),
33
- esc_attr( strip_tags( $item->get_title() ) ),
34
- esc_html( $item->get_title() )
35
- );
36
- }
37
- ?>
38
- </ul>
39
- </div>
40
- </div>
41
- <?php
42
- endif;
43
- endif;
44
- ?>
45
-
46
- <!-- Donation button -->
47
- <div id="donate" class="postbox">
48
- <h3 class="hndle"><?php _e('Donate $10, $20 or $50!', 'broken-link-checker'); ?></h3>
49
- <div class="inside">
50
- <p><?php
51
- _e('If you like this plugin, please donate to support development and maintenance!', 'broken-link-checker');
52
- ?></p>
53
-
54
- <form style="text-align: center;" action="https://www.paypal.com/cgi-bin/webscr" method="post">
55
- <input type="hidden" name="cmd" value="_donations">
56
- <input type="hidden" name="business" value="G3GGNXHBSHKYC">
57
- <input type="hidden" name="lc" value="US">
58
- <input type="hidden" name="item_name" value="Broken Link Checker">
59
- <input type="hidden" name="no_note" value="1">
60
- <input type="hidden" name="no_shipping" value="1">
61
- <input type="hidden" name="currency_code" value="USD">
62
- <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted">
63
-
64
- <input type="hidden" name="rm" value="2">
65
- <input type="hidden" name="return" value="<?php
66
- echo esc_attr(admin_url('options-general.php?page=link-checker-settings&donated=1'));
67
- ?>" />
68
- <input type="hidden" name="cbt" value="<?php
69
- echo esc_attr(__('Return to WordPress Dashboard', 'broken-link-checker'));
70
- ?>" />
71
- <input type="hidden" name="cancel_return" value="<?php
72
- echo esc_attr(admin_url('options-general.php?page=link-checker-settings&donation_canceled=1'));
73
- ?>" />
74
-
75
- <input type="image" src="https://www.sandbox.paypal.com/en_US/GB/i/btn/btn_donateCC_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." style="max-width:170px;height:47px;border:0;">
76
- </form>
77
- </div>
78
- </div>
79
-
80
- <!-- Other advertising -->
81
- <?php
82
  if ( !$configuration->get('user_has_donated') ):
83
  ?>
84
  <div id="managewp-ad" class="postbox">
1
+ <!-- Advertising -->
2
  <?php
3
  $configuration = blc_get_configuration();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  if ( !$configuration->get('user_has_donated') ):
5
  ?>
6
  <div id="managewp-ad" class="postbox">
includes/config-manager.php CHANGED
@@ -7,121 +7,121 @@
7
 
8
  if ( !class_exists('blcConfigurationManager') ){
9
 
10
- class blcConfigurationManager {
11
-
12
- var $option_name;
13
-
14
- var $options;
15
- var $defaults;
16
- var $loaded_values;
17
-
18
- /**
19
- * @var bool Whether options have been successfully loaded from the database.
20
- */
21
- public $db_option_loaded = false;
22
-
23
- function __construct( $option_name = '', $default_settings = null ){
24
- $this->option_name = $option_name;
25
-
26
- if ( is_array($default_settings) ){
27
- $this->defaults = $default_settings;
28
- } else {
29
- $this->defaults = array();
30
- }
31
- $this->loaded_values = array();
32
-
33
- $this->options = $this->defaults;
34
-
35
- if ( !empty( $this->option_name ) ) {
36
- $this->load_options();
37
- }
38
  }
39
-
40
- function set_defaults( $default_settings = null ){
41
- if ( is_array($default_settings) ){
42
- $this->defaults = array();
43
- } else {
44
- $this->defaults = $default_settings;
45
- }
46
- $this->options = array_merge($this->defaults, $this->loaded_values);
47
  }
48
-
49
- /**
50
- * blcOptionManager::load_options()
51
- * Load plugin options from the database. The current $options values are not affected
52
- * if this function fails.
53
- *
54
- * @param string $option_name
55
- * @return bool True if options were loaded, false otherwise.
56
- */
57
- function load_options( $option_name = '' ){
58
- $this->db_option_loaded = false;
59
-
60
- if ( !empty($option_name) ){
61
- $this->option_name = $option_name;
62
- }
63
-
64
- if ( empty($this->option_name) ) return false;
65
-
66
- $new_options = get_option($this->option_name);
67
-
68
- //Decode JSON (if applicable).
69
- if ( is_string($new_options) && !empty($new_options) ) {
70
- $new_options = json_decode($new_options, true);
71
- }
72
-
73
- if( !is_array( $new_options ) ){
74
- return false;
75
- } else {
76
- $this->loaded_values = $new_options;
77
- $this->options = array_merge( $this->defaults, $this->loaded_values );
78
- $this->db_option_loaded = true;
79
- return true;
80
- }
81
  }
82
-
83
- /**
84
- * blcOptionManager::save_options()
85
- * Save plugin options to the database.
86
- *
87
- * @param string $option_name (Optional) Save the options under this name
88
- * @return bool True if settings were saved, false if settings haven't been changed or if there was an error.
89
- */
90
- function save_options( $option_name = '' ){
91
- if ( !empty($option_name) ){
92
- $this->option_name = $option_name;
93
- }
94
-
95
- if ( empty($this->option_name) ) return false;
96
-
97
- return update_option( $this->option_name, json_encode($this->options) );
 
 
 
 
 
 
 
 
 
98
  }
99
 
100
- /**
101
- * Retrieve a specific setting.
102
- *
103
- * @param string $key
104
- * @param mixed $default
105
- * @return mixed
106
- */
107
- function get($key, $default = null){
108
- if ( array_key_exists($key, $this->options) ){
109
- return $this->options[$key];
110
- } else {
111
- return $default;
112
- }
 
 
 
 
 
 
 
113
  }
 
 
114
 
115
- /**
116
- * Update or add a setting.
117
- *
118
- * @param string $key
119
- * @param mixed $value
120
- * @return void
121
- */
122
- function set($key, $value){
123
- $this->options[$key] = $value;
 
 
 
 
 
 
124
  }
125
  }
126
-
 
 
 
 
 
 
 
 
 
 
127
  }
 
 
7
 
8
  if ( !class_exists('blcConfigurationManager') ){
9
 
10
+ class blcConfigurationManager {
11
+
12
+ var $option_name;
13
+
14
+ var $options;
15
+ var $defaults;
16
+ var $loaded_values;
17
+
18
+ /**
19
+ * @var bool Whether options have been successfully loaded from the database.
20
+ */
21
+ public $db_option_loaded = false;
22
+
23
+ function __construct( $option_name = '', $default_settings = null ){
24
+ $this->option_name = $option_name;
25
+
26
+ if ( is_array($default_settings) ){
27
+ $this->defaults = $default_settings;
28
+ } else {
29
+ $this->defaults = array();
 
 
 
 
 
 
 
 
30
  }
31
+ $this->loaded_values = array();
32
+
33
+ $this->options = $this->defaults;
34
+
35
+ if ( !empty( $this->option_name ) ) {
36
+ $this->load_options();
 
 
37
  }
38
+ }
39
+
40
+ function set_defaults( $default_settings = null ){
41
+ if ( is_array($default_settings) ){
42
+ $this->defaults = array();
43
+ } else {
44
+ $this->defaults = $default_settings;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
+ $this->options = array_merge($this->defaults, $this->loaded_values);
47
+ }
48
+
49
+ /**
50
+ * blcOptionManager::load_options()
51
+ * Load plugin options from the database. The current $options values are not affected
52
+ * if this function fails.
53
+ *
54
+ * @param string $option_name
55
+ * @return bool True if options were loaded, false otherwise.
56
+ */
57
+ function load_options( $option_name = '' ){
58
+ $this->db_option_loaded = false;
59
+
60
+ if ( !empty($option_name) ){
61
+ $this->option_name = $option_name;
62
+ }
63
+
64
+ if ( empty($this->option_name) ) return false;
65
+
66
+ $new_options = get_option($this->option_name);
67
+
68
+ //Decode JSON (if applicable).
69
+ if ( is_string($new_options) && !empty($new_options) ) {
70
+ $new_options = json_decode($new_options, true);
71
  }
72
 
73
+ if( !is_array( $new_options ) ){
74
+ return false;
75
+ } else {
76
+ $this->loaded_values = $new_options;
77
+ $this->options = array_merge( $this->defaults, $this->loaded_values );
78
+ $this->db_option_loaded = true;
79
+ return true;
80
+ }
81
+ }
82
+
83
+ /**
84
+ * blcOptionManager::save_options()
85
+ * Save plugin options to the database.
86
+ *
87
+ * @param string $option_name (Optional) Save the options under this name
88
+ * @return bool True if settings were saved, false if settings haven't been changed or if there was an error.
89
+ */
90
+ function save_options( $option_name = '' ){
91
+ if ( !empty($option_name) ){
92
+ $this->option_name = $option_name;
93
  }
94
+
95
+ if ( empty($this->option_name) ) return false;
96
 
97
+ return update_option( $this->option_name, json_encode($this->options) );
98
+ }
99
+
100
+ /**
101
+ * Retrieve a specific setting.
102
+ *
103
+ * @param string $key
104
+ * @param mixed $default
105
+ * @return mixed
106
+ */
107
+ function get($key, $default = null){
108
+ if ( array_key_exists($key, $this->options) ){
109
+ return $this->options[$key];
110
+ } else {
111
+ return $default;
112
  }
113
  }
114
+
115
+ /**
116
+ * Update or add a setting.
117
+ *
118
+ * @param string $key
119
+ * @param mixed $value
120
+ * @return void
121
+ */
122
+ function set($key, $value){
123
+ $this->options[$key] = $value;
124
+ }
125
  }
126
+
127
+ }
includes/containers.php CHANGED
@@ -274,12 +274,18 @@ class blcContainer {
274
  //FB::log("Parsing $name with '{$parser->parser_type}' parser");
275
  $found_instances = $parser->parse( $value, $base_url, $default_link_text );
276
  //FB::log($found_instances, "Found instances");
277
-
 
 
 
278
  //Complete the link instances by adding container info, then save them to the DB.
279
  foreach($found_instances as $instance){
280
  $instance->set_container($this, $name);
281
  $instance->save();
282
  }
 
 
 
283
  }
284
  }
285
 
274
  //FB::log("Parsing $name with '{$parser->parser_type}' parser");
275
  $found_instances = $parser->parse( $value, $base_url, $default_link_text );
276
  //FB::log($found_instances, "Found instances");
277
+
278
+ $transactionManager = TransactionManager::getInstance();
279
+ $transactionManager->start();
280
+
281
  //Complete the link instances by adding container info, then save them to the DB.
282
  foreach($found_instances as $instance){
283
  $instance->set_container($this, $name);
284
  $instance->save();
285
  }
286
+
287
+ $transactionManager->commit();
288
+
289
  }
290
  }
291
 
includes/links.php CHANGED
@@ -105,7 +105,7 @@ class blcLink {
105
  509=>'Bandwidth Limit Exceeded',
106
  510=>'Not Extended',
107
  );
108
-
109
  function __construct($arg = null){
110
  global $wpdb, $blclog; /** @var wpdb $wpdb */
111
 
@@ -529,7 +529,9 @@ class blcLink {
529
  $values = $this->to_db_format($values);
530
 
531
  if ( $this->is_new ){
532
-
 
 
533
  //BUG: Technically, there should be a 'LOCK TABLES wp_blc_links WRITE' here. In fact,
534
  //the plugin should probably lock all involved tables whenever it parses something, lest
535
  //the user (ot another plugin) modify the thing being parsed while we're working.
@@ -575,7 +577,10 @@ class blcLink {
575
  return $rez;
576
 
577
  } else {
578
-
 
 
 
579
  //Generate the field = dbvalue expressions
580
  $set_exprs = array();
581
  foreach($values as $name => $value){
105
  509=>'Bandwidth Limit Exceeded',
106
  510=>'Not Extended',
107
  );
108
+ var $isOptionLinkChanged = false;
109
  function __construct($arg = null){
110
  global $wpdb, $blclog; /** @var wpdb $wpdb */
111
 
529
  $values = $this->to_db_format($values);
530
 
531
  if ( $this->is_new ){
532
+
533
+ TransactionManager::getInstance()->commit();
534
+
535
  //BUG: Technically, there should be a 'LOCK TABLES wp_blc_links WRITE' here. In fact,
536
  //the plugin should probably lock all involved tables whenever it parses something, lest
537
  //the user (ot another plugin) modify the thing being parsed while we're working.
577
  return $rez;
578
 
579
  } else {
580
+ if ($this->isOptionLinkChanged !== true ) {
581
+ TransactionManager::getInstance()->start();
582
+ }
583
+ $this->isOptionLinkChanged = false;
584
  //Generate the field = dbvalue expressions
585
  $set_exprs = array();
586
  foreach($values as $name => $value){
includes/module-base.php CHANGED
@@ -7,22 +7,22 @@
7
 
8
  /**
9
  * Base class for BLC modules.
10
- *
11
  * @package Broken Link Checker
12
  * @author Janis Elsts
13
  * @access public
14
  */
15
  class blcModule {
16
-
17
  var $module_id; //The ID of this module. Usually a lowercase string.
18
  var $cached_header; //An associative array containing the header data of the module file.
19
  /** @var blcConfigurationManager $plugin__conf */
20
  var $plugin_conf; //A reference to the plugin's global configuration object.
21
  var $module_manager; //A reference to the module manager.
22
-
23
  /**
24
  * Class constructor
25
- *
26
  * @param string $module_id
27
  * @param array $cached_header
28
  * @param blcConfigurationManager $plugin_conf
@@ -34,25 +34,25 @@ class blcModule {
34
  $this->cached_header = $cached_header;
35
  $this->plugin_conf = &$plugin_conf;
36
  $this->module_manager = &$module_manager;
37
-
38
  $this->init();
39
- }
40
-
41
  /**
42
  * Module initializer. Called when the module is first instantiated.
43
  * The default implementation does nothing. Override it in a subclass to
44
- * specify some sort of start-up behaviour.
45
- *
46
  * @return void
47
  */
48
  function init(){
49
  //Should be overridden in a sub-class.
50
  }
51
-
52
  /**
53
  * Called when the module is activated.
54
  * Should be overridden in a sub-class.
55
- *
56
  * @return void
57
  */
58
  function activated(){
@@ -62,7 +62,7 @@ class blcModule {
62
  /**
63
  * Called when the module is deactivated.
64
  * Should be overridden in a sub-class.
65
- *
66
  * @return void
67
  */
68
  function deactivated(){
@@ -76,4 +76,5 @@ class blcModule {
76
  function plugin_activated() {
77
  $this->activated();
78
  }
79
- }
 
7
 
8
  /**
9
  * Base class for BLC modules.
10
+ *
11
  * @package Broken Link Checker
12
  * @author Janis Elsts
13
  * @access public
14
  */
15
  class blcModule {
16
+
17
  var $module_id; //The ID of this module. Usually a lowercase string.
18
  var $cached_header; //An associative array containing the header data of the module file.
19
  /** @var blcConfigurationManager $plugin__conf */
20
  var $plugin_conf; //A reference to the plugin's global configuration object.
21
  var $module_manager; //A reference to the module manager.
22
+
23
  /**
24
  * Class constructor
25
+ *
26
  * @param string $module_id
27
  * @param array $cached_header
28
  * @param blcConfigurationManager $plugin_conf
34
  $this->cached_header = $cached_header;
35
  $this->plugin_conf = &$plugin_conf;
36
  $this->module_manager = &$module_manager;
37
+
38
  $this->init();
39
+ }
40
+
41
  /**
42
  * Module initializer. Called when the module is first instantiated.
43
  * The default implementation does nothing. Override it in a subclass to
44
+ * specify some sort of start-up behaviour.
45
+ *
46
  * @return void
47
  */
48
  function init(){
49
  //Should be overridden in a sub-class.
50
  }
51
+
52
  /**
53
  * Called when the module is activated.
54
  * Should be overridden in a sub-class.
55
+ *
56
  * @return void
57
  */
58
  function activated(){
62
  /**
63
  * Called when the module is deactivated.
64
  * Should be overridden in a sub-class.
65
+ *
66
  * @return void
67
  */
68
  function deactivated(){
76
  function plugin_activated() {
77
  $this->activated();
78
  }
79
+ }
80
+
includes/screen-meta-links.php CHANGED
@@ -9,89 +9,89 @@
9
  if ( !class_exists('wsScreenMetaLinks11') ):
10
 
11
  //Load JSON functions for PHP < 5.2
12
- if ( !(function_exists('json_encode') && function_exists('json_decode')) && !(class_exists('Services_JSON') || class_exists('Moxiecode_JSON')) ){
13
- $class_json_path = ABSPATH.WPINC.'/class-json.php';
14
- $class_moxiecode_json_path = ABSPATH.WPINC.'/js/tinymce/plugins/spellchecker/classes/utils/JSON.php';
15
- if ( file_exists($class_json_path) ){
16
- require $class_json_path;
17
-
18
- } elseif ( file_exists($class_moxiecode_json_path) ) {
19
- require $class_moxiecode_json_path;
20
- }
21
  }
22
-
23
- class wsScreenMetaLinks11 {
24
- var $registered_links; //List of meta links registered for each page.
25
-
26
- /**
27
- * Class constructor.
28
- *
29
- * @return void
30
- */
31
- function __construct(){
32
- $this->registered_links = array();
33
-
34
- add_action('admin_notices', array(&$this, 'append_meta_links'));
35
- add_action('admin_print_styles', array(&$this, 'add_link_styles'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
-
38
- /**
39
- * Add a new link to the screen meta area.
40
- *
41
- * Do not call this method directly. Instead, use the global add_screen_meta_link() function.
42
- *
43
- * @param string $id Link ID. Should be unique and a valid value for a HTML ID attribute.
44
- * @param string $text Link text.
45
- * @param string $href Link URL.
46
- * @param string|array $page The page(s) where you want to add the link.
47
- * @param array $attributes Optional. Additional attributes for the link tag.
48
- * @return void
49
- */
50
- function add_screen_meta_link($id, $text, $href, $page, $attributes = null){
51
- if ( !is_array($page) ){
52
- $page = array($page);
53
- }
54
- if ( is_null($attributes) ){
55
- $attributes = array();
56
- }
57
-
58
- //Basically a list of props for a jQuery() call
59
- $link = compact('id', 'text', 'href');
60
- $link = array_merge($link, $attributes);
61
-
62
- //Add the CSS classes that will make the look like a proper meta link
63
- if ( empty($link['class']) ){
64
- $link['class'] = '';
65
- }
66
- $link['class'] = 'show-settings custom-screen-meta-link ' . $link['class'];
67
-
68
- //Save the link in each relevant page's list
69
- foreach($page as $page_id){
70
- if ( !isset($this->registered_links[$page_id]) ){
71
- $this->registered_links[$page_id] = array();
72
- }
73
- $this->registered_links[$page_id][] = $link;
74
- }
75
  }
76
-
77
- /**
78
- * Output the JS that appends the custom meta links to the page.
79
- * Callback for the 'admin_notices' action.
80
- *
81
- * @access private
82
- * @return void
83
- */
84
- function append_meta_links(){
85
- global $hook_suffix;
86
-
87
- //Find links registered for this page
88
- $links = $this->get_links_for_page($hook_suffix);
89
- if ( empty($links) ){
90
- return;
91
  }
92
-
93
- ?>
94
- <script type="text/javascript">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  (function($, links){
96
  var container = $('#screen-meta-links');
97
  if ( container.length == 0 ) {
@@ -109,185 +109,185 @@ if ( !class_exists('wsScreenMetaLinks11') ):
109
  }
110
  })(jQuery, <?php echo $this->json_encode($links); ?>);
111
  </script>
112
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  }
114
-
115
- /**
116
- * Get a list of custom screen meta links registered for a specific page.
117
- *
118
- * @param string $page
119
- * @return array
120
- */
121
- function get_links_for_page($page){
122
- $links = array();
123
-
124
- if ( isset($this->registered_links[$page]) ){
125
- $links = array_merge($links, $this->registered_links[$page]);
126
- }
127
- $page_as_screen = $this->page_to_screen_id($page);
128
- if ( ($page_as_screen != $page) && isset($this->registered_links[$page_as_screen]) ){
129
- $links = array_merge($links, $this->registered_links[$page_as_screen]);
130
- }
131
-
132
- return $links;
133
  }
134
-
135
- /**
136
- * Output the CSS code for custom screen meta links. Required because WP only
137
- * has styles for specific meta links (by #id), not meta links in general.
138
- *
139
- * Callback for 'admin_print_styles'.
140
- *
141
- * @access private
142
- * @return void
143
- */
144
- function add_link_styles(){
145
- global $hook_suffix;
146
- //Don't output the CSS if there are no custom meta links for this page.
147
- $links = $this->get_links_for_page($hook_suffix);
148
- if ( empty($links) ){
149
- return;
150
- }
151
-
152
- if ( !isset($GLOBALS['wp_version']) || version_compare($GLOBALS['wp_version'], '3.8-RC1', '<') ) {
153
- $this->print_old_link_styles();
154
- } else {
155
- $this->print_link_styles();
156
- }
157
  }
158
-
159
- /**
160
- * Print screen meta button styles (WP 3.8+).
161
- */
162
- private function print_link_styles() {
163
- ?>
164
- <style type="text/css">
165
- .custom-screen-meta-link-wrap {
166
- float: right;
167
- height: 28px;
168
- margin: 0 0 0 6px;
169
-
170
- border: 1px solid #ddd;
171
- border-top: none;
172
- background: #fff;
173
- -webkit-box-shadow: 0 1px 1px -1px rgba(0,0,0,0.1);
174
- box-shadow: 0 1px 1px -1px rgba(0,0,0,0.1);
175
- }
176
-
177
- #screen-meta .custom-screen-meta-link-wrap a.custom-screen-meta-link,
178
- #screen-meta-links .custom-screen-meta-link-wrap a.custom-screen-meta-link
179
- {
180
- padding: 3px 16px 3px 16px;
181
- }
182
-
183
- #screen-meta-links a.custom-screen-meta-link::after {
184
- display: none;
185
- }
186
- </style>
187
- <?php
188
  }
 
189
 
190
- /**
191
- * Print old screen meta button styles (WP 3.7.x and older).
192
- */
193
- private function print_old_link_styles() {
194
- ?>
195
- <style type="text/css">
196
- .custom-screen-meta-link-wrap {
197
- float: right;
198
- height: 22px;
199
- padding: 0;
200
- margin: 0 0 0 6px;
201
- font-family: sans-serif;
202
- -moz-border-radius-bottomleft: 3px;
203
- -moz-border-radius-bottomright: 3px;
204
- -webkit-border-bottom-left-radius: 3px;
205
- -webkit-border-bottom-right-radius: 3px;
206
- border-bottom-left-radius: 3px;
207
- border-bottom-right-radius: 3px;
208
-
209
- background: #e3e3e3;
210
 
211
- border-right: 1px solid transparent;
212
- border-left: 1px solid transparent;
213
- border-bottom: 1px solid transparent;
214
- background-image: -ms-linear-gradient(bottom, #dfdfdf, #f1f1f1); /* IE10 */
215
- background-image: -moz-linear-gradient(bottom, #dfdfdf, #f1f1f1); /* Firefox */
216
- background-image: -o-linear-gradient(bottom, #dfdfdf, #f1f1f1); /* Opera */
217
- background-image: -webkit-gradient(linear, left bottom, left top, from(#dfdfdf), to(#f1f1f1)); /* old Webkit */
218
- background-image: -webkit-linear-gradient(bottom, #dfdfdf, #f1f1f1); /* new Webkit */
219
- background-image: linear-gradient(bottom, #dfdfdf, #f1f1f1); /* proposed W3C Markup */
220
- }
221
 
222
- #screen-meta .custom-screen-meta-link-wrap a.custom-screen-meta-link,
223
- #screen-meta-links .custom-screen-meta-link-wrap a.custom-screen-meta-link
224
- {
225
- background-image: none;
226
- padding-right: 6px;
227
- color: #777;
228
- }
229
  </style>
230
- <?php
231
- }
232
 
233
- /**
234
- * Convert a page hook name to a screen ID.
235
- *
236
- * @uses convert_to_screen()
237
- * @access private
238
- *
239
- * @param string $page
240
- * @return string
241
- */
242
- function page_to_screen_id($page){
243
- if ( function_exists('convert_to_screen') ){
244
- $screen = convert_to_screen($page);
245
- if ( isset($screen->id) ){
246
- return $screen->id;
247
- } else {
248
- return '';
249
- }
250
- } else {
251
- return str_replace( array('.php', '-new', '-add' ), '', $page);
 
 
 
 
 
 
 
 
 
 
 
252
  }
253
- }
254
 
255
- /**
256
- * Back-wards compatible json_encode(). Used to encode link data before
257
- * passing it to the JavaScript that actually creates the links.
258
- *
259
- * @param mixed $data
260
- * @return string
261
- */
262
- function json_encode($data){
263
- if ( function_exists('json_encode') ){
264
- return json_encode($data);
265
  }
266
- if ( class_exists('Services_JSON') ){
267
- $json = new Services_JSON();
268
- return( $json->encodeUnsafe($data) );
269
- } elseif ( class_exists('Moxiecode_JSON') ){
270
- $json = new Moxiecode_JSON();
271
- return $json->encode($data);
 
 
 
 
 
 
 
 
 
 
 
 
272
  } else {
273
- trigger_error('No JSON parser available', E_USER_ERROR);
274
- return null;
275
  }
 
 
276
  }
277
-
278
  }
279
-
280
- global $ws_screen_meta_links_versions;
281
- if ( !isset($ws_screen_meta_links_versions) ){
282
- $ws_screen_meta_links_versions = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  }
284
- $ws_screen_meta_links_versions['1.1'] = 'wsScreenMetaLinks11';
 
 
 
 
 
 
 
285
 
286
  endif;
287
 
288
  /**
289
  * Add a new link to the screen meta area.
290
- *
291
  * @param string $id Link ID. Should be unique and a valid value for a HTML ID attribute.
292
  * @param string $text Link text.
293
  * @param string $href Link URL.
@@ -297,7 +297,7 @@ endif;
297
  */
298
  function add_screen_meta_link($id, $text, $href, $page, $attributes = null){
299
  global $ws_screen_meta_links_versions;
300
-
301
  static $instance = null;
302
  if ( is_null($instance) ){
303
  //Instantiate the latest version of the wsScreenMetaLinks class
@@ -305,8 +305,8 @@ function add_screen_meta_link($id, $text, $href, $page, $attributes = null){
305
  $className = end($ws_screen_meta_links_versions);
306
  $instance = new $className;
307
  }
308
-
309
  $instance->add_screen_meta_link($id, $text, $href, $page, $attributes);
310
  }
311
 
312
- ?>
9
  if ( !class_exists('wsScreenMetaLinks11') ):
10
 
11
  //Load JSON functions for PHP < 5.2
12
+ if ( !(function_exists('json_encode') && function_exists('json_decode')) && !(class_exists('Services_JSON') || class_exists('Moxiecode_JSON')) ){
13
+ $class_json_path = ABSPATH.WPINC.'/class-json.php';
14
+ $class_moxiecode_json_path = ABSPATH.WPINC.'/js/tinymce/plugins/spellchecker/classes/utils/JSON.php';
15
+ if ( file_exists($class_json_path) ){
16
+ require $class_json_path;
17
+
18
+ } elseif ( file_exists($class_moxiecode_json_path) ) {
19
+ require $class_moxiecode_json_path;
 
20
  }
21
+ }
22
+
23
+ class wsScreenMetaLinks11 {
24
+ var $registered_links; //List of meta links registered for each page.
25
+
26
+ /**
27
+ * Class constructor.
28
+ *
29
+ * @return void
30
+ */
31
+ function __construct(){
32
+ $this->registered_links = array();
33
+
34
+ add_action('admin_notices', array(&$this, 'append_meta_links'));
35
+ add_action('admin_print_styles', array(&$this, 'add_link_styles'));
36
+ }
37
+
38
+ /**
39
+ * Add a new link to the screen meta area.
40
+ *
41
+ * Do not call this method directly. Instead, use the global add_screen_meta_link() function.
42
+ *
43
+ * @param string $id Link ID. Should be unique and a valid value for a HTML ID attribute.
44
+ * @param string $text Link text.
45
+ * @param string $href Link URL.
46
+ * @param string|array $page The page(s) where you want to add the link.
47
+ * @param array $attributes Optional. Additional attributes for the link tag.
48
+ * @return void
49
+ */
50
+ function add_screen_meta_link($id, $text, $href, $page, $attributes = null){
51
+ if ( !is_array($page) ){
52
+ $page = array($page);
53
  }
54
+ if ( is_null($attributes) ){
55
+ $attributes = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  }
57
+
58
+ //Basically a list of props for a jQuery() call
59
+ $link = compact('id', 'text', 'href');
60
+ $link = array_merge($link, $attributes);
61
+
62
+ //Add the CSS classes that will make the look like a proper meta link
63
+ if ( empty($link['class']) ){
64
+ $link['class'] = '';
65
+ }
66
+ $link['class'] = 'show-settings custom-screen-meta-link ' . $link['class'];
67
+
68
+ //Save the link in each relevant page's list
69
+ foreach($page as $page_id){
70
+ if ( !isset($this->registered_links[$page_id]) ){
71
+ $this->registered_links[$page_id] = array();
72
  }
73
+ $this->registered_links[$page_id][] = $link;
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Output the JS that appends the custom meta links to the page.
79
+ * Callback for the 'admin_notices' action.
80
+ *
81
+ * @access private
82
+ * @return void
83
+ */
84
+ function append_meta_links(){
85
+ global $hook_suffix;
86
+
87
+ //Find links registered for this page
88
+ $links = $this->get_links_for_page($hook_suffix);
89
+ if ( empty($links) ){
90
+ return;
91
+ }
92
+
93
+ ?>
94
+ <script type="text/javascript">
95
  (function($, links){
96
  var container = $('#screen-meta-links');
97
  if ( container.length == 0 ) {
109
  }
110
  })(jQuery, <?php echo $this->json_encode($links); ?>);
111
  </script>
112
+ <?php
113
+ }
114
+
115
+ /**
116
+ * Get a list of custom screen meta links registered for a specific page.
117
+ *
118
+ * @param string $page
119
+ * @return array
120
+ */
121
+ function get_links_for_page($page){
122
+ $links = array();
123
+
124
+ if ( isset($this->registered_links[$page]) ){
125
+ $links = array_merge($links, $this->registered_links[$page]);
126
  }
127
+ $page_as_screen = $this->page_to_screen_id($page);
128
+ if ( ($page_as_screen != $page) && isset($this->registered_links[$page_as_screen]) ){
129
+ $links = array_merge($links, $this->registered_links[$page_as_screen]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  }
131
+
132
+ return $links;
133
+ }
134
+
135
+ /**
136
+ * Output the CSS code for custom screen meta links. Required because WP only
137
+ * has styles for specific meta links (by #id), not meta links in general.
138
+ *
139
+ * Callback for 'admin_print_styles'.
140
+ *
141
+ * @access private
142
+ * @return void
143
+ */
144
+ function add_link_styles(){
145
+ global $hook_suffix;
146
+ //Don't output the CSS if there are no custom meta links for this page.
147
+ $links = $this->get_links_for_page($hook_suffix);
148
+ if ( empty($links) ){
149
+ return;
 
 
 
 
150
  }
151
+
152
+ if ( !isset($GLOBALS['wp_version']) || version_compare($GLOBALS['wp_version'], '3.8-RC1', '<') ) {
153
+ $this->print_old_link_styles();
154
+ } else {
155
+ $this->print_link_styles();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  }
157
+ }
158
 
159
+ /**
160
+ * Print screen meta button styles (WP 3.8+).
161
+ */
162
+ private function print_link_styles() {
163
+ ?>
164
+ <style type="text/css">
165
+ .custom-screen-meta-link-wrap {
166
+ float: right;
167
+ height: 28px;
168
+ margin: 0 0 0 6px;
169
+
170
+ border: 1px solid #ddd;
171
+ border-top: none;
172
+ background: #fff;
173
+ -webkit-box-shadow: 0 1px 1px -1px rgba(0,0,0,0.1);
174
+ box-shadow: 0 1px 1px -1px rgba(0,0,0,0.1);
175
+ }
 
 
 
176
 
177
+ #screen-meta .custom-screen-meta-link-wrap a.custom-screen-meta-link,
178
+ #screen-meta-links .custom-screen-meta-link-wrap a.custom-screen-meta-link
179
+ {
180
+ padding: 3px 16px 3px 16px;
181
+ }
 
 
 
 
 
182
 
183
+ #screen-meta-links a.custom-screen-meta-link::after {
184
+ display: none;
185
+ }
 
 
 
 
186
  </style>
187
+ <?php
188
+ }
189
 
190
+ /**
191
+ * Print old screen meta button styles (WP 3.7.x and older).
192
+ */
193
+ private function print_old_link_styles() {
194
+ ?>
195
+ <style type="text/css">
196
+ .custom-screen-meta-link-wrap {
197
+ float: right;
198
+ height: 22px;
199
+ padding: 0;
200
+ margin: 0 0 0 6px;
201
+ font-family: sans-serif;
202
+ -moz-border-radius-bottomleft: 3px;
203
+ -moz-border-radius-bottomright: 3px;
204
+ -webkit-border-bottom-left-radius: 3px;
205
+ -webkit-border-bottom-right-radius: 3px;
206
+ border-bottom-left-radius: 3px;
207
+ border-bottom-right-radius: 3px;
208
+
209
+ background: #e3e3e3;
210
+
211
+ border-right: 1px solid transparent;
212
+ border-left: 1px solid transparent;
213
+ border-bottom: 1px solid transparent;
214
+ background-image: -ms-linear-gradient(bottom, #dfdfdf, #f1f1f1); /* IE10 */
215
+ background-image: -moz-linear-gradient(bottom, #dfdfdf, #f1f1f1); /* Firefox */
216
+ background-image: -o-linear-gradient(bottom, #dfdfdf, #f1f1f1); /* Opera */
217
+ background-image: -webkit-gradient(linear, left bottom, left top, from(#dfdfdf), to(#f1f1f1)); /* old Webkit */
218
+ background-image: -webkit-linear-gradient(bottom, #dfdfdf, #f1f1f1); /* new Webkit */
219
+ background-image: linear-gradient(bottom, #dfdfdf, #f1f1f1); /* proposed W3C Markup */
220
  }
 
221
 
222
+ #screen-meta .custom-screen-meta-link-wrap a.custom-screen-meta-link,
223
+ #screen-meta-links .custom-screen-meta-link-wrap a.custom-screen-meta-link
224
+ {
225
+ background-image: none;
226
+ padding-right: 6px;
227
+ color: #777;
 
 
 
 
228
  }
229
+ </style>
230
+ <?php
231
+ }
232
+
233
+ /**
234
+ * Convert a page hook name to a screen ID.
235
+ *
236
+ * @uses convert_to_screen()
237
+ * @access private
238
+ *
239
+ * @param string $page
240
+ * @return string
241
+ */
242
+ function page_to_screen_id($page){
243
+ if ( function_exists('convert_to_screen') ){
244
+ $screen = convert_to_screen($page);
245
+ if ( isset($screen->id) ){
246
+ return $screen->id;
247
  } else {
248
+ return '';
 
249
  }
250
+ } else {
251
+ return str_replace( array('.php', '-new', '-add' ), '', $page);
252
  }
 
253
  }
254
+
255
+ /**
256
+ * Back-wards compatible json_encode(). Used to encode link data before
257
+ * passing it to the JavaScript that actually creates the links.
258
+ *
259
+ * @param mixed $data
260
+ * @return string
261
+ */
262
+ function json_encode($data){
263
+ if ( function_exists('json_encode') ){
264
+ return json_encode($data);
265
+ }
266
+ if ( class_exists('Services_JSON') ){
267
+ $json = new Services_JSON();
268
+ return( $json->encodeUnsafe($data) );
269
+ } elseif ( class_exists('Moxiecode_JSON') ){
270
+ $json = new Moxiecode_JSON();
271
+ return $json->encode($data);
272
+ } else {
273
+ trigger_error('No JSON parser available', E_USER_ERROR);
274
+ return null;
275
+ }
276
  }
277
+
278
+ }
279
+
280
+ global $ws_screen_meta_links_versions;
281
+ if ( !isset($ws_screen_meta_links_versions) ){
282
+ $ws_screen_meta_links_versions = array();
283
+ }
284
+ $ws_screen_meta_links_versions['1.1'] = 'wsScreenMetaLinks11';
285
 
286
  endif;
287
 
288
  /**
289
  * Add a new link to the screen meta area.
290
+ *
291
  * @param string $id Link ID. Should be unique and a valid value for a HTML ID attribute.
292
  * @param string $text Link text.
293
  * @param string $href Link URL.
297
  */
298
  function add_screen_meta_link($id, $text, $href, $page, $attributes = null){
299
  global $ws_screen_meta_links_versions;
300
+
301
  static $instance = null;
302
  if ( is_null($instance) ){
303
  //Instantiate the latest version of the wsScreenMetaLinks class
305
  $className = end($ws_screen_meta_links_versions);
306
  $instance = new $className;
307
  }
308
+
309
  $instance->add_screen_meta_link($id, $text, $href, $page, $attributes);
310
  }
311
 
312
+ ?>
includes/survey.php DELETED
@@ -1,58 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * @author Janis Elsts
5
- * @copyright 2010
6
- */
7
-
8
- //Appearify the survey notice to people who have used BLC for at least 2 weeks (doesn't need to be very accurate)
9
- $blc_config = blc_get_configuration();
10
- $blc_show_survey = empty($blc_config->options['hide_surveyio_notice'])
11
- && !empty($blc_config->options['first_installation_timestamp'])
12
- && ( time() - $blc_config->options['first_installation_timestamp'] > 2*7*24*60*60 );
13
-
14
- if ( $blc_show_survey ){
15
- add_action('admin_notices', 'blc_display_survey_notice');
16
- }
17
-
18
- /**
19
- * Display a notice asking the user to take the Broken Link Checker user survey.
20
- *
21
- * @return void
22
- */
23
- function blc_display_survey_notice(){
24
- //Only people who can actually use the plugin will see the notice
25
- if ( !current_user_can('manage_links') ) return;
26
-
27
- if ( !empty($_GET['dismiss-blc-survey']) ){
28
- //The user has chosen to hide the survey notice
29
- $blc_config = blc_get_configuration();
30
- $blc_config->options['hide_surveyio_notice'] = true;
31
- $blc_config->save_options();
32
- return;
33
- }
34
-
35
- $survey_url = 'http://survey.io/survey/7fbf0';
36
-
37
- $msg = sprintf(
38
- '<strong>Help improve Broken Link Checker - <a href="%s" target="_blank" title="This link will open in a new window" id="blc-take-survey-link">take a user feedback survey!</a></strong>
39
- <br><a href="%s" id="blc-dismiss-survey-notice">Hide this notice</a>',
40
- $survey_url,
41
- esc_attr(add_query_arg('dismiss-blc-survey', 1))
42
- );
43
-
44
- echo '<div id="update-nag" class="blc-survey-notice" style="text-align: left; padding-left: 10px;">'.$msg.'</div>';
45
-
46
- //Auto-hide the notice after the user clicks the survey link
47
- ?>
48
- <script type="text/javascript">
49
- jQuery(function($){
50
- $('#blc-take-survey-link').click(function(){
51
- $('.blc-survey-notice').hide('fast');
52
- $.get($('#blc-dismiss-survey-notice').attr('href'));
53
- });
54
- });
55
- </script>
56
- <?php
57
- }
58
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/transactions-manager.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class TransactionManager
4
+ {
5
+ private $isTransactionStarted = false;
6
+ static private $instance;
7
+
8
+ public function start()
9
+ {
10
+ global $wpdb;
11
+
12
+ if (!$this->isTransactionStarted) {
13
+ $wpdb->query('BEGIN');
14
+ $this->isTransactionStarted = true;
15
+ }
16
+ }
17
+
18
+ public function commit()
19
+ {
20
+ global $wpdb;
21
+
22
+ $this->start();
23
+
24
+ try {
25
+ $wpdb->query('COMMIT');
26
+ $this->isTransactionStarted = false;
27
+ } catch (Exception $e) {
28
+ $wpdb->query('ROLLBACK');
29
+ $this->isTransactionStarted = false;
30
+ }
31
+ }
32
+
33
+ static public function getInstance()
34
+ {
35
+ if (empty(static::$instance)) {
36
+ static::$instance = new static();
37
+ }
38
+
39
+ return static::$instance;
40
+ }
41
+ }
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link:
4
  Tags: links, broken, maintenance, blogroll, custom fields, admin, comments, posts
5
  Requires at least: 3.2
6
  Tested up to: 4.4.1
7
- Stable tag: 1.10.11
8
 
9
  This plugin will check your posts, comments and other content for broken links and missing images, and notify you if any are found.
10
 
@@ -101,6 +101,10 @@ To upgrade your installation
101
 
102
  == Changelog ==
103
 
 
 
 
 
104
  = 1.10.11 =
105
  * Fixed the issue with HTTPS (Thanks to [gmcinnes](https://wordpress.org/support/profile/gmcinnes))
106
  * Broken Link Checker is now on [GitHub](https://github.com/ManageWP/broken-link-checker). Pull Requests welcome.
4
  Tags: links, broken, maintenance, blogroll, custom fields, admin, comments, posts
5
  Requires at least: 3.2
6
  Tested up to: 4.4.1
7
+ Stable tag: 1.11.1
8
 
9
  This plugin will check your posts, comments and other content for broken links and missing images, and notify you if any are found.
10
 
101
 
102
  == Changelog ==
103
 
104
+ = 1.11.1 =
105
+ * Major performance improvement. Database queries reduced up to 10x in some cases.
106
+ * Feel free to contribute to the plugin on [GitHub](https://github.com/ManageWP/broken-link-checker). Pull requests welcome!
107
+
108
  = 1.10.11 =
109
  * Fixed the issue with HTTPS (Thanks to [gmcinnes](https://wordpress.org/support/profile/gmcinnes))
110
  * Broken Link Checker is now on [GitHub](https://github.com/ManageWP/broken-link-checker). Pull Requests welcome.