Broken Link Checker - Version 0.1

Version Description

Download this release

Release Info

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

Version 0.1

Files changed (3) hide show
  1. broken-link-checker.php +341 -0
  2. readme.txt +36 -0
  3. wsblc_ajax.php +257 -0
broken-link-checker.php ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
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 posts for broken links in background and notifies you on the dashboard if any are found.
6
+ Version: 0.1
7
+ Author: Janis Elsts
8
+ Author URI: http://w-shadow.com/blog/
9
+ */
10
+
11
+ /*
12
+ Copyright 2007 Janis Elsts (email : whiteshadow@w-shadow.com)
13
+ */
14
+
15
+ if (!class_exists('ws_broken_link_checker')) {
16
+
17
+ class ws_broken_link_checker {
18
+ var $options;
19
+ var $options_name='wsblc_options';
20
+ var $postdata_name;
21
+ var $linkdata_name;
22
+ var $version='0.1';
23
+ var $myfile='';
24
+ var $myfolder='';
25
+ var $mybasename='';
26
+
27
+
28
+ function ws_broken_link_checker() {
29
+ global $wpdb;
30
+
31
+ $this->postdata_name=$wpdb->prefix . "blc_postdata";
32
+ $this->linkdata_name=$wpdb->prefix . "blc_linkdata";
33
+ $this->options=get_option($this->options_name);
34
+
35
+ $my_file = str_replace('\\', '/',__FILE__);
36
+ $my_file = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', $my_file);
37
+ add_action('activate_'.$my_file, array(&$this,'activation'));
38
+ $this->myfile=$my_file;
39
+ $this->myfolder=basename(dirname(__FILE__));
40
+ $this->mybasename=plugin_basename(__FILE__);
41
+
42
+ add_action('admin_menu', array(&$this,'options_menu'));
43
+
44
+ add_action('delete_post', array(&$this,'post_deleted'));
45
+ add_action('save_post', array(&$this,'post_saved'));
46
+ add_action('admin_footer', array(&$this,'admin_footer'));
47
+ add_action('admin_print_scripts', array(&$this,'admin_print_scripts'));
48
+ add_action('activity_box_end', array(&$this,'activity_box'));
49
+ }
50
+
51
+ function admin_footer(){
52
+ ?>
53
+ <!-- wsblc admin footer -->
54
+ <div id='wsblc_updater_div'></div>
55
+ <script type='text/javascript'>
56
+ new Ajax.PeriodicalUpdater('wsblc_updater_div', '<?php
57
+ echo get_option( "siteurl" ).'/wp-content/plugins/'.$this->myfolder.'/wsblc_ajax.php?action=run_check' ; ?>',
58
+ {
59
+ method: 'get',
60
+ frequency: <?php echo ($this->options['max_work_session']-1); ?>,
61
+ decay: 1.3
62
+ });
63
+ </script>
64
+ <!-- /wsblc admin footer -->
65
+ <?php
66
+ }
67
+
68
+ function activity_box(){
69
+ ?>
70
+ <!-- wsblc activity box -->
71
+ <div id='wsblc_activity_box'></div>
72
+ <script type='text/javascript'>
73
+ new Ajax.Updater('wsblc_activity_box', '<?php
74
+ echo get_option( "siteurl" ).'/wp-content/plugins/'.$this->myfolder.'/wsblc_ajax.php?action=dashboard_status' ; ?>');
75
+ </script>
76
+ <!-- /wsblc activity box -->
77
+ <?php
78
+ }
79
+
80
+ function admin_print_scripts(){
81
+ // use JavaScript Prototype library for AJAX
82
+ wp_print_scripts( array( 'prototype' ) );
83
+ }
84
+
85
+ function post_deleted($post_id){
86
+ global $wpdb;
87
+ $sql="DELETE FROM ".$this->linksdata_name." WHERE post_id=$post_id";
88
+ $wpdb->query($sql);
89
+ $sql="DELETE FROM ".$this->postdata_name." WHERE post_id=$post_id";
90
+ $wpdb->query($sql);
91
+ }
92
+
93
+ function post_saved($post_id){
94
+ global $wpdb;
95
+
96
+ $found=$wpdb->get_var("SELECT post_id FROM $this->postdata_name WHERE post_id=$post_id LIMIT 1");
97
+ if($found===NULL){
98
+ //this post hasn't been saved previously, save the additional data now
99
+ $wpdb->query("INSERT INTO $this->postdata_name (post_id, last_check) VALUES($post_id, '00-00-0000 00:00:00')");
100
+ } else {
101
+ //mark the post as not checked
102
+ $wpdb->query("UPDATE $this->postdata_name SET last_check='00-00-0000 00:00:00' WHERE post_id=$post_id");
103
+ //delete the previously extracted links - they are possibly no longer in the post
104
+ $wpdb->query("DELETE FROM $this->linkdata_name WHERE post_id=$post_id");
105
+ }
106
+ }
107
+
108
+
109
+ function sync_posts_to_db(){
110
+ global $wpdb;
111
+
112
+ $sql="INSERT INTO ".$this->postdata_name."( post_id, last_check )
113
+ SELECT id, '00-00-0000 00:00:00'
114
+ FROM $wpdb->posts b
115
+ WHERE NOT EXISTS (
116
+ SELECT post_id
117
+ FROM ".$this->postdata_name." a
118
+ WHERE a.post_id = b.id
119
+ )";
120
+ $wpdb->query($sql);
121
+ }
122
+
123
+ function activation(){
124
+ global $wpdb;
125
+
126
+ if(!is_array($this->options)){
127
+
128
+ //set default options
129
+ $this->options=array(
130
+ 'version' => $this->version,
131
+ 'max_work_session' => 27,
132
+ 'check_treshold' => 72
133
+ );
134
+
135
+ update_option($this->options_name, $this->options);
136
+ };
137
+
138
+ if($wpdb->get_var("show tables like '".($this->postdata_name)."'") != $this->postdata_name) {
139
+ $sql="CREATE TABLE ".$this->postdata_name." (
140
+ post_id BIGINT( 20 ) NOT NULL ,
141
+ last_check DATETIME NOT NULL ,
142
+ UNIQUE KEY post_id (post_id)
143
+ );";
144
+
145
+ require_once(ABSPATH . 'wp-admin/upgrade-functions.php');
146
+ dbDelta($sql);
147
+ }
148
+
149
+ if($wpdb->get_var("show tables like '".($this->linkdata_name)."'") != $this->linkdata_name) {
150
+ $sql="CREATE TABLE ".$this->linkdata_name." (
151
+ id BIGINT( 20 ) UNSIGNED NOT NULL AUTO_INCREMENT ,
152
+ post_id BIGINT( 20 ) NOT NULL ,
153
+ url TEXT NOT NULL ,
154
+ link_text VARCHAR( 50 ) NOT NULL ,
155
+ broken TINYINT( 1 ) UNSIGNED DEFAULT '0' NOT NULL,
156
+ last_check DATETIME NOT NULL ,
157
+ hidden TINYINT( 1 ) UNSIGNED DEFAULT '0' NOT NULL,
158
+ PRIMARY KEY id (id)
159
+ );";
160
+
161
+ require_once(ABSPATH . 'wp-admin/upgrade-functions.php');
162
+ dbDelta($sql);
163
+ }
164
+
165
+ $this->sync_posts_to_db();
166
+ }
167
+
168
+ function options_menu(){
169
+ add_options_page('Link Checker Settings', 'Link Checker', 'manage_options',
170
+ __FILE__,array(&$this, 'options_page'));
171
+ add_management_page('View Broken Links', 'Broken Links', 'manage_options',
172
+ __FILE__,array(&$this, 'broken_links_page'));
173
+ }
174
+
175
+ function mytruncate($str, $max_length=50){
176
+ if(strlen($str)<=$max_length) return $str;
177
+ return (substr($str, 0, $max_length-3).'...');
178
+ }
179
+
180
+ function options_page(){
181
+
182
+ $this->options = get_option('wsblc_options');
183
+ $reminder = '';
184
+ if (isset($_GET['updated']) && ($_GET['updated'] == 'true')) {
185
+ if(isset($_POST['Submit'])) {
186
+
187
+ $new_session_length=intval($_POST['max_work_session']);
188
+ if( $new_session_length >0 ){
189
+ $this->options['max_work_session']=$new_session_length;
190
+ }
191
+
192
+ $new_check_treshold=intval($_POST['check_treshold']);
193
+ if( $new_check_treshold > 0 ){
194
+ $this->options['check_treshold']=$new_check_treshold;
195
+ }
196
+
197
+ update_option($this->options_name,$this->options);
198
+ }
199
+
200
+ }
201
+ echo $reminder;
202
+ ?>
203
+ <div class="wrap"><h2>Broken Link Checker Options</h2>
204
+ <form name="link_checker_options" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=<?php echo plugin_basename(__FILE__); ?>&amp;updated=true">
205
+ <p class="submit"><input type="submit" name="Submit" value="Update Options &raquo;" /></p>
206
+
207
+ <table class="optiontable">
208
+
209
+ <tr valign="top">
210
+ <th scope="row">Status:</th>
211
+ <td>
212
+
213
+
214
+ <div id='wsblc_full_status'>
215
+ <br/><br/>
216
+ </div>
217
+ <script type='text/javascript'>
218
+ new Ajax.PeriodicalUpdater('wsblc_full_status', '<?php
219
+ echo get_option( "siteurl" ).'/wp-content/plugins/'.$this->myfolder.'/wsblc_ajax.php?action=full_status' ; ?>',
220
+ {
221
+ method: 'get',
222
+ frequency: 10,
223
+ decay: 2
224
+ });
225
+ </script>
226
+ </td>
227
+ </tr>
228
+
229
+ <tr valign="top">
230
+ <th scope="row">Check Every Post:</th>
231
+ <td>
232
+
233
+ Every <input type="text" name="check_treshold" id="check_treshold"
234
+ value="<?php echo $this->options['check_treshold']; ?>" size='5' maxlength='3'/>
235
+ hours
236
+ <br/>
237
+ Links in old posts will be re-checked this often. New posts will be usually checked ASAP.
238
+
239
+ </td>
240
+ </tr>
241
+
242
+ <tr valign="top">
243
+ <th scope="row">Work Session Length:</th>
244
+ <td>
245
+
246
+ <input type="text" name="max_work_session" id="max_work_session"
247
+ value="<?php echo $this->options['max_work_session']; ?>" size='5' maxlength='3'/>
248
+ seconds
249
+ <br/>
250
+ The link checker does its work in short "sessions" while any page of the WP admin panel is open.
251
+ Typically you won't need to change this value.
252
+
253
+ </td>
254
+ </tr>
255
+
256
+ </table>
257
+
258
+ <p class="submit"><input type="submit" name="Submit" value="Update Options &raquo;" /></p>
259
+ </form>
260
+ </div>
261
+ <?php
262
+ }
263
+
264
+ function broken_links_page(){
265
+ global $wpdb;
266
+ $sql="SELECT count(*) FROM $this->linkdata_name WHERE broken=1 AND hidden=0";
267
+ $broken_links=$wpdb->get_var($sql);
268
+
269
+ ?>
270
+ <div class="wrap">
271
+ <h2><?php
272
+ echo ($broken_links>0)?"$broken_links Broken Links":"No broken links found";
273
+ ?></h2>
274
+ <br style="clear:both;" />
275
+ <?php
276
+ $sql="SELECT b.post_title, a.* FROM $this->linkdata_name a, $wpdb->posts b
277
+ WHERE a.post_id=b.id AND a.broken=1 AND a.hidden=0 ORDER BY a.last_check DESC";
278
+ $links=$wpdb->get_results($sql, OBJECT);
279
+ if($links && (count($links)>0)){
280
+ ?>
281
+ <table class="widefat">
282
+ <thead>
283
+ <tr>
284
+
285
+ <th scope="col"><div style="text-align: center">#</div></th>
286
+
287
+ <th scope="col">Post</th>
288
+ <th scope="col">Link Text</th>
289
+ <th scope="col">URL</th>
290
+
291
+ <th scope="col"></th>
292
+ <th scope="col"></th>
293
+ <th scope="col"></th>
294
+
295
+ </tr>
296
+ </thead>
297
+ <tbody id="the-list">
298
+ <?php
299
+
300
+ $rownumber=0;
301
+ foreach ($links as $link) {
302
+ $rownumber++;
303
+ echo "<tr id='link-$link->id' class='alternate'>
304
+ <th scope='row' style='text-align: center'>$rownumber</th>
305
+ <td>$link->post_title</td>
306
+
307
+ <td>$link->link_text</td>
308
+ <td><a href='$link->url'>".$this->mytruncate($link->url)."</a></td>
309
+ <td><a href='".get_option('siteurl')."?p=$link->post_id' class='edit'>View</a></td>
310
+
311
+ <td><a href='post.php?action=edit&amp;post=$link->post_id' class='edit'>Edit Post</a></td>
312
+ <td><a href='javascript:void(0);' class='delete'
313
+ onclick='discardLinkMessage($link->id);return false;' );' title='Discard This Message'>Discard</a></td>
314
+ </tr>";
315
+
316
+ }
317
+
318
+ echo '</tbody></table>';
319
+ };
320
+ ?>
321
+
322
+ <script type='text/javascript'>
323
+ function discardLinkMessage(link_id){
324
+ new Ajax.Request('<?php
325
+ echo get_option( "siteurl" ).'/wp-content/plugins/'.$this->myfolder.'/wsblc_ajax.php?';
326
+ ?>action=discard_link&id='+link_id,
327
+ { method:'get' });
328
+ $('link-'+link_id).hide();
329
+ }
330
+ </script>
331
+ </div>
332
+ <?php
333
+ }
334
+
335
+ }//class ends here
336
+
337
+ } // if class_exists...
338
+
339
+ $ws_link_checker = new ws_broken_link_checker();
340
+
341
+ ?>
readme.txt ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Broken Link Checker ===
2
+ Contributors: whiteshadow
3
+ Tags: links, broken, maintenance
4
+ Requires at least: 2.0.2
5
+ Tested up to: 2.3
6
+ Stable tag: 0.1
7
+
8
+ This plugin will check your posts for broken links in background and notify you on the dashboard if any are found. It runs while any page of WP admin panel is open.
9
+
10
+ == Description ==
11
+
12
+ Sometimes, links get broken. A page is deleted, a subdirectory forgotten, a site moved to a different domain. Most likely some of your blog posts contain links. It is almost inevitable that over time some of them will start giving the 404 Not Found error. Obviously you don't want your readers to be annoyed by clicking a link that leads nowhere. You can check the links yourself but that might be quite a task if you have a lot of posts. You could use your webserver's stats but that only works for local links. So I've made a plugin for WordPress that will check your posts (and pages) in the background, looking for broken links, and let you know if any are found.
13
+
14
+ The broken links, if any are found, will show up in a new tab of WP admin panel - Manage -> Broken Links. There are several buttons for each broken link - "View" and "Edit Post" do exactly what they say and "Discard" will remove the message about a broken link, but not the link itself (so it will show up again later unless you fix it).
15
+
16
+ You can modify the few available options at Options -> Link Checker. You can see the current checking status there, too - e.g. how many posts need to be checked and how many links are in the queue.
17
+
18
+ The plugin runs while you have any page of the WordPress admin panel open.
19
+
20
+
21
+ == Installation ==
22
+
23
+ To do a new installation of the plugin, please follow these steps
24
+
25
+ 1. Download the broken-link-checker.zip file to your local machine.
26
+ 1. Unzip the file
27
+ 1. Upload `broken-link-checker` folder to the `/wp-content/plugins/` directory
28
+ 1. Activate the plugin through the 'Plugins' menu in WordPress
29
+
30
+ That's it.
31
+
32
+ To upgrade your installation
33
+
34
+ 1. De-activate the plugin
35
+ 1. Get and upload the new files (do steps 1. - 3. from "new installation" instructions)
36
+ 1. Reactivate the plugin. Your settings should have been retained from the previous version.
wsblc_ajax.php ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ The AJAX-y part of the link checker.
4
+ */
5
+ require_once("../../../wp-config.php");
6
+ require_once("../../../wp-includes/wp-db.php");
7
+
8
+ error_reporting(E_ALL);
9
+
10
+ $execution_start_time=microtime(true);
11
+
12
+ function execution_time(){
13
+ global $execution_start_time;
14
+ return microtime(true)-$execution_start_time;
15
+ }
16
+
17
+ @set_time_limit(0);
18
+ @ignore_user_abort(true);
19
+
20
+ $url_pattern='/(<a[\s]+[^>]*href\s*=\s*[\"\']?)([^\'\" >]+)([\'\"]+[^<>]*>)((?sU).*)(<\/a>)/i';
21
+
22
+ $postdata_name=$wpdb->prefix . "blc_postdata";
23
+ $linkdata_name=$wpdb->prefix . "blc_linkdata";
24
+
25
+ $options=get_option('wsblc_options');
26
+ $siteurl=get_option('siteurl');
27
+ $max_execution_time=isset($options['max_work_session'])?intval($options['max_work_session']):27;
28
+
29
+ $check_treshold=date('Y-m-d H:i:s', strtotime('-'.$options['check_treshold'].' hours'));
30
+
31
+ $action=isset($_GET['action'])?$_GET['action']:'run_check';
32
+
33
+ if($action=='dashboard_status'){
34
+ /* displays a notification if broken links have been found */
35
+ $sql="SELECT count(*) FROM $linkdata_name WHERE broken=1 AND hidden=0";
36
+ $broken_links=$wpdb->get_var($sql);
37
+ if($broken_links>0){
38
+ echo "<div>
39
+ <h3>Broken Links</h3>
40
+ <p><a href='".get_option('siteurl')."/wp-admin/edit.php?page=".
41
+ $ws_link_checker->mybasename."' title='View broken links'>Found $broken_links broken links</a></p>
42
+ </div>";
43
+ };
44
+
45
+ } else if($action=='full_status'){
46
+ /* give some stats about the current situation */
47
+ $sql="SELECT count(*) FROM $postdata_name WHERE last_check<'$check_treshold'";
48
+ $posts_unchecked=$wpdb->get_var($sql);
49
+
50
+ $sql="SELECT count(*) FROM $linkdata_name WHERE last_check<'$check_treshold' AND hidden=0";
51
+ $links_unchecked=$wpdb->get_var($sql);
52
+
53
+ $sql="SELECT count(*) FROM $linkdata_name WHERE broken=1 AND hidden=0";
54
+ $broken_links=$wpdb->get_var($sql);
55
+
56
+ if($broken_links>0){
57
+ echo "<a href='".get_option('siteurl')."/wp-admin/edit.php?page=".
58
+ $ws_link_checker->mybasename."' title='View broken links'><strong>Found $broken_links broken links</strong></a>";
59
+ } else {
60
+ echo "No broken links found.";
61
+ }
62
+
63
+ echo "<br/>";
64
+
65
+ if($posts_unchecked || $links_unchecked) {
66
+ echo "$posts_unchecked posts and $links_unchecked links in the work queue.";
67
+ } else {
68
+ echo "The work queue is empty.";
69
+ }
70
+
71
+
72
+ } else if($action=='run_check'){
73
+ /* check for posts that haven't been checked for a long time & parse them for links, put the links in queue */
74
+ echo "<!-- run_check -->";
75
+
76
+ $sql="SELECT b.* FROM $postdata_name a, $wpdb->posts b
77
+ WHERE a.last_check<'$check_treshold' AND a.post_id=b.id ORDER BY a.last_check ASC LIMIT 20";
78
+
79
+ $rows=$wpdb->get_results($sql, OBJECT);
80
+ if($rows && (count($rows)>0)){
81
+ //some rows found
82
+ echo "<!-- parsing pages (rand : ".rand(1,1000).") -->";
83
+ foreach ($rows as $post) {
84
+ $wpdb->query("DELETE FROM $linkdata_name WHERE post_id=$post->ID");
85
+ gather_and_save_links($post->post_content, $post->ID);
86
+ $wpdb->query("UPDATE $postdata_name SET last_check=NOW() WHERE post_id=$post->ID");
87
+ }
88
+ };
89
+
90
+ if(execution_time()>$max_execution_time){
91
+ die('<!-- general timeout -->');
92
+ }
93
+
94
+ /* check the queue and process any links unchecked */
95
+ $sql="SELECT * FROM $linkdata_name WHERE last_check<'$check_treshold' AND hidden=0 LIMIT 100";
96
+ $links=$wpdb->get_results($sql, OBJECT);
97
+ if($links && (count($links)>0)){
98
+ //some unchecked links found
99
+ echo "<!-- checking links (rand : ".rand(1,1000).") -->";
100
+ foreach ($links as $link) {
101
+ if(page_exists_simple($link->url)){
102
+ //link OK, remove from queue
103
+ $wpdb->query("DELETE FROM $linkdata_name WHERE id=$link->id");
104
+ } else {
105
+ $wpdb->query("UPDATE $linkdata_name SET broken=1, last_check=NOW() WHERE id=$link->id");
106
+ };
107
+
108
+
109
+ if(execution_time()>$max_execution_time){
110
+ die('<!-- url loop timeout -->');
111
+ }
112
+ }
113
+ };
114
+
115
+ die('<!-- /run_check -->');
116
+
117
+ } else if ($action=='discard_link'){
118
+ $id=intval($_GET['id']);
119
+ $wpdb->query("DELETE FROM $linkdata_name WHERE id=$id LIMIT 1");
120
+ };
121
+
122
+
123
+ function parse_link($matches, $post_id){
124
+ global $wpdb, $siteurl, $linkdata_name;
125
+
126
+ $url=$matches[2];
127
+
128
+ $parts=@parse_url($url);
129
+
130
+ if(!$parts) return false;
131
+
132
+ $url=preg_replace(
133
+ array('/([\?&]PHPSESSID=\w+)$/i','/(#[^\/]*)$/i', '/&amp;/','/^(javascript:.*)/i','/([\?&]sid=\w+)$/i'),
134
+ array('','','&','',''),
135
+ $url);
136
+
137
+ $url=trim($url);
138
+ if($url=='') return false;
139
+
140
+ // turn relative URLs into absolute URLs
141
+ $url = relative2absolute($siteurl, $url);
142
+
143
+ if(strlen($url)>5){
144
+ $wpdb->query(
145
+ "INSERT INTO $linkdata_name(post_id, url, link_text)
146
+ VALUES($post_id, '".$wpdb->escape($url)."', '".$wpdb->escape(strip_tags($matches[4]))."')"
147
+ );
148
+ };
149
+
150
+ return true;
151
+ }
152
+
153
+ function gather_and_save_links($content, $post_id){
154
+ $url_pattern='/(<a[\s]+[^>]*href\s*=\s*[\"\']?)([^\'\" >]+)([\'\"]+[^<>]*>)((?sU).*)(<\/a>)/i';
155
+
156
+ if(preg_match_all($url_pattern, $content, $matches, PREG_SET_ORDER)){
157
+ foreach($matches as $link){
158
+ parse_link($link, $post_id);
159
+ }
160
+ };
161
+
162
+ return $content;
163
+ }
164
+
165
+ function page_exists_simple($url){
166
+ $parts=parse_url($url);
167
+ if(!$parts) return false;
168
+
169
+ if(!isset($parts['scheme'])) $url='http://'.$url;
170
+
171
+ $ch = curl_init();
172
+ curl_setopt($ch, CURLOPT_URL, $url);
173
+ curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
174
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
175
+
176
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
177
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
178
+ curl_setopt($ch, CURLOPT_TIMEOUT, 20);
179
+
180
+ //curl_setopt($ch, CURLOPT_FAILONERROR, true);
181
+ curl_setopt($ch, CURLOPT_HEADER, true);
182
+
183
+ if($parts['scheme']=='https'){
184
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
185
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
186
+ } else {
187
+ curl_setopt($ch, CURLOPT_NOBODY, true);
188
+ }
189
+
190
+ $response = curl_exec($ch);
191
+ curl_close($ch);
192
+
193
+ if(preg_match('/HTTP\/1\.\d+\s+(\d+)/', $response, $matches)){
194
+ $code=intval($matches[1]);
195
+ } else {
196
+ return false;
197
+ };
198
+
199
+ return (($code>=200) && ($code<400));
200
+ }
201
+
202
+ function relative2absolute($absolute, $relative) {
203
+ $p = @parse_url($relative);
204
+ if(!$p) {
205
+ //WTF? $relative is a seriously malformed URL
206
+ return false;
207
+ }
208
+ if(isset($p["scheme"])) return $relative;
209
+
210
+ $parts=(parse_url($absolute));
211
+
212
+ if(substr($relative,0,1)=='/') {
213
+ $cparts = (explode("/", $relative));
214
+ array_shift($cparts);
215
+ } else {
216
+ if(isset($parts['path'])){
217
+ $aparts=explode('/',$parts['path']);
218
+ array_pop($aparts);
219
+ $aparts=array_filter($aparts);
220
+ } else {
221
+ $aparts=array();
222
+ }
223
+
224
+ $rparts = (explode("/", $relative));
225
+
226
+ $cparts = array_merge($aparts, $rparts);
227
+ foreach($cparts as $i => $part) {
228
+ if($part == '.') {
229
+ unset($cparts[$i]);
230
+ } else if($part == '..') {
231
+ unset($cparts[$i]);
232
+ unset($cparts[$i-1]);
233
+ }
234
+ }
235
+ }
236
+ $path = implode("/", $cparts);
237
+
238
+ $url = '';
239
+ if($parts['scheme']) {
240
+ $url = "$parts[scheme]://";
241
+ }
242
+ if(isset($parts['user'])) {
243
+ $url .= $parts['user'];
244
+ if(isset($parts['pass'])) {
245
+ $url .= ":".$parts['pass'];
246
+ }
247
+ $url .= "@";
248
+ }
249
+ if(isset($parts['host'])) {
250
+ $url .= $parts['host']."/";
251
+ }
252
+ $url .= $path;
253
+
254
+ return $url;
255
+ }
256
+
257
+ ?>