| [ Index ] |
|
Code source de b2evolution 2.1.0-beta |
1 <?php 2 /** 3 * This file implements the Comment class. 4 * 5 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}. 6 * See also {@link http://sourceforge.net/projects/evocms/}. 7 * 8 * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/}. 9 * Parts of this file are copyright (c)2004-2005 by Daniel HAHLER - {@link http://thequod.de/contact}. 10 * 11 * @license http://b2evolution.net/about/license.html GNU General Public License (GPL) 12 * 13 * {@internal Open Source relicensing agreement: 14 * Daniel HAHLER grants Francois PLANQUE the right to license 15 * Daniel HAHLER's contributions to this file and the b2evolution project 16 * under any OSI approved OSS license (http://www.opensource.org/licenses/). 17 * }} 18 * 19 * @package evocore 20 * 21 * {@internal Below is a list of authors who have contributed to design/coding of this file: }} 22 * @author blueyed: Daniel HAHLER. 23 * @author fplanque: Francois PLANQUE 24 * 25 * @version $Id: _comment.class.php,v 1.4 2007/11/03 04:56:03 fplanque Exp $ 26 */ 27 if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' ); 28 29 load_class('_core/model/dataobjects/_dataobject.class.php'); 30 31 /** 32 * Comment Class 33 * 34 * @package evocore 35 */ 36 class Comment extends DataObject 37 { 38 /** 39 * The item (parent) of this Comment (lazy-filled). 40 * @see Comment::get_Item() 41 * @see Comment::set_Item() 42 * @access protected 43 * @var Item 44 */ 45 var $Item; 46 /** 47 * The ID of the comment's Item. 48 * @var integer 49 */ 50 var $item_ID; 51 /** 52 * The comment's user, this is NULL for (anonymous) visitors (lazy-filled). 53 * @see Comment::get_author_User() 54 * @see Comment::set_author_User() 55 * @access protected 56 * @var User 57 */ 58 var $author_User; 59 /** 60 * The ID of the author's user. NULL for anonymous visitors. 61 * @var integer 62 */ 63 var $author_ID; 64 /** 65 * Comment type: 'comment', 'linkback', 'trackback' or 'pingback' 66 * @var string 67 */ 68 var $type; 69 /** 70 * Comment visibility status: 'published', 'deprecated', 'redirected', 'protected', 'private' or 'draft' 71 * @var string 72 */ 73 var $status; 74 /** 75 * Name of the (anonymous) visitor (if any). 76 * @var string 77 */ 78 var $author; 79 /** 80 * Email address of the (anonymous) visitor (if any). 81 * @var string 82 */ 83 var $author_email; 84 /** 85 * URL/Homepage of the (anonymous) visitor (if any). 86 * @var string 87 */ 88 var $author_url; 89 /** 90 * IP address of the comment's author (while posting). 91 * @var string 92 */ 93 var $author_IP; 94 /** 95 * Date of the comment (MySQL DATETIME - use e.g. {@link mysql2timestamp()}); local time ({@link $localtimenow}) 96 * @var string 97 */ 98 var $date; 99 /** 100 * @var string 101 */ 102 var $content; 103 /** 104 * Spam karma of the comment (0-100), 0 being "probably no spam at all" 105 * @var integer 106 */ 107 var $spam_karma; 108 /** 109 * Does an anonymous commentator allow to send messages through a message form? 110 * @var boolean 111 */ 112 var $allow_msgform; 113 114 115 /** 116 * Constructor 117 */ 118 function Comment( $db_row = NULL ) 119 { 120 // Call parent constructor: 121 parent::DataObject( 'T_comments', 'comment_', 'comment_ID' ); 122 123 if( $db_row == NULL ) 124 { 125 // echo 'null comment'; 126 $this->rating = NULL; 127 $this->featured = 0; 128 $this->nofollow = 1; 129 } 130 else 131 { 132 $this->ID = $db_row['comment_ID']; 133 $this->item_ID = $db_row['comment_post_ID']; 134 if( ! empty($db_row['comment_author_ID']) ) 135 { 136 $this->author_user_ID = $db_row['comment_author_ID']; 137 } 138 $this->type = $db_row['comment_type']; 139 $this->status = $db_row['comment_status']; 140 $this->author = $db_row['comment_author']; 141 $this->author_email = $db_row['comment_author_email']; 142 $url = trim( $db_row['comment_author_url'] ); 143 if( ! empty($url) && ! preg_match( '~^\w+://~', $url ) ) 144 { // URL given and does not start with a protocol: 145 $url = 'http://'.$url; 146 } 147 $this->author_url = $url; 148 $this->author_IP = $db_row['comment_author_IP']; 149 $this->date = $db_row['comment_date']; 150 $this->content = $db_row['comment_content']; 151 $this->rating = $db_row['comment_rating']; 152 $this->featured = $db_row['comment_featured']; 153 $this->nofollow = $db_row['comment_nofollow']; 154 $this->spam_karma = $db_row['comment_spam_karma']; 155 $this->allow_msgform = $db_row['comment_allow_msgform']; 156 } 157 } 158 159 160 /** 161 * Get the author User of the comment. This is NULL for anonymous visitors. 162 * 163 * @return User 164 */ 165 function & get_author_User() 166 { 167 if( isset($this->author_user_ID) && ! isset($this->author_User) ) 168 { 169 $UserCache = & get_Cache( 'UserCache' ); 170 $this->author_User = & $UserCache->get_by_ID( $this->author_user_ID ); 171 } 172 173 return $this->author_User; 174 } 175 176 177 /** 178 * Get the Item this comment relates to 179 * 180 * @return Item 181 */ 182 function & get_Item() 183 { 184 if( ! isset($this->Item) ) 185 { 186 $ItemCache = & get_Cache( 'ItemCache' ); 187 $this->Item = & $ItemCache->get_by_ID( $this->item_ID ); 188 } 189 190 return $this->Item; 191 } 192 193 194 /** 195 * Get a member param by its name 196 * 197 * @param mixed Name of parameter 198 * @return mixed Value of parameter 199 */ 200 function get( $parname ) 201 { 202 global $post_statuses; 203 204 switch( $parname ) 205 { 206 case 't_status': 207 // Text status: 208 return T_( $post_statuses[$this->status] ); 209 } 210 211 return parent::get( $parname ); 212 } 213 214 215 /** 216 * Set param value 217 * 218 * @param string parameter name 219 * @param mixed parameter value 220 * @return boolean true, if a value has been set; false if it has not changed 221 */ 222 function set( $parname, $parvalue ) 223 { 224 switch( $parname ) 225 { 226 case 'rating': 227 return parent::set_param( $parname, 'string', $parvalue, true ); 228 229 default: 230 return parent::set_param( $parname, 'string', $parvalue ); 231 } 232 } 233 234 235 /** 236 * Set Item this comment relates to 237 * @param Item 238 */ 239 function set_Item( & $Item ) 240 { 241 $this->Item = & $Item; 242 $this->item_ID = $Item->ID; 243 parent::set_param( 'post_ID', 'number', $Item->ID ); 244 } 245 246 247 /** 248 * Set author User of this comment 249 */ 250 function set_author_User( & $author_User ) 251 { 252 $this->author_User = & $author_User; 253 parent::set_param( 'author_ID', 'number', $author_User->ID ); 254 } 255 256 257 /** 258 * Set the spam karma, as a number. 259 * @param integer Spam karma (-100 - 100) 260 * @access protected 261 */ 262 function set_spam_karma( $spam_karma ) 263 { 264 return parent::set_param( 'spam_karma', 'number', $spam_karma ); 265 } 266 267 268 /** 269 * Get the anchor-ID of the comment 270 * 271 * @return string 272 */ 273 function get_anchor() 274 { 275 return 'c'.$this->ID; 276 } 277 278 279 /** 280 * Template function: display anchor for permalinks to refer to 281 */ 282 function anchor() 283 { 284 echo '<a id="'.$this->get_anchor().'"></a>'; 285 } 286 287 288 /** 289 * Get the comment author's name. 290 * 291 * @return string 292 */ 293 function get_author_name() 294 { 295 if( $this->get_author_User() ) 296 { 297 return $this->author_User->preferred_name( 'raw', false ); 298 } 299 else 300 { 301 return $this->author; 302 } 303 } 304 305 306 /** 307 * Get the EMail of the comment's author. 308 * 309 * @return string 310 */ 311 function get_author_email() 312 { 313 if( $this->get_author_User() ) 314 { // Author is a user 315 return $this->author_User->get('email'); 316 } 317 else 318 { 319 return $this->author_email; 320 } 321 } 322 323 324 /** 325 * Get the URL of the comment's author. 326 * 327 * @return string 328 */ 329 function get_author_url() 330 { 331 if( $this->get_author_User() ) 332 { // Author is a user 333 return $this->author_User->get('url'); 334 } 335 else 336 { 337 return $this->author_url; 338 } 339 } 340 341 342 /** 343 * Template function: display author of comment 344 * 345 * @param string String to display before author name if not a user 346 * @param string String to display after author name if not a user 347 * @param string String to display before author name if he's a user 348 * @param string String to display after author name if he's a user 349 * @param string Output format, see {@link format_to_output()} 350 * @param boolean true for link, false if you want NO html link 351 */ 352 function author( $before = '', $after = '#', $before_user = '', $after_user = '#', 353 $format = 'htmlbody', $makelink = false ) 354 { 355 global $Plugins; 356 357 $r = ''; 358 359 if( $this->get_author_User() ) 360 { // Author is a user 361 if( strlen( $this->author_User->url ) <= 10 ) $makelink = false; 362 if( $after_user == '#' ) $after_user = ' ['.T_('Member').']'; 363 $r .= $before_user; 364 if( $makelink ) $r .= '<a href="'.htmlspecialchars($this->author_User->url).'">'; 365 $r .= $this->author_User->preferred_name( $format, false ); 366 if( $makelink ) $r .= '</a>'; 367 $r .= $after_user; 368 } 369 else 370 { // Display info recorded at edit time: 371 if( strlen( $this->author_url ) <= 10 ) $makelink = false; 372 if( $after == '#' ) $after = ' ['.T_('Visitor').']'; 373 $r .= $before; 374 375 if( $makelink ) $r .= '<a href="'.htmlspecialchars($this->author_url).'">'; 376 $r .= $this->dget( 'author', $format ); 377 if( $makelink ) $r .= '</a>'; 378 $r .= $after; 379 } 380 381 $Plugins->trigger_event( 'FilterCommentAuthor', array( 'data' => & $r, 'makelink' => $makelink, 'Comment' => $this ) ); 382 383 echo $r; 384 } 385 386 387 /** 388 * Template function: display comment's author's IP 389 * 390 * @param string String to display before IP, if IP exists 391 * @param string String to display after IP, if IP exists 392 */ 393 function author_ip( $before='', $after='' ) 394 { 395 if( !empty( $this->author_IP ) ) 396 { 397 global $Plugins; 398 399 echo $before; 400 // Filter the IP by plugins for display, allowing e.g. the DNSBL plugin to add a link that displays info about the IP: 401 echo $Plugins->get_trigger_event( 'FilterIpAddress', array( 402 'format'=>'htmlbody', 403 'data' => $this->author_IP ), 404 'data' ); 405 echo $after; 406 } 407 } 408 409 410 /** 411 * Template function: display link to comment author's provided email 412 * 413 * @param string String to display for link: leave empty to display email 414 * @param string String to display before email, if email exists 415 * @param string String to display after email, if email exists 416 * @param boolean false if you want NO html link 417 */ 418 function author_email( $linktext='', $before='', $after='', $makelink = true ) 419 { 420 $email = $this->get_author_email(); 421 422 if( strlen( $email ) > 5 ) 423 { // If email exists: 424 echo $before; 425 if( $makelink ) echo '<a href="mailto:'.$email.'">'; 426 echo ($linktext != '') ? $linktext : $email; 427 if( $makelink ) echo '</a>'; 428 echo $after; 429 } 430 } 431 432 433 /** 434 * Template function: display link to comment author's provided URL 435 * 436 * @param string String to display for link: leave empty to display URL 437 * @param string String to display before link, if link exists 438 * @param string String to display after link, if link exists 439 * @param boolean false if you want NO html link 440 * @return boolean true if URL has been displayed 441 */ 442 function author_url( $linktext='', $before='', $after='', $makelink = true ) 443 { 444 global $Plugins; 445 446 $url = $this->get_author_url(); 447 448 if( strlen( $url ) < 10 ) 449 { 450 return false; 451 } 452 453 // If URL exists: 454 $r = $before; 455 if( $makelink ) 456 { 457 $r .= '<a href="'.$url.'">'; 458 } 459 $r .= ( empty($linktext) ? $url : $linktext ); 460 if( $makelink ) $r .= '</a>'; 461 $r .= $after; 462 463 $Plugins->trigger_event( 'FilterCommentAuthorUrl', array( 'data' => & $r, 'makelink' => $makelink, 'Comment' => $this ) ); 464 465 echo $r; 466 return true; 467 } 468 469 470 /** 471 * Template function: display spam karma of the comment (in percent) 472 * 473 * "%s" gets replaced by the karma value 474 * 475 * @param string Template string to display, if we have a karma value 476 * @param string Template string to display, if we have no karma value (pre-Phoenix) 477 */ 478 function spam_karma( $template = '%s%', $template_unknown = NULL ) 479 { 480 if( isset($this->spam_karma) ) 481 { 482 echo str_replace( '%s', $this->spam_karma, $template ); 483 } 484 else 485 { 486 if( ! isset($template_unknown) ) 487 { 488 echo /* TRANS: "not available" */ T_('N/A'); 489 } 490 else 491 { 492 echo $template_unknown; 493 } 494 } 495 } 496 497 498 /** 499 * Provide link to edit a comment if user has edit rights 500 * 501 * @param string to display before link 502 * @param string to display after link 503 * @param string link text 504 * @param string link title 505 * @param string class name 506 * @return boolean 507 */ 508 function edit_link( $before = ' ', $after = ' ', $text = '#', $title = '#', $class = '', $glue = '&', $save_context = true ) 509 { 510 global $current_User, $admin_url; 511 512 if( ! is_logged_in() ) return false; 513 514 $this->get_Item(); 515 516 if( ! $current_User->check_perm( 'blog_comments', '', false, $this->Item->get( 'blog_ID' ) ) ) 517 { // If User has no permission to edit comments: 518 return false; 519 } 520 521 if( $text == '#' ) $text = get_icon( 'edit' ).' '.T_('Edit...'); 522 if( $title == '#' ) $title = T_('Edit this comment'); 523 524 echo $before; 525 echo '<a href="'.$admin_url.'?ctrl=comments&action=edit&comment_ID='.$this->ID; 526 if( $save_context ) 527 { 528 echo $glue.'redirect_to='.rawurlencode( regenerate_url( '', '', '', '&' ) ); 529 } 530 echo '" title="'.$title.'"'; 531 if( !empty( $class ) ) echo ' class="'.$class.'"'; 532 echo '>'.$text.'</a>'; 533 echo $after; 534 535 return true; 536 } 537 538 539 /** 540 * Displays button for deleeing the Comment if user has proper rights 541 * 542 * @param string to display before link 543 * @param string to display after link 544 * @param string link text 545 * @param string link title 546 * @param string class name 547 * @param boolean true to make this a button instead of a link 548 */ 549 function delete_link( $before = ' ', $after = ' ', $text = '#', $title = '#', $class = '', $button = false, $glue = '&', $save_context = true ) 550 { 551 global $current_User, $admin_url; 552 553 if( ! is_logged_in() ) return false; 554 555 $this->get_Item(); 556 557 if( ! $current_User->check_perm( 'blog_comments', '', false, $this->Item->get( 'blog_ID' ) ) ) 558 { // If User has permission to edit comments: 559 return false; 560 } 561 562 if( $text == '#' ) 563 { // Use icon+text as default, if not displayed as button (otherwise just the text) 564 if( ! $button ) 565 { 566 $text = get_icon( 'delete', 'imgtag' ).' '.T_('Delete!'); 567 } 568 else 569 { 570 $text = T_('Delete!'); 571 } 572 } 573 if( $title == '#' ) $title = T_('Delete this comment'); 574 575 $url = $admin_url.'?ctrl=comments&action=delete&comment_ID='.$this->ID; 576 if( $save_context ) 577 { 578 $url .= $glue.'redirect_to='.rawurlencode( regenerate_url( '', '', '', '&' ) ); 579 } 580 581 echo $before; 582 if( $button ) 583 { // Display as button 584 echo '<input type="button"'; 585 echo ' value="'.$text.'" title="'.$title.'" onclick="if ( confirm(\''; 586 echo TS_('You are about to delete this comment!\\nThis cannot be undone!'); 587 echo '\') ) { document.location.href=\''.$url.'\' }"'; 588 if( !empty( $class ) ) echo ' class="'.$class.'"'; 589 echo '/>'; 590 } 591 else 592 { // Display as link 593 echo '<a href="'.$url.'" title="'.$title.'" onclick="return confirm(\''; 594 echo TS_('You are about to delete this comment!\\nThis cannot be undone!'); 595 echo '\')"'; 596 if( !empty( $class ) ) echo ' class="'.$class.'"'; 597 echo '>'.$text.'</a>'; 598 } 599 echo $after; 600 601 return true; 602 } 603 604 605 /** 606 * Provide link to deprecate a comment if user has edit rights 607 * 608 * @param string to display before link 609 * @param string to display after link 610 * @param string link text 611 * @param string link title 612 * @param string class name 613 * @param string glue between url params 614 * @param boolean save context? 615 */ 616 function get_deprecate_link( $before = ' ', $after = ' ', $text = '#', $title = '#', $class = '', $glue = '&', $save_context = true ) 617 { 618 global $current_User, $admin_url; 619 620 if( ! is_logged_in() ) return false; 621 622 $this->get_Item(); 623 624 if( ($this->status == 'deprecated') // Already deprecateded! 625 || ! $current_User->check_perm( 'blog_comments', '', false, $this->Item->get( 'blog_ID' ) ) ) 626 { // If User has permission to edit comments: 627 return false; 628 } 629 630 if( $text == '#' ) $text = get_icon( 'deprecate', 'imgtag' ).' '.T_('Deprecate!'); 631 if( $title == '#' ) $title = T_('Deprecate this comment!'); 632 633 $r = $before; 634 $r .= '<a href="'; 635 $r .= $admin_url.'?ctrl=comments'.$glue.'action=deprecate'.$glue.'comment_ID='.$this->ID; 636 if( $save_context ) 637 { 638 $r .= $glue.'redirect_to='.rawurlencode( regenerate_url( '', '', '', '&' ) ); 639 } 640 $r .= '" title="'.$title.'"'; 641 if( !empty( $class ) ) $r .= ' class="'.$class.'"'; 642 $r .= '>'.$text.'</a>'; 643 $r .= $after; 644 645 return $r; 646 } 647 648 649 /** 650 * Display link to deprecate a comment if user has edit rights 651 * 652 * @param string to display before link 653 * @param string to display after link 654 * @param string link text 655 * @param string link title 656 * @param string class name 657 * @param string glue between url params 658 * @param boolean save context? 659 */ 660 function deprecate_link( $before = ' ', $after = ' ', $text = '#', $title = '#', $class = '', $glue = '&', $save_context = true ) 661 { 662 echo $this->get_deprecate_link( $before, $after, $text, $title, $class, $glue, $save_context ); 663 } 664 665 666 /** 667 * Provide link to publish a comment if user has edit rights 668 * 669 * @param string to display before link 670 * @param string to display after link 671 * @param string link text 672 * @param string link title 673 * @param string class name 674 * @param string glue between url params 675 * @param boolean save context? 676 */ 677 function get_publish_link( $before = ' ', $after = ' ', $text = '#', $title = '#', $class = '', $glue = '&', $save_context = true ) 678 { 679 global $current_User, $admin_url; 680 681 if( ! is_logged_in() ) return false; 682 683 $this->get_Item(); 684 685 if( ($this->status == 'published') // Already published! 686 || ! $current_User->check_perm( 'blog_comments', '', false, $this->Item->get( 'blog_ID' ) ) ) 687 { // If User has permission to edit comments: 688 return false; 689 } 690 691 if( $text == '#' ) $text = get_icon( 'publish', 'imgtag' ).' '.T_('Publish!'); 692 if( $title == '#' ) $title = T_('Publish this comment!'); 693 694 $r = $before; 695 $r .= '<a href="'; 696 $r .= $admin_url.'?ctrl=comments'.$glue.'action=publish'.$glue.'comment_ID='.$this->ID; 697 if( $save_context ) 698 { 699 $r .= $glue.'redirect_to='.rawurlencode( regenerate_url( '', '', '', '&' ) ); 700 } 701 $r .= '" title="'.$title.'"'; 702 if( !empty( $class ) ) $r .= ' class="'.$class.'"'; 703 $r .= '>'.$text.'</a>'; 704 $r .= $after; 705 706 return $r; 707 } 708 709 710 /** 711 * Display link to publish a comment if user has edit rights 712 * 713 * @param string to display before link 714 * @param string to display after link 715 * @param string link text 716 * @param string link title 717 * @param string class name 718 * @param string glue between url params 719 * @param boolean save context? 720 */ 721 function publish_link( $before = ' ', $after = ' ', $text = '#', $title = '#', $class = '', $glue = '&', $save_context = true ) 722 { 723 echo $this->get_publish_link( $before, $after, $text, $title, $class, $glue, $save_context ); 724 } 725 726 727 /** 728 * Provide link to message form for this comment's author 729 * 730 * @param string url of the message form 731 * @param string to display before link 732 * @param string to display after link 733 * @param string link text 734 * @param string link title 735 * @param string class name 736 */ 737 function msgform_link( $form_url, $before = ' ', $after = ' ', $text = '#', $title = '#', $class = '' ) 738 { 739 if( $this->get_author_User() ) 740 { // This comment is from a registered user: 741 if( empty($this->author_User->email) ) 742 { // We have no email for this Author :( 743 return false; 744 } 745 elseif( empty($this->author_User->allow_msgform) ) 746 { // User does not allow message form 747 return false; 748 } 749 $form_url = url_add_param( $form_url, 'recipient_id='.$this->author_User->ID ); 750 } 751 else 752 { // This comment is from a visitor: 753 if( empty($this->author_email) ) 754 { // We have no email for this comment :( 755 return false; 756 } 757 elseif( empty($this->allow_msgform) ) 758 { // Anonymous commentator does not allow message form (for this comment) 759 return false; 760 } 761 } 762 763 $form_url = url_add_param( $form_url, 'comment_id='.$this->ID.'&post_id='.$this->item_ID 764 .'&redirect_to='.rawurlencode(url_rel_to_same_host(regenerate_url('','','','&'), $form_url)) ); 765 766 if( $title == '#' ) $title = T_('Send email to comment author'); 767 if( $text == '#' ) $text = get_icon( 'email', 'imgtag', array( 'class' => 'middle', 'title' => $title ) ); 768 769 echo $before; 770 echo '<a href="'.$form_url.'" title="'.$title.'"'; 771 if( !empty( $class ) ) echo ' class="'.$class.'"'; 772 echo '>'.$text.'</a>'; 773 echo $after; 774 775 return true; 776 } 777 778 779 /** 780 * Generate permalink to this comment. 781 * 782 * Note: This actually only returns the URL, to get a real link, use Comment::get_permanent_link() 783 */ 784 function get_permanent_url() 785 { 786 $this->get_Item(); 787 788 $post_permalink = $this->Item->get_single_url( 'auto' ); 789 790 return $post_permalink.'#'.$this->get_anchor(); 791 } 792 793 794 /** 795 * Template function: display permalink to this comment 796 * 797 * Note: This actually only returns the URL, to get a real link, use Comment::permanent_link() 798 * 799 * @param string 'urltitle', 'pid', 'archive#id' or 'archive#title' 800 * @param string url to use 801 */ 802 function permanent_url( $mode = '', $blogurl='' ) 803 { 804 echo $this->get_permanent_url( $mode, $blogurl ); 805 } 806 807 808 /** 809 * Returns a permalink link to the Comment 810 * 811 * Note: If you only want the permalink URL, use Comment::get_permanent_url() 812 * 813 * @param string link text or special value: '#', '#icon#', '#text#' 814 * @param string link title 815 * @param string class name 816 */ 817 function get_permanent_link( $text = '#', $title = '#', $class = '' ) 818 { 819 global $current_User, $baseurl; 820 821 switch( $text ) 822 { 823 case '#': 824 $text = get_icon( 'permalink' ).T_('Permalink'); 825 break; 826 827 case '#icon#': 828 $text = get_icon( 'permalink' ); 829 break; 830 831 case '#text#': 832 $text = T_('Permalink'); 833 break; 834 } 835 836 if( $title == '#' ) $title = T_('Permanent link to this comment'); 837 838 $url = $this->get_permanent_url(); 839 840 // Display as link 841 $r = '<a href="'.$url.'" title="'.$title.'"'; 842 if( !empty( $class ) ) $r .= ' class="'.$class.'"'; 843 $r .= '>'.$text.'</a>'; 844 845 return $r; 846 } 847 848 849 /** 850 * Displays a permalink link to the Comment 851 * 852 * Note: If you only want the permalink URL, use Comment::permanent_url() 853 * 854 * @param string link text 855 * @param string link title 856 * @param string class name 857 */ 858 function permanent_link( $text = '#', $title = '#', $class = '' ) 859 { 860 echo $this->get_permanent_link( $text, $title, $class ); 861 } 862 863 864 /** 865 * Template function: get content of comment 866 * 867 * @param string Output format, see {@link format_to_output()} 868 * @return string 869 */ 870 function get_content( $format = 'htmlbody' ) 871 { 872 global $Plugins; 873 874 $comment = $this->content; 875 // fp> obsolete: $comment = str_replace('<trackback />', '', $comment); 876 $Plugins->trigger_event( 'FilterCommentContent', array( 'data' => & $comment, 'Comment' => $this ) ); 877 $comment = format_to_output( $comment, $format ); 878 879 return $comment; 880 } 881 882 883 /** 884 * Template function: display content of comment 885 * 886 * @param string Output format, see {@link format_to_output()} 887 */ 888 function content( $format = 'htmlbody' ) 889 { 890 echo $this->get_content( $format ); 891 } 892 893 894 /** 895 * Template function: display date (datetime) of comment 896 * 897 * @param string date/time format: leave empty to use locale default date format 898 * @param boolean true if you want GMT 899 */ 900 function date( $format='', $useGM = false ) 901 { 902 if( empty($format) ) 903 echo mysql2date( locale_datefmt(), $this->date, $useGM); 904 else 905 echo mysql2date( $format, $this->date, $useGM); 906 } 907 908 909 /** 910 * Template function: display time (datetime) of comment 911 * 912 * @param string date/time format: leave empty to use locale default time format 913 * @param boolean true if you want GMT 914 */ 915 function time( $format='', $useGM = false ) 916 { 917 if( empty($format) ) 918 echo mysql2date( locale_timefmt(), $this->date, $useGM ); 919 else 920 echo mysql2date( $format, $this->date, $useGM ); 921 } 922 923 924 /** 925 * Template tag: display rating 926 */ 927 function rating( $params = array() ) 928 { 929 if( empty( $this->rating ) ) 930 { 931 return false; 932 } 933 934 // Make sure we are not missing any param: 935 $params = array_merge( array( 936 'before' => '<div class="comment_rating">', 937 'after' => '</div>', 938 ), $params ); 939 940 echo $params['before']; 941 942 for( $i=1; $i<=5; $i++ ) 943 { 944 if( $i <= $this->rating ) 945 { 946 echo get_icon( 'star_on', 'imgtag', array( 'class'=>'middle' ) ); 947 } 948 else 949 { 950 echo get_icon( 'star_off', 'imgtag', array( 'class'=>'middle' ) ); 951 } 952 } 953 954 echo $params['after']; 955 } 956 957 /** 958 * Rating input 959 */ 960 function rating_input( $params = array() ) 961 { 962 $params = array_merge( array( 963 'before' => '', 964 'after' => '', 965 'label_low' => T_('Poor'), 966 'label_high' => T_('Excellent'), 967 ), $params ); 968 969 echo $params['before']; 970 971 echo $params['label_low']; 972 973 for( $i=1; $i<=5; $i++ ) 974 { 975 echo '<input type="radio" class="radio" name="comment_rating" value="'.$i.'"'; 976 if( $this->rating == $i ) 977 { 978 echo ' checked="checked"'; 979 } 980 echo ' />'; 981 } 982 983 echo $params['label_high']; 984 985 echo $params['after']; 986 } 987 988 989 /** 990 * Rating reset input 991 */ 992 function rating_none_input( $params = array() ) 993 { 994 $params = array_merge( array( 995 'before' => '', 996 'after' => '', 997 'label' => T_('No rating'), 998 ), $params ); 999 1000 echo $params['before']; 1001 1002 echo '<label><input type="radio" class="radio" name="comment_rating" value="0"'; 1003 if( empty($this->rating) ) 1004 { 1005 echo ' checked="checked"'; 1006 } 1007 echo ' />'; 1008 1009 echo $params['label'].'</label>'; 1010 1011 echo $params['after']; 1012 } 1013 1014 1015 /** 1016 * Template function: display status of comment 1017 * 1018 * Statuses: 1019 * - published 1020 * - deprecated 1021 * - protected 1022 * - private 1023 * - draft 1024 * 1025 * @param string Output format, see {@link format_to_output()} 1026 */ 1027 function status( $format = 'htmlbody' ) 1028 { 1029 global $post_statuses; 1030 1031 if( $format == 'raw' ) 1032 { 1033 $this->disp( 'status', 'raw' ); 1034 } 1035 else 1036 { 1037 echo format_to_output( $this->get('t_status'), $format ); 1038 } 1039 } 1040 1041 1042 /** 1043 * Send email notifications to subscribed users: 1044 * 1045 * @todo shall we notify suscribers of blog were this is in extra-cat? 1046 * @todo cache message by locale like {@link Item::send_email_notifications()} 1047 * @todo dh> Indicator in url to see where the user came from (&from=subnote ["subscription notification"]) - Problem: too long urls. 1048 * @todo dh> "Beautify" like {@link Item::send_email_notifications()} ? 1049 * @todo Should include "visibility status" in the mail to the Item's Author 1050 */ 1051 function send_email_notifications() 1052 { 1053 global $DB, $admin_url, $debug, $Debuglog; 1054 1055 $edited_Item = & $this->get_Item(); 1056 $edited_Blog = & $edited_Item->get_Blog(); 1057 1058 $notify_array = array(); 1059 1060 if( $edited_Blog->get_setting( 'allow_subscriptions' ) ) 1061 { // Get list of users who want to be notfied: 1062 // TODO: also use extra cats/blogs?? 1063 // So far you get notifications for everything. We'll need a setting to decide if you want to received unmoderated (aka unpublished) comments or not. 1064 // Note: users receive comments on their own posts. This is done on purpose. Otherwise they think it's broken when they test the app. 1065 $sql = 'SELECT DISTINCT user_email, user_locale 1066 FROM T_subscriptions INNER JOIN T_users ON sub_user_ID = user_ID 1067 WHERE sub_coll_ID = '.$this->Item->blog_ID.' 1068 AND sub_comments <> 0 1069 AND LENGTH(TRIM(user_email)) > 0'; 1070 $notify_list = $DB->get_results( $sql ); 1071 1072 // Preprocess list: 1073 foreach( $notify_list as $notification ) 1074 { 1075 $notify_array[$notification->user_email] = $notification->user_locale; 1076 } 1077 } 1078 1079 // Check if we need to include the author: 1080 $item_author_User = & $edited_Item->get_creator_User(); 1081 if( $item_author_User->notify 1082 && ( ! empty( $item_author_User->email ) ) ) 1083 { // Author wants to be notified: 1084 $notify_array[$item_author_User->email] = $item_author_User->locale; 1085 } 1086 1087 if( ! count($notify_array) ) 1088 { // No-one to notify: 1089 return false; 1090 } 1091 1092 1093 /* 1094 * We have a list of email addresses to notify: 1095 */ 1096 // fp>SUSPECT 1097 // TODO: dh> this reveals the comments author's email address to all subscribers!! 1098 // $notify_from should get used by default, unless the user has opted in to be the sender! 1099 // fp>If the subscriber has permission to moderate the comments, he SHOULD receive the email address. 1100 if( $this->get_author_User() ) 1101 { // Comment from a registered user: 1102 $mail_from = '"'.$this->author_User->get('preferredname').'" <'.$this->author_User->get('email').'>'; 1103 } 1104 elseif( ! empty( $this->author_email ) ) 1105 { // non-member, but with email address: 1106 $mail_from = "\"$this->author\" <$this->author_email>"; 1107 } 1108 else 1109 { // Fallback (we have no email address): fp>TODO: or the subscriber is not allowed to view it. 1110 global $notify_from; 1111 $mail_from = $notify_from; 1112 } 1113 // SUSPECT<fp 1114 1115 // Send emails: 1116 foreach( $notify_array as $notify_email => $notify_locale ) 1117 { 1118 locale_temp_switch($notify_locale); 1119 1120 switch( $this->type ) 1121 { 1122 case 'trackback': 1123 /* TRANS: Subject of the mail to send on new trackbacks. First %s is the blog's shortname, the second %s is the item's title. */ 1124 $subject = T_('[%s] New trackback on "%s"'); 1125 break; 1126 1127 default: 1128 /* TRANS: Subject of the mail to send on new comments. First %s is the blog's shortname, the second %s is the item's title. */ 1129 $subject = T_('[%s] New comment on "%s"'); 1130 } 1131 1132 $subject = sprintf( $subject, $edited_Blog->get('shortname'), $edited_Item->get('title') ); 1133 1134 $notify_message = T_('Blog').': '.$edited_Blog->get('shortname')."\n" 1135 // Mail bloat: .' ( '.str_replace('&', '&', $edited_Blog->gen_blogurl())." )\n" 1136 .T_('Post').': '.$edited_Item->get('title')."\n"; 1137 // Mail bloat: .' ( '.str_replace('&', '&', $edited_Item->get_permanent_url())." )\n"; 1138 // TODO: fp> We MAY want to force short URL and avoid it to wrap on a new line in the mail which may prevent people from clicking 1139 1140 switch( $this->type ) 1141 { 1142 case 'trackback': 1143 $user_domain = gethostbyaddr($this->author_IP); 1144 $notify_message .= T_('Website').": $this->author (IP: $this->author_IP, $user_domain)\n"; 1145 $notify_message .= T_('Url').": $this->author_url\n"; 1146 break; 1147 1148 default: 1149 if( $this->get_author_User() ) 1150 { // Comment from a registered user: 1151 $notify_message .= T_('Author').': '.$this->author_User->get('preferredname').' ('.$this->author_User->get('login').")\n"; 1152 } 1153 else 1154 { // Comment from visitor: 1155 $user_domain = gethostbyaddr($this->author_IP); 1156 $notify_message .= T_('Author').": $this->author (IP: $this->author_IP, $user_domain)\n"; 1157 $notify_message .= T_('Email').": $this->author_email\n"; 1158 $notify_message .= T_('Url').": $this->author_url\n"; 1159 } 1160 } 1161 1162 $notify_message .= 1163 T_('Comment').': '.str_replace('&', '&', $this->get_permanent_url())."\n" 1164 // TODO: fp> We MAY want to force a short URL and avoid it to wrap on a new line in the mail which may prevent people from clicking 1165 .$this->get('content')."\n\n" 1166 .T_('Edit/Delete').': '.$admin_url.'?ctrl=items&blog='.$edited_Blog->ID.'&p='.$edited_Item->ID.'&c=1#c'.$this->ID."\n\n" 1167 .T_('Edit your subscriptions/notifications').': '.str_replace('&', '&', url_add_param( $edited_Blog->gen_blogurl(), 'disp=subs' ) )."\n"; 1168 1169 if( $debug ) 1170 { 1171 $mail_dump = "Sending notification to $notify_email:<pre>Subject: $subject\n$notify_message</pre>"; 1172 1173 if( $debug >= 2 ) 1174 { // output mail content - NOTE: this will kill sending of headers. 1175 echo "<p>$mail_dump</p>"; 1176 } 1177 1178 $Debuglog->add( $mail_dump, 'notification' ); 1179 } 1180 1181 send_mail( $notify_email, $subject, $notify_message, $mail_from ); 1182 1183 locale_restore_previous(); 1184 } 1185 } 1186 1187 1188 /** 1189 * Trigger event AfterCommentUpdate after calling parent method. 1190 * 1191 * @return boolean true on success 1192 */ 1193 function dbupdate() 1194 { 1195 global $Plugins; 1196 1197 $dbchanges = $this->dbchanges; 1198 1199 if( $r = parent::dbupdate() ) 1200 { 1201 $Plugins->trigger_event( 'AfterCommentUpdate', $params = array( 'Comment' => & $this, 'dbchanges' => $dbchanges ) ); 1202 } 1203 1204 return $r; 1205 } 1206 1207 1208 /** 1209 * Get karma and set it before adding the Comment to DB. 1210 * 1211 * @return boolean true on success, false if it did not get inserted 1212 */ 1213 function dbinsert() 1214 { 1215 /** 1216 * @var Plugins 1217 */ 1218 global $Plugins; 1219 global $Settings; 1220 1221 // Get karma percentage (interval -100 - 100) 1222 $spam_karma = $Plugins->trigger_karma_collect( 'GetSpamKarmaForComment', array( 'Comment' => & $this ) ); 1223 1224 $this->set_spam_karma( $spam_karma ); 1225 1226 // Change status accordingly: 1227 if( ! is_null($spam_karma) ) 1228 { 1229 if( $spam_karma < $Settings->get('antispam_threshold_publish') ) 1230 { // Publish: 1231 $this->set( 'status', 'published' ); 1232 } 1233 elseif( $spam_karma > $Settings->get('antispam_threshold_delete') ) 1234 { // Delete/No insert: 1235 return false; 1236 } 1237 } 1238 1239 $dbchanges = $this->dbchanges; 1240 1241 if( $r = parent::dbinsert() ) 1242 { 1243 $Plugins->trigger_event( 'AfterCommentInsert', $params = array( 'Comment' => & $this, 'dbchanges' => $dbchanges ) ); 1244 } 1245 1246 return $r; 1247 } 1248 1249 1250 /** 1251 * Trigger event AfterCommentDelete after calling parent method. 1252 * 1253 * @return boolean true on success 1254 */ 1255 function dbdelete() 1256 { 1257 global $Plugins; 1258 1259 // remember ID, because parent method resets it to 0 1260 $old_ID = $this->ID; 1261 1262 if( $r = parent::dbdelete() ) 1263 { 1264 // re-set the ID for the Plugin event 1265 $this->ID = $old_ID; 1266 1267 $Plugins->trigger_event( 'AfterCommentDelete', $params = array( 'Comment' => & $this ) ); 1268 1269 $this->ID = 0; 1270 } 1271 1272 return $r; 1273 } 1274 1275 } 1276 1277 1278 /* 1279 * $Log: _comment.class.php,v $ 1280 * Revision 1.4 2007/11/03 04:56:03 fplanque 1281 * permalink / title links cleanup 1282 * 1283 * Revision 1.3 2007/11/02 01:50:54 fplanque 1284 * comment ratings 1285 * 1286 * Revision 1.2 2007/09/04 19:51:26 fplanque 1287 * in-context comment editing 1288 * 1289 * Revision 1.1 2007/06/25 10:59:40 fplanque 1290 * MODULES (refactored MVC) 1291 * 1292 * Revision 1.65 2007/05/28 15:18:30 fplanque 1293 * cleanup 1294 * 1295 * Revision 1.64 2007/05/20 20:54:49 fplanque 1296 * better comment moderation links 1297 * 1298 * Revision 1.63 2007/04/26 00:11:08 fplanque 1299 * (c) 2007 1300 * 1301 * Revision 1.62 2007/03/24 20:41:16 fplanque 1302 * Refactored a lot of the link junk. 1303 * Made options blog specific. 1304 * Some junk still needs to be cleaned out. Will do asap. 1305 * 1306 * Revision 1.61 2007/03/22 00:03:40 blueyed 1307 * Escape author_url and author_User->url in author_url() template function 1308 * 1309 * Revision 1.60 2007/03/11 23:57:06 fplanque 1310 * item editing: allow setting to 'redirected' status 1311 * 1312 * Revision 1.59 2007/02/28 23:37:52 blueyed 1313 * doc 1314 * 1315 * Revision 1.58 2007/02/25 01:34:19 fplanque 1316 * doc 1317 * 1318 * Revision 1.57 2007/02/21 23:59:00 blueyed 1319 * Trigger FilterIpAddress event in author_ip() 1320 * 1321 * Revision 1.56 2006/12/26 00:08:29 fplanque 1322 * wording 1323 * 1324 * Revision 1.55 2006/12/16 01:30:46 fplanque 1325 * Setting to allow/disable email subscriptions on a per blog basis 1326 * 1327 * Revision 1.54 2006/12/12 02:53:56 fplanque 1328 * Activated new item/comments controllers + new editing navigation 1329 * Some things are unfinished yet. Other things may need more testing. 1330 * 1331 * Revision 1.53 2006/12/07 23:13:10 fplanque 1332 * @var needs to have only one argument: the variable type 1333 * Otherwise, I can't code! 1334 * 1335 * Revision 1.52 2006/12/03 18:10:22 fplanque 1336 * SUSPECT code. Not releasable. Discussion by email. 1337 * 1338 * Revision 1.51 2006/11/26 02:30:39 fplanque 1339 * doc / todo 1340 * 1341 * Revision 1.50 2006/11/17 18:36:23 blueyed 1342 * dbchanges param for AfterItemUpdate, AfterItemInsert, AfterCommentUpdate and AfterCommentInsert 1343 * 1344 * Revision 1.49 2006/11/16 22:41:59 blueyed 1345 * Fixed email from address in notifications, but also added TODO 1346 * 1347 * Revision 1.48 2006/11/16 19:23:12 fplanque 1348 * minor 1349 * 1350 * Revision 1.47 2006/11/14 21:02:57 blueyed 1351 * TODO 1352 * 1353 * Revision 1.46 2006/11/06 00:05:36 blueyed 1354 * Encoding of "&" in Comment::author_url makes no sense, should get done on output. 1355 * 1356 * Revision 1.45 2006/11/05 22:12:35 blueyed 1357 * Fix 1358 * 1359 * Revision 1.44 2006/10/23 22:19:02 blueyed 1360 * Fixed/unified encoding of redirect_to param. Use just rawurlencode() and no funky & replacements 1361 * 1362 * Revision 1.43 2006/10/18 00:03:50 blueyed 1363 * Some forgotten url_rel_to_same_host() additions 1364 */ 1365 ?>
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 |
|