b2evolution PHP Cross Reference Blogging Systems

Source: /inc/comments/model/_commentquery.class.php - 636 lines - 15853 bytes - Summary - Text - Print

Description: This file implements the CommentQuery class. 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 the CommentQuery 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-2014 by Francois Planque - {@link http://fplanque.com/}.
   9  *
  10   * @license http://b2evolution.net/about/license.html GNU General Public License (GPL)
  11   *
  12   * {@internal Open Source relicensing agreement:
  13   * EVO FACTORY grants Francois PLANQUE the right to license
  14   * EVO FACTORY contributions to this file and the b2evolution project
  15   * under any OSI approved OSS license (http://www.opensource.org/licenses/).
  16   * }}
  17   *
  18   * @package evocore
  19   *
  20   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  21   * @author asimo: Evo Factory / Attila Simo
  22   *
  23   * @version $Id: _commentquery.class.php 6136 2014-03-08 07:59:48Z manuel $
  24   */
  25  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  26  
  27  load_class( '_core/model/db/_sql.class.php', 'SQL' );
  28  
  29  /**
  30   * CommentQuery: help constructing queries on Comments
  31   * @package evocore
  32   */
  33  class CommentQuery extends SQL
  34  {
  35      var $c;
  36      var $cl;
  37      var $post;
  38      var $author;
  39      var $author_email;
  40      var $author_url;
  41      var $url_match;
  42      var $include_emptyurl;
  43      var $author_IP;
  44      var $rating_toshow;
  45      var $rating_turn;
  46      var $rating_limit;
  47      var $show_statuses;
  48      var $types;
  49      var $keywords;
  50      var $phrase;
  51      var $exact;
  52  
  53      var $Blog;
  54  
  55  
  56      /**
  57       * Constructor.
  58       *
  59       * @param string Name of table in database
  60       * @param string Prefix of fields in the table
  61       * @param string Name of the ID field (including prefix)
  62       */
  63  	function CommentQuery( $dbtablename = 'T_comments', $dbprefix = 'comment_', $dbIDname = 'comment_ID' )
  64      {
  65          $this->dbtablename = $dbtablename;
  66          $this->dbprefix = $dbprefix;
  67          $this->dbIDname = $dbIDname;
  68  
  69          $this->FROM( $this->dbtablename );
  70      }
  71  
  72  
  73      /**
  74       * Restrict to a specific comment
  75       */
  76  	function where_ID( $c = '', $author = '' )
  77      {
  78          $r = false;
  79  
  80          $this->c = $c;
  81          if( empty( $this->author ) )
  82          { // Change $this->author only if it is empty, because possible that it was set previously 
  83              $this->author = $author;
  84          }
  85  
  86          // if a comment number is specified, load that comment
  87          if( !empty($c) )
  88          {
  89              $this->WHERE_and( $this->dbIDname.' = '. intval($c) );
  90              $r = true;
  91          }
  92  
  93          // if a comment author is specified, load that comment
  94          if( !empty( $author ) )
  95          {
  96              global $DB;
  97              $this->WHERE_and( $this->dbprefix.'author = '.$DB->quote($author) );
  98              $r = true;
  99          }
 100  
 101          return $r;
 102      }
 103  
 104  
 105      /**
 106       * Restrict to a specific list of comments
 107       */
 108  	function where_ID_list( $cl = '' )
 109      {
 110          $r = false;
 111  
 112          $this->cl = $cl;
 113  
 114          if( empty( $cl ) ) return $r; // nothing to do
 115  
 116          if( substr( $this->cl, 0, 1 ) == '-' )
 117          {    // List starts with MINUS sign:
 118              $eq = 'NOT IN';
 119              $this->cl = substr( $this->cl, 1 );
 120          }
 121          else
 122          {
 123              $eq = 'IN';
 124          }
 125  
 126          $c_ID_array = array();
 127          $c_id_list = explode( ',', $this->cl );
 128          foreach( $c_id_list as $c_id )
 129          {
 130              $c_ID_array[] = intval( $c_id );// make sure they're all numbers
 131          }
 132  
 133          $this->cl = implode( ',', $c_ID_array );
 134  
 135          $this->WHERE_and( $this->dbIDname.' '.$eq.'( '.$this->cl.' )' );
 136          $r = true;
 137  
 138          return $r;
 139      }
 140  
 141  
 142      /**
 143       * Restrict to a specific post comments
 144       */
 145  	function where_post_ID( $post )
 146      {
 147          $this->post = $post;
 148  
 149          if( empty( $post ) )
 150          {
 151              return;
 152          }
 153  
 154          if( substr( $post, 0, 1 ) == '-' )
 155          {    // List starts with MINUS sign:
 156              $eq = 'NOT IN';
 157              $post_list = substr( $post, 1 );
 158          }
 159          else
 160          {
 161              $eq = 'IN';
 162              $post_list = $post;
 163          }
 164  
 165          // Validate post ID list
 166          $post_ids = array();
 167          $post_list = explode( ',', $post_list );
 168          foreach( $post_list as $p_id )
 169          {
 170              $post_ids[] = intval( $p_id );// make sure they're all numbers
 171          }
 172          $this->post = implode( ',', $post_ids );
 173  
 174          $this->WHERE_and( $this->dbprefix.'post_ID '.$eq.' ('.$this->post.')' );
 175      }
 176  
 177  
 178      /**
 179       * Restrict to a specific post comments by post_datestart
 180       * 
 181       * @param timestamp min - Do not show comments from posts before this timestamp
 182       * @param timestamp max - Do not show comments from posts after this timestamp
 183       */
 184  	function where_post_datestart( $timestamp_min, $timestamp_max )
 185      {
 186          if( empty( $timestamp_min ) && empty ( $timestamp_max ) )
 187          {    // Don't restrict
 188              return;
 189          }
 190  
 191          $dbtable = 'T_items__item';
 192          $dbprefix = 'post_';
 193          $dbIDname = 'ID';
 194  
 195          $ItemQuery = new ItemQuery( $dbtable, $dbprefix, $dbIDname );
 196          $ItemQuery->where_datestart( '', '', '', '', $timestamp_min, $timestamp_max );
 197  
 198          $this->WHERE_and( $ItemQuery->get_where( '' ) );
 199      }
 200  
 201  
 202      /**
 203       * Restrict to specific authors
 204       *
 205       * @param string List of authors (author IDs) to restrict to (must have been previously validated)
 206       */
 207  	function where_author( $author )
 208      {
 209          $this->author = $author;
 210  
 211          if( empty( $author ) )
 212          {
 213              return;
 214          }
 215  
 216          if( substr( $author, 0, 1 ) == '-' )
 217          {    // List starts with MINUS sign:
 218              $eq = 'NOT IN';
 219              $author_list = substr( $author, 1 );
 220          }
 221          else
 222          {
 223              $eq = 'IN';
 224              $author_list = $author;
 225          }
 226  
 227          if( preg_match( '/^[0-9]+(,[0-9]+)*$/', $author_list ) === false )
 228          {
 229              debug_die( 'Invalid comment author filter request' );
 230          }
 231  
 232          $this->WHERE_and( $this->dbprefix.'author_ID '.$eq.' ('.$author_list.')' );
 233      }
 234  
 235  
 236      /**
 237       * Restrict to specific authors email
 238       *
 239       * @param string List of authors email to restrict to (must have been previously validated)
 240       */
 241  	function where_author_email( $author_email )
 242      {
 243          global $DB;
 244  
 245          $this->author_email = $author_email;
 246  
 247          if( empty( $author_email ) )
 248          {
 249              return;
 250          }
 251  
 252          if( substr( $author_email, 0, 1 ) == '-' )
 253          {    // List starts with MINUS sign:
 254              $eq = 'NOT IN';
 255              $author_email_list = explode( ',', substr( $author_email, 1 ) );
 256          }
 257          else
 258          {
 259              $eq = 'IN';
 260              $author_email_list = explode( ',', $author_email );
 261          }
 262  
 263          $this->WHERE_and( $this->dbprefix.'author_email '.$eq.' ( '.$DB->quote( $author_email_list ).' )' );
 264      }
 265  
 266  
 267      /**
 268       * Restrict to specific author url
 269       *
 270       * @param string authors url to restrict to
 271       * @param string equal or not equal restriction
 272       * @param boolean include or not comments, with no url
 273       */
 274  	function where_author_url( $author_url, $url_match, $include_emptyurl )
 275      {
 276          $this->author_url = $author_url;
 277          $this->url_match = $url_match;
 278          $this->include_emptyurl = $include_emptyurl;
 279  
 280          if( empty( $author_url ) )
 281          {
 282              return;
 283          }
 284  
 285          if( empty( $url_match) )
 286          {
 287              $url_match = "IN";
 288          }
 289          elseif( $url_match == '=' )
 290          {
 291              $author_url = '%'.$author_url.'%';
 292              $url_match = 'LIKE';
 293          }
 294          elseif( $url_match == '!=' )
 295          {
 296              $author_url = '%'.$author_url.'%';
 297              $url_match = 'NOT LIKE';
 298          }
 299  
 300          $include_empty = '';
 301          if( $include_emptyurl )
 302          {    // include comments with no url
 303              $include_empty = ' OR '.$this->dbprefix.'author_url IS NULL';
 304          }
 305  
 306          $this->WHERE_and( $this->dbprefix.'author_url '.$url_match.' ("'.$author_url.'")'.$include_empty );
 307      }
 308  
 309  
 310      /**
 311       * Restrict to specific author IPs
 312       *
 313       * @param string List of authors IPs to restrict to (must have been previously validated)
 314       */
 315  	function where_author_IP( $author_IP )
 316      {
 317          $this->author_IP = $author_IP;
 318  
 319          if( empty( $author_IP ) )
 320          {
 321              return;
 322          }
 323  
 324          global $DB;
 325  
 326          $this->WHERE_and( $this->dbprefix.'author_IP LIKE '.$DB->quote( $author_IP ) );
 327      }
 328  
 329  
 330      /**
 331       * Restrict to specific rating or rating interval
 332       *
 333       * @param array show none rated comments or show comments with specific rating values or none/both
 334       * @param string search above, below or exact rating values
 335       * @param integer rating value - limit
 336       */
 337  	function where_rating( $rating_toshow, $rating_turn, $rating_limit )
 338      {
 339          $this->rating_toshow = $rating_toshow;
 340          $this->rating_turn = $rating_turn;
 341          $this->rating_limit = $rating_limit;
 342  
 343          if( empty( $rating_toshow) )
 344          {    //    no nead where condition for ratings
 345              return;
 346          }
 347  
 348          $search = '';
 349          if( in_array( 'norating', $rating_toshow ) )
 350          {    //    include comments with no rating
 351              $search = $this->dbprefix.'rating IS NULL';
 352          }
 353  
 354          if( in_array( 'haverating', $rating_toshow ) )
 355          {    //    specify search direction
 356              switch( $rating_turn )
 357              {
 358                  case 'exact':
 359                      $comp = '=';
 360                      break;
 361                  case 'above':
 362                      $comp = '>=';
 363                      break;
 364                  case 'below':
 365                      $comp = '<=';
 366                      break;
 367                  default:
 368                      debug_die( 'Unknown search direction!' );
 369              }
 370              if( $search != '' )
 371              {
 372                  $search = ' '.$search.' OR ';
 373                  $where_end = ' )';
 374              }
 375              $search = $search.$this->dbprefix.'rating '.$comp.' '.$rating_limit;
 376          }
 377  
 378          $this->WHERE_and( $search );
 379      }
 380  
 381  
 382      /**
 383       * Restrict to specific statuses
 384       *
 385       * @param string List of statuses to restrict to (must have been previously validated)
 386       * @param boolean Filter by user permission. Set to false to select each comment with the correspondong visibily statuses even if current User has no permission to view them.
 387       */
 388  	function where_statuses( $show_statuses, $filter_by_perm = true )
 389      {
 390          global $DB;
 391  
 392          if( empty( $show_statuses ) )
 393          { // initialize if emty
 394              $show_statuses = get_visibility_statuses( 'keys', array( 'trash', 'redirected' ) );
 395          }
 396          $this->show_statuses = $show_statuses;
 397  
 398          if( $filter_by_perm )
 399          { // show not published comments corresponding to the given blog perms
 400              // When Blog is empty we must set blog param to 0, this way we will check all blogs
 401              $blog = empty( $this->Blog ) ? 0 : $this->Blog->ID;
 402              $this->WHERE_and( statuses_where_clause( $this->show_statuses, $this->dbprefix, $blog, 'blog_comment!', true, $this->author ) );
 403          }
 404          else
 405          {
 406              $list = '';
 407              $sep = '';
 408              foreach( $show_statuses as $status )
 409              {
 410                  $list .= $sep.$DB->quote( $status );
 411                  $sep = ',';
 412              }
 413  
 414              $this->WHERE_and( $this->dbprefix.'status IN ('.$list.')' );
 415          }
 416      }
 417  
 418  
 419      /**
 420       * Restrict to specific item types
 421       *
 422       * @param string List of types to restrict to (must have been previously validated)
 423       */
 424  	function where_types( $types )
 425      {
 426          global $DB;
 427  
 428          $this->types = $types;
 429  
 430          if( empty( $types ) )
 431          {
 432              return;
 433          }
 434  
 435          $list = '';
 436          $sep = '';
 437          foreach( $types as $type )
 438          {
 439              $list .= $sep.$DB->quote( $type );
 440              $sep = ',';
 441          }
 442  
 443          $this->WHERE_and( $this->dbprefix.'type IN ('.$list.')' );
 444      }
 445  
 446  
 447      /**
 448       * Restrict with keywords
 449       *
 450       * @param string Keyword search string
 451       * @param mixed Search for entire phrase or for individual words
 452       * @param mixed Require exact match of author or contents
 453       */
 454  	function where_keywords( $keywords, $phrase, $exact )
 455      {
 456          global $DB;
 457  
 458          $this->keywords = $keywords;
 459          $this->phrase = $phrase;
 460          $this->exact = $exact;
 461  
 462          if( empty($keywords) )
 463          {
 464              return;
 465          }
 466  
 467          $search = '';
 468  
 469          if( $exact )
 470          {    // We want exact match of author or contents
 471              $n = '';
 472          }
 473          else
 474          { // The words/sentence are/is to be included in in the author or the contents
 475              $n = '%';
 476          }
 477  
 478          if( ($phrase == '1') or ($phrase == 'sentence') )
 479          { // Sentence search
 480              $keywords = $DB->escape(trim($keywords));
 481              $search .= '('.$this->dbprefix.'author LIKE \''. $n. $keywords. $n. '\') OR ('.$this->dbprefix.'content LIKE \''. $n. $keywords. $n.'\')';
 482          }
 483          else
 484          { // Word search
 485              if( strtoupper( $phrase ) == 'OR' )
 486                  $swords = 'OR';
 487              else
 488                  $swords = 'AND';
 489  
 490              // puts spaces instead of commas
 491              $keywords = preg_replace('/, +/', '', $keywords);
 492              $keywords = str_replace(',', ' ', $keywords);
 493              $keywords = str_replace('"', ' ', $keywords);
 494              $keywords = trim($keywords);
 495              $keyword_array = explode(' ',$keywords);
 496              $join = '';
 497              for ( $i = 0; $i < count($keyword_array); $i++)
 498              {
 499                  $search .= ' '. $join. ' ( ('.$this->dbprefix.'author LIKE \''. $n. $DB->escape($keyword_array[$i]). $n. '\')
 500                                                                  OR ('.$this->dbprefix.'content LIKE \''. $n. $DB->escape($keyword_array[$i]). $n.'\') ) ';
 501                  $join = $swords;
 502              }
 503          }
 504  
 505          //echo $search;
 506          $this->WHERE_and( $search );
 507      }
 508  
 509  
 510      /**
 511       * Restrict to specific blog
 512       *
 513       * @param integer blog to restrict to
 514       */
 515  	function blog_restrict( $Blog )
 516      {
 517          $this->Blog = $Blog;
 518  
 519          if( empty($Blog) )
 520          {
 521              return;
 522          }
 523  
 524          $this->FROM_add( 'INNER JOIN T_postcats ON '.$this->dbprefix.'post_ID = postcat_post_ID
 525                           INNER JOIN T_categories othercats ON postcat_cat_ID = othercats.cat_ID ' );
 526  
 527          $this->WHERE_and( $Blog->get_sql_where_aggregate_coll_IDs('othercats.cat_blog_ID') );
 528      }
 529  
 530  
 531      /**
 532       * Restrict to show or hide active/expired comments ( ecpired comments are older then the post expiry delay value )
 533       * By default only active comments will be allowed
 534       * 
 535       * @param array expiry statuses to show
 536       */
 537  	function expiry_restrict( $expiry_statuses )
 538      {
 539          global $localtimenow, $DB;
 540  
 541          $show_active = empty( $expiry_statuses ) || in_array( 'active', $expiry_statuses );
 542          $show_expired = !empty( $expiry_statuses ) && in_array( 'expired', $expiry_statuses );
 543  
 544          if( !$show_expired )
 545          {
 546              $this->FROM_add( 'LEFT JOIN T_items__item_settings as expiry_setting ON iset_item_ID = comment_post_ID AND iset_name = "post_expiry_delay"' );
 547              $this->WHERE_and( 'expiry_setting.iset_value IS NULL OR expiry_setting.iset_value = "" OR TIMESTAMPDIFF(SECOND, comment_date, '.$DB->quote( date2mysql( $localtimenow ) ).') < expiry_setting.iset_value' );
 548          }
 549          elseif( !$show_active )
 550          {
 551              $this->FROM_add( 'LEFT JOIN T_items__item_settings as expiry_setting ON iset_item_ID = comment_post_ID AND iset_name = "post_expiry_delay"' );
 552              $this->WHERE_and( 'expiry_setting.iset_value IS NOT NULL AND expiry_setting.iset_value <> "" AND TIMESTAMPDIFF(SECOND, comment_date, '.$DB->quote( date2mysql( $localtimenow ) ).') >= expiry_setting.iset_value' );
 553          }
 554      }
 555  
 556  
 557      /**
 558       * Restrict to show only those comments where user has some specific permission
 559       * 
 560       * @param string the required permission to check
 561       * @param integer the blog ID
 562       */
 563  	function user_perm_restrict( $user_perm, $blog_ID )
 564      {
 565          global $current_User, $DB;
 566  
 567          if( !is_logged_in( false ) )
 568          { // Anonymous users can see only published comments, no need further restriction
 569              return;
 570          }
 571  
 572          if( ( $user_perm !== 'moderate' ) && ( $user_perm !== 'edit' ) )
 573          { // No need furhter restriciton because the user doesn't want to edit/moderate these comments
 574              return;
 575          }
 576  
 577          if( $current_User->check_perm( 'blogs', 'editall' ) )
 578          { // User has global permission one ach blog
 579              return;
 580          }
 581  
 582          $BlogCache = & get_BlogCache();
 583          $Blog = $BlogCache->get_by_ID( $blog_ID );
 584          if( $current_User->ID == $Blog->get( 'owner_user_ID' ) )
 585          { // User is the blog owner, so has permission on edit/moderate each comment
 586              return;
 587          }
 588  
 589          if( ! $Blog->get( 'advanced_perms' ) )
 590          { // Blog advanced perm settings is not enabled, user has no permission to edit/moderate comments 
 591              $this->WHERE_and( 'FALSE' );
 592              return;
 593          }
 594  
 595          $SQL = new SQL();
 596          $SQL->SELECT( 'IF( bloguser_perm_edit_cmt + 0 > bloggroup_perm_edit_cmt + 0, bloguser_perm_edit_cmt, bloggroup_perm_edit_cmt ) as perm_edit_cmt' );
 597          $SQL->FROM( 'T_blogs' );
 598          $SQL->FROM_add( 'LEFT JOIN T_coll_user_perms ON bloguser_blog_ID = blog_ID AND bloguser_user_ID = '.$current_User->ID );
 599          $SQL->FROM_add( 'LEFT JOIN T_coll_group_perms ON bloggroup_blog_ID = blog_ID AND bloggroup_group_ID = '.$current_User->grp_ID );
 600          $SQL->WHERE( 'blog_ID = '.$blog_ID );
 601  
 602          $perm_edit_cmt = $DB->get_var( $SQL->get() );
 603          $user_level = $current_User->level;
 604          $condition = '';
 605  
 606          switch( $perm_edit_cmt )
 607          {
 608              case 'le':
 609              case 'lt':
 610                  $operator = ( $perm_edit_cmt == 'le' ) ? '<=' : '<';
 611                  $condition = '( comment_author_ID IN ( SELECT user_ID FROM T_users WHERE user_level '.$operator.' '.$current_User->level.' ) )';
 612                  $condition .= ' OR ';
 613              case 'anon':
 614                  $condition .= 'comment_author_ID IS NULL';
 615                  break;
 616  
 617              case 'own':
 618                  $condition = 'comment_author_ID = '.$current_User->ID;
 619                  break;
 620  
 621              case 'no':
 622                  $condtion = 'FALSE';
 623                  break;
 624  
 625              case 'all': // In this case we don't add any specific permission check because everything is permitted
 626                  break;
 627  
 628              default:
 629                  debug_die('This value of edit permission is not implemented!');
 630          }
 631  
 632          $this->WHERE_and( $condition );
 633      }
 634  }
 635  
 636  ?>

title

Description

title

Description

title

Description

title

title

Body