b2evolution PHP Cross Reference Blogging Systems

Source: /inc/comments/model/_comment.funcs.php - 1526 lines - 44688 bytes - Summary - Text - Print

Description: This file implements Comment handling functions. This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}. See also {@link http://sourceforge.net/projects/evocms/}.

   1  <?php
   2  /**
   3   * This file implements Comment handling functions.
   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-2014 by Francois Planque - {@link http://fplanque.com/}.
   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   * @todo implement CommentCache based on LinkCache
  22   *
  23   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  24   * @author cafelog (team)
  25   * @author blueyed: Daniel HAHLER.
  26   * @author fplanque: Francois PLANQUE.
  27   *
  28   * @version $Id: _comment.funcs.php 6136 2014-03-08 07:59:48Z manuel $
  29   */
  30  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  31  
  32  load_class( 'comments/model/_comment.class.php', 'Comment' );
  33  
  34  /**
  35   * Generic comments/trackbacks/pingbacks counting
  36   *
  37   * @todo check this in a multiblog page...
  38   * @todo This should support visibility: at least in the default front office (_feedback.php), there should only the number of visible comments/trackbacks get used ({@link Item::feedback_link()}).
  39   *
  40   * @param integer
  41   * @param string what to count
  42   * @param mixed string or array to count comments with this/these status(es)
  43   * @param boolean set true to count expired comments, leave on false otherwise
  44   */
  45  function generic_ctp_number( $post_id, $mode = 'comments', $status = 'published', $count_expired = false, $filter_by_perm = true )
  46  {
  47      global $DB, $debug, $postdata, $cache_ctp_number, $preview, $servertimenow, $blog;
  48  
  49      if( $preview )
  50      { // we are in preview mode, no comments yet!
  51          return 0;
  52      }
  53  
  54      $show_statuses = is_admin_page() ? get_visibility_statuses( 'keys', array( 'trash', 'redirected' ) ) : get_inskin_statuses();
  55      $filter_index = $filter_by_perm ? 0 : 1;
  56      if( !isset($cache_ctp_number) || !isset($cache_ctp_number[$filter_index][$post_id]) )
  57      { // we need a query to count comments
  58          $count_SQL = new SQL();
  59          $count_SQL->SELECT( 'comment_post_ID, comment_type, comment_status, COUNT(*) AS type_count' );
  60          $count_SQL->FROM( 'T_comments' );
  61          $count_SQL->GROUP_BY( 'comment_post_ID, comment_type, comment_status' );
  62          if( !empty( $blog ) )
  63          {
  64              $count_SQL->WHERE( statuses_where_clause( $show_statuses, 'comment_', $blog, 'blog_comment!', $filter_by_perm ) );
  65          }
  66  
  67          if( !$count_expired )
  68          {
  69              $count_SQL->FROM_add( 'LEFT JOIN T_items__item_settings as expiry_setting ON comment_post_ID = iset_item_ID AND iset_name = "post_expiry_delay"' );
  70              $count_SQL->WHERE_and( 'expiry_setting.iset_value IS NULL OR expiry_setting.iset_value = "" OR TIMESTAMPDIFF(SECOND, comment_date, '.$DB->quote( date2mysql( $servertimenow ) ).') < expiry_setting.iset_value' );
  71          }
  72      }
  73  
  74      // init statuses count array
  75      $statuses_array = array( 'published' => 0, 'community' => 0, 'protected' => 0, 'private' => 0, 'review' => 0, 'draft' => 0, 'deprecated' => 0, 'trash' => 0, 'total' => 0 );
  76  
  77      /*
  78       * Make sure cache is loaded for current display list:
  79       */
  80      if( !isset($cache_ctp_number) || !isset($cache_ctp_number[$filter_index]) )
  81      {
  82          global $postIDlist, $postIDarray;
  83  
  84          // if( $debug ) echo "LOADING generic_ctp_number CACHE for posts: $postIDlist<br />";
  85  
  86          if( ! empty( $postIDlist ) )    // This can happen when displaying a featured post of something that's not in the MainList
  87          {
  88              foreach( $postIDarray as $tmp_post_id)
  89              {    // Initializes each post to nocount!
  90                  $cache_ctp_number[$filter_index][$tmp_post_id] = array(
  91                          'comments'   => $statuses_array,
  92                          'trackbacks' => $statuses_array,
  93                          'pingbacks'  => $statuses_array,
  94                          'feedbacks'  => $statuses_array
  95                      );
  96              }
  97  
  98              $countall_SQL = $count_SQL;
  99              $countall_SQL->WHERE_and( 'comment_post_ID IN ('.$postIDlist.')' );
 100  
 101              foreach( $DB->get_results( $countall_SQL->get() ) as $row )
 102              {
 103                  // detail by status, tyep and post:
 104                  $cache_ctp_number[$filter_index][$row->comment_post_ID][$row->comment_type.'s'][$row->comment_status] = $row->type_count;
 105  
 106                  // Total for type on post:
 107                  $cache_ctp_number[$filter_index][$row->comment_post_ID][$row->comment_type.'s']['total'] += $row->type_count;
 108  
 109                  // Total for status on post:
 110                  $cache_ctp_number[$filter_index][$row->comment_post_ID]['feedbacks'][$row->comment_status] += $row->type_count;
 111  
 112                  // Total for post:
 113                  $cache_ctp_number[$filter_index][$row->comment_post_ID]['feedbacks']['total'] += $row->type_count;
 114              }
 115          }
 116      }
 117      /*    else
 118      {
 119          echo "cache set";
 120      }*/
 121  
 122  
 123      if( !isset($cache_ctp_number[$filter_index][$post_id]) )
 124      { // this should be extremely rare...
 125          // echo "CACHE not set for $post_id";
 126  
 127          // Initializes post to nocount!
 128          $cache_ctp_number[$filter_index][intval($post_id)] = array(
 129                  'comments' => $statuses_array,
 130                  'trackbacks' => $statuses_array,
 131                  'pingbacks' => $statuses_array,
 132                  'feedbacks' => $statuses_array
 133              );
 134  
 135          $count_SQL->WHERE_and( 'comment_post_ID = '.intval($post_id) );
 136  
 137          foreach( $DB->get_results( $count_SQL->get() ) as $row )
 138          {
 139              // detail by status, type and post:
 140              $cache_ctp_number[$filter_index][$row->comment_post_ID][$row->comment_type.'s'][$row->comment_status] = $row->type_count;
 141  
 142              // Total for type on post:
 143              $cache_ctp_number[$filter_index][$row->comment_post_ID][$row->comment_type.'s']['total'] += $row->type_count;
 144  
 145              // Total for status on post:
 146              $cache_ctp_number[$filter_index][$row->comment_post_ID]['feedbacks'][$row->comment_status] += $row->type_count;
 147  
 148              // Total for post:
 149              $cache_ctp_number[$filter_index][$row->comment_post_ID]['feedbacks']['total'] += $row->type_count;
 150          }
 151      }
 152  
 153      if( ($mode != 'comments') && ($mode != 'trackbacks') && ($mode != 'pingbacks') )
 154      {
 155          $mode = 'feedbacks';
 156      }
 157  
 158      if( is_array( $status ) )
 159      { // $status is an array and probably contains more then one visibility status
 160          $result = 0;
 161          foreach( $status as $one_status )
 162          {
 163              if( isset( $cache_ctp_number[$filter_index][$post_id][$mode][$one_status] ) )
 164              {
 165                  $result = $result + $cache_ctp_number[$filter_index][$post_id][$mode][$one_status];
 166              }
 167          }
 168      }
 169      elseif( isset( $cache_ctp_number[$filter_index][$post_id][$mode][$status] ) )
 170      { // $status is a string with one visibility status
 171          $result = $cache_ctp_number[$filter_index][$post_id][$mode][$status];
 172      }
 173      else
 174      { // $status is not recognized return total feedback number
 175          $result = $cache_ctp_number[$filter_index][$post_id][$mode]['total'];
 176      }
 177  
 178      // pre_dump( $cache_ctp_number[$filter_index][$post_id] );
 179  
 180      return $result;
 181  }
 182  
 183  
 184  /**
 185   * Get a Comment by ID. Exits if the requested comment does not exist!
 186   *
 187   * @param integer
 188   * @param boolean
 189   * @return Comment
 190   */
 191  function & Comment_get_by_ID( $comment_ID, $halt_on_error = true )
 192  {
 193      $CommentCache = & get_CommentCache();
 194      return $CommentCache->get_by_ID( $comment_ID, $halt_on_error );
 195  }
 196  
 197  
 198  /*
 199   * last_comments_title(-)
 200   *
 201   * @movedTo _obsolete092.php
 202   */
 203  
 204  
 205  /***** Comment tags *****/
 206  
 207  /**
 208   * comments_number(-)
 209   *
 210   * @deprecated deprecated by {@link Item::feedback_link()}, used in _edit_showposts.php
 211   */
 212  function comments_number( $zero='#', $one='#', $more='#', $post_ID = NULL )
 213  {
 214      if( $zero == '#' ) $zero = T_('Leave a comment');
 215      if( $one == '#' ) $one = T_('1 comment');
 216      if( $more == '#' ) $more = T_('%d comments');
 217  
 218      if( empty( $post_ID ) )
 219      {
 220          global $id;
 221          $post_ID = $id;
 222      }
 223  
 224      // attila> This function is called only from the backoffice ( _item_list_full.view.php ).
 225      // There we always have to show all comments.
 226      $number = generic_ctp_number( $post_ID, 'comments', 'total' );
 227      if ($number == 0)
 228      {
 229          $blah = $zero;
 230      }
 231      elseif ($number == 1)
 232      {
 233          $blah = $one;
 234      }
 235      elseif ($number  > 1)
 236      {
 237          $n = $number;
 238          $more = str_replace('%d', $n, $more);
 239          $blah = $more;
 240      }
 241      echo $blah;
 242  }
 243  
 244  /**
 245   * Get advanced perm for comment moderation on this blog
 246   *
 247   * @param int blog ID
 248   * @return array statuses - current user has permission to moderate comments with these statuses
 249   */
 250  function get_allowed_statuses( $blog )
 251  {
 252      global $current_User;
 253      $statuses = array();
 254  
 255      if( $current_User->check_perm( 'blog_draft_comments', 'edit', false, $blog ) )
 256      {
 257          $statuses[] = 'draft';
 258      }
 259  
 260      if( $current_User->check_perm( 'blog_published_comments', 'edit', false, $blog ) )
 261      {
 262          $statuses[] = 'published';
 263      }
 264  
 265      if( $current_User->check_perm( 'blog_deprecated_comments', 'edit', false, $blog ) )
 266      {
 267          $statuses[] = 'deprecated';
 268      }
 269  
 270      return $statuses;
 271  }
 272  
 273  
 274  /**
 275   * Create comment form submit buttons
 276   *
 277   * Note: Publsih in only displayed when comment is in draft status
 278   *
 279   * @param $Form
 280   * @param $edited_Comment
 281   *
 282   */
 283  function echo_comment_buttons( $Form, $edited_Comment )
 284  {
 285      global $Blog, $current_User, $highest_publish_status;
 286  
 287      // ---------- SAVE ------------
 288      $Form->submit( array( 'actionArray[update]', T_('Save!'), 'SaveButton' ) );
 289  
 290      // ---------- PUBLISH ---------
 291      list( $highest_publish_status, $publish_text ) = get_highest_publish_status( 'comment', $Blog->ID );
 292      $current_status_value = get_status_permvalue( $edited_Comment->status );
 293      $highest_status_value = get_status_permvalue( $highest_publish_status );
 294      $Form->hidden( 'publish_status', $highest_publish_status );
 295      if( ( $current_status_value < $highest_status_value ) && ( $highest_publish_status != 'draft' )
 296          && $current_User->check_perm( 'comment!'.$highest_publish_status, 'edit', false, $edited_Comment ) )
 297      { // User may publish this comment with a "more public" status
 298           $publish_style = 'display: inline';
 299      }
 300      else
 301      {
 302          $publish_style = 'display: none';
 303      }
 304      $Form->submit( array(
 305          'actionArray[update_publish]',
 306          $publish_text,
 307          'SaveButton',
 308          '',
 309          $publish_style
 310      ) );
 311  }
 312  
 313  
 314  /**
 315   * JS Behaviour: Output JavaScript code to dynamically show or hide the "Publish!"
 316   * button depending on the selected comment status.
 317   *
 318   * This function is used by the comment edit screen.
 319   */
 320  function echo_comment_publishbt_js()
 321  {
 322      global $next_action, $highest_publish_status;
 323      ?>
 324      <script type="text/javascript">
 325      jQuery( '#commentform_visibility input[type=radio]' ).click( function()
 326      {
 327          var commentpublish_btn = jQuery( '.edit_actions input[name="actionArray[update_publish]"]' );
 328          var public_status = '<?php echo $highest_publish_status; ?>';
 329  
 330          if( this.value == public_status || public_status == 'draft' )
 331          {    // Hide the "Publish NOW !" button:
 332              commentpublish_btn.css( 'display', 'none' );
 333          }
 334          else
 335          {    // Show the button:
 336              commentpublish_btn.css( 'display', 'inline' );
 337          }
 338      } );
 339      </script>
 340      <?php
 341  }
 342  
 343  
 344  /**
 345   * Add a javascript ban action icon after the given url
 346   *
 347   * @param string url
 348   * @return string the url with ban icon
 349   */
 350  function add_jsban( $url )
 351  {
 352      global $admin_url;
 353  
 354      $url = rawurlencode( get_ban_domain( $url ) );
 355      $ban_url = $admin_url.'?ctrl=antispam&amp;action=ban&amp;keyword='.$url.'&amp;'.url_crumb('antispam');
 356  
 357      return '<a id="ban_url" href="'.$ban_url.'" onclick="ban_url(\''.$url.'\'); return false;">'.get_icon( 'ban' ).'</a>';
 358  }
 359  
 360  
 361  /**
 362   * Add a javascript ban action icon after each url in the given content
 363   *
 364   * @param string Comment content
 365   * @return string the content with a ban icon after each url if the user has spamblacklist permission, the incoming content otherwise
 366   */
 367  function add_ban_icons( $content )
 368  {
 369      global $current_User;
 370      if( ! $current_User->check_perm( 'spamblacklist', 'edit' ) )
 371      {
 372          return $content;
 373      }
 374  
 375      $atags = get_atags( $content );
 376      $imgtags = get_imgtags( $content );
 377      $urls = get_urls( $content );
 378      $result = '';
 379      $from = 0; // current processing position
 380      $length = 0; // current url or tag length
 381      $i = 0; // url counter
 382      $j = 0; // "a" tag counter
 383      $k = 0; // "img" tag counter
 384      while( isset($urls[$i]) )
 385      { // there is unprocessed url
 386          $url = $urls[$i];
 387          if( validate_url( $url, 'posting', false ) )
 388          { // skip not valid urls
 389              $i++;
 390              continue;
 391          }
 392          while( isset( $imgtags[$k] ) && ( strpos( $content, $imgtags[$k] ) < $from ) )
 393          { // skipp already passed img tags
 394              $k++;
 395          }
 396  
 397          $pos = strpos( $content, $url, $from );
 398          $length = evo_strlen($url);
 399          $i++;
 400  
 401          // check img tags
 402          if( isset( $imgtags[$k] ) && ( strpos( $imgtags[$k], $url ) !== false )
 403              && ( $pos > strpos( $content, $imgtags[$k], $from ) ) )
 404          { // current url is inside the img tag, we need to skip this url.
 405              $result .= substr( $content, $from, $pos + $length - $from );
 406              $from = $pos + $length;
 407              $k++;
 408              continue;
 409          }
 410  
 411          // check a tags
 412          if( isset($atags[$j]) )
 413          { // there is unprocessed "a" tag
 414              $tag = $atags[$j];
 415              if( ( ( $urlpos = strpos( $tag, $url ) ) !== false ) && ( $pos > strpos( $content, $tag, $from ) ) )
 416              { // the url is inside the current tag, we have to add ban icon after the tag
 417                  $pos = strpos( $content, $tag, $from );
 418                  $length = strlen($tag);
 419                  while( isset($urls[$i]) && ( ( $urlpos = strpos( $tag, $urls[$i], $urlpos + 1 ) ) !== false ) )
 420                  { // skip all other urls from this tag
 421                      $i++;
 422                  }
 423                  $j++;
 424              }
 425          }
 426          // add processed part and ban icon to result and set current position
 427          $result .= substr( $content, $from, $pos + $length - $from );
 428          $from = $pos + $length;
 429          $result .= add_jsban( $url );
 430      }
 431  
 432      // add the end of the content to the result
 433      $result .= substr( $content, $from, strlen($content) - $from );
 434      return $result;
 435  }
 436  
 437  
 438  /**
 439   * Get opentrash link
 440   *
 441   * @param boolean check permission or not. Should be false only if it was already checked.
 442   * @param boolean show "Open recycle bin" link even if there is no comment with 'trash' status
 443   * @return Open recycle bin link if user has the corresponding 'blogs' - 'editall' permission, empty string otherwise
 444   */
 445  function get_opentrash_link( $check_perm = true, $force_show = false )
 446  {
 447      global $admin_url, $current_User, $DB, $blog;
 448  
 449      $show_recycle_bin = ( !$check_perm || $current_User->check_perm( 'blogs', 'editall' ) );
 450      if( $show_recycle_bin && ( !$force_show ) )
 451      { // get number of trash comments:
 452          $SQL = new SQL( 'Get number of trash comments' );
 453          $SQL->SELECT( 'COUNT( comment_ID )' );
 454          $SQL->FROM( 'T_comments' );
 455          $SQL->FROM_add( 'INNER JOIN T_items__item ON comment_post_ID = post_ID' );
 456          $SQL->FROM_add( 'INNER JOIN T_categories ON post_main_cat_ID = cat_ID' );
 457          $SQL->WHERE( 'comment_status = "trash"' );
 458          if( isset( $blog ) )
 459          {
 460              $SQL->WHERE_and( 'cat_blog_ID = '.$DB->quote( $blog ) );
 461          }
 462          $show_recycle_bin = ( $DB->get_var( $SQL->get() ) > 0 );
 463      }
 464  
 465      $result = '<div id="recycle_bin">';
 466      if( $show_recycle_bin )
 467      { // show "Open recycle bin"
 468          global $CommentList;
 469          $comment_list_param_prefix = 'cmnt_fullview_';
 470          if( !empty( $CommentList->param_prefix ) )
 471          {
 472              $comment_list_param_prefix = $CommentList->param_prefix;
 473          }
 474          $result .= '<span class="floatright">'.action_icon( T_('Open recycle bin'), 'recycle_full',
 475                          $admin_url.'?ctrl=comments&amp;blog='.$blog.'&amp;'.$comment_list_param_prefix.'show_statuses[]=trash', T_('Open recycle bin'), 5, 3 ).'</span> ';
 476      }
 477      return $result.'</div>';
 478  }
 479  
 480  
 481  /**
 482   * Display disabled comment form
 483   *
 484   * @param string Blog allow comments settings value
 485   * @param string Item url, where this comment form should be displayed
 486   * @param array Skin params
 487   */
 488  function echo_disabled_comments( $allow_comments_value, $item_url, $params = array() )
 489  {
 490      global $Settings, $current_User;
 491  
 492      $params = array_merge( array(
 493              'comments_disabled_text_member'     => T_( 'You must be a member of this blog to comment.' ),
 494              'comments_disabled_text_registered' => T_( 'You must be logged in to leave a comment.' ),
 495              'comments_disabled_text_validated'  => T_( 'You must activate your account before you can leave a comment.' ),
 496              'form_comment_text'                 => T_('Comment text'),
 497          ), $params );
 498  
 499      if( empty( $params['form_params'] ) )
 500      {
 501          $params['form_params'] = array();
 502      }
 503  
 504      $params['form_params'] = array_merge( array(
 505              'formstart'      => '',
 506              'formend'        => '',
 507              'fieldset_begin' => '<fieldset>',
 508              'fieldset_end'   => '</fieldset>',
 509              'fieldstart'     => '',
 510              'fieldend'       => '',
 511              'labelstart'     => '<div class="label"><label for="p">',
 512              'labelend'       => '</label></div>',
 513              'inputstart'     => '<div class="input">',
 514              'inputend'       => '</div>',
 515          ), $params['form_params'] );
 516  
 517      switch( $allow_comments_value )
 518      {
 519          case 'member':
 520              $disabled_text = $params['comments_disabled_text_member'];
 521              break;
 522  
 523          case 'registered':
 524              $disabled_text = $params['comments_disabled_text_registered'];
 525              break;
 526  
 527          default:
 528              // case any or never, in this case comment form is already displayed, or comments are not allowed at all.
 529              return;
 530      }
 531  
 532      $login_link = '';
 533      $activateinfo_link = '';
 534      $is_logged_in = is_logged_in();
 535      if( !$is_logged_in )
 536      { // user is not logged in
 537          $login_link = '<a href="'.get_login_url( 'cannot comment', $item_url ).'">'.T_( 'Log in now!' ).'</a>';
 538      }
 539      elseif( $current_User->check_status( 'can_be_validated' ) )
 540      { // logged in but the account is not activated
 541          $disabled_text = $params['comments_disabled_text_validated'];
 542          $activateinfo_link = '<a href="'.get_activate_info_url( $item_url ).'">'.T_( 'More info &raquo;' ).'</a>';
 543      }
 544      // else -> user is logged in and account was activated
 545  
 546      $register_link = '';
 547      if( ( !$is_logged_in ) && ( $Settings->get( 'newusers_canregister' ) ) )
 548      {
 549          $register_link = '<p>'.sprintf( T_( 'If you have no account yet, you can <a href="%s">register now</a>...<br />(It only takes a few seconds!)' ), get_user_register_url( $item_url, 'reg to post comment' ) ).'</p>';
 550      }
 551  
 552      // disabled comment form
 553      echo '<form class="bComment" action="">';
 554  
 555      echo '<div class="comment_posting_disabled_msg">';
 556      if( $is_logged_in )
 557      {
 558          echo '<p>'.$disabled_text.' '.$activateinfo_link.'</p>';
 559      }
 560      else
 561      { // not logged in, add login and register links
 562          echo '<p>'.$disabled_text.' '.$login_link.'</p>';
 563          echo $register_link;
 564      }
 565      echo '</div>';
 566  
 567      echo $params['form_params']['formstart'];
 568  
 569      echo $params['form_params']['fieldset_begin'];
 570      echo $params['form_params']['fieldstart'];
 571      echo $params['form_params']['labelstart'].$params['form_comment_text'].':'.$params['form_params']['labelend'];
 572      echo $params['form_params']['inputstart'];
 573      echo '<textarea id="p" class="bComment form_text_areainput" rows="5" name="p" cols="40" disabled="disabled">'.$disabled_text.'</textarea>';
 574      echo $params['form_params']['inputend'];
 575      echo $params['form_params']['fieldend'];
 576      echo $params['form_params']['fieldset_end'];
 577  
 578      echo $params['form_params']['formend'];
 579  
 580      // margin at the bottom of the form
 581      echo '<div style="margin-top:10px"></div>';
 582      echo '</form>';
 583  }
 584  
 585  
 586  /**
 587   * Save Comment object into the current Session
 588   *
 589   * @param $Comment
 590   */
 591  function save_comment_to_session( $Comment )
 592  {
 593      global $Session;
 594      $Session->set( 'core.unsaved_Comment', $Comment );
 595  }
 596  
 597  
 598  /**
 599   * Get Comment object from the current Session
 600   *
 601   * @return Comment|NULL Comment object if Session core.unsaved_Comment param is set, NULL otherwise
 602   */
 603  function get_comment_from_session()
 604  {
 605      global $Session;
 606      if( ( $mass_Comment = $Session->get( 'core.unsaved_Comment' ) ) && is_a( $mass_Comment, 'Comment' ) )
 607      {
 608          $Session->delete( 'core.unsaved_Comment' );
 609          return $mass_Comment;
 610      }
 611      return NULL;
 612  }
 613  
 614  
 615  /**
 616   * Dispay the replies of a comment
 617   *
 618   * @param integer Comment ID
 619   * @param array Template params
 620   * @param integer Level
 621   */
 622  function display_comment_replies( $comment_ID, $params = array(), $level = 1 )
 623  {
 624      global $CommentReplies;
 625  
 626      $params = array_merge( array(
 627              'comment_template'    => '_item_comment.inc.php',
 628              'preview_block_start' => '',
 629              'preview_start'       => '<div class="bComment" id="comment_preview">',
 630              'preview_end'         => '</div>',
 631              'preview_block_end'   => '',
 632              'comment_start'       => '<div class="bComment">',
 633              'comment_end'         => '</div>',
 634              'comment_error_start' => '<div class="bComment" id="comment_error">',
 635              'comment_error_end'   => '</div>',
 636              'link_to'             => 'userurl>userpage', // 'userpage' or 'userurl' or 'userurl>userpage' or 'userpage>userurl'
 637              'author_link_text'    => 'login', // avatar | only_avatar | login | nickname | firstname | lastname | fullname | preferredname
 638          ), $params );
 639  
 640      if( isset( $CommentReplies[ $comment_ID ] ) )
 641      { // This comment has the replies
 642          foreach( $CommentReplies[ $comment_ID ] as $Comment )
 643          { // Loop through the replies:
 644              if( empty( $Comment->ID ) )
 645              { // Get html tag of the comment block of preview
 646                  $comment_start = $Comment->email_is_detected ? $params['comment_error_start'] : $params['preview_start'];
 647              }
 648              else
 649              { // Get html tag of the comment block of existing comment
 650                  $comment_start = $params['comment_start'];
 651              }
 652  
 653              // Set margin left for each sub level comment
 654              $attrs = ' style="margin-left:'.( 20 * $level ).'px"';
 655              if( strpos( $comment_start, 'class="' ) === false )
 656              { // Add a class attribute for the replied comment
 657                  $attrs .= ' class="replied_comment"';
 658              }
 659              else
 660              { // Add a class name for the replied comment
 661                  $comment_start = str_replace( 'class="', 'class="replied_comment ', $comment_start );
 662              }
 663              $comment_start = str_replace( '>', $attrs.'>', $comment_start );
 664  
 665              if( ! empty( $Comment->ID ) )
 666              { // Comment from DB
 667                  skin_include( $params['comment_template'], array(
 668                          'Comment'          => & $Comment,
 669                          'comment_start'    => $comment_start,
 670                          'comment_end'      => $params['comment_end'],
 671                          'link_to'          => $params['link_to'],        // 'userpage' or 'userurl' or 'userurl>userpage' or 'userpage>userurl'
 672                          'author_link_text' => $params['author_link_text'],
 673                      ) );
 674              }
 675              else
 676              { // PREVIEW comment
 677                  skin_include( $params['comment_template'], array(
 678                          'Comment'              => & $Comment,
 679                          'comment_block_start'  => $Comment->email_is_detected ? '' : $params['preview_block_start'],
 680                          'comment_start'        => $comment_start,
 681                          'comment_end'          => $Comment->email_is_detected ? $params['comment_error_end'] : $params['preview_end'],
 682                          'comment_block_end'    => $Comment->email_is_detected ? '' : $params['preview_block_end'],
 683                          'author_link_text'     => $params['author_link_text'],
 684                      ) );
 685              }
 686  
 687              // Display the rest replies recursively
 688              display_comment_replies( $Comment->ID, $params, $level + 1 );
 689          }
 690      }
 691  }
 692  
 693  
 694  /**
 695   * JS Behaviour: Output JavaScript code to reply the comments
 696   *
 697   * @param object Item
 698   */
 699  function echo_comment_reply_js( $Item )
 700  {
 701      global $Blog;
 702  
 703      if( !isset( $Blog ) )
 704      {
 705          return false;
 706      }
 707  
 708      if( !$Blog->get_setting( 'threaded_comments' ) )
 709      {
 710          return false;
 711      }
 712  
 713  ?>
 714  <script type="text/javascript">
 715  jQuery( 'a.comment_reply' ).click( function()
 716  {    // The click action for the links "Reply to this comment"
 717      var comment_ID = jQuery( this ).attr( 'rel' );
 718  
 719      // Remove data of a previous comment
 720      jQuery( 'a.comment_reply_current' ).remove();
 721      jQuery( 'input[name=reply_ID]' ).remove();
 722      jQuery( 'a.comment_reply' ).removeClass( 'active' )
 723          .html( '<?php echo TS_('Reply to this comment') ?>' );
 724  
 725      // Add data for a current comment
 726      var link_back_comment = '<a href="<?php echo url_add_param( $Item->get_permanent_url(), 'reply_ID=\' + comment_ID + \'&amp;redir=no' ) ?>#c' + comment_ID + '" class="comment_reply_current" rel="' + comment_ID + '"><?php echo TS_('You are currently replying to a specific comment') ?></a>';
 727      var hidden_reply_ID = '<input type="hidden" name="reply_ID" value="' + comment_ID + '" />';
 728      jQuery( '#bComment_form_id_<?php echo $Item->ID; ?>' ).prepend( link_back_comment + hidden_reply_ID );
 729  
 730      jQuery( this ).addClass( 'active' )
 731          .html( '<?php echo TS_('You are currently replying to this comment') ?>' );
 732      // Scroll to the comment form
 733      jQuery( window ).scrollTop( jQuery( '#bComment_form_id_<?php echo $Item->ID ?>' ).offset().top - 30 );
 734  
 735      return false;
 736  } );
 737  
 738  jQuery( document ).on( 'click', 'a.comment_reply_current', function()
 739  {    // The click action for a link "You are currently replying to a specific comment"
 740      var comment_ID = jQuery( this ).attr( 'rel' );
 741  
 742      // Scroll to the comment
 743      jQuery( window ).scrollTop( jQuery( 'a#c' + comment_ID ).offset().top - 10 );
 744  
 745      return false;
 746  } );
 747  </script>
 748  <?php
 749  
 750  }
 751  
 752  
 753  /**
 754   * JS Behaviour: Output JavaScript code to moderate the comments
 755   * Vote on the comment
 756   * Change a status of the comment
 757   */
 758  function echo_comment_moderate_js()
 759  {
 760      if( !is_logged_in( false ) )
 761      {
 762          return false;
 763      }
 764  
 765      global $Blog;
 766  
 767      if( empty( $Blog ) )
 768      {
 769          return false;
 770      }
 771  ?>
 772  <script type="text/javascript">
 773  /* <![CDATA[ */
 774  function fadeIn( selector, color )
 775  {
 776      if( jQuery( selector ).length == 0 )
 777      {
 778          return;
 779      }
 780      if( jQuery( selector ).get(0).tagName == 'TR' )
 781      { // Fix selector, <tr> cannot have a css property background-color
 782          selector = selector + ' td';
 783      }
 784      var bg_color = jQuery( selector ).css( 'backgroundColor' );
 785      jQuery( selector ).animate( { backgroundColor: color }, 200 );
 786      return bg_color;
 787  }
 788  
 789  function fadeInStatus( selector, status )
 790  {
 791      switch( status )
 792      {
 793          case 'published':
 794              return fadeIn( selector, '#99EE44' );
 795          case 'community':
 796              return fadeIn( selector, '#2E8BB9' );
 797          case 'protected':
 798              return fadeIn( selector, '#FF9C2A' );
 799          case 'review':
 800              return fadeIn( selector, '#CC0099' );
 801      }
 802  }
 803  
 804  // Display voting tool when JS is enable
 805  jQuery( '.vote_spam' ).show();
 806  
 807  // Set comments vote
 808  function setCommentVote( id, type, vote )
 809  {
 810      var row_selector = '#comment_row_' + id;
 811      var highlight_class = '';
 812      var color = '';
 813      switch(vote)
 814      {
 815          case 'spam':
 816              color = fadeIn( row_selector, '#ffc9c9' );
 817              highlight_class = 'roundbutton_red';
 818              break;
 819          case 'notsure':
 820              color = fadeIn( row_selector, '#bbbbbb' );
 821              break;
 822          case 'ok':
 823              color = fadeIn( row_selector, '#bcffb5' );
 824              highlight_class = 'roundbutton_green';
 825              break;
 826      }
 827  
 828      if( highlight_class != '' )
 829      {
 830          jQuery( '#vote_'+type+'_'+id ).find( 'a.roundbutton, span.roundbutton' ).addClass( highlight_class );
 831      }
 832  
 833      jQuery.ajax({
 834      type: "POST",
 835      url: "<?php echo get_samedomain_htsrv_url(); ?>anon_async.php",
 836      data:
 837          { "blogid": "<?php echo $Blog->ID; ?>",
 838              "commentid": id,
 839              "type": type,
 840              "vote": vote,
 841              "action": "set_comment_vote",
 842              "crumb_comment": "<?php echo get_crumb('comment'); ?>",
 843          },
 844      success: function(result)
 845          {
 846              if( color != '' )
 847              { // Revert the color
 848                  fadeIn( row_selector, color );
 849              }
 850              jQuery("#vote_"+type+"_"+id).after( ajax_debug_clear( result ) );
 851              jQuery("#vote_"+type+"_"+id).remove();
 852          }
 853      });
 854  }
 855  
 856  // Set comment status
 857  function setCommentStatus( id, status, redirect_to )
 858  {
 859      var row_selector = '[id=comment_row_' + id + ']';
 860      var color = fadeInStatus( row_selector, status );
 861  
 862      jQuery.ajax({
 863      type: 'POST',
 864      url: '<?php echo get_samedomain_htsrv_url(); ?>anon_async.php',
 865      data:
 866          { 'blogid': '<?php echo $Blog->ID; ?>',
 867              'commentid': id,
 868              'status': status,
 869              'action': 'moderate_comment',
 870              'redirect_to': redirect_to,
 871              'crumb_comment': '<?php echo get_crumb('comment'); ?>',
 872          },
 873      success: function(result)
 874          {
 875              if( color != '' )
 876              { // Revert the color
 877                  fadeIn( row_selector, color );
 878              }
 879              var statuses = ajax_debug_clear( result ).split( ':' );
 880              var new_status = statuses[0];
 881              if( new_status == '' )
 882              { // Status was not changed
 883                  return;
 884              }
 885              var class_name = jQuery( row_selector ).attr( 'class' );
 886              class_name = class_name.replace( /vs_([a-z]+)/g, 'vs_' + new_status );
 887              jQuery( row_selector ).attr( 'class', class_name );
 888              update_moderation_buttons( row_selector, statuses[1], statuses[2] );
 889          }
 890      });
 891  }
 892  
 893  // Add classes for first and last roundbuttons, because css pseudo-classes don't support to exclude hidden elements
 894  function update_moderation_buttons( selector, raise_status, lower_status )
 895  {
 896      var parent_selector = '.roundbutton_group ';
 897      if( typeof( selector ) != 'undefined' )
 898      {
 899          parent_selector = selector + ' ' + parent_selector;
 900      }
 901      selector = parent_selector + '.roundbutton_text';
 902  
 903      // Clear previous classes of first and last visible buttons
 904      jQuery( selector ).removeClass( 'first-child last-child btn_next_status' );
 905      // Make the raise and lower button are visible
 906      jQuery( selector + '.btn_raise_' + raise_status ).addClass( 'btn_next_status' );
 907      jQuery( selector + '.btn_lower_' + lower_status ).addClass( 'btn_next_status' );
 908      // Add classes for first and last buttons to fix round corners
 909      jQuery( selector + ':visible:first' ).addClass( 'first-child' );
 910      jQuery( selector + ':visible:last' ).addClass( 'last-child' );
 911  }
 912  /* ]]> */
 913  </script>
 914  <?php
 915  }
 916  
 917  
 918  /**
 919   * Check to display a form to mass delete the comments
 920   *
 921   * @param object Comment List
 922   * @return boolean TRUE - if a form is available
 923   */
 924  function check_comment_mass_delete( $CommentList )
 925  {
 926      global $current_User;
 927      if( !$current_User->check_perm( 'blogs', 'all' ) )
 928      {    // Check permission
 929          return false;
 930      }
 931  
 932      if( $CommentList->total_rows == 0 )
 933      {    // No comments for current list
 934          return false;
 935      }
 936  
 937      // Form is available to mass delete the comments
 938      return true;
 939  }
 940  
 941  
 942  /**
 943   * Dispay a form to mass delete the comments
 944   *
 945   * @param object Comment List
 946   */
 947  function display_comment_mass_delete( $CommentList )
 948  {
 949  
 950      $action = param_action();
 951  
 952      if( $action != 'mass_delete' )
 953      {    // Display this form only for action "mass_delete"
 954          return;
 955      }
 956  
 957      if( !check_comment_mass_delete( $CommentList ) )
 958      {    // Form is not available
 959          return;
 960      }
 961  
 962      require dirname(__FILE__).'/../views/_comment_mass.form.php';
 963  }
 964  
 965  
 966  /**
 967   * Delete the comments
 968   *
 969   * @param string Type of deleting:
 970   *               'recycle' - to move into recycle bin
 971   *               'delete' - to delete permanently
 972   * @param string sql query to get deletable comment ids
 973   */
 974  function comment_mass_delete_process( $mass_type, $deletable_comments_query )
 975  {
 976      if( $mass_type != 'recycle' && $mass_type != 'delete' )
 977      { // Incorrect action
 978          return;
 979      }
 980  
 981      global $DB, $cache_comments_has_replies, $user_post_read_statuses, $cache_postcats;
 982  
 983      /**
 984       * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..."
 985       */
 986      $DB->log_queries = false;
 987  
 988      $Form = new Form();
 989  
 990      $Form->begin_form( 'fform' );
 991  
 992      $Form->begin_fieldset( T_('Mass deleting log') );
 993  
 994      echo T_('The comments are deleting...');
 995      evo_flush();
 996  
 997      $CommentCache = & get_CommentCache();
 998      $ItemCache = & get_ItemCache();
 999      $ChapterCache = & get_ChapterCache();
1000  
1001      // Get the comments by 1000 to avoid an exhausting of memory
1002      $deletable_comment_ids = $DB->get_col( $deletable_comments_query.' LIMIT 1000' );
1003      while( !empty( $deletable_comment_ids ) )
1004      {
1005          // Get the first slice of the deletable comment ids list
1006          $ids = array_splice( $deletable_comment_ids, 0, 100 );
1007          // Make sure the CommentCache is empty
1008          $CommentCache->clear();
1009          // Load deletable comment ids
1010          $CommentCache->load_list( $ids );
1011  
1012          while( ( $iterator_Comment = & $CommentCache->get_next() ) != NULL )
1013          { // Delete all comments from CommentCache
1014              $iterator_Comment->dbdelete( $mass_type == 'delete' );
1015          }
1016  
1017          // Display progress dot
1018          echo ' .';
1019          evo_flush();
1020  
1021          if( empty( $deletable_comment_ids ) )
1022          {
1023              // Clear all caches to save memory
1024              $ItemCache->clear();
1025              $ChapterCache->clear();
1026              $cache_comments_has_replies = array();
1027              $user_post_read_statuses = array();
1028              $cache_postcats = array();
1029  
1030              // Get new portion of deletable comments
1031              $deletable_comment_ids = $DB->get_col( $deletable_comments_query.' LIMIT 1000' );
1032          }
1033      }
1034  
1035      echo ' OK';
1036  
1037      $Form->end_form();
1038  
1039      // Clear a comment cache
1040      $CommentCache->clear();
1041  }
1042  
1043  
1044  /**
1045   * Display comments results table
1046   *
1047   * @param array Params
1048   */
1049  function comments_results_block( $params = array() )
1050  {
1051      // Make sure we are not missing any param:
1052      $params = array_merge( array(
1053              'edited_User'          => NULL,
1054              'results_param_prefix' => 'actv_comment_',
1055              'results_title'        => T_('Comments posted by the user'),
1056              'results_no_text'      => T_('User has not posted any comment yet'),
1057          ), $params );
1058  
1059      if( !is_logged_in() )
1060      {    // Only logged in users can access to this function
1061          return;
1062      }
1063  
1064      global $current_User;
1065      if( !$current_User->check_perm( 'users', 'edit' ) )
1066      {    // Check minimum permission:
1067          return;
1068      }
1069  
1070      $edited_User = $params['edited_User'];
1071      if( !$edited_User )
1072      {    // No defined User, probably the function is calling from AJAX request
1073          $user_ID = param( 'user_ID', 'integer', 0 );
1074          if( empty( $user_ID ) )
1075          {    // Bad request, Exit here
1076              return;
1077          }
1078          $UserCache = & get_UserCache();
1079          if( ( $edited_User = & $UserCache->get_by_ID( $user_ID, false ) ) === false )
1080          {    // Bad request, Exit here
1081              return;
1082          }
1083      }
1084  
1085      global $DB;
1086  
1087      param( 'user_tab', 'string', '', true );
1088      param( 'user_ID', 'integer', 0, true );
1089  
1090  
1091      $SQL = new SQL();
1092      $SQL->SELECT( '*' );
1093      $SQL->FROM( 'T_comments' );
1094      $SQL->WHERE( 'comment_author_ID = '.$DB->quote( $edited_User->ID ) );
1095  
1096      // Create result set:
1097      $comments_Results = new Results( $SQL->get(), $params['results_param_prefix'], 'D' );
1098      $comments_Results->Cache = & get_CommentCache();
1099      $comments_Results->title = $params['results_title'];
1100      $comments_Results->no_results_text = $params['results_no_text'];
1101  
1102      // Get a count of the comments which current user can delete
1103      $deleted_comments_count = count( $edited_User->get_deleted_comments() );
1104      if( $comments_Results->total_rows > 0 && $deleted_comments_count )
1105      {    // Display action icon to delete all records if at least one record exists & current user can delete at least one comment posted by user
1106          $comments_Results->global_icon( sprintf( T_('Delete all comments posted by %s'), $edited_User->login ), 'delete', '?ctrl=user&amp;user_tab=activity&amp;action=delete_all_comments&amp;user_ID='.$edited_User->ID.'&amp;'.url_crumb('user'), ' '.T_('Delete all'), 3, 4 );
1107      }
1108  
1109      // Initialize Results object
1110      comments_results( $comments_Results, array(
1111              'field_prefix' => 'comment_',
1112              'display_kind' => false,
1113              'display_additional_columns' => true,
1114              'plugin_table_name' => 'activity',
1115              'display_spam' => false,
1116          ) );
1117  
1118      if( is_ajax_content() )
1119      {    // init results param by template name
1120          if( !isset( $params[ 'skin_type' ] ) || ! isset( $params[ 'skin_name' ] ) )
1121          {
1122              debug_die( 'Invalid ajax results request!' );
1123          }
1124          $comments_Results->init_params_by_skin( $params[ 'skin_type' ], $params[ 'skin_name' ] );
1125      }
1126  
1127      $display_params = array(
1128          'before' => '<div class="results" style="margin-top:25px" id="comments_result">'
1129      );
1130      $comments_Results->display( $display_params );
1131  
1132      if( !is_ajax_content() )
1133      {    // Create this hidden div to get a function name for AJAX request
1134          echo '<div id="'.$params['results_param_prefix'].'ajax_callback" style="display:none">'.__FUNCTION__.'</div>';
1135      }
1136  }
1137  
1138  
1139  /**
1140   * Initialize Results object for comments list
1141   *
1142   * @param object Results
1143   * @param array Params
1144   */
1145  function comments_results( & $comments_Results, $params = array() )
1146  {
1147      // Make sure we are not missing any param:
1148      $params = array_merge( array(
1149              'field_prefix' => '',
1150              'display_date' => true,
1151              'display_permalink' => true,
1152              'display_item' => false,
1153              'display_status' => false,
1154              'display_kind' => true,
1155              'display_author' => true,
1156              'display_url' => true,
1157              'display_email' => true,
1158              'display_ip' => true,
1159              'display_additional_columns' => false,
1160              'plugin_table_name' => '',
1161              'display_spam' => true,
1162              'display_visibility' => true,
1163              'display_actions' => true,
1164              'col_post' => T_('Post'),
1165          ), $params );
1166  
1167      if( $params['display_date'] )
1168      {    // Display Date column
1169          $td = '<span class="date">@date()@</span>';
1170          if( $params['display_permalink'] )
1171          {
1172              $td = '@get_permanent_link( get_icon(\'permalink\') )@ '.$td;
1173          }
1174          $comments_Results->cols[] = array(
1175                  'th' => T_('Date'),
1176                  'order' => $params['field_prefix'].'date',
1177                  'default_dir' => 'D',
1178                  'th_class' => 'shrinkwrap',
1179                  'td_class' => 'shrinkwrap',
1180                  'td' => $td,
1181              );
1182      }
1183  
1184      if( $params['display_item'] )
1185      {    // Display Date column
1186          $td = '%{Obj}->get_permanent_item_link()%';
1187          if( $params['display_status'] )
1188          { // Dislpay status banner
1189              $td = '%{Obj}->get_status( "styled" )%'.$td;
1190          }
1191          $comments_Results->cols[] = array(
1192                  'th' => $params['col_post'],
1193                  'order' => $params['field_prefix'].'post_ID',
1194                  'td' => $td,
1195              );
1196      }
1197  
1198      if( $params['display_kind'] )
1199      {    // Display Kind column
1200          $comments_Results->cols[] = array(
1201                  'th' => T_('Kind'),
1202                  'order' => $params['field_prefix'].'type',
1203                  'th_class' => 'nowrap',
1204                  'td' => '%get_type( {Obj} )%',
1205              );
1206      }
1207  
1208      if( $params['display_author'] )
1209      {    // Display Author column
1210          $comments_Results->cols[] = array(
1211                  'th' => T_('Author'),
1212                  'order' => $params['field_prefix'].'author',
1213                  'th_class' => 'nowrap',
1214                  'td' => '%get_author( {Obj} )%',
1215              );
1216      }
1217  
1218      if( $params['display_url'] )
1219      {    // Display Url column
1220          $comments_Results->cols[] = array(
1221                  'th' => T_('URL'),
1222                  'order' => $params['field_prefix'].'author_url',
1223                  'th_class' => 'nowrap',
1224                  'td' => '%get_url( {Obj} )%',
1225              );
1226      }
1227  
1228      if( $params['display_email'] )
1229      {    // Display Email column
1230          $comments_Results->cols[] = array(
1231                  'th' => T_('Email'),
1232                  'order' => $params['field_prefix'].'author_email',
1233                  'th_class' => 'nowrap',
1234                  'td_class' => 'nowrap',
1235                  'td' => '%get_author_email( {Obj} )%',
1236              );
1237      }
1238  
1239      if( $params['display_ip'] )
1240      {    // Display IP column
1241          $comments_Results->cols[] = array(
1242                  'th' => T_('IP'),
1243                  'order' => $params['field_prefix'].'author_IP',
1244                  'th_class' => 'nowrap',
1245                  'td_class' => 'nowrap',
1246                  'td' => '%get_author_ip( {Obj}, "'.$comments_Results->param_prefix.'" )%',
1247              );
1248      }
1249  
1250  
1251      if( $params['display_additional_columns'] )
1252      {    // Display additional columns from the Plugins
1253          global $Plugins;
1254          $Plugins->trigger_event( 'GetAdditionalColumnsTable', array(
1255              'table'   => $params['plugin_table_name'],
1256              'column'  => $params['field_prefix'].'author_IP',
1257              'Results' => $comments_Results ) );
1258      }
1259  
1260      if( $params['display_spam'] )
1261      {    // Display Spam karma column
1262          $comments_Results->cols[] = array(
1263                  'th' => T_('Spam karma'),
1264                  'order' => $params['field_prefix'].'spam_karma',
1265                  'th_class' => 'shrinkwrap',
1266                  'td_class' => 'shrinkwrap',
1267                  'td' => '%get_spam_karma( {Obj} )%'
1268              );
1269      }
1270  
1271      if( $params['display_visibility'] )
1272      {    // Display Visibility column
1273          $comments_Results->cols[] = array(
1274                  'th' => T_('Visibility'),
1275                  'order' => $params['field_prefix'].'status',
1276                  'th_class' => 'nowrap',
1277                  'td_class' => 'shrinkwrap',
1278                  'td' => '%{Obj}->get_status( "styled" )%',
1279              );
1280      }
1281  
1282      if( $params['display_actions'] )
1283      {    // Display Actions column
1284          $comments_Results->cols[] = array(
1285                  'th' => T_('Actions'),
1286                  'th_class' => 'shrinkwrap',
1287                  'td_class' => 'shrinkwrap',
1288                  'td' => '%comment_edit_actions( {Obj} )%'
1289              );
1290      }
1291  }
1292  
1293  
1294  /**
1295   * Helper functions to display Comments results.
1296   * New ( not display helper ) functions must be created above comments_results function
1297   */
1298  
1299  /**
1300   * Get comment type.
1301   *
1302   * @param object Comment
1303   * @return string Comment type OR '---' if user has no permission to moderate this comment
1304   */
1305  function get_type( $Comment )
1306  {
1307      global $current_User;
1308  
1309      if( $current_User->check_perm( 'comment!CURSTATUS', 'moderate', false, $Comment ) )
1310      {
1311          return $Comment->get( 'type' );
1312      }
1313      else
1314      {
1315          return '<span class="dimmed">---</span>';
1316      }
1317  }
1318  
1319  
1320  /**
1321   * Get comment author
1322   *
1323   * @param object Comment
1324   * @return string Comment author OR '---' if user has no permission to moderate this comment
1325   */
1326  function get_author( $Comment )
1327  {
1328      global $current_User;
1329  
1330      if( $Comment->get( 'status' ) == 'published' || $current_User->check_perm( 'comment!CURSTATUS', 'moderate', false, $Comment ) )
1331      {
1332          $author_User = $Comment->get_author_User();
1333          if( $author_User != NULL )
1334          {    // author is a registered user
1335              return $author_User->get_identity_link();
1336          }
1337          // author is not a registered user
1338          return $Comment->get_author( array( 'link_to' => 'userpage' )  );
1339      }
1340      else
1341      {
1342          return '<span class="dimmed">---</span>';
1343      }
1344  }
1345  
1346  
1347  /**
1348   * Get comment author url
1349   *
1350   * @param object Comment
1351   * @return string Comment url OR '---' if user has no permission to moderate this comment
1352   */
1353  function get_url( $Comment )
1354  {
1355      global $current_User;
1356  
1357      if( $current_User->check_perm( 'comment!CURSTATUS', 'moderate', false, $Comment ) )
1358      {
1359          return $Comment->author_url_with_actions( NULL, false );
1360      }
1361      else
1362      {
1363          return '<span class="dimmed">---</span>';
1364      }
1365  }
1366  
1367  
1368  /**
1369   * Get comment author email
1370   *
1371   * @param object Comment
1372   * @return string Comment author email OR '---' if user has no permission to moderate this comment
1373   */
1374  function get_author_email( $Comment )
1375  {
1376      global $current_User;
1377  
1378      if( $current_User->check_perm( 'comment!CURSTATUS', 'moderate', false, $Comment ) )
1379      {
1380          return $Comment->get_author_email();
1381      }
1382      else
1383      {
1384          return '<span class="dimmed">---</span>';
1385      }
1386  }
1387  
1388  
1389  /**
1390   * Get comment author IP
1391   *
1392   * @param object Comment
1393   * @return string Comment author IP OR '---' if user has no permission to moderate this comment
1394   */
1395  function get_author_ip( $Comment, $param_prefix = '' )
1396  {
1397      global $current_User;
1398  
1399      if( $current_User->check_perm( 'comment!CURSTATUS', 'moderate', false, $Comment ) )
1400      {
1401          $filter_IP_url = regenerate_url( 'filter', $param_prefix.'author_IP='.$Comment->get( 'author_IP' ) );
1402          $country = $Comment->get_ip_country( ' ' );
1403          return '<a href="'.$filter_IP_url.'">'.$Comment->get( 'author_IP' ).'</a>'.$country;
1404      }
1405      else
1406      {
1407          return '<span class="dimmed">---</span>';
1408      }
1409  }
1410  
1411  
1412  /**
1413   * Get comment spam karma
1414   *
1415   * @param object Comment
1416   * @return string Comment spam karma OR '---' if user has no permission to moderate this comment
1417   */
1418  function get_spam_karma( $Comment )
1419  {
1420      global $current_User;
1421  
1422      if( $current_User->check_perm( 'comment!CURSTATUS', 'moderate', false, $Comment ) )
1423      {
1424          return $Comment->get( 'spam_karma' );
1425      }
1426      else
1427      {
1428          return '<span class="dimmed">---</span>';
1429      }
1430  }
1431  
1432  
1433  /**
1434   * Get comment status
1435   *
1436   * @param object Comment
1437   * @return string Comment status OR '---' if user has no permission to edit this comment
1438   */
1439  function get_colored_status( $Comment )
1440  {
1441      return '<span class="tdComment'.$Comment->get( 'status' ).'">'.$Comment->get( 't_status' ).'</span>';
1442  }
1443  
1444  
1445  /**
1446   * Get template for the styled status of comment or item
1447   *
1448   * @param string Status value
1449   * @param string Status title
1450   * @return string Styled template for status
1451   */
1452  function get_styled_status( $status_value, $status_title )
1453  {
1454      return '<div class="floatright">'
1455          .'<span class="note status_'.$status_value.'">'
1456          .'<span>'.format_to_output( $status_title ).'</span>'
1457          .'</span>'
1458          .'</div>';
1459  }
1460  
1461  
1462  /**
1463   * Get the edit actions for comment
1464   *
1465   * @param object Comment
1466   * @return string The edit actions
1467   */
1468  function comment_edit_actions( $Comment )
1469  {
1470      global $current_User, $admin_url;
1471  
1472      $r = '';
1473      if( !is_logged_in() )
1474      {
1475          return $r;
1476      }
1477  
1478      $user_has_edit_perm = $current_User->check_perm( 'comment!CURSTATUS', 'edit', false, $Comment );
1479      $user_has_delete_perm = $current_User->check_perm( 'comment!CURSTATUS', 'delete', false, $Comment );
1480  
1481      if( $user_has_edit_perm || $user_has_delete_perm )
1482      { // Display edit and delete button if current user has the rights:
1483          $redirect_to = rawurlencode( regenerate_url( 'comment_ID,action', 'filter=restore', '', '&' ) );
1484  
1485          if( $user_has_edit_perm )
1486          { // Display edit button only if current user can edit comment with current status
1487              $Comment->get_Item();
1488              $item_Blog = & $Comment->Item->get_Blog();
1489              if( $item_Blog->get_setting( 'in_skin_editing' ) && !is_admin_page() )
1490              {
1491                  $edit_url = url_add_param( $item_Blog->gen_blogurl(), 'disp=edit_comment&amp;c='.$Comment->ID );
1492              }
1493              else
1494              {
1495                  $edit_url = $admin_url.'?ctrl=comments&amp;comment_ID='.$Comment->ID.'&amp;action=edit&amp;redirect_to='.$redirect_to;
1496              }
1497              $r .= action_icon( TS_('Edit this comment...'), 'properties', $edit_url );
1498          }
1499  
1500          if( $user_has_delete_perm )
1501          { // Display delete/recycle button because current user has permission to delete/recycle this comment
1502              $params = array();
1503              if( $Comment->status == 'trash' )
1504              { // Comment is already in the recycle bin, display delete action and add js confirm
1505                  $title = T_('Delete this comment!');
1506                  $params['onclick'] = "return confirm('".TS_('You are about to delete this comment!\\nThis cannot be undone!')."')";
1507              }
1508              else
1509              { // Comment will be moved into the recycle bin
1510                  $title = T_('Recycle this comment!');
1511              }
1512  
1513              $r .=  action_icon( $title, 'delete',
1514                  $admin_url.'?ctrl=comments&amp;comment_ID='.$Comment->ID.'&amp;action=delete&amp;'.url_crumb('comment')
1515                  .'&amp;redirect_to='.$redirect_to, NULL, NULL, NULL, $params );
1516          }
1517      }
1518  
1519      return $r;
1520  }
1521  
1522  /**
1523   * End of helper functions block to display Comments results.
1524   * New ( not display helper ) functions must be created above comments_results function
1525   */
1526  ?>

title

Description

title

Description

title

Description

title

title

Body