b2evolution PHP Cross Reference Blogging Systems

Source: /inc/cron/jobs/_comment_moderation_reminder.job.php - 340 lines - 15644 bytes - Text - Print

Description: This file implements the comments moderation reminder cron job

   1  <?php
   2  /**

   3   * This file implements the comments moderation reminder cron job

   4   *

   5   * @author attila: Attila Simo

   6   *

   7   * @version $Id: $

   8   */
   9  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  10  
  11  global $DB, $Settings, $UserSettings;
  12  
  13  global $servertimenow, $comment_moderation_reminder_threshold;
  14  
  15  // Check if UserSettings exists because it must be initialized before email sending

  16  if( empty( $UserSettings ) )
  17  { // initialize UserSettings, because in CLI mode is not initialized yet
  18      load_class( 'users/model/_usersettings.class.php', 'UserSettings' );
  19      $UserSettings = new UserSettings();
  20  }
  21  
  22  // Only those blogs are selected for moderation where we can find at least one comment awaiting moderation which is older then the threshold date defined below

  23  $threshold_date = date2mysql( $servertimenow - $comment_moderation_reminder_threshold );
  24  
  25  // Statuses defined in this array should be notified. This should be configurable, but this is the default value.

  26  $notify_statuses = get_visibility_statuses( 'moderation' );
  27  
  28  // Select blogs where are comments awaiting moderation more then x ( = configured threshold ) hours

  29  $SQL = new SQL();
  30  $SQL->SELECT( 'DISTINCT cat_blog_ID' );
  31  $SQL->FROM( 'T_categories' );
  32  $SQL->FROM_add( 'INNER JOIN T_items__item ON post_main_cat_ID = cat_ID AND post_status IN ('.$DB->quote( array( 'published', 'community', 'protected' ) ).')' );
  33  $SQL->FROM_add( 'INNER JOIN T_comments ON comment_post_ID = post_ID AND comment_status IN ('.$DB->quote( $notify_statuses ).') AND comment_date < '.$DB->quote( $threshold_date ) );
  34  
  35  $moderation_blogs = $DB->get_col( $SQL->get() );
  36  
  37  if( empty( $moderation_blogs ) )
  38  { // There are no blogs where exists draft comments older then the threshold ( 24 hours by default )
  39      $result_message = sprintf( T_('No comments have been awaiting moderation for more than %s.'), seconds_to_period( $comment_moderation_reminder_threshold ) );
  40      return 1;
  41  }
  42  
  43  $moderation_blogs_cond = '%s IN ( '.implode( ',', $moderation_blogs ).' )';
  44  
  45  // Select global moderators

  46  $SQL = new SQL();
  47  $SQL->SELECT( 'user_ID' );
  48  $SQL->FROM( 'T_users' );
  49  $SQL->FROM_add( 'LEFT JOIN T_groups ON grp_ID = user_grp_ID' );
  50  $SQL->WHERE( 'grp_perm_blogs = '.$DB->quote( 'editall' ) );
  51  
  52  $global_moderators = $DB->get_col( $SQL->get() );
  53  $not_global_moderator = ( count( $global_moderators ) ) ? '%s NOT IN ( '.implode( ',', $global_moderators ).' )' : NULL;
  54  
  55  // Select blog owners, because they are moderators in their own blogs

  56  $SQL = new SQL();
  57  $SQL->SELECT( 'blog_owner_user_ID, GROUP_CONCAT( DISTINCT cast(blog_ID as CHAR) ORDER BY blog_ID SEPARATOR \',\') as blogs' );
  58  $SQL->FROM( 'T_blogs' );
  59  $SQL->WHERE( sprintf( $not_global_moderator, 'blog_owner_user_ID' ) );
  60  $SQL->WHERE_and( sprintf( $moderation_blogs_cond, 'blog_ID' ) );
  61  $SQL->GROUP_BY( 'blog_owner_user_ID' );
  62  // Get blog owner users with their blogs

  63  $blog_owners = $DB->get_assoc( $SQL->get() );
  64  
  65  // Select comment moderators based on the blogs advanced user permissions

  66  $bloguser_SQL = new SQL();
  67  $bloguser_SQL->SELECT( 'bloguser_user_ID as user_ID, bloguser_blog_ID as blog_ID, bloguser_perm_cmtstatuses + 0 as perm_cmtstatuses, bloguser_perm_edit_cmt as perm_edit_cmt' );
  68  $bloguser_SQL->FROM( 'T_coll_user_perms' );
  69  $bloguser_SQL->FROM_add( 'LEFT JOIN T_blogs ON blog_ID = bloguser_blog_ID' );
  70  $bloguser_SQL->WHERE( sprintf( $not_global_moderator, 'bloguser_user_ID' ) );
  71  $bloguser_SQL->WHERE_and( 'blog_advanced_perms <> 0' );
  72  $bloguser_SQL->WHERE_and( sprintf( $moderation_blogs_cond, 'bloguser_blog_ID' ) );
  73  $bloguser_SQL->WHERE_and( 'bloguser_perm_cmtstatuses <> "" AND bloguser_perm_edit_cmt <> "no" AND bloguser_perm_edit_cmt <> "own"' );
  74  // Select comment moderators based on the blogs advanced group permissions

  75  $bloggroup_SQL = new  SQL();
  76  $bloggroup_SQL->SELECT( 'user_ID, bloggroup_blog_ID as blog_ID, bloggroup_perm_cmtstatuses + 0 as perm_cmtstatuses, bloggroup_perm_edit_cmt as perm_edit_cmt' );
  77  $bloggroup_SQL->FROM( 'T_users' );
  78  $bloggroup_SQL->FROM_add( 'LEFT JOIN T_coll_group_perms ON bloggroup_group_ID = user_grp_ID' );
  79  $bloggroup_SQL->FROM_add( 'LEFT JOIN T_blogs ON blog_ID = bloggroup_blog_ID' );
  80  $bloggroup_SQL->WHERE( sprintf( $not_global_moderator, 'user_ID' ) );
  81  $bloggroup_SQL->WHERE_and( 'blog_advanced_perms <> 0' );
  82  $bloggroup_SQL->WHERE_and( sprintf( $moderation_blogs_cond, 'bloggroup_blog_ID' ) );
  83  $bloggroup_SQL->WHERE_and( 'bloggroup_perm_cmtstatuses <> "" AND bloggroup_perm_edit_cmt <> "no" AND bloggroup_perm_edit_cmt <> "own"' );
  84  // Get specific moderator users with their permissions in each different blog

  85  $specific_blog_moderators = $DB->get_results( '( '.$bloguser_SQL->get().' ) UNION ( '.$bloggroup_SQL->get().' ) ORDER BY user_ID, blog_ID' );
  86  
  87  // Highest edit level

  88  $max_perm_edit = 'all';
  89  // Highest value of the comment statuses perm

  90  $max_perm_statuses = 127;
  91  // Create a general moderators array to collect all blog owners and different blog moderators

  92  $moderators = array();
  93  foreach( $specific_blog_moderators as $row )
  94  { // Loop through each different blog's moderator users and their permissions
  95      if( !isset( $moderators[$row->user_ID] ) )
  96      { // Initialize user perm array
  97          $moderators[$row->user_ID] = array();
  98      }
  99      if( isset( $moderators[$row->user_ID][$row->blog_ID] ) )
 100      { // Update user permissions on this blog
 101          if( $moderators[$row->user_ID][$row->blog_ID]['perm_edit'] < $row->perm_edit_cmt )
 102          { // The user and the group advanced comment edit perm for this user are not the same, keep the higher perm value
 103              $moderators[$row->user_ID][$row->blog_ID]['perm_edit'] = $row->perm_edit_cmt;
 104          }
 105          $current_perm_statuses = $moderators[$row->user_ID][$row->blog_ID]['perm_statuses'];
 106          $row_perm_status = (int) $row->perm_cmtstatuses;
 107          if( $current_perm_statuses != $row_perm_status )
 108          { // The advanced user and the group comment statuses perm for this user are not the same, the union of this perms must be accepted
 109              $moderators[$row->user_ID][$row->blog_ID]['perm_statuses'] = ( $current_perm_statuses | $row_perm_status );
 110          }
 111      }
 112      else
 113      { // Initialize a new setting for this user / blog
 114          $moderators[$row->user_ID][$row->blog_ID] = array( 'perm_edit' => $row->perm_edit_cmt, 'perm_statuses' => (int) $row->perm_cmtstatuses );
 115      }
 116  }
 117  foreach( $blog_owners as $moderator_ID => $moderator_blogs )
 118  { // Loop through each blog owner users and set the highest permission in their own blogs
 119      $blogs = explode( ',', $moderator_blogs );
 120      foreach( $blogs as $blog_ID )
 121      { // Loop through each blogs of this user
 122          if( !isset( $moderators[$moderator_ID] ) )
 123          { // Init this user moderator perms if it was not initialized yet
 124              $moderators[$moderator_ID] = array();
 125          }
 126          $moderators[$moderator_ID][$blog_ID] = array( 'perm_edit' => $max_perm_edit, 'perm_statuses' => $max_perm_statuses );
 127      }
 128  }
 129  
 130  // Set notify moderation condition

 131  $def_send_moderation_reminder = $UserSettings->get( 'send_cmt_moderation_reminder' );
 132  if( $def_send_moderation_reminder )
 133  { // Send comment moderation reminder is set by default
 134      $send_moderation_reminder_cond = '( ( uset_value IS NOT NULL AND uset_value <> \'0\' ) OR ( uset_value IS NULL ) )';
 135  }
 136  else
 137  { // Send comment moderation reminder is NOT set by default
 138      $send_moderation_reminder_cond = '( uset_value IS NOT NULL AND uset_value <> \'0\' )';
 139  }
 140  
 141  // Select blocked and spam email addresses to prevent sending emails to them

 142  $blocked_emails = $DB->get_col( 'SELECT emblk_address FROM T_email__blocked WHERE '.get_mail_blocked_condition() );
 143  $blocked_emails_condition = ( count( $blocked_emails ) ) ? 'user_email NOT IN ( "'.implode( '","', $blocked_emails ).'" )' : NULL;
 144  
 145  // load all required Users ( global moderators, blog owners and users with advanced blog perms )

 146  $all_required_users = array_unique( array_merge( $global_moderators, array_keys( $moderators ) ) );
 147  $SQL = new SQL();
 148  $SQL->SELECT( 'T_users.*' );
 149  $SQL->FROM( 'T_users' );
 150  $SQL->FROM_add( 'LEFT JOIN T_users__usersettings ON uset_user_ID = user_ID AND uset_name = "send_cmt_moderation_reminder"' );
 151  $SQL->WHERE( 'user_ID IN ('.implode( ',', $all_required_users ).')' );
 152  $SQL->WHERE_and( $send_moderation_reminder_cond );
 153  $SQL->WHERE_and( 'LENGTH(TRIM(user_email)) > 0' );
 154  $SQL->WHERE_and( $blocked_emails_condition );
 155  
 156  // Load moderator users who would like to get notificaions

 157  $UserCache = & get_UserCache();
 158  $UserCache->clear( true );
 159  $UserCache->load_by_sql( $SQL );
 160  $loaded_ids = $UserCache->get_ID_array();
 161  
 162  if( empty( $loaded_ids ) )
 163  { // UserCache result is empty which means nobody wants to receive notifications
 164      $result_message = sprintf( T_( 'Could not find any moderators wanting to receive comment moderation notifications for the blogs that have comments pending moderation!' ) );
 165      return 1;
 166  }
 167  
 168  // load all required Blogs

 169  $BlogCache = & get_BlogCache();
 170  $BlogCache->load_list( $moderation_blogs );
 171  
 172  // count all comments awaiting for moderation in the required blogs, group by blog/comment_status/author_level

 173  $SQL = new SQL();
 174  $SQL->SELECT( 'cat_blog_ID as blog_ID, comment_status, IF( comment_author_ID IS NULL, 0, user_level ) as author_level, count( comment_ID ) as cmt_count' );
 175  $SQL->FROM( 'T_comments' );
 176  $SQL->FROM_add( 'LEFT JOIN T_users ON user_ID = comment_author_ID' );
 177  $SQL->FROM_add( 'LEFT JOIN T_items__item ON post_ID = comment_post_ID' );
 178  $SQL->FROM_add( 'LEFT JOIN T_categories ON cat_ID = post_main_cat_ID' );
 179  $SQL->WHERE( 'comment_status IN ( '.$DB->quote( $notify_statuses ).' )' );
 180  $SQL->WHERE_and( 'post_status IN ( '.$DB->quote( array( 'published', 'community', 'protected' ) ).' )' );
 181  $SQL->WHERE_and( 'cat_blog_ID IN ('.implode( ',', $moderation_blogs ).')' );
 182  $SQL->GROUP_BY( 'cat_blog_ID, comment_status, author_level' );
 183  $blog_comments = $DB->get_results( $SQL->get() );
 184  
 185  // Create a comments map by blog_ID:comment_status:author_level:count. This way it will be much easier to get allowed comments for a specific permission

 186  $comments_map = array();
 187  $last_blog_ID = NULL;
 188  foreach( $blog_comments as $row )
 189  {
 190      if( $last_blog_ID != $row->blog_ID )
 191      {
 192          $Blog = & $BlogCache->get_by_ID( $row->blog_ID );
 193          $blog_moderation_statuses = $Blog->get_setting( 'moderation_statuses' );
 194          $last_blog_ID = $row->blog_ID;
 195      }
 196      if( strpos( $blog_moderation_statuses, $row->comment_status ) === false )
 197      { // This status shouldn't be notified on this blog
 198          continue;
 199      }
 200      if( isset( $comments_map[$row->blog_ID] ) )
 201      { // This blog comments were already initialized
 202          if( isset( $comments_map[$row->blog_ID][$row->comment_status] ) )
 203          { // Comments with this status were already initialized
 204              // Set new author level filter for this status and the corresponding amount of comments

 205              $comments_map[$row->blog_ID][$row->comment_status][$row->author_level] = $row->cmt_count;
 206          }
 207          else
 208          { // Initialize blog comments with this status, and set the first element
 209              $comments_map[$row->blog_ID][$row->comment_status] = array( $row->author_level => $row->cmt_count );
 210          }
 211      }
 212      else
 213      { // Initialize blog array, and set the first element
 214          $comments_map[$row->blog_ID] = array( $row->comment_status => array( $row->author_level => $row->cmt_count ) );
 215      }
 216  }
 217  
 218  $mail_sent = 0;
 219  $params = array();
 220  
 221  // Collect comments data for global moderators

 222  $moderator_comments = array();
 223  foreach( $moderation_blogs as $blog_ID )
 224  { // Collect the number of comments from all blogs
 225      if( !isset( $comments_map[$blog_ID] ) )
 226      { // this blog doesn't contains comments awaiting moderation which statuses corresponds to this blog moderation statutes
 227          continue;
 228      }
 229      $cmt_count = 0;
 230      foreach( $comments_map[$blog_ID] as $status => $content )
 231      { // collect the number of commetns with all statuses
 232          foreach( $content as $level => $count )
 233          { // collect the number of commetns with all kind of users
 234              $cmt_count += $count;
 235          }
 236      }
 237      $moderator_comments[$blog_ID] = $cmt_count;
 238  }
 239  
 240  foreach( $loaded_ids as $moderator_ID )
 241  { // Loop trhough each moderators and send comment moderation emails if it is required
 242      $moderator_User = $UserCache->get_by_ID( $moderator_ID );
 243      $blog_comments = array();
 244      if( in_array( $moderator_ID, $global_moderators ) )
 245      { // This is a global moderator user
 246          $blog_comments = $moderator_comments;
 247      }
 248      else
 249      { // This moderator user may have different permission on different blogs, collect the comments corresponding to the perms
 250          foreach( $moderators[$moderator_ID] as $blog_ID => $perms )
 251          {
 252              if( !isset( $comments_map[$blog_ID] ) )
 253              { // this blog doesn't contains comments awaiting moderation which statuses corresponds to this blog moderation statutes
 254                  continue;
 255              }
 256              $cmt_count = 0;
 257              foreach( $comments_map[$blog_ID] as $status => $content )
 258              {
 259                  $status_perm_value = get_status_permvalue( $status );
 260                  if( $perms['perm_statuses'] & $status_perm_value )
 261                  { // User has permission to edit comments with this status
 262                      // TODO asimo> Here probably we should also check if user is able to deprecate/recycle the comment.

 263                      // Check if User has permission to raise comment status

 264                      $ordered_statuses = get_visibility_statuses( 'ordered-index' );
 265                      $raise_status_allowed = false;
 266                      $current_status_found = false;
 267                      foreach( $ordered_statuses as $ordered_status => $order_index )
 268                      {
 269                          if( $ordered_status == $status )
 270                          {
 271                              $current_status_found = true;
 272                          }
 273                          elseif( $current_status_found  && ( $order_index !== 0 ) )
 274                          { // This is a higher status then the currently checked status
 275                              $ordered_status_perm_value = get_status_permvalue( $ordered_status );
 276                              if( $perms['perm_statuses'] & $ordered_status_perm_value )
 277                              { // User has permission to a higher status, so the comment status can be raised
 278                                  $raise_status_allowed = true;
 279                                  break;
 280                              }
 281                          }
 282                      }
 283                      if( !$raise_status_allowed )
 284                      { // User is not allowed to raise these comment statuses
 285                          continue;
 286                      }
 287                      // Check if the comment author level allows the edit permission:

 288                      foreach( $content as $level => $count )
 289                      {
 290                          switch( $perms['perm_edit'] )
 291                          {
 292                              case 'all':
 293                                  $allowed = true;
 294                                  break;
 295                              case 'le':
 296                                  $allowed = ( $level <= $moderator_User->level );
 297                                  break;
 298                              case 'lt':
 299                                  $allowed = ( $level < $moderator_User->level );
 300                                  break;
 301                              case 'anon':
 302                                  $allowed = ( $level == 0 );
 303                                  break;
 304                              default:
 305                                  $allowed = false;
 306                          }
 307                          if( $allowed )
 308                          { // User has permission to edit comments with this author level
 309                              $cmt_count += $count;
 310                          }
 311                      }
 312                  }
 313              }
 314              if( $cmt_count > 0 )
 315              { // There are comments awaiting moderation on this blog and user has permission to moderate
 316                  $blog_comments[$blog_ID] = $cmt_count;
 317              }
 318          }
 319      }
 320  
 321      if( empty( $blog_comments ) )
 322      { // There are no comments awaiting moderation that this user could moderate
 323          continue;
 324      }
 325  
 326      $params['blogs'] = array_keys( $blog_comments ); // This can be remvoved if this solution will remain

 327      $params['comments'] = $blog_comments;
 328  
 329      // Change locale here to localize the email subject and content

 330      locale_temp_switch( $moderator_User->get( 'locale' ) );
 331      if( send_mail_to_User( $moderator_ID, T_( 'Comment moderation reminder' ), 'comments_unmoderated_reminder', $params, false ) )
 332      {
 333          $mail_sent++;
 334      }
 335      locale_restore_previous();
 336  }
 337  
 338  $result_message = sprintf( T_( '%d moderator have been notified!' ), $mail_sent );
 339  return 1; /*OK*/
 340  ?>

title

Description

title

Description

title

Description

title

title

Body