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