Wordpress 2.0.11
[autoinstalls/wordpress.git] / wp-includes / comment-functions.php
1 <?php
2
3 // Template functions
4
5 function wp_comment_form_unfiltered_html_nonce() {
6         global $post;
7         if ( current_user_can('unfiltered_html') )
8                 wp_nonce_field('unfiltered-html-comment_' . $post->ID, '_wp_unfiltered_html_comment', false);
9 }
10
11 function comments_template( $file = '/comments.php' ) {
12         global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_ID, $user_identity;
13
14         if ( ! (is_single() || is_page() || $withcomments) )
15                 return;
16
17         $req = get_settings('require_name_email');
18         $commenter = wp_get_current_commenter();
19         extract($commenter);
20
21         // TODO: Use API instead of SELECTs.
22         if ( empty($comment_author) ) {
23                 $comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post->ID' AND comment_approved = '1' ORDER BY comment_date");
24         } else {
25                 $author_db = $wpdb->escape($comment_author);
26                 $email_db  = $wpdb->escape($comment_author_email);
27                 $comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post->ID' AND ( comment_approved = '1' OR ( comment_author = '$author_db' AND comment_author_email = '$email_db' AND comment_approved = '0' ) ) ORDER BY comment_date");
28         }
29
30         define('COMMENTS_TEMPLATE', true);
31         $include = apply_filters('comments_template', TEMPLATEPATH . $file );
32         if ( file_exists( $include ) )
33                 require( $include );
34         else
35                 require( ABSPATH . 'wp-content/themes/default/comments.php');
36 }
37
38 function wp_new_comment( $commentdata ) {
39         $commentdata = apply_filters('preprocess_comment', $commentdata);
40
41         $commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID'];
42         $commentdata['user_ID']         = (int) $commentdata['user_ID'];
43
44         $commentdata['comment_author_IP'] = $_SERVER['REMOTE_ADDR'];
45         $commentdata['comment_agent']     = $_SERVER['HTTP_USER_AGENT'];
46
47         $commentdata['comment_date']     = current_time('mysql');
48         $commentdata['comment_date_gmt'] = current_time('mysql', 1);
49         
50
51         $commentdata = wp_filter_comment($commentdata);
52
53         $commentdata['comment_approved'] = wp_allow_comment($commentdata);
54
55         $comment_ID = wp_insert_comment($commentdata);
56
57         do_action('comment_post', $comment_ID, $commentdata['comment_approved']);
58
59         if ( 'spam' !== $commentdata['comment_approved'] ) { // If it's spam save it silently for later crunching
60                 if ( '0' == $commentdata['comment_approved'] )
61                         wp_notify_moderator($comment_ID);
62
63                 $post = &get_post($commentdata['comment_post_ID']); // Don't notify if it's your own comment
64
65                 if ( get_settings('comments_notify') && $commentdata['comment_approved'] && $post->post_author != $commentdata['user_ID'] )
66                         wp_notify_postauthor($comment_ID, $commentdata['comment_type']);
67         }
68
69         return $comment_ID;
70 }
71
72 function wp_insert_comment($commentdata) {
73         global $wpdb;
74         extract($commentdata);
75
76         if ( ! isset($comment_author_IP) )
77                 $comment_author_IP = $_SERVER['REMOTE_ADDR'];
78         if ( ! isset($comment_date) )
79                 $comment_date = current_time('mysql');
80         if ( ! isset($comment_date_gmt) )
81                 $comment_date_gmt = gmdate('Y-m-d H:i:s', strtotime($comment_date) );
82         if ( ! isset($comment_parent) )
83                 $comment_parent = 0;
84         if ( ! isset($comment_approved) )
85                 $comment_approved = 1;
86
87         $result = $wpdb->query("INSERT INTO $wpdb->comments 
88         (comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_author_IP, comment_date, comment_date_gmt, comment_content, comment_approved, comment_agent, comment_type, comment_parent, user_id)
89         VALUES 
90         ('$comment_post_ID', '$comment_author', '$comment_author_email', '$comment_author_url', '$comment_author_IP', '$comment_date', '$comment_date_gmt', '$comment_content', '$comment_approved', '$comment_agent', '$comment_type', '$comment_parent', '$user_id')
91         ");
92
93         $id = (int) $wpdb->insert_id;
94
95         if ( $comment_approved == 1) {
96                 $count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND comment_approved = '1'");
97                 $wpdb->query( "UPDATE $wpdb->posts SET comment_count = $count WHERE ID = '$comment_post_ID'" );
98         }
99         return $id;
100 }
101
102 function wp_filter_comment($commentdata) {
103         $commentdata['user_id']              = apply_filters('pre_user_id', $commentdata['user_ID']);
104         $commentdata['comment_agent']        = apply_filters('pre_comment_user_agent', $commentdata['comment_agent']);
105         $commentdata['comment_author']       = apply_filters('pre_comment_author_name', $commentdata['comment_author']);
106         $commentdata['comment_content']      = apply_filters('pre_comment_content', $commentdata['comment_content']);
107         $commentdata['comment_author_IP']    = apply_filters('pre_comment_user_ip', $commentdata['comment_author_IP']);
108         $commentdata['comment_author_url']   = apply_filters('pre_comment_author_url', $commentdata['comment_author_url']);
109         $commentdata['comment_author_email'] = apply_filters('pre_comment_author_email', $commentdata['comment_author_email']);
110         $commentdata['filtered'] = true;
111         return $commentdata;
112 }
113
114 function wp_allow_comment($commentdata) {
115         global $wpdb;
116         extract($commentdata);
117
118         // Simple duplicate check
119         $dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND ( comment_author = '$comment_author' ";
120         if ( $comment_author_email )
121                 $dupe .= "OR comment_author_email = '$comment_author_email' ";
122         $dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
123         if ( $wpdb->get_var($dupe) )
124                 die( __('Duplicate comment detected; it looks as though you\'ve already said that!') );
125
126         // Simple flood-protection
127         if ( $lasttime = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_author_IP = '$comment_author_IP' OR comment_author_email = '$comment_author_email' ORDER BY comment_date DESC LIMIT 1") ) {
128                 $time_lastcomment = mysql2date('U', $lasttime);
129                 $time_newcomment  = mysql2date('U', $comment_date_gmt);
130                 if ( ($time_newcomment - $time_lastcomment) < 15 ) {
131                         do_action('comment_flood_trigger', $time_lastcomment, $time_newcomment);
132                         die( __('Sorry, you can only post a new comment once every 15 seconds. Slow down cowboy.') );
133                 }
134         }
135
136         if ( $user_id ) {
137                 $userdata = get_userdata($user_id);
138                 $user = new WP_User($user_id);
139                 $post_author = $wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = '$comment_post_ID' LIMIT 1");
140         }
141
142         // The author and the admins get respect.
143         if ( $userdata && ( $user_id == $post_author || $user->has_cap('level_9') ) ) {
144                 $approved = 1;
145         }
146
147         // Everyone else's comments will be checked.
148         else {
149                 if ( check_comment($comment_author, $comment_author_email, $comment_author_url, $comment_content, $comment_author_IP, $comment_agent, $comment_type) )
150                         $approved = 1;
151                 else
152                         $approved = 0;
153                 if ( wp_blacklist_check($comment_author, $comment_author_email, $comment_author_url, $comment_content, $comment_author_IP, $comment_agent) )
154                         $approved = 'spam';
155         }
156
157         $approved = apply_filters('pre_comment_approved', $approved);
158         return $approved;
159 }
160
161
162 function wp_update_comment($commentarr) {
163         global $wpdb;
164
165         // First, get all of the original fields
166         $comment = get_comment($commentarr['comment_ID'], ARRAY_A);
167
168         // Escape data pulled from DB.
169         foreach ($comment as $key => $value)
170                 $comment[$key] = $wpdb->escape($value);
171
172         // Merge old and new fields with new fields overwriting old ones.
173         $commentarr = array_merge($comment, $commentarr);
174
175         $commentarr = wp_filter_comment( $commentarr );
176
177         // Now extract the merged array.
178         extract($commentarr);
179
180         $comment_content = apply_filters('comment_save_pre', $comment_content);
181
182         $result = $wpdb->query(
183                 "UPDATE $wpdb->comments SET
184                         comment_content = '$comment_content',
185                         comment_author = '$comment_author',
186                         comment_author_email = '$comment_author_email',
187                         comment_approved = '$comment_approved',
188                         comment_author_url = '$comment_author_url',
189                         comment_date = '$comment_date'
190                 WHERE comment_ID = $comment_ID" );
191
192         $rval = $wpdb->rows_affected;
193
194         $c = $wpdb->get_row( "SELECT count(*) as c FROM {$wpdb->comments} WHERE comment_post_ID = '$comment_post_ID' AND comment_approved = '1'" );
195         if( is_object( $c ) )
196                 $wpdb->query( "UPDATE $wpdb->posts SET comment_count = '$c->c' WHERE ID = '$comment_post_ID'" );
197
198         do_action('edit_comment', $comment_ID);
199
200         return $rval;
201 }
202
203 function wp_delete_comment($comment_id) {
204         global $wpdb;
205         do_action('delete_comment', $comment_id);
206
207         $comment = get_comment($comment_id);
208
209         if ( ! $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1") )
210                 return false;
211
212         $post_id = $comment->comment_post_ID;
213         if ( $post_id && $comment->comment_approved == 1 ) {
214                 $count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = '$post_id' AND comment_approved = '1'");
215                 $wpdb->query( "UPDATE $wpdb->posts SET comment_count = $count WHERE ID = '$post_id'" );
216         }
217
218         do_action('wp_set_comment_status', $comment_id, 'delete');
219         return true;
220 }
221
222 function get_comments_number( $post_id = 0 ) {
223         global $wpdb, $comment_count_cache, $id;
224         $post_id = (int) $post_id;
225
226         if ( !$post_id )
227                 $post_id = (int) $id;
228
229         if ( !isset($comment_count_cache[$post_id]) )
230                 $comment_count_cache[$id] = $wpdb->get_var("SELECT comment_count FROM $wpdb->posts WHERE ID = '$post_id'");
231         
232         return apply_filters('get_comments_number', $comment_count_cache[$post_id]);
233 }
234
235 function comments_number( $zero = 'No Comments', $one = '1 Comment', $more = '% Comments', $number = '' ) {
236         global $id, $comment;
237         $number = get_comments_number( $id );
238         if ($number == 0) {
239                 $blah = $zero;
240         } elseif ($number == 1) {
241                 $blah = $one;
242         } elseif ($number  > 1) {
243                 $blah = str_replace('%', $number, $more);
244         }
245         echo apply_filters('comments_number', $blah);
246 }
247
248 function get_comments_link() {
249         return get_permalink() . '#comments';
250 }
251
252 function get_comment_link() {
253         global $comment;
254         return get_permalink( $comment->comment_post_ID ) . '#comment-' . $comment->comment_ID;
255 }
256
257 function comments_link( $file = '', $echo = true ) {
258     echo get_comments_link();
259 }
260
261 function comments_popup_script($width=400, $height=400, $file='') {
262     global $wpcommentspopupfile, $wptrackbackpopupfile, $wppingbackpopupfile, $wpcommentsjavascript;
263
264                 if (empty ($file)) {
265                         $wpcommentspopupfile = '';  // Use the index.
266                 } else {
267                         $wpcommentspopupfile = $file;
268                 }
269
270     $wpcommentsjavascript = 1;
271     $javascript = "<script type='text/javascript'>\nfunction wpopen (macagna) {\n    window.open(macagna, '_blank', 'width=$width,height=$height,scrollbars=yes,status=yes');\n}\n</script>\n";
272     echo $javascript;
273 }
274
275 function comments_popup_link($zero='No Comments', $one='1 Comment', $more='% Comments', $CSSclass='', $none='Comments Off') {
276         global $id, $wpcommentspopupfile, $wpcommentsjavascript, $post, $wpdb;
277         global $comment_count_cache;
278         
279         if (! is_single() && ! is_page()) {
280         if ( !isset($comment_count_cache[$id]) )
281                 $comment_count_cache[$id] = $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_post_ID = $id AND comment_approved = '1';");
282         
283         $number = $comment_count_cache[$id];
284         
285         if (0 == $number && 'closed' == $post->comment_status && 'closed' == $post->ping_status) {
286                 echo $none;
287                 return;
288         } else {
289                 if (!empty($post->post_password)) { // if there's a password
290                         if ($_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password) {  // and it doesn't match the cookie
291                                 echo(__('Enter your password to view comments'));
292                                 return;
293                         }
294                 }
295                 echo '<a href="';
296                 if ($wpcommentsjavascript) {
297                         if ( empty($wpcommentspopupfile) )
298                                 $home = get_settings('home');
299                         else
300                                 $home = get_settings('siteurl');
301                         echo $home . '/' . $wpcommentspopupfile.'?comments_popup='.$id;
302                         echo '" onclick="wpopen(this.href); return false"';
303                 } else { // if comments_popup_script() is not in the template, display simple comment link
304                         if ( 0 == $number )
305                                 echo get_permalink() . '#respond';
306                         else
307                                 comments_link();
308                         echo '"';
309                 }
310                 if (!empty($CSSclass)) {
311                         echo ' class="'.$CSSclass.'"';
312                 }
313                 $title = attribute_escape(apply_filters('the_title', get_the_title()));
314                 echo ' title="' . sprintf( __('Comment on %s'), $title ) .'">';
315                 comments_number($zero, $one, $more, $number);
316                 echo '</a>';
317         }
318         }
319 }
320
321 function get_comment_ID() {
322         global $comment;
323         return apply_filters('get_comment_ID', $comment->comment_ID);
324 }
325
326 function comment_ID() {
327         echo get_comment_ID();
328 }
329
330 function get_comment_author() {
331         global $comment;
332         if ( empty($comment->comment_author) )
333                 $author = __('Anonymous');
334         else
335                 $author = $comment->comment_author;
336         return apply_filters('get_comment_author', $author);
337 }
338
339 function comment_author() {
340         $author = apply_filters('comment_author', get_comment_author() );
341         echo $author;
342 }
343
344 function get_comment_author_email() {
345         global $comment;
346         return apply_filters('get_comment_author_email', $comment->comment_author_email);       
347 }
348
349 function comment_author_email() {
350         echo apply_filters('author_email', get_comment_author_email() );
351 }
352
353 function get_comment_author_link() {
354         global $comment;
355         $url    = get_comment_author_url();
356         $author = get_comment_author();
357
358         if ( empty( $url ) || 'http://' == $url )
359                 $return = $author;
360         else
361                 $return = "<a href='$url' rel='external nofollow'>$author</a>";
362         return apply_filters('get_comment_author_link', $return);
363 }
364
365 function comment_author_link() {
366         echo get_comment_author_link();
367 }
368
369 function get_comment_type() {
370         global $comment;
371
372         if ( '' == $comment->comment_type )
373                 $comment->comment_type = 'comment';
374
375         return apply_filters('get_comment_type', $comment->comment_type);
376 }
377
378 function comment_type($commenttxt = 'Comment', $trackbacktxt = 'Trackback', $pingbacktxt = 'Pingback') {
379         $type = get_comment_type();
380         switch( $type ) {
381                 case 'trackback' :
382                         echo $trackbacktxt;
383                         break;
384                 case 'pingback' :
385                         echo $pingbacktxt;
386                         break;
387                 default :
388                         echo $commenttxt;
389         }
390 }
391
392 function get_comment_author_url() {
393         global $comment;
394         return apply_filters('get_comment_author_url', $comment->comment_author_url);
395 }
396
397 function comment_author_url() {
398         echo apply_filters('comment_url', get_comment_author_url());
399 }
400
401 function comment_author_email_link($linktext='', $before='', $after='') {
402         global $comment;
403         $email = apply_filters('comment_email', $comment->comment_author_email);
404         if ((!empty($email)) && ($email != '@')) {
405         $display = ($linktext != '') ? $linktext : $email;
406                 echo $before;
407                 echo "<a href='mailto:$email'>$display</a>";
408                 echo $after;
409         }
410 }
411
412 function get_comment_author_url_link( $linktext = '', $before = '', $after = '' ) {
413         global $comment;
414         $url = get_comment_author_url();
415         $display = ($linktext != '') ? $linktext : $url;
416         $return = "$before<a href='$url' rel='external'>$display</a>$after";
417         return apply_filters('get_comment_author_url_link', $return);
418 }
419
420 function comment_author_url_link( $linktext = '', $before = '', $after = '' ) {
421         echo get_comment_author_url_link( $linktext, $before, $after );
422 }
423
424 function get_comment_author_IP() {
425         global $comment;
426         return apply_filters('get_comment_author_IP', $comment->comment_author_IP);
427 }
428
429 function comment_author_IP() {
430         echo get_comment_author_IP();
431 }
432
433 function get_comment_text() {
434         global $comment;
435         return apply_filters('get_comment_text', $comment->comment_content);
436 }
437
438 function comment_text() {
439         echo apply_filters('comment_text', get_comment_text() );
440 }
441
442 function get_comment_excerpt() {
443         global $comment;
444         $comment_text = strip_tags($comment->comment_content);
445         $blah = explode(' ', $comment_text);
446         if (count($blah) > 20) {
447                 $k = 20;
448                 $use_dotdotdot = 1;
449         } else {
450                 $k = count($blah);
451                 $use_dotdotdot = 0;
452         }
453         $excerpt = '';
454         for ($i=0; $i<$k; $i++) {
455                 $excerpt .= $blah[$i] . ' ';
456         }
457         $excerpt .= ($use_dotdotdot) ? '...' : '';
458         return apply_filters('get_comment_excerpt', $excerpt);
459 }
460
461 function comment_excerpt() {
462         echo apply_filters('comment_excerpt', get_comment_excerpt() );
463 }
464
465 function get_comment_date( $d = '' ) {
466         global $comment;
467         if ( '' == $d )
468                 $date = mysql2date( get_settings('date_format'), $comment->comment_date);
469         else
470                 $date = mysql2date($d, $comment->comment_date);
471         return apply_filters('get_comment_date', $date);
472 }
473
474 function comment_date( $d = '' ) {
475         echo get_comment_date( $d );
476 }
477
478 function get_comment_time( $d = '', $gmt = false ) {
479         global $comment;
480         $comment_date = $gmt? $comment->comment_date_gmt : $comment->comment_date;
481         if ( '' == $d )
482                 $date = mysql2date(get_settings('time_format'), $comment_date);
483         else
484                 $date = mysql2date($d, $comment_date);
485         return apply_filters('get_comment_time', $date);
486 }
487
488 function comment_time( $d = '' ) {
489         echo get_comment_time($d);
490 }
491
492 function get_trackback_url() {
493         global $id;
494         $tb_url = get_settings('siteurl') . '/wp-trackback.php?p=' . $id;
495
496         if ( '' != get_settings('permalink_structure') )
497                 $tb_url = trailingslashit(get_permalink()) . 'trackback/';
498
499         return $tb_url;
500 }
501 function trackback_url( $display = true ) {
502         if ( $display)
503                 echo get_trackback_url();
504         else
505                 return get_trackback_url();
506 }
507
508 function trackback_rdf($timezone = 0) {
509         global $id;
510         if (!stristr($_SERVER['HTTP_USER_AGENT'], 'W3C_Validator')) {
511         echo '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
512             xmlns:dc="http://purl.org/dc/elements/1.1/"
513             xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
514                 <rdf:Description rdf:about="';
515         the_permalink();
516         echo '"'."\n";
517         echo '    dc:identifier="';
518         the_permalink();
519         echo '"'."\n";
520         echo '    dc:title="'.str_replace('--', '&#x2d;&#x2d;', wptexturize(strip_tags(get_the_title()))).'"'."\n";
521         echo '    trackback:ping="'.trackback_url(0).'"'." />\n";
522         echo '</rdf:RDF>';
523         }
524 }
525
526 function comments_open() {
527         global $post;
528         if ( 'open' == $post->comment_status )
529                 return true;
530         else
531                 return false;
532 }
533
534 function pings_open() {
535         global $post;
536         if ( 'open' == $post->ping_status ) 
537                 return true;
538         else
539                 return false;
540 }
541
542 // Non-template functions
543
544 function get_lastcommentmodified($timezone = 'server') {
545         global $cache_lastcommentmodified, $pagenow, $wpdb;
546         $add_seconds_blog = get_settings('gmt_offset') * 3600;
547         $add_seconds_server = date('Z');
548         $now = current_time('mysql', 1);
549         if ( !isset($cache_lastcommentmodified[$timezone]) ) {
550                 switch(strtolower($timezone)) {
551                         case 'gmt':
552                                 $lastcommentmodified = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
553                                 break;
554                         case 'blog':
555                                 $lastcommentmodified = $wpdb->get_var("SELECT comment_date FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
556                                 break;
557                         case 'server':
558                                 $lastcommentmodified = $wpdb->get_var("SELECT DATE_ADD(comment_date_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
559                                 break;
560                 }
561                 $cache_lastcommentmodified[$timezone] = $lastcommentmodified;
562         } else {
563                 $lastcommentmodified = $cache_lastcommentmodified[$timezone];
564         }
565         return $lastcommentmodified;
566 }
567
568 function get_commentdata( $comment_ID, $no_cache = 0, $include_unapproved = false ) { // less flexible, but saves DB queries
569         global $postc, $id, $commentdata, $wpdb;
570         if ($no_cache) {
571                 $query = "SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_ID'";
572                 if (false == $include_unapproved) {
573                     $query .= " AND comment_approved = '1'";
574                 }
575                 $myrow = $wpdb->get_row($query, ARRAY_A);
576         } else {
577                 $myrow['comment_ID'] = $postc->comment_ID;
578                 $myrow['comment_post_ID'] = $postc->comment_post_ID;
579                 $myrow['comment_author'] = $postc->comment_author;
580                 $myrow['comment_author_email'] = $postc->comment_author_email;
581                 $myrow['comment_author_url'] = $postc->comment_author_url;
582                 $myrow['comment_author_IP'] = $postc->comment_author_IP;
583                 $myrow['comment_date'] = $postc->comment_date;
584                 $myrow['comment_content'] = $postc->comment_content;
585                 $myrow['comment_karma'] = $postc->comment_karma;
586                 $myrow['comment_approved'] = $postc->comment_approved;
587                 $myrow['comment_type'] = $postc->comment_type;
588         }
589         return $myrow;
590 }
591
592 function pingback($content, $post_ID) {
593         global $wp_version, $wpdb;
594         include_once (ABSPATH . WPINC . '/class-IXR.php');
595
596         // original code by Mort (http://mort.mine.nu:8080)
597         $log = debug_fopen(ABSPATH . '/pingback.log', 'a');
598         $post_links = array();
599         debug_fwrite($log, 'BEGIN '.date('YmdHis', time())."\n");
600
601         $pung = get_pung($post_ID);
602
603         // Variables
604         $ltrs = '\w';
605         $gunk = '/#~:.?+=&%@!\-';
606         $punc = '.:?\-';
607         $any = $ltrs . $gunk . $punc;
608
609         // Step 1
610         // Parsing the post, external links (if any) are stored in the $post_links array
611         // This regexp comes straight from phpfreaks.com
612         // http://www.phpfreaks.com/quickcode/Extract_All_URLs_on_a_Page/15.php
613         preg_match_all("{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp);
614
615         // Debug
616         debug_fwrite($log, 'Post contents:');
617         debug_fwrite($log, $content."\n");
618         
619         // Step 2.
620         // Walking thru the links array
621         // first we get rid of links pointing to sites, not to specific files
622         // Example:
623         // http://dummy-weblog.org
624         // http://dummy-weblog.org/
625         // http://dummy-weblog.org/post.php
626         // We don't wanna ping first and second types, even if they have a valid <link/>
627
628         foreach($post_links_temp[0] as $link_test) :
629                 if ( !in_array($link_test, $pung) && (url_to_postid($link_test) != $post_ID) // If we haven't pung it already and it isn't a link to itself
630                                 && !is_local_attachment($link_test) ) : // Also, let's never ping local attachments.
631                         $test = parse_url($link_test);
632                         if (isset($test['query']))
633                                 $post_links[] = $link_test;
634                         elseif(($test['path'] != '/') && ($test['path'] != ''))
635                                 $post_links[] = $link_test;
636                 endif;
637         endforeach;
638
639         do_action('pre_ping',  array(&$post_links, &$pung));
640
641         foreach ($post_links as $pagelinkedto){
642                 debug_fwrite($log, "Processing -- $pagelinkedto\n");
643                 $pingback_server_url = discover_pingback_server_uri($pagelinkedto, 2048);
644
645                 if ($pingback_server_url) {
646                         @ set_time_limit( 60 ); 
647                          // Now, the RPC call
648                         debug_fwrite($log, "Page Linked To: $pagelinkedto \n");
649                         debug_fwrite($log, 'Page Linked From: ');
650                         $pagelinkedfrom = get_permalink($post_ID);
651                         debug_fwrite($log, $pagelinkedfrom."\n");
652
653                         // using a timeout of 3 seconds should be enough to cover slow servers
654                         $client = new IXR_Client($pingback_server_url);
655                         $client->timeout = 3;
656                         $client->useragent .= ' -- WordPress/' . $wp_version;
657
658                         // when set to true, this outputs debug messages by itself
659                         $client->debug = false;
660                         
661                         if ( $client->query('pingback.ping', $pagelinkedfrom, $pagelinkedto ) )
662                                 add_ping( $post_ID, $pagelinkedto );
663                         else
664                                 debug_fwrite($log, "Error.\n Fault code: ".$client->getErrorCode()." : ".$client->getErrorMessage()."\n");
665                 }
666         }
667
668         debug_fwrite($log, "\nEND: ".time()."\n****************************\n");
669         debug_fclose($log);
670 }
671
672 function discover_pingback_server_uri($url, $timeout_bytes = 2048) {
673         global $wp_version;
674
675         $byte_count = 0;
676         $contents = '';
677         $headers = '';
678         $pingback_str_dquote = 'rel="pingback"';
679         $pingback_str_squote = 'rel=\'pingback\'';
680         $x_pingback_str = 'x-pingback: ';
681         $pingback_href_original_pos = 27;
682
683         extract(parse_url($url));
684
685         if (!isset($host)) {
686                 // Not an URL. This should never happen.
687                 return false;
688         }
689
690         $path  = (!isset($path)) ? '/'        : $path;
691         $path .= (isset($query)) ? '?'.$query : '';
692         $port  = (isset($port))  ? $port      : 80;
693
694         // Try to connect to the server at $host
695         $fp = @fsockopen($host, $port, $errno, $errstr, 2);
696         if (!$fp) {
697                 // Couldn't open a connection to $host;
698                 return false;
699         }
700
701         // Send the GET request
702         $request = "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: WordPress/$wp_version \r\n\r\n";
703 //      ob_end_flush();
704         fputs($fp, $request);
705
706         // Let's check for an X-Pingback header first
707         while (!feof($fp)) {
708                 $line = fgets($fp, 512);
709                 if (trim($line) == '') {
710                         break;
711                 }
712                 $headers .= trim($line)."\n";
713                 $x_pingback_header_offset = strpos(strtolower($headers), $x_pingback_str);
714                 if ($x_pingback_header_offset) {
715                         // We got it!
716                         preg_match('#x-pingback: (.+)#is', $headers, $matches);
717                         $pingback_server_url = trim($matches[1]);
718                         return $pingback_server_url;
719                 }
720                 if(strpos(strtolower($headers), 'content-type: ')) {
721                         preg_match('#content-type: (.+)#is', $headers, $matches);
722                         $content_type = trim($matches[1]);
723                 }
724         }
725
726         if (preg_match('#(image|audio|video|model)/#is', $content_type)) {
727                 // Not an (x)html, sgml, or xml page, no use going further
728                 return false;
729         }
730
731         while (!feof($fp)) {
732                 $line = fgets($fp, 1024);
733                 $contents .= trim($line);
734                 $pingback_link_offset_dquote = strpos($contents, $pingback_str_dquote);
735                 $pingback_link_offset_squote = strpos($contents, $pingback_str_squote);
736                 if ($pingback_link_offset_dquote || $pingback_link_offset_squote) {
737                         $quote = ($pingback_link_offset_dquote) ? '"' : '\'';
738                         $pingback_link_offset = ($quote=='"') ? $pingback_link_offset_dquote : $pingback_link_offset_squote;
739                         $pingback_href_pos = @strpos($contents, 'href=', $pingback_link_offset);
740                         $pingback_href_start = $pingback_href_pos+6;
741                         $pingback_href_end = @strpos($contents, $quote, $pingback_href_start);
742                         $pingback_server_url_len = $pingback_href_end - $pingback_href_start;
743                         $pingback_server_url = substr($contents, $pingback_href_start, $pingback_server_url_len);
744                         // We may find rel="pingback" but an incomplete pingback URI
745                         if ($pingback_server_url_len > 0) {
746                                 // We got it!
747                                 return $pingback_server_url;
748                         }
749                 }
750                 $byte_count += strlen($line);
751                 if ($byte_count > $timeout_bytes) {
752                         // It's no use going further, there probably isn't any pingback
753                         // server to find in this file. (Prevents loading large files.)
754                         return false;
755                 }
756         }
757
758         // We didn't find anything.
759         return false;
760 }
761
762 function is_local_attachment($url) {
763         if ( !strstr($url, get_bloginfo('home') ) )
764                 return false;
765         if ( strstr($url, get_bloginfo('home') . '/?attachment_id=') )
766                 return true;
767         if ( $id = url_to_postid($url) ) {
768                 $post = & get_post($id);
769                 if ( 'attachment' == $post->post_status )
770                         return true;
771         }               
772         return false;
773 }
774
775 function wp_set_comment_status($comment_id, $comment_status) {
776     global $wpdb;
777
778     switch($comment_status) {
779                 case 'hold':
780                         $query = "UPDATE $wpdb->comments SET comment_approved='0' WHERE comment_ID='$comment_id' LIMIT 1";
781                 break;
782                 case 'approve':
783                         $query = "UPDATE $wpdb->comments SET comment_approved='1' WHERE comment_ID='$comment_id' LIMIT 1";
784                 break;
785                 case 'spam':
786                         $query = "UPDATE $wpdb->comments SET comment_approved='spam' WHERE comment_ID='$comment_id' LIMIT 1";
787                 break;
788                 case 'delete':
789                         return wp_delete_comment($comment_id);
790                 break;
791                 default:
792                         return false;
793     }
794     
795     if ($wpdb->query($query)) {
796                 do_action('wp_set_comment_status', $comment_id, $comment_status);
797                 
798                 $comment = get_comment($comment_id);
799                 $comment_post_ID = $comment->comment_post_ID;
800                 $c = $wpdb->get_row( "SELECT count(*) as c FROM {$wpdb->comments} WHERE comment_post_ID = '$comment_post_ID' AND comment_approved = '1'" );
801                 if( is_object( $c ) )
802                         $wpdb->query( "UPDATE $wpdb->posts SET comment_count = '$c->c' WHERE ID = '$comment_post_ID'" );
803                 return true;
804     } else {
805                 return false;
806     }
807 }
808
809 function wp_get_comment_status($comment_id) {
810         global $wpdb;
811         
812         $result = $wpdb->get_var("SELECT comment_approved FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1");
813         if ($result == NULL) {
814                 return 'deleted';
815         } else if ($result == '1') {
816                 return 'approved';
817         } else if ($result == '0') {
818                 return 'unapproved';
819         } else if ($result == 'spam') {
820                 return 'spam';
821         } else {
822                 return false;
823         }
824 }
825
826 function check_comment($author, $email, $url, $comment, $user_ip, $user_agent, $comment_type) {
827         global $wpdb;
828
829         if (1 == get_settings('comment_moderation')) return false; // If moderation is set to manual
830
831         if ( preg_match_all("|(href\t*?=\t*?['\"]?)?(https?:)?//|i", $comment, $out) >= get_option('comment_max_links') )
832                 return false; // Check # of external links
833
834         $mod_keys = trim( get_settings('moderation_keys') );
835         if ( !empty($mod_keys) ) {
836                 $words = explode("\n", $mod_keys );
837
838                 foreach ($words as $word) {
839                         $word = trim($word);
840
841                         // Skip empty lines
842                         if (empty($word)) { continue; }
843
844                         // Do some escaping magic so that '#' chars in the 
845                         // spam words don't break things:
846                         $word = preg_quote($word, '#');
847                 
848                         $pattern = "#$word#i"; 
849                         if ( preg_match($pattern, $author) ) return false;
850                         if ( preg_match($pattern, $email) ) return false;
851                         if ( preg_match($pattern, $url) ) return false;
852                         if ( preg_match($pattern, $comment) ) return false;
853                         if ( preg_match($pattern, $user_ip) ) return false;
854                         if ( preg_match($pattern, $user_agent) ) return false;
855                 }
856         }
857
858         // Comment whitelisting:
859         if ( 1 == get_settings('comment_whitelist')) {
860                 if ( 'trackback' == $comment_type || 'pingback' == $comment_type ) { // check if domain is in blogroll
861                         $uri = parse_url($url);
862                         $domain = $uri['host'];
863                         $uri = parse_url( get_option('home') );
864                         $home_domain = $uri['host'];
865                         if ( $wpdb->get_var("SELECT link_id FROM $wpdb->links WHERE link_url LIKE ('%$domain%') LIMIT 1") || $domain == $home_domain )
866                                 return true;
867                         else
868                                 return false;
869                 } elseif( $author != '' && $email != '' ) {
870                         $ok_to_comment = $wpdb->get_var("SELECT comment_approved FROM $wpdb->comments WHERE comment_author = '$author' AND comment_author_email = '$email' and comment_approved = '1' LIMIT 1");
871                         if ( ( 1 == $ok_to_comment ) &&
872                                 ( empty($mod_keys) || false === strpos( $email, $mod_keys) ) )
873                                         return true;
874                         else
875                                 return false;
876                 } else {
877                         return false;
878                 }
879         }
880
881         return true;
882 }
883
884 function get_approved_comments($post_id) {
885         global $wpdb;
886
887         $post_id = (int) $post_id;
888         return $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = $post_id AND comment_approved = '1' ORDER BY comment_date");
889 }
890
891 function sanitize_comment_cookies() {
892         if ( isset($_COOKIE['comment_author_'.COOKIEHASH]) ) {
893                 $comment_author = apply_filters('pre_comment_author_name', $_COOKIE['comment_author_'.COOKIEHASH]);
894                 $comment_author = stripslashes($comment_author);
895                 $comment_author = attribute_escape($comment_author);
896                 $_COOKIE['comment_author_'.COOKIEHASH] = $comment_author;
897         }
898
899         if ( isset($_COOKIE['comment_author_email_'.COOKIEHASH]) ) {
900                 $comment_author_email = apply_filters('pre_comment_author_email', $_COOKIE['comment_author_email_'.COOKIEHASH]);
901                 $comment_author_email = stripslashes($comment_author_email);
902                 $comment_author_email = attribute_escape($comment_author_email);        
903                 $_COOKIE['comment_author_email_'.COOKIEHASH] = $comment_author_email;
904         }
905
906         if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) ) {
907                 $comment_author_url = apply_filters('pre_comment_author_url', $_COOKIE['comment_author_url_'.COOKIEHASH]);
908                 $comment_author_url = stripslashes($comment_author_url);
909                 $comment_author_url = attribute_escape($comment_author_url);
910                 $_COOKIE['comment_author_url_'.COOKIEHASH] = $comment_author_url;
911         }
912 }
913
914 function wp_get_current_commenter() {
915         // Cookies should already be sanitized.
916
917         $comment_author = '';
918         if ( isset($_COOKIE['comment_author_'.COOKIEHASH]) )
919                 $comment_author = $_COOKIE['comment_author_'.COOKIEHASH];
920
921         $comment_author_email = '';
922         if ( isset($_COOKIE['comment_author_email_'.COOKIEHASH]) )
923                 $comment_author_email = $_COOKIE['comment_author_email_'.COOKIEHASH];
924
925         $comment_author_url = '';
926         if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) )
927                 $comment_author_url = $_COOKIE['comment_author_url_'.COOKIEHASH];
928
929         return compact('comment_author', 'comment_author_email', 'comment_author_url');
930 }
931
932 ?>