root/tags/1.3/wp-includes/comment.php

Revision 1139, 27.8 kB (checked in by donncha, 1 year ago)

Merge with WordPress? 2.3.1

Line 
1 <?php
2
3 function check_comment($author, $email, $url, $comment, $user_ip, $user_agent, $comment_type) {
4     global $wpdb;
5
6     if ( 1 == get_option('comment_moderation') )
7         return false; // If moderation is set to manual
8
9     if ( preg_match_all("|(href\t*?=\t*?['\"]?)?(https?:)?//|i", $comment, $out) >= get_option('comment_max_links') )
10         return false; // Check # of external links
11
12     $mod_keys = trim(get_option('moderation_keys'));
13     if ( !empty($mod_keys) ) {
14         $words = explode("\n", $mod_keys );
15
16         foreach ($words as $word) {
17             $word = trim($word);
18
19             // Skip empty lines
20             if ( empty($word) )
21                 continue;
22
23             // Do some escaping magic so that '#' chars in the
24             // spam words don't break things:
25             $word = preg_quote($word, '#');
26
27             $pattern = "#$word#i";
28             if ( preg_match($pattern, $author) ) return false;
29             if ( preg_match($pattern, $email) ) return false;
30             if ( preg_match($pattern, $url) ) return false;
31             if ( preg_match($pattern, $comment) ) return false;
32             if ( preg_match($pattern, $user_ip) ) return false;
33             if ( preg_match($pattern, $user_agent) ) return false;
34         }
35     }
36
37     // Comment whitelisting:
38     if ( 1 == get_option('comment_whitelist')) {
39         if ( 'trackback' == $comment_type || 'pingback' == $comment_type ) { // check if domain is in blogroll
40             $uri = parse_url($url);
41             $domain = $uri['host'];
42             $uri = parse_url( get_option('home') );
43             $home_domain = $uri['host'];
44             if ( $wpdb->get_var("SELECT link_id FROM $wpdb->links WHERE link_url LIKE ('%$domain%') LIMIT 1") || $domain == $home_domain )
45                 return true;
46             else
47                 return false;
48         } elseif ( $author != '' && $email != '' ) {
49             $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");
50             if ( ( 1 == $ok_to_comment ) &&
51                 ( empty($mod_keys) || false === strpos( $email, $mod_keys) ) )
52                     return true;
53             else
54                 return false;
55         } else {
56             return false;
57         }
58     }
59     return true;
60 }
61
62
63 function get_approved_comments($post_id) {
64     global $wpdb;
65
66     $post_id = (int) $post_id;
67     return $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post_id' AND comment_approved = '1' ORDER BY comment_date");
68 }
69
70
71 // Retrieves comment data given a comment ID or comment object.
72 // Handles comment caching.
73 function &get_comment(&$comment, $output = OBJECT) {
74     global $wpdb;
75
76     if ( empty($comment) ) {
77         if ( isset($GLOBALS['comment']) )
78             $_comment = & $GLOBALS['comment'];
79         else
80             $_comment = null;
81     } elseif ( is_object($comment) ) {
82         wp_cache_add($comment->comment_ID, $comment, 'comment');
83         $_comment = $comment;
84     } else {
85         $comment = (int) $comment;
86         if ( isset($GLOBALS['comment']) && ($GLOBALS['comment']->comment_ID == $comment) ) {
87             $_comment = & $GLOBALS['comment'];
88         } elseif ( ! $_comment = wp_cache_get($comment, 'comment') ) {
89             $_comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment' LIMIT 1");
90             wp_cache_add($_comment->comment_ID, $_comment, 'comment');
91         }
92     }
93
94     $_comment = apply_filters('get_comment', $_comment);
95
96     if ( $output == OBJECT ) {
97         return $_comment;
98     } elseif ( $output == ARRAY_A ) {
99         return get_object_vars($_comment);
100     } elseif ( $output == ARRAY_N ) {
101         return array_values(get_object_vars($_comment));
102     } else {
103         return $_comment;
104     }
105 }
106
107
108 // Deprecate in favor of get_comment()?
109 function get_commentdata( $comment_ID, $no_cache = 0, $include_unapproved = false ) { // less flexible, but saves DB queries
110     global $postc, $id, $commentdata, $wpdb;
111     if ( $no_cache ) {
112         $query = "SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_ID'";
113         if ( false == $include_unapproved )
114             $query .= " AND comment_approved = '1'";
115         $myrow = $wpdb->get_row($query, ARRAY_A);
116     } else {
117         $myrow['comment_ID']           = $postc->comment_ID;
118         $myrow['comment_post_ID']      = $postc->comment_post_ID;
119         $myrow['comment_author']       = $postc->comment_author;
120         $myrow['comment_author_email'] = $postc->comment_author_email;
121         $myrow['comment_author_url']   = $postc->comment_author_url;
122         $myrow['comment_author_IP']    = $postc->comment_author_IP;
123         $myrow['comment_date']         = $postc->comment_date;
124         $myrow['comment_content']      = $postc->comment_content;
125         $myrow['comment_karma']        = $postc->comment_karma;
126         $myrow['comment_approved']     = $postc->comment_approved;
127         $myrow['comment_type']         = $postc->comment_type;
128     }
129     return $myrow;
130 }
131
132
133 function get_lastcommentmodified($timezone = 'server') {
134     global $cache_lastcommentmodified, $pagenow, $wpdb;
135     $add_seconds_blog = get_option('gmt_offset') * 3600;
136     $add_seconds_server = date('Z');
137     $now = current_time('mysql', 1);
138     if ( !isset($cache_lastcommentmodified[$timezone]) ) {
139         switch ( strtolower($timezone)) {
140             case 'gmt':
141                 $lastcommentmodified = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_date_gmt <= '$now' AND comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1");
142                 break;
143             case 'blog':
144                 $lastcommentmodified = $wpdb->get_var("SELECT comment_date FROM $wpdb->comments WHERE comment_date_gmt <= '$now' AND comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1");
145                 break;
146             case 'server':
147                 $lastcommentmodified = $wpdb->get_var("SELECT DATE_ADD(comment_date_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->comments WHERE comment_date_gmt <= '$now' AND comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1");
148                 break;
149         }
150         $cache_lastcommentmodified[$timezone] = $lastcommentmodified;
151     } else {
152         $lastcommentmodified = $cache_lastcommentmodified[$timezone];
153     }
154     return $lastcommentmodified;
155 }
156
157
158 function sanitize_comment_cookies() {
159     if ( isset($_COOKIE['comment_author_'.COOKIEHASH]) ) {
160         $comment_author = apply_filters('pre_comment_author_name', $_COOKIE['comment_author_'.COOKIEHASH]);
161         $comment_author = stripslashes($comment_author);
162         $comment_author = attribute_escape($comment_author);
163         $_COOKIE['comment_author_'.COOKIEHASH] = $comment_author;
164     }
165
166     if ( isset($_COOKIE['comment_author_email_'.COOKIEHASH]) ) {
167         $comment_author_email = apply_filters('pre_comment_author_email', $_COOKIE['comment_author_email_'.COOKIEHASH]);
168         $comment_author_email = stripslashes($comment_author_email);
169         $comment_author_email = attribute_escape($comment_author_email);
170         $_COOKIE['comment_author_email_'.COOKIEHASH] = $comment_author_email;
171     }
172
173     if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) ) {
174         $comment_author_url = apply_filters('pre_comment_author_url', $_COOKIE['comment_author_url_'.COOKIEHASH]);
175         $comment_author_url = stripslashes($comment_author_url);
176         $_COOKIE['comment_author_url_'.COOKIEHASH] = $comment_author_url;
177     }
178 }
179
180
181 function wp_allow_comment($commentdata) {
182     global $wpdb;
183     extract($commentdata, EXTR_SKIP);
184
185     // Simple duplicate check
186     $dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND ( comment_author = '$comment_author' ";
187     if ( $comment_author_email )
188         $dupe .= "OR comment_author_email = '$comment_author_email' ";
189     $dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
190     if ( $wpdb->get_var($dupe) )
191         wp_die( __('Duplicate comment detected; it looks as though you\'ve already said that!') );
192
193     do_action( 'check_comment_flood', $comment_author_IP, $comment_author_email, $comment_date_gmt );
194
195     if ( $user_id ) {
196         $userdata = get_userdata($user_id);
197         $user = new WP_User($user_id);
198         $post_author = $wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = '$comment_post_ID' LIMIT 1");
199     }
200
201     if ( $userdata && is_site_admin( $userdata->user_login ) == false && ( $user_id == $post_author || $user->has_cap('level_9' ) ) ) {
202         // The author and the admins get respect.
203         $approved = 1;
204      } else {
205         // Everyone else's comments will be checked.
206         if ( check_comment($comment_author, $comment_author_email, $comment_author_url, $comment_content, $comment_author_IP, $comment_agent, $comment_type) )
207             $approved = 1;
208         else
209             $approved = 0;
210         if ( wp_blacklist_check($comment_author, $comment_author_email, $comment_author_url, $comment_content, $comment_author_IP, $comment_agent) )
211             $approved = 'spam';
212     }
213
214     $approved = apply_filters('pre_comment_approved', $approved);
215     return $approved;
216 }
217
218 function check_comment_flood_db( $ip, $email, $date ) {
219     global $wpdb;
220     if ( $lasttime = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_author_IP = '$ip' OR comment_author_email = '$email' ORDER BY comment_date DESC LIMIT 1") ) {
221         $time_lastcomment = mysql2date('U', $lasttime);
222         $time_newcomment  = mysql2date('U', $date);
223         $flood_die = apply_filters('comment_flood_filter', false, $time_lastcomment, $time_newcomment);
224         if ( $flood_die ) {
225             do_action('comment_flood_trigger', $time_lastcomment, $time_newcomment);
226             wp_die( __('You are posting comments too quickly.  Slow down.') );
227         }
228     }
229 }
230
231 function wp_blacklist_check($author, $email, $url, $comment, $user_ip, $user_agent) {
232     global $wpdb;
233
234     do_action('wp_blacklist_check', $author, $email, $url, $comment, $user_ip, $user_agent);
235
236     if ( preg_match_all('/&#(\d+);/', $comment . $author . $url, $chars) ) {
237         foreach ( (array) $chars[1] as $char ) {
238             // If it's an encoded char in the normal ASCII set, reject
239             if ( 38 == $char )
240                 continue; // Unless it's &
241             if ( $char < 128 )
242                 return true;
243         }
244     }
245
246     $mod_keys = trim( get_option('blacklist_keys') );
247     if ( '' == $mod_keys )
248         return false; // If moderation keys are empty
249     $words = explode("\n", $mod_keys );
250
251     foreach ( (array) $words as $word ) {
252         $word = trim($word);
253
254         // Skip empty lines
255         if ( empty($word) ) { continue; }
256
257         // Do some escaping magic so that '#' chars in the
258         // spam words don't break things:
259         $word = preg_quote($word, '#');
260
261         $pattern = "#$word#i";
262         if (
263                preg_match($pattern, $author)
264             || preg_match($pattern, $email)
265             || preg_match($pattern, $url)
266             || preg_match($pattern, $comment)
267             || preg_match($pattern, $user_ip)
268             || preg_match($pattern, $user_agent)
269          )
270             return true;
271     }
272     return false;
273 }
274
275
276 function wp_delete_comment($comment_id) {
277     global $wpdb;
278     do_action('delete_comment', $comment_id);
279
280     $comment = get_comment($comment_id);
281
282     if ( ! $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1") )
283         return false;
284
285     $post_id = $comment->comment_post_ID;
286     if ( $post_id && $comment->comment_approved == 1 )
287         wp_update_comment_count($post_id);
288
289     clean_comment_cache($comment_id);
290
291     do_action('wp_set_comment_status', $comment_id, 'delete');
292     return true;
293 }
294
295
296 function wp_get_comment_status($comment_id) {
297     global $wpdb;
298
299     $comment = get_comment($comment_id);
300     if ( !$comment )
301         return false;
302
303     $approved = $comment->comment_approved;
304
305     if ( $approved == NULL )
306         return 'deleted';
307     elseif ( $approved == '1' )
308         return 'approved';
309     elseif ( $approved == '0' )
310         return 'unapproved';
311     elseif ( $approved == 'spam' )
312         return 'spam';
313     else
314         return false;
315 }
316
317
318 function wp_get_current_commenter() {
319     // Cookies should already be sanitized.
320
321     $comment_author = '';
322     if ( isset($_COOKIE['comment_author_'.COOKIEHASH]) )
323         $comment_author = $_COOKIE['comment_author_'.COOKIEHASH];
324
325     $comment_author_email = '';
326     if ( isset($_COOKIE['comment_author_email_'.COOKIEHASH]) )
327         $comment_author_email = $_COOKIE['comment_author_email_'.COOKIEHASH];
328
329     $comment_author_url = '';
330     if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) )
331         $comment_author_url = $_COOKIE['comment_author_url_'.COOKIEHASH];
332
333     return compact('comment_author', 'comment_author_email', 'comment_author_url');
334 }
335
336
337 function wp_insert_comment($commentdata) {
338     global $wpdb;
339     extract($commentdata, EXTR_SKIP);
340
341     if ( ! isset($comment_author_IP) )
342         $comment_author_IP = preg_replace( '/[^0-9., ]/', '',$_SERVER['REMOTE_ADDR'] );
343     if ( ! isset($comment_date) )
344         $comment_date = current_time('mysql');
345     if ( ! isset($comment_date_gmt) )
346         $comment_date_gmt = get_gmt_from_date($comment_date);
347     if ( ! isset($comment_parent) )
348         $comment_parent = 0;
349     if ( ! isset($comment_approved) )
350         $comment_approved = 1;
351     if ( ! isset($user_id) )
352         $user_id = 0;
353
354     $result = $wpdb->query("INSERT INTO $wpdb->comments
355     (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)
356     VALUES
357     ('$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')
358     ");
359
360     $id = (int) $wpdb->insert_id;
361
362     if ( $comment_approved == 1)
363         wp_update_comment_count($comment_post_ID);
364
365     return $id;
366 }
367
368
369 function wp_filter_comment($commentdata) {
370     $commentdata['user_id']              = apply_filters('pre_user_id', $commentdata['user_ID']);
371     $commentdata['comment_agent']        = apply_filters('pre_comment_user_agent', $commentdata['comment_agent']);
372     $commentdata['comment_author']       = apply_filters('pre_comment_author_name', $commentdata['comment_author']);
373     $commentdata['comment_content']      = apply_filters('pre_comment_content', $commentdata['comment_content']);
374     $commentdata['comment_author_IP']    = apply_filters('pre_comment_user_ip', $commentdata['comment_author_IP']);
375     $commentdata['comment_author_url']   = apply_filters('pre_comment_author_url', $commentdata['comment_author_url']);
376     $commentdata['comment_author_email'] = apply_filters('pre_comment_author_email', $commentdata['comment_author_email']);
377     $commentdata['filtered'] = true;
378     return $commentdata;
379 }
380
381
382 function wp_throttle_comment_flood($block, $time_lastcomment, $time_newcomment) {
383     if ( $block ) // a plugin has already blocked... we'll let that decision stand
384         return $block;
385     if ( ($time_newcomment - $time_lastcomment) < 15 )
386         return true;
387     return false;
388 }
389
390
391 function wp_new_comment( $commentdata ) {
392     $commentdata = apply_filters('preprocess_comment', $commentdata);
393
394     $commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID'];
395     $commentdata['user_ID']         = (int) $commentdata['user_ID'];
396
397     $commentdata['comment_author_IP'] = preg_replace( '/[^0-9., ]/', '',$_SERVER['REMOTE_ADDR'] );
398     $commentdata['comment_agent']     = $_SERVER['HTTP_USER_AGENT'];
399
400     $commentdata['comment_date']     = current_time('mysql');
401     $commentdata['comment_date_gmt'] = current_time('mysql', 1);
402
403     $commentdata = wp_filter_comment($commentdata);
404
405     $commentdata['comment_approved'] = wp_allow_comment($commentdata);
406
407     $comment_ID = wp_insert_comment($commentdata);
408
409     do_action('comment_post', $comment_ID, $commentdata['comment_approved']);
410
411     if ( 'spam' !== $commentdata['comment_approved'] ) { // If it's spam save it silently for later crunching
412         if ( '0' == $commentdata['comment_approved'] )
413             wp_notify_moderator($comment_ID);
414
415         $post = &get_post($commentdata['comment_post_ID']); // Don't notify if it's your own comment
416
417         if ( get_option('comments_notify') && $commentdata['comment_approved'] && $post->post_author != $commentdata['user_ID'] )
418             wp_notify_postauthor($comment_ID, $commentdata['comment_type']);
419     }
420
421     return $comment_ID;
422 }
423
424
425 function wp_set_comment_status($comment_id, $comment_status) {
426     global $wpdb;
427
428     switch ( $comment_status ) {
429         case 'hold':
430             $query = "UPDATE $wpdb->comments SET comment_approved='0' WHERE comment_ID='$comment_id' LIMIT 1";
431             break;
432         case 'approve':
433             $query = "UPDATE $wpdb->comments SET comment_approved='1' WHERE comment_ID='$comment_id' LIMIT 1";
434             break;
435         case 'spam':
436             $query = "UPDATE $wpdb->comments SET comment_approved='spam' WHERE comment_ID='$comment_id' LIMIT 1";
437             break;
438         case 'delete':
439             return wp_delete_comment($comment_id);
440             break;
441         default:
442             return false;
443     }
444
445     if ( !$wpdb->query($query) )
446         return false;
447
448     clean_comment_cache($comment_id);
449
450     do_action('wp_set_comment_status', $comment_id, $comment_status);
451     $comment = get_comment($comment_id);
452     wp_update_comment_count($comment->comment_post_ID);
453
454     return true;
455 }
456
457
458 function wp_update_comment($commentarr) {
459     global $wpdb;
460
461     // First, get all of the original fields
462     $comment = get_comment($commentarr['comment_ID'], ARRAY_A);
463
464     // Escape data pulled from DB.
465     foreach ( (array) $comment as $key => $value )
466         $comment[$key] = $wpdb->escape($value);
467
468     // Merge old and new fields with new fields overwriting old ones.
469     $commentarr = array_merge($comment, $commentarr);
470