[ Index ] |
|
Code source de b2evolution 2.1.0-beta |
1 <?php 2 /** 3 * This file posts a comment! 4 * 5 * This file is part of the evoCore framework - {@link http://evocore.net/} 6 * See also {@link http://sourceforge.net/projects/evocms/}. 7 * 8 * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/} 9 * 10 * {@internal License choice 11 * - If you have received this file as part of a package, please find the license.txt file in 12 * the same folder or the closest folder above for complete license terms. 13 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/) 14 * then you must choose one of the following licenses before using the file: 15 * - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php 16 * - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php 17 * }} 18 * 19 * {@internal Open Source relicensing agreement: 20 * }} 21 * 22 * @package htsrv 23 */ 24 25 26 /** 27 * Initialize everything: 28 */ 29 require_once dirname(__FILE__).'/../conf/_config.php'; 30 31 require_once $inc_path.'_main.inc.php'; 32 33 header( 'Content-Type: text/html; charset='.$io_charset ); 34 35 36 // Getting GET or POST parameters: 37 param( 'comment_post_ID', 'integer', true ); // required 38 param( 'redirect_to', 'string', '' ); 39 40 41 $action = param_arrayindex( 'submit_comment_post_'.$comment_post_ID, 'save' ); 42 43 44 $ItemCache = & get_Cache( 'ItemCache' ); 45 $commented_Item = & $ItemCache->get_by_ID( $comment_post_ID ); 46 47 if( ! $commented_Item->can_comment( NULL ) ) 48 { 49 $Messages->add( T_('You cannot leave comments on this post!'), 'error' ); 50 } 51 52 // Note: we use funky field names to defeat the most basic guestbook spam bots and/or their most basic authors 53 $comment = param( 'p', 'html' ); 54 55 param( 'comment_autobr', 'integer', ($comments_use_autobr == 'always') ? 1 : 0 ); 56 57 if( is_logged_in() ) 58 { 59 $User = & $current_User; 60 $author = null; 61 $email = null; 62 $url = null; 63 $comment_cookies = null; 64 $comment_allow_msgform = null; 65 } 66 else 67 { // User is not logged in (registered users), we need some id info from him: 68 $User = NULL; 69 // Note: we use funky field names to defeat the most basic guestbook spam bots and/or their most basic authors 70 $author = param( 'u', 'string' ); 71 $email = param( 'i', 'string' ); 72 $url = param( 'o', 'string' ); 73 param( 'comment_cookies', 'integer', 0 ); 74 param( 'comment_allow_msgform', 'integer', 0 ); // checkbox 75 } 76 77 param( 'comment_rating', 'integer', NULL ); 78 79 $now = date( 'Y-m-d H:i:s', $localtimenow ); 80 81 82 // VALIDATION: 83 84 $original_comment = $comment; 85 86 // Trigger event: a Plugin could add a $category="error" message here.. 87 // This must get triggered before any internal validation and must pass all relevant params. 88 // openID plugin will validate a given OpenID here 89 $Plugins->trigger_event( 'CommentFormSent', array( 90 'comment_post_ID' => $comment_post_ID, 91 'comment' => & $comment, 92 'original_comment' => & $original_comment, 93 'comment_autobr' => & $comment_autobr, 94 'action' => & $action, 95 'anon_name' => & $author, 96 'anon_email' => & $email, 97 'anon_url' => & $url, 98 'rating' => & $comment_rating, 99 'anon_allow_msgform' => & $comment_allow_msgform, 100 'anon_cookies' => & $comment_cookies, 101 'User' => & $User, 102 'redirect_to' => & $redirect_to, 103 ) ); 104 105 106 // CHECK and FORMAT content 107 if( ! $use_html_checker ) 108 { 109 //echo 'allowed tags:',htmlspecialchars($comment_allowed_tags); 110 $comment = strip_tags($comment, $comment_allowed_tags); 111 } 112 // TODO: AutoBR should really be a "comment renderer" (like with Items) 113 $comment = format_to_post($comment, $comment_autobr, 1); 114 115 116 if( ! $User ) 117 { // User is still not logged in, we need some id info from him: 118 if ($require_name_email) 119 { // We want Name and EMail with comments 120 if( empty($author) ) 121 { 122 $Messages->add( T_('Please fill in your name.'), 'error' ); 123 } 124 if( empty($email) ) 125 { 126 $Messages->add( T_('Please fill in your email.'), 'error' ); 127 } 128 } 129 130 if( !empty($author) && antispam_check( $author ) ) 131 { 132 $Messages->add( T_('Supplied name is invalid.'), 'error' ); 133 } 134 135 if( !empty($email) 136 && ( !is_email($email)|| antispam_check( $email ) ) ) 137 { 138 $Messages->add( T_('Supplied email address is invalid.'), 'error' ); 139 } 140 141 142 if( !stristr($url, '://') && !stristr($url, '@') ) 143 { // add 'http://' if no protocol defined for URL; but not if the user seems to be entering an email address alone 144 $url = 'http://'.$url; 145 } 146 147 if( strlen($url) <= 8 ) 148 { // ex: https:// is 8 chars 149 $url = ''; 150 } 151 152 // Note: as part of the validation we require teh url to be absolute; otherwise we cannot detect bozos typing in 153 // a title for their comment or whatever... 154 if( $error = validate_url( $url, $comments_allowed_uri_scheme, true ) ) 155 { 156 $Messages->add( T_('Supplied website address is invalid: ').$error, 'error' ); 157 } 158 } 159 160 if( empty($comment) ) 161 { // comment should not be empty! 162 $Messages->add( T_('Please do not send empty comments.'), 'error' ); 163 } 164 elseif( antispam_check( strip_tags($comment) ) ) 165 { 166 $Messages->add( T_('Supplied comment is invalid.'), 'error' ); 167 } 168 169 // Flood protection was here and SHOULD NOT have moved down! 170 171 /** 172 * Create comment object. Gets validated, before recording it into DB: 173 */ 174 $Comment = & new Comment(); 175 $Comment->set( 'type', 'comment' ); 176 $Comment->set_Item( $commented_Item ); 177 if( $User ) 178 { // User is logged in, we'll use his ID 179 $Comment->set_author_User( $User ); 180 } 181 else 182 { // User is not logged in: 183 $Comment->set( 'author', $author ); 184 $Comment->set( 'author_email', $email ); 185 $Comment->set( 'author_url', $url ); 186 $Comment->set( 'allow_msgform', $comment_allow_msgform ); 187 } 188 if( $commented_Item->can_rate() ) 189 { // Comment rating: 190 $Comment->set( 'rating', $comment_rating ); 191 } 192 $Comment->set( 'author_IP', $Hit->IP ); 193 $Comment->set( 'date', $now ); 194 $Comment->set( 'content', $comment ); 195 196 $commented_Item->get_Blog(); // Make sure Blog is loaded 197 198 // Assign default status for new comments: 199 $Comment->set( 'status', $commented_Item->Blog->get_setting('new_feedback_status') ); 200 201 if( $action != 'preview' ) 202 { 203 /* 204 * Flood-protection 205 * NOTE: devs can override the flood protection delay in /conf/_overrides_TEST.php 206 * TODO: Put time check into query? 207 * TODO: move that as far !!UP!! as possible! We want to waste minimum resources on Floods 208 * TODO: have several thresholds. For example: 209 * 1 comment max every 30 sec + 5 comments max every 10 minutes + 15 comments max every 24 hours 210 * TODO: factorize with trackback 211 */ 212 $query = 'SELECT MAX(comment_date) 213 FROM T_comments 214 WHERE comment_author_IP = '.$DB->quote($Hit->IP).' 215 OR comment_author_email = '.$DB->quote($Comment->get_author_email()); 216 $ok = 1; 217 if( $then = $DB->get_var( $query ) ) 218 { 219 $time_lastcomment = mysql2date("U",$then); 220 $time_newcomment = mysql2date("U",$now); 221 if( ($time_newcomment - $time_lastcomment) < $minimum_comment_interval ) 222 $ok = 0; 223 } 224 if( !$ok ) 225 { 226 $Messages->add( sprintf( T_('You can only post a new comment every %d seconds.'), $minimum_comment_interval ), 'error' ); 227 } 228 /* end flood-protection */ 229 } 230 231 232 // Trigger event: a Plugin could add a $category="error" message here.. 233 $Plugins->trigger_event('BeforeCommentFormInsert', array( 234 'Comment' => & $Comment, 235 'original_comment' => $original_comment, 236 'is_preview' => ($action == 'preview'), 237 'action' => & $action ) ); 238 239 240 /* 241 * Display error messages: 242 */ 243 if( $Messages->count('error') ) 244 { 245 if( ! isset($page_title) ) 246 { 247 $page_title = T_('Errors while processing your comment'); 248 } 249 // TODO: dh> HEAD part should be some global front end include file.. 250 // fp> actually, I'd like the error messages to de displayed in a skinnable file. Something that looks like the _main skin file but with minimum extra gadgets (in order to save on DB requests at each "spam denied" error) 251 // fp> So please don't waste time on implementing a half baked solution. 252 // fp> We may want to rethink skins more deeply beofre implementing this. 253 ?> 254 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 255 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php locale_lang() ?>" lang="<?php locale_lang() ?>"> 256 <head> 257 <title><?php echo $app_shortname.' › '.$page_title ?></title> 258 <meta name="ROBOTS" content="NOINDEX" /> 259 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $io_charset ?>" /> 260 </head> 261 <body> 262 <?php 263 $Messages->display( T_('Cannot post comment, please correct these errors:'), 264 '[<a href="javascript:history.go(-1)">'.T_('Back to comment editing').'</a>]' ); 265 266 debug_info(); // output debug info, useful to see what a plugin might have done 267 ?> 268 </body> 269 </html> 270 <?php 271 exit(); 272 } 273 274 if( $action == 'preview' ) 275 { // set the Comment into user's session and redirect. 276 $Comment->set( 'original_content', $original_comment ); // used in the textarea input field again 277 $Session->set( 'core.preview_Comment', $Comment ); 278 $Session->set( 'core.no_CachePageContent', 1 ); 279 $Session->dbsave(); 280 281 $redirect_to .= '#comment_preview'; 282 283 header_nocache(); 284 header_redirect(); 285 exit(); 286 } 287 else 288 { // delete any preview comment from session data: 289 $Session->delete( 'core.preview_Comment' ); 290 } 291 292 293 // RECORD comment: 294 295 $Comment->dbinsert(); 296 297 298 /* 299 * --------------- 300 * Handle cookies: 301 * --------------- 302 */ 303 if( !is_logged_in() ) 304 { 305 if( $comment_cookies ) 306 { // Set cookies: 307 if ($email == '') 308 $email = ' '; // this to make sure a cookie is set for 'no email' 309 if ($url == '') 310 $url = ' '; // this to make sure a cookie is set for 'no url' 311 312 // fplanque: made cookies available for whole site 313 setcookie( $cookie_name, $author, $cookie_expires, $cookie_path, $cookie_domain); 314 setcookie( $cookie_email, $email, $cookie_expires, $cookie_path, $cookie_domain); 315 setcookie( $cookie_url, $url, $cookie_expires, $cookie_path, $cookie_domain); 316 } 317 else 318 { // Erase cookies: 319 if( !empty($_COOKIE[$cookie_name]) ) 320 { 321 setcookie( $cookie_name, '', $cookie_expired, $cookie_path, $cookie_domain); 322 } 323 if( !empty($_COOKIE['comment_author_email']) ) 324 { 325 setcookie( $cookie_email, '', $cookie_expired, $cookie_path, $cookie_domain); 326 } 327 if( !empty($_COOKIE['comment_author_url']) ) 328 { 329 setcookie( $cookie_url, '', $cookie_expired, $cookie_path, $cookie_domain); 330 } 331 } 332 } 333 334 // Note: we don't give any clue that we have automatically deleted a comment. Il would only give spammers the perfect tool to find out how to pass the filter. 335 336 if( $Comment->ID ) 337 { // comment has not been deleted 338 // Trigger event: a Plugin should cleanup any temporary data here.. 339 $Plugins->trigger_event( 'AfterCommentFormInsert', array( 'Comment' => & $Comment, 'original_comment' => $original_comment ) ); 340 341 /* 342 * -------------------------- 343 * New comment notifications: 344 * -------------------------- 345 */ 346 // TODO: dh> this should only send published feedback probably and should also use "outbound_notifications_mode" 347 // fp> yes for general users, but comment moderators need to receive notifications for new unpublished comments 348 $Comment->send_email_notifications(); 349 350 351 // Add a message, according to the comment's status: 352 if( $Comment->status == 'published' ) 353 { 354 $Messages->add( T_('Your comment has been submitted.'), 'success' ); 355 356 // Append anchor to the redirect_to param, so the user sees his comment: 357 $redirect_to .= '#'.$Comment->get_anchor(); 358 } 359 else 360 { 361 $Messages->add( T_('Your comment has been submitted. It will appear once it has been approved.'), 'success' ); 362 } 363 } 364 365 366 header_nocache(); 367 header_redirect(); // Will save $Messages into Session 368 369 370 /* 371 * $Log: comment_post.php,v $ 372 * Revision 1.115 2007/11/02 01:57:57 fplanque 373 * comment ratings 374 * 375 * Revision 1.114 2007/11/01 19:52:47 fplanque 376 * better comment forms 377 * 378 * Revision 1.113 2007/07/09 21:24:12 fplanque 379 * cleanup of admin page top 380 * 381 * Revision 1.112 2007/06/23 22:04:17 fplanque 382 * minor 383 * 384 * Revision 1.111 2007/05/20 20:54:49 fplanque 385 * better comment moderation links 386 * 387 * Revision 1.110 2007/04/26 00:11:14 fplanque 388 * (c) 2007 389 * 390 * Revision 1.109 2007/02/28 23:21:53 blueyed 391 * Pass $original_comment to CommentFormSent and "action" to BeforeCommentFormInsert 392 * 393 * Revision 1.108 2007/02/22 22:14:14 blueyed 394 * Improved CommentFormSent hook 395 * 396 * Revision 1.107 2007/02/21 23:52:26 fplanque 397 * doc 398 * 399 * Revision 1.106 2007/02/13 01:30:31 blueyed 400 * TODO: do not notify about not published comments / use "outbound_notifications_mode" setting for comments, too 401 * 402 * Revision 1.105 2007/02/03 18:52:15 fplanque 403 * doc 404 * 405 * Revision 1.104 2007/01/28 23:58:46 blueyed 406 * - Added hook CommentFormSent 407 * - Re-ordered comment_post.php to: init, validate, process 408 * - RegisterFormSent hook can now filter the form values in a clean way 409 * 410 * Revision 1.103 2007/01/25 00:59:49 blueyed 411 * Do not pass "original_comment" in BeforeCommentFormInsert as a reference: makes no sense 412 * 413 * Revision 1.102 2007/01/21 23:26:31 fplanque 414 * preserve "fail on spam" by default 415 * 416 * Revision 1.101 2007/01/21 22:51:17 blueyed 417 * Security fix: tags have not been stripped 418 * 419 * Revision 1.100 2007/01/21 02:05:48 fplanque 420 * cleanup 421 * 422 * Revision 1.99 2007/01/16 22:48:13 blueyed 423 * Plugin hook TODO 424 * 425 * Revision 1.98 2006/12/26 00:08:30 fplanque 426 * wording 427 * 428 * Revision 1.97 2006/12/03 04:34:44 fplanque 429 * doc 430 * 431 * Revision 1.96 2006/12/03 02:01:19 blueyed 432 * Removed unused $evo_html_headlines handling 433 * 434 * Revision 1.95 2006/12/03 01:58:27 blueyed 435 * Renamed $admin_path_seprator to $admin_path_separator and AdminUI_general::pathSeperator to AdminUI::pathSeparator 436 * 437 * Revision 1.94 2006/11/26 02:30:38 fplanque 438 * doc / todo 439 * 440 * Revision 1.93 2006/11/24 18:27:22 blueyed 441 * Fixed link to b2evo CVS browsing interface in file docblocks 442 * 443 * Revision 1.92 2006/11/24 18:06:02 blueyed 444 * Handle saving of $Messages centrally in header_redirect() 445 * 446 * Revision 1.91 2006/11/16 01:59:14 fplanque 447 * doc 448 * 449 * Revision 1.89 2006/10/30 13:48:56 blueyed 450 * Fixed charset/HTML for comment-post page (errors) 451 */ 452 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 23:58:50 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |