b2evolution PHP Cross Reference Blogging Systems

Source: /inc/messaging/_messaging.init.php - 582 lines - 19502 bytes - Summary - Text - Print

Description: This file is part of b2evolution - {@link http://b2evolution.net/} See also {@link http://sourceforge.net/projects/evocms/}.

   1  <?php
   2  /**
   3   * This file is part of b2evolution - {@link http://b2evolution.net/}
   4   * See also {@link http://sourceforge.net/projects/evocms/}.
   5   *
   6   * @copyright (c)2009-2014 by Francois PLANQUE - {@link http://fplanque.net/}
   7   * Parts of this file are copyright (c)2009 by The Evo Factory - {@link http://www.evofactory.com/}.
   8   *
   9   * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
  10   *
  11   * {@internal Open Source relicensing agreement:
  12   * The Evo Factory grants Francois PLANQUE the right to license
  13   * The Evo Factory's contributions to this file and the b2evolution project
  14   * under any OSI approved OSS license (http://www.opensource.org/licenses/).
  15   * }}
  16   *
  17   * @package messaging
  18   *
  19   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  20   * @author efy-maxim: Evo Factory / Maxim.
  21   * @author fplanque: Francois Planque.
  22   *
  23   * @version $Id: _messaging.init.php 6136 2014-03-08 07:59:48Z manuel $
  24   */
  25  if( !defined('EVO_CONFIG_LOADED') ) die( 'Please, do not access this page directly.' );
  26  
  27  /**
  28   * Minimum PHP version required for messaging module to function properly
  29   */
  30  $required_php_version[ 'messaging' ] = '5.0';
  31  
  32  /**
  33   * Minimum MYSQL version required for messaging module to function properly
  34   */
  35  $required_mysql_version[ 'messaging' ] = '5.0.3';
  36  
  37  /**
  38   * Aliases for table names:
  39   *
  40   * (You should not need to change them.
  41   *  If you want to have multiple b2evo installations in a single database you should
  42   *  change {@link $tableprefix} in _basic_config.php)
  43   */
  44  $db_config['aliases']['T_messaging__thread'] = $tableprefix.'messaging__thread';
  45  $db_config['aliases']['T_messaging__message'] = $tableprefix.'messaging__message';
  46  $db_config['aliases']['T_messaging__threadstatus'] = $tableprefix.'messaging__threadstatus';
  47  $db_config['aliases']['T_messaging__contact'] = $tableprefix.'messaging__contact';
  48  $db_config['aliases']['T_messaging__contact_groups'] = $tableprefix.'messaging__contact_groups';
  49  $db_config['aliases']['T_messaging__contact_groupusers'] = $tableprefix.'messaging__contact_groupusers';
  50  
  51  /**
  52   * Controller mappings.
  53   *
  54   * For each controller name, we associate a controller file to be found in /inc/ .
  55   * The advantage of this indirection is that it is easy to reorganize the controllers into
  56   * subdirectories by modules. It is also easy to deactivate some controllers if you don't
  57   * want to provide this functionality on a given installation.
  58   *
  59   * Note: while the controller mappings might more or less follow the menu structure, we do not merge
  60   * the two tables since we could, at any time, decide to make a skin with a different menu structure.
  61   * The controllers however would most likely remain the same.
  62   *
  63   * @global array
  64   */
  65  $ctrl_mappings['messages'] = 'messaging/messages.ctrl.php';
  66  $ctrl_mappings['threads'] = 'messaging/threads.ctrl.php';
  67  $ctrl_mappings['contacts'] = 'messaging/contacts.ctrl.php';
  68  $ctrl_mappings['msgsettings'] = 'messaging/msg_settings.ctrl.php';
  69  $ctrl_mappings['abuse'] = 'messaging/abuse.ctrl.php';
  70  
  71  
  72  
  73  /**
  74   * Get the MessageCache
  75   *
  76   * @return MessageCache
  77   */
  78  function & get_MessageCache()
  79  {
  80      global $MessageCache;
  81  
  82      if( ! isset( $MessageCache ) )
  83      {    // Cache doesn't exist yet:
  84          load_class( 'messaging/model/_message.class.php', 'Message' );
  85          $MessageCache = new DataObjectCache( 'Message', false, 'T_messaging__message', 'msg_', 'msg_ID' );
  86      }
  87  
  88      return $MessageCache;
  89  }
  90  
  91  
  92  /**
  93   * Get the ThreadCache
  94   *
  95   * @return ThreadCache
  96   */
  97  function & get_ThreadCache()
  98  {
  99      global $ThreadCache;
 100  
 101      if( ! isset( $ThreadCache ) )
 102      {    // Cache doesn't exist yet:
 103          load_class( 'messaging/model/_thread.class.php', 'Thread' );
 104          $ThreadCache = new DataObjectCache( 'Thread', false, 'T_messaging__thread', 'thrd_', 'thrd_ID', 'thrd_title' );
 105      }
 106  
 107      return $ThreadCache;
 108  }
 109  
 110  
 111  /**
 112   * messaging_Module definition
 113   */
 114  class messaging_Module extends Module
 115  {
 116      /**
 117       * Do the initializations. Called from in _main.inc.php.
 118       * This is typically where classes matching DB tables for this module are registered/loaded.
 119       *
 120       * Note: this should only load/register things that are going to be needed application wide,
 121       * for example: for constructing menus.
 122       * Anything that is needed only in a specific controller should be loaded only there.
 123       * Anything that is needed only in a specific view should be loaded only there.
 124       */
 125  	function init()
 126      {
 127          $this->check_required_php_version( 'messaging' );
 128  
 129          load_funcs( 'messaging/model/_messaging.funcs.php' );
 130      }
 131  
 132  
 133      /**
 134       * Get default module permissions
 135       *
 136       * #param integer Group ID
 137       * @return array
 138       */
 139  	function get_default_group_permissions( $grp_ID )
 140      {
 141          switch( $grp_ID )
 142          {
 143              case 1: // Administrators group ID equals 1
 144                  global $test_install_all_features;
 145                  $perm_messaging = $test_install_all_features ? 'abuse' : 'delete';
 146                  $max_new_threads = ''; // empty = no limit
 147                  break;
 148              case 2: // Moderators group equals 2
 149              case 3: // Trusted users group ID equals 3
 150                  $perm_messaging = 'write';
 151                  $max_new_threads = '10';
 152                  break;
 153              case 4: // Normal users group ID equals 4
 154                  $perm_messaging = 'write';
 155                  $max_new_threads = '3';
 156                  break;
 157              default: // Other groups
 158                  $perm_messaging = 'reply';
 159                  $max_new_threads = '5';
 160                  break;
 161          }
 162  
 163          // We can return as many default permissions as we want:
 164          // e.g. array ( permission_name => permission_value, ... , ... )
 165          return $permissions = array( 'perm_messaging' => $perm_messaging, 'max_new_threads' => $max_new_threads );
 166      }
 167  
 168  
 169      /**
 170       * Get available group permissions
 171       *
 172       * @return array
 173       */
 174  	function get_available_group_permissions()
 175      {
 176          // 'label' is used in the group form as label for radio buttons group
 177          // 'user_func' is used to check user permission. This function should be defined in module initializer.
 178          // 'group_func' is used to check group permission. This function should be defined in module initializer.
 179          // 'perm_block' group form block where this permissions will be displayed. Now available, the following blocks: additional, system
 180          // 'options' is permission options
 181          $permissions = array(
 182              'perm_messaging' => array(
 183                  'label' => T_('Messages'),
 184                  'user_func'  => 'check_messaging_user_perm',
 185                  'group_func' => 'check_messaging_group_perm',
 186                  'perm_block' => 'additional',
 187                  'options'  => array(
 188                          // format: array( radio_button_value, radio_button_label, radio_button_note )
 189                          array( 'none', T_( 'No Access' ), '' ),
 190                          array( 'reply', T_( 'Read & Send messages to people in contacts list only (except for blocked contacts)' ), '' ),
 191                          array( 'write', T_( 'Read & Send messages to anyone (except for blocked contacts)' ), '' ),
 192                          array( 'delete', T_( 'Read, Send & Delete any messages (including for blocked contacts)' ), '' ),
 193                          array( 'abuse', T_( 'Abuse Management' ), '' )  ) ),
 194              'max_new_threads' => array(
 195                  'label' => T_( 'Maximum number of new threads per day' ),
 196                  'group_func' => 'get_group_settings',
 197                  'perm_block' => 'additional',
 198                  'perm_type' => 'text_input',
 199                  'note' => T_( 'Leave empty for no limit' ),
 200                  'maxlength' => 5 ),
 201          );
 202          // We can return as many permissions as we want.
 203          // In other words, one module can return many pluggable permissions.
 204          return $permissions;
 205      }
 206  
 207  
 208      /**
 209       * Check a permission for the user. ( see 'user_func' in get_available_group_permissions() function  )
 210       *
 211       * @param string Requested permission level
 212       * @param string Permission value
 213       * @param mixed Permission target (blog ID, array of cat IDs...)
 214       * @return boolean True on success (permission is granted), false if permission is not granted
 215       */
 216  	function check_messaging_user_perm( $permlevel, $permvalue, $permtarget )
 217      {
 218          global $current_User;
 219  
 220          if( $permtarget > 0 )
 221          {   // Check user permission for current thread
 222              $ThreadCache = & get_ThreadCache();
 223              $Thread = & $ThreadCache->get_by_ID( $permtarget, false );
 224  
 225              if( $Thread === false || ! $Thread->check_thread_recipient( $current_User->ID ) )
 226              {
 227                  return false;
 228              }
 229          }
 230  
 231          return true;
 232      }
 233  
 234  
 235      /**
 236       * Check a permission for the group. ( see 'group_func' in get_available_group_permissions() function )
 237       *
 238       * @param string Requested permission level
 239       * @param string Permission value
 240       * @param mixed Permission target (blog ID, array of cat IDs...)
 241       * @return boolean True on success (permission is granted), false if permission is not granted
 242       */
 243  	function check_messaging_group_perm( $permlevel, $permvalue, $permtarget )
 244      {
 245          $perm = false;
 246          switch ( $permvalue )
 247          {
 248              case 'abuse':
 249                  // Abuse Management & Read, Send & Delete any messages (able to send messages even for blocked contacts)
 250                  if( $permlevel == 'abuse' )
 251                  {
 252                      $perm = true;
 253                      break;
 254                  }
 255              case 'delete':
 256                  // Read, Send & Delete any messages (able to send messages even for blocked contacts)
 257                  if( $permlevel == 'delete' )
 258                  { // User can ask for delete perm...
 259                      $perm = true;
 260                      break;
 261                  }
 262              case 'write':
 263                  // Read & Send messages to anyone (except for blocked contacts)
 264                  if( $permlevel == 'write' )
 265                  {
 266                      $perm = true;
 267                      break;
 268                  }
 269              case 'reply':
 270                  //  Read & Send messages to people in contacts list only (except for blocked contacts)
 271                  if( $permlevel == 'reply' )
 272                  {
 273                      $perm = true;
 274                      break;
 275                  }
 276          }
 277  
 278          return $perm;
 279      }
 280  
 281  
 282      /**
 283       * Get pluggable group settings value
 284       */
 285  	function get_group_settings( $permname, $permvalue, $permtarget )
 286      {
 287          return $permvalue;
 288      }
 289  
 290  
 291      /**
 292       * Build the evobar menu
 293       */
 294  	function build_evobar_menu()
 295      {
 296          global $DB;
 297          global $topleft_Menu, $topright_Menu;
 298          global $admin_url;
 299          global $current_User;
 300          global $unread_messages_count;
 301  
 302          $left_entries = array();
 303          $right_entries = array();
 304  
 305          if( $current_User->check_perm( 'perm_messaging', 'reply' ) )
 306          {
 307              if( ! empty( $topleft_Menu->_menus['entries']['tools']['entries'] ) )
 308              {
 309                  // TODO: this is hackish and would require a proper function call
 310                  $topleft_Menu->_menus['entries']['tools']['disabled'] = false;
 311  
 312                  $left_entries['messaging'] = array(
 313                          'text' => T_('Messages').'&hellip;',
 314                          'href' => $admin_url.'?ctrl=threads',
 315                      );
 316              }
 317  
 318              $right_entries['messaging'] = array(
 319                  'text' => T_('Messages'),
 320                  'href' => get_dispctrl_url( 'threads' ),
 321                  'style' => 'padding: 3px 1ex;',
 322              );
 323  
 324              // Count unread messages for current user
 325              $unread_messages_count = get_unread_messages_count();
 326              if( $unread_messages_count > 0 )
 327              {
 328                  $right_entries['messaging']['text'] = '<b>'.T_('Messages').' <span class="badge">'.$unread_messages_count.'</span></b>';
 329              }
 330          }
 331  
 332          $topleft_Menu->add_menu_entries( 'tools', $left_entries );
 333          $topright_Menu->insert_menu_entries_after( 'userprefs', $right_entries );
 334      }
 335  
 336      /**
 337       * Builds the 3rd half of the menu. This is the one with the configuration features
 338       *
 339       * At some point this might be displayed differently than the 1st half.
 340       */
 341  	function build_menu_3()
 342      {
 343          global $dispatcher;
 344          /**
 345           * @var User
 346           */
 347          global $current_User;
 348  
 349          /**
 350           * @var AdminUI_general
 351           */
 352          global $AdminUI;
 353  
 354          if( !$current_User->check_perm( 'admin', 'restricted' ) )
 355          {
 356              return;
 357          }
 358  
 359          if( $current_User->check_perm( 'perm_messaging', 'reply' ) )
 360          {    // Permission to view messaging:
 361              $AdminUI->add_menu_entries( NULL, array(
 362                          'messaging' => array(
 363                          'text' => T_('Messages'),
 364                          'title' => T_('Messages'),
 365                          'href' => $dispatcher.'?ctrl=threads',
 366                          'entries' => get_messaging_sub_entries( true )
 367                      ),
 368                  ), 'users' );
 369          }
 370      }
 371  
 372  
 373      /**
 374       * Handle messaging module htsrv actions
 375       */
 376  	function handle_htsrv_action()
 377      {
 378          global $current_User, $Blog, $Session, $Messages, $samedomain_htsrv_url;
 379  
 380          // Init objects we want to work on.
 381          $action = param_action( true, true );
 382          $disp = param( 'disp', '/^[a-z0-9\-_]+$/', 'threads' );
 383  
 384          // Check that this action request is not a CSRF hacked request:
 385          $Session->assert_received_crumb( 'messaging_'.$disp );
 386  
 387          // Load classes
 388          load_class( 'messaging/model/_thread.class.php', 'Thread' );
 389          load_class( 'messaging/model/_message.class.php', 'Message' );
 390  
 391          if( !is_logged_in() )
 392          { // user must be logged in
 393              debug_die( 'User must be logged in to proceed with messaging updates!' );
 394          }
 395  
 396          // Check permission:
 397          $current_User->check_perm( 'perm_messaging', 'reply', true );
 398  
 399          // set where to redirect
 400          $redirect_to = param( 'redirect_to', 'url', NULL );
 401          if( empty( $redirect_to ) )
 402          {
 403              if( isset( $Blog ) )
 404              {
 405                  $redirect_to = url_add_param( $Blog->gen_baseurl(), 'disp='.$disp );
 406              }
 407              else
 408              {
 409                  $redirect_to = url_add_param( $baseurl, 'disp='.$disp );
 410              }
 411          }
 412  
 413          if( ( $disp != 'contacts' ) && ( $thrd_ID = param( 'thrd_ID', 'integer', '', true ) ) )
 414          {// Load thread from cache:
 415              $ThreadCache = & get_ThreadCache();
 416              if( ($edited_Thread = & $ThreadCache->get_by_ID( $thrd_ID, false )) === false )
 417              {    unset( $edited_Thread );
 418                  forget_param( 'thrd_ID' );
 419                  $Messages->add( sprintf( T_('Requested &laquo;%s&raquo; object does not exist any longer.'), T_('Thread') ), 'error' );
 420                  $action = 'nil';
 421              }
 422          }
 423  
 424          switch( $disp )
 425          {
 426              // threads action
 427              case 'threads':
 428                  if( $action != 'create' )
 429                  { // Make sure we got a thrd_ID:
 430                      param( 'thrd_ID', 'integer', true );
 431                  }
 432  
 433                  switch( $action )
 434                  {
 435                      case 'create': // create thread
 436                          // check if create new thread is allowed
 437                          if( check_create_thread_limit() )
 438                          { // max new threads limit reached, don't allow to create new thread
 439                              debug_die( 'Invalid request, new conversation limit already reached!' );
 440                          }
 441  
 442                          if( !create_new_thread() )
 443                          { // unsuccessful new thread creation
 444                              global $edited_Thread, $edited_Message, $thrd_recipients, $thrd_recipients_array;
 445  
 446                              $redirect_to .= '&action=new';
 447                              // save new message and thread params into the Session to not lose the content
 448                              $unsaved_message_params = array();
 449                              $unsaved_message_params[ 'subject' ] = $edited_Thread->title;
 450                              $unsaved_message_params[ 'message' ] = $edited_Message->text;
 451                              $unsaved_message_params[ 'thrdtype' ] = param( 'thrdtype', 'string', 'individual' );  // alternative: discussion
 452                              $unsaved_message_params[ 'thrd_recipients' ] = $thrd_recipients;
 453                              $unsaved_message_params[ 'thrd_recipients_array' ] = $thrd_recipients_array;
 454                              save_message_params_to_session( $unsaved_message_params );
 455                          }
 456                          break;
 457  
 458                      case 'delete': // delete thread
 459                          // Check permission:
 460                          $current_User->check_perm( 'perm_messaging', 'delete', true );
 461  
 462                          $confirmed = param( 'confirmed', 'integer', 0 );
 463                          if( $confirmed )
 464                          {
 465                              $msg = sprintf( T_('Thread &laquo;%s&raquo; deleted.'), $edited_Thread->dget('title') );
 466                              $edited_Thread->dbdelete( true );
 467                              unset( $edited_Thread );
 468                              forget_param( 'thrd_ID' );
 469                              $Messages->add( $msg, 'success' );
 470                          }
 471                          else
 472                          {
 473                              $delete_url = $samedomain_htsrv_url.'action.php?mname=messaging&thrd_ID='.$edited_Thread->ID.'&action=delete&confirmed=1&redirect_to='.$redirect_to.'&'.url_crumb( 'messaging_threads' );
 474                              $ok_button = '<span class="linkbutton"><a href="'.$delete_url.'">'.T_( 'I am sure!' ).'!</a></span>';
 475                              $cancel_button = '<span class="linkbutton"><a href="'.$redirect_to.'">CANCEL</a></span>';
 476                              $msg = sprintf( T_( 'You are about to delete all messages in the conversation &laquo;%s&raquo;.' ), $edited_Thread->dget('title') );
 477                              $msg .= '<br />'.T_( 'This CANNOT be undone!').'<br />'.T_( 'Are you sure?' ).'<br /><br />'.$ok_button."\t".$cancel_button;
 478                              $Messages->add( $msg, 'error' );
 479                          }
 480                          break;
 481  
 482                      case 'leave': // user wants to leave the thread
 483                          leave_thread( $edited_Thread->ID, $current_User->ID, false );
 484  
 485                          $Messages->add( sprintf( T_( 'You have successfuly left the &laquo;%s&raquo; conversation!' ), $edited_Thread->get( 'title' ) ), 'success' );
 486                          break;
 487  
 488                      case 'close': // close the thread
 489                      case 'close_and_block': // close the thread and block contact
 490                          leave_thread( $edited_Thread->ID, $current_User->ID, true );
 491  
 492                          // user has closed this conversation because there was only one other user involved
 493                          $Messages->add( sprintf( T_( 'You have successfuly closed the &laquo;%s&raquo; conversation!' ), $edited_Thread->get( 'title' ) ), 'success' );
 494                          if( $action == 'close_and_block' )
 495                          { // user also wants to block contact with the other user involved in this thread
 496                              $block_user_ID = param( 'block_ID', 'integer', true );
 497                              $UserCache = & get_UserCache();
 498                              $blocked_User = $UserCache->get_by_ID( $block_user_ID );
 499  
 500                              set_contact_blocked( $block_user_ID, true );
 501                              $Messages->add( sprintf( T_( '&laquo;%s&raquo; was blocked.' ), $blocked_User->get( 'login' ) ), 'success' );
 502                          }
 503                          break;
 504                  }
 505                  break; // break from threads action switch
 506  
 507              // contacts action
 508              case 'contacts':
 509                  $user_ID = param( 'user_ID', 'string', true );
 510  
 511                  if( ( $action != 'block' ) && ( $action != 'unblock' ) )
 512                  { // only block or unblock is valid
 513                      debug_die( "Invalid action param" );
 514                  }
 515                  set_contact_blocked( $user_ID, ( ( $action == 'block' ) ? 1 : 0 ) );
 516                  $redirect_to = str_replace( '&amp;', '&', $redirect_to );
 517                  break;
 518  
 519              // messages action
 520              case 'messages':
 521                  if( $action == 'create' )
 522                  { // create new message
 523                      create_new_message( $thrd_ID );
 524                  }
 525                  elseif( $action == 'delete' )
 526                  {
 527                      // Check permission:
 528                      $current_User->check_perm( 'perm_messaging', 'delete', true );
 529  
 530                      $msg_ID = param( 'msg_ID', 'integer', true );
 531                      $MessageCache = & get_MessageCache();
 532                      if( ($edited_Message = & $MessageCache->get_by_ID( $msg_ID, false )) === false )
 533                      {
 534                          $Messages->add( sprintf( T_('Requested &laquo;%s&raquo; object does not exist any longer.'), T_('Message') ), 'error' );
 535                          break;
 536                      }
 537  
 538                      $confirmed = param( 'confirmed', 'integer', 0 );
 539                      if( $confirmed )
 540                      { // delete message
 541                          $edited_Message->dbdelete();
 542                          unset( $edited_Message );
 543                          $Messages->add( T_('Message deleted.'), 'success' );
 544                      }
 545                      else
 546                      {
 547                          $delete_url = $samedomain_htsrv_url.'action.php?mname=messaging&disp=messages&thrd_ID='.$thrd_ID.'&msg_ID='.$msg_ID.'&action=delete&confirmed=1';
 548                          $delete_url = url_add_param( $delete_url, 'redirect_to='.rawurlencode( $redirect_to ), '&' ).'&'.url_crumb( 'messaging_messages' );
 549                          $ok_button = '<span class="linkbutton"><a href="'.$delete_url.'">'.T_( 'I am sure!' ).'!</a></span>';
 550                          $cancel_button = '<span class="linkbutton"><a href="'.$redirect_to.'">CANCEL</a></span>';
 551                          $msg = T_('You are about to delete this message. ').'<br /> '.T_('This CANNOT be undone!').'<br />'.T_( 'Are you sure?' ).'<br /><br />'.$ok_button.$cancel_button;
 552                          $Messages->add( $msg, 'error' );
 553                      }
 554                  }
 555                  break;
 556          }
 557  
 558          header_redirect( $redirect_to ); // Will save $Messages into Session
 559      }
 560  
 561  
 562      /**
 563       * Get contacts list params
 564       */
 565  	function get_contacts_list_params()
 566      {
 567          global $module_contacts_list_params;
 568  
 569          if( !isset( $module_contacts_list_params ) )
 570          {    // Initialize this array first time
 571              $module_contacts_list_params = array();
 572          }
 573  
 574          $module_contacts_list_params['title_selected'] = T_('Send a message to all selected contacts');
 575          $module_contacts_list_params['title_group'] = T_('Send a message to all %d contacts in the &laquo;%s&raquo; group');
 576          $module_contacts_list_params['recipients_link'] = get_dispctrl_url( 'threads', 'action=new' );
 577      }
 578  }
 579  
 580  $messaging_Module = new messaging_Module();
 581  
 582  ?>

title

Description

title

Description

title

Description

title

title

Body