root/branches/2.1/wp-includes/comment.php

Revision 5120, 27.7 kB (checked in by ryan, 2 years ago)

More clean_url and int casts for 2.1.

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