Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

functions_privmsgs.php

Zuletzt modifiziert: 09.10.2024, 12:50 - Dateigröße: 51.58 KiB


 0001  <?php
 0002  /**
 0003  *
 0004  * @package phpBB3
 0005  * @version $Id$
 0006  * @copyright (c) 2005 phpBB Group
 0007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 0008  *
 0009  */
 0010   
 0011  /**
 0012  */
 0013  if (!defined('IN_PHPBB'))
 0014  {
 0015      exit;
 0016  }
 0017   
 0018  /*
 0019      Ability to simply add own rules by doing three things:
 0020          1) Add an appropriate constant
 0021          2) Add a new check array to the global_privmsgs_rules variable and the condition array (if one is required)
 0022          3) Add a new language variable to ucp.php
 0023   
 0024          The user is then able to select the new rule. It will be checked against and handled as specified.
 0025          To add new actions (yes, checks can be added here too) to the rule management, the core code has to be modified.
 0026  */
 0027   
 0028  define('RULE_IS_LIKE', 1);        // Is Like
 0029  define('RULE_IS_NOT_LIKE', 2);    // Is Not Like
 0030  define('RULE_IS', 3);            // Is
 0031  define('RULE_IS_NOT', 4);        // Is Not
 0032  define('RULE_BEGINS_WITH', 5);    // Begins with
 0033  define('RULE_ENDS_WITH', 6);    // Ends with
 0034  define('RULE_IS_FRIEND', 7);    // Is Friend
 0035  define('RULE_IS_FOE', 8);        // Is Foe
 0036  define('RULE_IS_USER', 9);        // Is User
 0037  define('RULE_IS_GROUP', 10);    // Is In Usergroup
 0038  define('RULE_ANSWERED', 11);    // Answered
 0039  define('RULE_FORWARDED', 12);    // Forwarded
 0040  define('RULE_TO_GROUP', 14);    // Usergroup
 0041  define('RULE_TO_ME', 15);        // Me
 0042   
 0043  define('ACTION_PLACE_INTO_FOLDER', 1);
 0044  define('ACTION_MARK_AS_READ', 2);
 0045  define('ACTION_MARK_AS_IMPORTANT', 3);
 0046  define('ACTION_DELETE_MESSAGE', 4);
 0047   
 0048  define('CHECK_SUBJECT', 1);
 0049  define('CHECK_SENDER', 2);
 0050  define('CHECK_MESSAGE', 3);
 0051  define('CHECK_STATUS', 4);
 0052  define('CHECK_TO', 5);
 0053   
 0054  /**
 0055  * Global private message rules
 0056  * These rules define what to do if a rule is hit
 0057  */
 0058  $global_privmsgs_rules = array(
 0059      CHECK_SUBJECT    => array(
 0060          RULE_IS_LIKE        => array('check0' => 'message_subject', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
 0061          RULE_IS_NOT_LIKE    => array('check0' => 'message_subject', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
 0062          RULE_IS                => array('check0' => 'message_subject', 'function' => '{CHECK0} == {STRING}'),
 0063          RULE_IS_NOT            => array('check0' => 'message_subject', 'function' => '{CHECK0} != {STRING}'),
 0064          RULE_BEGINS_WITH    => array('check0' => 'message_subject', 'function' => 'preg_match("/^" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
 0065          RULE_ENDS_WITH        => array('check0' => 'message_subject', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "$/i", {CHECK0})'),
 0066      ),
 0067   
 0068      CHECK_SENDER    => array(
 0069          RULE_IS_LIKE        => array('check0' => 'username', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
 0070          RULE_IS_NOT_LIKE    => array('check0' => 'username', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
 0071          RULE_IS                => array('check0' => 'username', 'function' => '{CHECK0} == {STRING}'),
 0072          RULE_IS_NOT            => array('check0' => 'username', 'function' => '{CHECK0} != {STRING}'),
 0073          RULE_BEGINS_WITH    => array('check0' => 'username', 'function' => 'preg_match("/^" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
 0074          RULE_ENDS_WITH        => array('check0' => 'username', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "$/i", {CHECK0})'),
 0075          RULE_IS_FRIEND        => array('check0' => 'friend', 'function' => '{CHECK0} == 1'),
 0076          RULE_IS_FOE            => array('check0' => 'foe', 'function' => '{CHECK0} == 1'),
 0077          RULE_IS_USER        => array('check0' => 'author_id', 'function' => '{CHECK0} == {USER_ID}'),
 0078          RULE_IS_GROUP        => array('check0' => 'author_in_group', 'function' => 'in_array({GROUP_ID}, {CHECK0})'),
 0079      ),
 0080   
 0081      CHECK_MESSAGE    => array(
 0082          RULE_IS_LIKE        => array('check0' => 'message_text', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
 0083          RULE_IS_NOT_LIKE    => array('check0' => 'message_text', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
 0084          RULE_IS                => array('check0' => 'message_text', 'function' => '{CHECK0} == {STRING}'),
 0085          RULE_IS_NOT            => array('check0' => 'message_text', 'function' => '{CHECK0} != {STRING}'),
 0086      ),
 0087   
 0088      CHECK_STATUS    => array(
 0089          RULE_ANSWERED        => array('check0' => 'pm_replied', 'function' => '{CHECK0} == 1'),
 0090          RULE_FORWARDED        => array('check0' => 'pm_forwarded', 'function' => '{CHECK0} == 1'),
 0091      ),
 0092   
 0093      CHECK_TO        => array(
 0094          RULE_TO_GROUP        => array('check0' => 'to', 'check1' => 'bcc', 'check2' => 'user_in_group', 'function' => 'in_array("g_" . {CHECK2}, {CHECK0}) || in_array("g_" . {CHECK2}, {CHECK1})'),
 0095          RULE_TO_ME            => array('check0' => 'to', 'check1' => 'bcc', 'function' => 'in_array("u_" . $user_id, {CHECK0}) || in_array("u_" . $user_id, {CHECK1})'),
 0096      )
 0097  );
 0098   
 0099  /**
 0100  * This is for defining which condition fields to show for which Rule
 0101  */
 0102  $global_rule_conditions = array(
 0103      RULE_IS_LIKE        => 'text',
 0104      RULE_IS_NOT_LIKE    => 'text',
 0105      RULE_IS                => 'text',
 0106      RULE_IS_NOT            => 'text',
 0107      RULE_BEGINS_WITH    => 'text',
 0108      RULE_ENDS_WITH        => 'text',
 0109      RULE_IS_USER        => 'user',
 0110      RULE_IS_GROUP        => 'group'
 0111  );
 0112   
 0113  /**
 0114  * Get all folder
 0115  */
 0116  function get_folder($user_id, $folder_id = false)
 0117  {
 0118      global $db, $user, $template;
 0119      global $phpbb_root_path, $phpEx;
 0120   
 0121      $folder = array();
 0122   
 0123      // Get folder information
 0124      $sql = 'SELECT folder_id, COUNT(msg_id) as num_messages, SUM(pm_unread) as num_unread
 0125          FROM ' . PRIVMSGS_TO_TABLE . "
 0126          WHERE user_id = $user_id
 0127              AND folder_id <> " . PRIVMSGS_NO_BOX . '
 0128          GROUP BY folder_id';
 0129      $result = $db->sql_query($sql);
 0130   
 0131      $num_messages = $num_unread = array();
 0132      while ($row = $db->sql_fetchrow($result))
 0133      {
 0134          $num_messages[(int) $row['folder_id']] = $row['num_messages'];
 0135          $num_unread[(int) $row['folder_id']] = $row['num_unread'];
 0136      }
 0137      $db->sql_freeresult($result);
 0138   
 0139      // Make sure the default boxes are defined
 0140      $available_folder = array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX);
 0141   
 0142      foreach ($available_folder as $default_folder)
 0143      {
 0144          if (!isset($num_messages[$default_folder]))
 0145          {
 0146              $num_messages[$default_folder] = 0;
 0147          }
 0148   
 0149          if (!isset($num_unread[$default_folder]))
 0150          {
 0151              $num_unread[$default_folder] = 0;
 0152          }
 0153      }
 0154   
 0155      // Adjust unread status for outbox
 0156      $num_unread[PRIVMSGS_OUTBOX] = $num_messages[PRIVMSGS_OUTBOX];
 0157   
 0158      $folder[PRIVMSGS_INBOX] = array(
 0159          'folder_name'        => $user->lang['PM_INBOX'],
 0160          'num_messages'        => $num_messages[PRIVMSGS_INBOX],
 0161          'unread_messages'    => $num_unread[PRIVMSGS_INBOX]
 0162      );
 0163   
 0164      // Custom Folder
 0165      $sql = 'SELECT folder_id, folder_name, pm_count
 0166          FROM ' . PRIVMSGS_FOLDER_TABLE . "
 0167              WHERE user_id = $user_id";
 0168      $result = $db->sql_query($sql);
 0169   
 0170      while ($row = $db->sql_fetchrow($result))
 0171      {
 0172          $folder[$row['folder_id']] = array(
 0173              'folder_name'        => $row['folder_name'],
 0174              'num_messages'        => $row['pm_count'],
 0175              'unread_messages'    => ((isset($num_unread[$row['folder_id']])) ? $num_unread[$row['folder_id']] : 0)
 0176          );
 0177      }
 0178      $db->sql_freeresult($result);
 0179   
 0180      $folder[PRIVMSGS_OUTBOX] = array(
 0181          'folder_name'        => $user->lang['PM_OUTBOX'],
 0182          'num_messages'        => $num_messages[PRIVMSGS_OUTBOX],
 0183          'unread_messages'    => $num_unread[PRIVMSGS_OUTBOX]
 0184      );
 0185   
 0186      $folder[PRIVMSGS_SENTBOX] = array(
 0187          'folder_name'        => $user->lang['PM_SENTBOX'],
 0188          'num_messages'        => $num_messages[PRIVMSGS_SENTBOX],
 0189          'unread_messages'    => $num_unread[PRIVMSGS_SENTBOX]
 0190      );
 0191   
 0192      // Define Folder Array for template designers (and for making custom folders usable by the template too)
 0193      foreach ($folder as $f_id => $folder_ary)
 0194      {
 0195          $folder_id_name = ($f_id == PRIVMSGS_INBOX) ? 'inbox' : (($f_id == PRIVMSGS_OUTBOX) ? 'outbox' : 'sentbox');
 0196   
 0197          $template->assign_block_vars('folder', array(
 0198              'FOLDER_ID'            => $f_id,
 0199              'FOLDER_NAME'        => $folder_ary['folder_name'],
 0200              'NUM_MESSAGES'        => $folder_ary['num_messages'],
 0201              'UNREAD_MESSAGES'    => $folder_ary['unread_messages'],
 0202   
 0203              'U_FOLDER'            => ($f_id > 0) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $f_id) : append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $folder_id_name),
 0204   
 0205              'S_CUR_FOLDER'        => ($f_id === $folder_id) ? true : false,
 0206              'S_UNREAD_MESSAGES'    => ($folder_ary['unread_messages']) ? true : false,
 0207              'S_CUSTOM_FOLDER'    => ($f_id > 0) ? true : false)
 0208          );
 0209      }
 0210   
 0211      return $folder;
 0212  }
 0213   
 0214  /**
 0215  * Delete Messages From Sentbox
 0216  * we are doing this here because this saves us a bunch of checks and queries
 0217  */
 0218  function clean_sentbox($num_sentbox_messages)
 0219  {
 0220      global $db, $user, $config;
 0221   
 0222      // Check Message Limit
 0223      if ($user->data['message_limit'] && $num_sentbox_messages > $user->data['message_limit'])
 0224      {
 0225          // Delete old messages
 0226          $sql = 'SELECT t.msg_id
 0227              FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p
 0228              WHERE t.msg_id = p.msg_id
 0229                  AND t.user_id = ' . $user->data['user_id'] . '
 0230                  AND t.folder_id = ' . PRIVMSGS_SENTBOX . '
 0231              ORDER BY p.message_time ASC';
 0232          $result = $db->sql_query_limit($sql, ($num_sentbox_messages - $user->data['message_limit']));
 0233   
 0234          $delete_ids = array();
 0235          while ($row = $db->sql_fetchrow($result))
 0236          {
 0237              $delete_ids[] = $row['msg_id'];
 0238          }
 0239          $db->sql_freeresult($result);
 0240          delete_pm($user->data['user_id'], $delete_ids, PRIVMSGS_SENTBOX);
 0241      }
 0242  }
 0243   
 0244  /**
 0245  * Check Rule against Message Information
 0246  */
 0247  function check_rule(&$rules, &$rule_row, &$message_row, $user_id)
 0248  {
 0249      global $user, $config;
 0250   
 0251      if (!isset($rules[$rule_row['rule_check']][$rule_row['rule_connection']]))
 0252      {
 0253          return false;
 0254      }
 0255   
 0256      $check_ary = $rules[$rule_row['rule_check']][$rule_row['rule_connection']];
 0257   
 0258      // Replace Check Literals
 0259      $evaluate = $check_ary['function'];
 0260      $evaluate = preg_replace('/{(CHECK[0-9])}/', '$message_row[$check_ary[strtolower("\1")]]', $evaluate);
 0261   
 0262      // Replace Rule Literals
 0263      $evaluate = preg_replace('/{(STRING|USER_ID|GROUP_ID)}/', '$rule_row["rule_" . strtolower("\1")]', $evaluate);
 0264   
 0265      // Evil Statement
 0266      $result = false;
 0267      eval('$result = (' . $evaluate . ') ? true : false;');
 0268   
 0269      if (!$result)
 0270      {
 0271          return false;
 0272      }
 0273   
 0274      switch ($rule_row['rule_action'])
 0275      {
 0276          case ACTION_PLACE_INTO_FOLDER:
 0277              return array('action' => $rule_row['rule_action'], 'folder_id' => $rule_row['rule_folder_id']);
 0278          break;
 0279          
 0280          case ACTION_MARK_AS_READ:
 0281          case ACTION_MARK_AS_IMPORTANT:
 0282              return array('action' => $rule_row['rule_action'], 'pm_unread' => $message_row['pm_unread'], 'pm_marked' => $message_row['pm_marked']);
 0283          break;
 0284   
 0285          case ACTION_DELETE_MESSAGE:
 0286              global $db, $auth;
 0287   
 0288              // Check for admins/mods - users are not allowed to remove those messages...
 0289              // We do the check here to make sure the data we use is consistent
 0290              $sql = 'SELECT user_id, user_type, user_permissions
 0291                  FROM ' . USERS_TABLE . '
 0292                  WHERE user_id = ' . (int) $message_row['author_id'];
 0293              $result = $db->sql_query($sql);
 0294              $userdata = $db->sql_fetchrow($result);
 0295              $db->sql_freeresult($result);
 0296   
 0297              $auth2 = new auth();
 0298              $auth2->acl($userdata);
 0299   
 0300              if (!$auth2->acl_get('a_') && !$auth2->acl_get('m_') && !$auth2->acl_getf_global('m_'))
 0301              {
 0302                  return array('action' => $rule_row['rule_action'], 'pm_unread' => $message_row['pm_unread'], 'pm_marked' => $message_row['pm_marked']);
 0303              }
 0304   
 0305              return false;
 0306          break;
 0307          
 0308          default:
 0309              return false;
 0310      }
 0311   
 0312      return false;
 0313  }
 0314   
 0315  /**
 0316  * Update user PM count
 0317  */
 0318  function update_pm_counts()
 0319  {
 0320      global $user, $db;
 0321   
 0322      // Update unread count
 0323      $sql = 'SELECT COUNT(msg_id) as num_messages
 0324          FROM ' . PRIVMSGS_TO_TABLE . '
 0325          WHERE pm_unread = 1
 0326              AND folder_id <> ' . PRIVMSGS_OUTBOX . '
 0327              AND user_id = ' . $user->data['user_id'];
 0328      $result = $db->sql_query($sql);
 0329      $user->data['user_unread_privmsg'] = (int) $db->sql_fetchfield('num_messages');
 0330      $db->sql_freeresult($result);
 0331   
 0332      // Update new pm count
 0333      $sql = 'SELECT COUNT(msg_id) as num_messages
 0334          FROM ' . PRIVMSGS_TO_TABLE . '
 0335          WHERE pm_new = 1
 0336              AND folder_id IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ')
 0337              AND user_id = ' . $user->data['user_id'];
 0338      $result = $db->sql_query($sql);
 0339      $user->data['user_new_privmsg'] = (int) $db->sql_fetchfield('num_messages');
 0340      $db->sql_freeresult($result);
 0341   
 0342      $db->sql_query('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
 0343          'user_unread_privmsg'    => (int) $user->data['user_unread_privmsg'],
 0344          'user_new_privmsg'        => (int) $user->data['user_new_privmsg'],
 0345      )) . ' WHERE user_id = ' . $user->data['user_id']);
 0346   
 0347      // Ok, here we need to repair something, other boxes than privmsgs_no_box and privmsgs_hold_box should not carry the pm_new flag.
 0348      if (!$user->data['user_new_privmsg'])
 0349      {
 0350          $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 0351              SET pm_new = 0
 0352              WHERE pm_new = 1
 0353                  AND folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ')
 0354                  AND user_id = ' . $user->data['user_id'];
 0355          $db->sql_query($sql);
 0356      }
 0357  }
 0358   
 0359  /**
 0360  * Place new messages into appropriate folder
 0361  */
 0362  function place_pm_into_folder(&$global_privmsgs_rules, $release = false)
 0363  {
 0364      global $db, $user, $config;
 0365   
 0366      if (!$user->data['user_new_privmsg'])
 0367      {
 0368          return array('not_moved' => 0, 'removed' => 0);
 0369      }
 0370   
 0371      $user_message_rules = (int) $user->data['user_message_rules'];
 0372      $user_id = (int) $user->data['user_id'];
 0373   
 0374      $action_ary = $move_into_folder = array();
 0375      $num_removed = 0;
 0376   
 0377      // Newly processing on-hold messages
 0378      if ($release)
 0379      {
 0380          $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 0381              SET folder_id = ' . PRIVMSGS_NO_BOX . '
 0382              WHERE folder_id = ' . PRIVMSGS_HOLD_BOX . "
 0383                  AND user_id = $user_id";
 0384          $db->sql_query($sql);
 0385      }
 0386   
 0387      // Get those messages not yet placed into any box
 0388      $retrieve_sql = 'SELECT t.*, p.*, u.username, u.user_id, u.group_id
 0389          FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . " u
 0390          WHERE t.user_id = $user_id
 0391              AND p.author_id = u.user_id
 0392              AND t.folder_id = " . PRIVMSGS_NO_BOX . '
 0393              AND t.msg_id = p.msg_id';
 0394   
 0395      // Just place into the appropriate arrays if no rules need to be checked
 0396      if (!$user_message_rules)
 0397      {
 0398          $result = $db->sql_query($retrieve_sql);
 0399   
 0400          while ($row = $db->sql_fetchrow($result))
 0401          {
 0402              $action_ary[$row['msg_id']][] = array('action' => false);
 0403          }
 0404          $db->sql_freeresult($result);
 0405      }
 0406      else
 0407      {
 0408          $user_rules = $zebra = $check_rows = array();
 0409          $user_ids = $memberships = array();
 0410   
 0411          // First of all, grab all rules and retrieve friends/foes
 0412          $sql = 'SELECT *
 0413              FROM ' . PRIVMSGS_RULES_TABLE . "
 0414              WHERE user_id = $user_id";
 0415          $result = $db->sql_query($sql);
 0416          $user_rules = $db->sql_fetchrowset($result);
 0417          $db->sql_freeresult($result);
 0418   
 0419          if (sizeof($user_rules))
 0420          {
 0421              $sql = 'SELECT zebra_id, friend, foe
 0422                  FROM ' . ZEBRA_TABLE . "
 0423                  WHERE user_id = $user_id";
 0424              $result = $db->sql_query($sql);
 0425   
 0426              while ($row = $db->sql_fetchrow($result))
 0427              {
 0428                  $zebra[$row['zebra_id']] = $row;
 0429              }
 0430              $db->sql_freeresult($result);
 0431          }
 0432   
 0433          // Now build a bare-bone check_row array
 0434          $result = $db->sql_query($retrieve_sql);
 0435   
 0436          while ($row = $db->sql_fetchrow($result))
 0437          {
 0438              $check_rows[] = array_merge($row, array(
 0439                  'to'                => explode(':', $row['to_address']),
 0440                  'bcc'                => explode(':', $row['bcc_address']),
 0441                  'friend'            => (isset($zebra[$row['author_id']])) ? $zebra[$row['author_id']]['friend'] : 0,
 0442                  'foe'                => (isset($zebra[$row['author_id']])) ? $zebra[$row['author_id']]['foe'] : 0,
 0443                  'user_in_group'        => array($user->data['group_id']),
 0444                  'author_in_group'    => array())
 0445              );
 0446   
 0447              $user_ids[] = $row['user_id'];
 0448          }
 0449          $db->sql_freeresult($result);
 0450   
 0451          // Retrieve user memberships
 0452          if (sizeof($user_ids))
 0453          {
 0454              $sql = 'SELECT *
 0455                  FROM ' . USER_GROUP_TABLE . '
 0456                  WHERE ' . $db->sql_in_set('user_id', $user_ids) . '
 0457                      AND user_pending = 0';
 0458              $result = $db->sql_query($sql);
 0459   
 0460              while ($row = $db->sql_fetchrow($result))
 0461              {
 0462                  $memberships[$row['user_id']][] = $row['group_id'];
 0463              }
 0464              $db->sql_freeresult($result);
 0465          }
 0466   
 0467          // Now place into the appropriate folder
 0468          foreach ($check_rows as $row)
 0469          {
 0470              // Add membership if set
 0471              if (isset($memberships[$row['author_id']]))
 0472              {
 0473                  $row['author_in_group'] = $memberships[$row['user_id']];
 0474              }
 0475   
 0476              // Check Rule - this should be very quick since we have all information we need
 0477              $is_match = false;
 0478              foreach ($user_rules as $rule_row)
 0479              {
 0480                  if (($action = check_rule($global_privmsgs_rules, $rule_row, $row, $user_id)) !== false)
 0481                  {
 0482                      $is_match = true;
 0483                      $action_ary[$row['msg_id']][] = $action;
 0484                  }
 0485              }
 0486   
 0487              if (!$is_match)
 0488              {
 0489                  $action_ary[$row['msg_id']][] = array('action' => false);
 0490              }
 0491          }
 0492   
 0493          unset($user_rules, $zebra, $check_rows, $user_ids, $memberships);
 0494      }
 0495   
 0496      // We place actions into arrays, to save queries.
 0497      $sql = $unread_ids = $delete_ids = $important_ids = array();
 0498   
 0499      foreach ($action_ary as $msg_id => $msg_ary)
 0500      {
 0501          // It is allowed to execute actions more than once, except placing messages into folder
 0502          $folder_action = $message_removed = false;
 0503   
 0504          foreach ($msg_ary as $pos => $rule_ary)
 0505          {
 0506              if ($folder_action && $rule_ary['action'] == ACTION_PLACE_INTO_FOLDER)
 0507              {
 0508                  continue;
 0509              }
 0510   
 0511              switch ($rule_ary['action'])
 0512              {
 0513                  case ACTION_PLACE_INTO_FOLDER:
 0514                      // Folder actions have precedence, so we will remove any other ones
 0515                      $folder_action = true;
 0516                      $move_into_folder[(int) $rule_ary['folder_id']][] = $msg_id;
 0517                  break;
 0518   
 0519                  case ACTION_MARK_AS_READ:
 0520                      if ($rule_ary['pm_unread'])
 0521                      {
 0522                          $unread_ids[] = $msg_id;
 0523                      }
 0524                  break;
 0525   
 0526                  case ACTION_DELETE_MESSAGE:
 0527                      $delete_ids[] = $msg_id;
 0528                      $message_removed = true;
 0529                  break;
 0530   
 0531                  case ACTION_MARK_AS_IMPORTANT:
 0532                      if (!$rule_ary['pm_marked'])
 0533                      {
 0534                          $important_ids[] = $msg_id;
 0535                      }
 0536                  break;
 0537              }
 0538          }
 0539   
 0540          // We place this here because it could happen that the messages are doubled if a rule marks a message and then moves it into a specific
 0541          // folder. Here we simply move the message into the INBOX if it gets not removed and also not put into a custom folder.
 0542          if (!$folder_action && !$message_removed)
 0543          {
 0544              $move_into_folder[PRIVMSGS_INBOX][] = $msg_id;
 0545          }
 0546      }
 0547   
 0548      // Do not change the order of processing
 0549      // The number of queries needed to be executed here highly depends on the defined rules and are
 0550      // only gone through if new messages arrive.
 0551   
 0552      // Delete messages
 0553      if (sizeof($delete_ids))
 0554      {
 0555          $num_removed += sizeof($delete_ids);
 0556          delete_pm($user_id, $delete_ids, PRIVMSGS_NO_BOX);
 0557      }
 0558   
 0559      // Set messages to Unread
 0560      if (sizeof($unread_ids))
 0561      {
 0562          $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 0563              SET pm_unread = 0
 0564              WHERE ' . $db->sql_in_set('msg_id', $unread_ids) . "
 0565                  AND user_id = $user_id
 0566                  AND folder_id = " . PRIVMSGS_NO_BOX;
 0567          $db->sql_query($sql);
 0568      }
 0569   
 0570      // mark messages as important
 0571      if (sizeof($important_ids))
 0572      {
 0573          $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 0574              SET pm_marked = 1 - pm_marked
 0575              WHERE folder_id = ' . PRIVMSGS_NO_BOX . "
 0576                  AND user_id = $user_id
 0577                  AND " . $db->sql_in_set('msg_id', $important_ids);
 0578          $db->sql_query($sql);
 0579      }
 0580   
 0581      // Move into folder
 0582      $folder = array();
 0583   
 0584      if (sizeof($move_into_folder))
 0585      {
 0586          // Determine Full Folder Action - we need the move to folder id later eventually
 0587          $full_folder_action = ($user->data['user_full_folder'] == FULL_FOLDER_NONE) ? ($config['full_folder_action'] - (FULL_FOLDER_NONE*(-1))) : $user->data['user_full_folder'];
 0588   
 0589          $sql_folder = array_keys($move_into_folder);
 0590          if ($full_folder_action >= 0)
 0591          {
 0592              $sql_folder[] = $full_folder_action;
 0593          }
 0594   
 0595          $sql = 'SELECT folder_id, pm_count
 0596              FROM ' . PRIVMSGS_FOLDER_TABLE . '
 0597              WHERE ' . $db->sql_in_set('folder_id', $sql_folder) . "
 0598                  AND user_id = $user_id";
 0599          $result = $db->sql_query($sql);
 0600   
 0601          while ($row = $db->sql_fetchrow($result))
 0602          {
 0603              $folder[(int) $row['folder_id']] = (int) $row['pm_count'];
 0604          }
 0605          $db->sql_freeresult($result);
 0606   
 0607          unset($sql_folder);
 0608   
 0609          if (in_array(PRIVMSGS_INBOX, array_keys($move_into_folder)))
 0610          {
 0611              $sql = 'SELECT COUNT(msg_id) as num_messages
 0612                  FROM ' . PRIVMSGS_TO_TABLE . "
 0613                  WHERE user_id = $user_id
 0614                      AND folder_id = " . PRIVMSGS_INBOX;
 0615              $result = $db->sql_query($sql);
 0616              $folder[PRIVMSGS_INBOX] = (int) $db->sql_fetchfield('num_messages');
 0617              $db->sql_freeresult($result);
 0618          }
 0619      }
 0620   
 0621      // Here we have ideally only one folder to move into
 0622      foreach ($move_into_folder as $folder_id => $msg_ary)
 0623      {
 0624          $dest_folder = $folder_id;
 0625          $full_folder_action = FULL_FOLDER_NONE;
 0626   
 0627          // Check Message Limit - we calculate with the complete array, most of the time it is one message
 0628          // But we are making sure that the other way around works too (more messages in queue than allowed to be stored)
 0629          if ($user->data['message_limit'] && $folder[$folder_id] && ($folder[$folder_id] + sizeof($msg_ary)) > $user->data['message_limit'])
 0630          {
 0631              $full_folder_action = ($user->data['user_full_folder'] == FULL_FOLDER_NONE) ? ($config['full_folder_action'] - (FULL_FOLDER_NONE*(-1))) : $user->data['user_full_folder'];
 0632   
 0633              // If destination folder itself is full...
 0634              if ($full_folder_action >= 0 && ($folder[$full_folder_action] + sizeof($msg_ary)) > $user->data['message_limit'])
 0635              {
 0636                  $full_folder_action = $config['full_folder_action'] - (FULL_FOLDER_NONE*(-1));
 0637              }
 0638   
 0639              // If Full Folder Action is to move to another folder, we simply adjust the destination folder
 0640              if ($full_folder_action >= 0)
 0641              {
 0642                  $dest_folder = $full_folder_action;
 0643              }
 0644              else if ($full_folder_action == FULL_FOLDER_DELETE)
 0645              {
 0646                  // Delete some messages. NOTE: Ordered by msg_id here instead of message_time!
 0647                  $sql = 'SELECT msg_id
 0648                      FROM ' . PRIVMSGS_TO_TABLE . "
 0649                      WHERE user_id = $user_id
 0650                          AND folder_id = $dest_folder
 0651                      ORDER BY msg_id ASC";
 0652                  $result = $db->sql_query_limit($sql, (($folder[$dest_folder] + sizeof($msg_ary)) - $user->data['message_limit']));
 0653   
 0654                  $delete_ids = array();
 0655                  while ($row = $db->sql_fetchrow($result))
 0656                  {
 0657                      $delete_ids[] = $row['msg_id'];
 0658                  }
 0659                  $db->sql_freeresult($result);
 0660   
 0661                  $num_removed += sizeof($delete_ids);
 0662                  delete_pm($user_id, $delete_ids, $dest_folder);
 0663              }
 0664          }
 0665   
 0666          //
 0667          if ($full_folder_action == FULL_FOLDER_HOLD)
 0668          {
 0669              $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 0670                  SET folder_id = ' . PRIVMSGS_HOLD_BOX . '
 0671                  WHERE folder_id = ' . PRIVMSGS_NO_BOX . "
 0672                      AND user_id = $user_id
 0673                      AND " . $db->sql_in_set('msg_id', $msg_ary);
 0674              $db->sql_query($sql);
 0675          }
 0676          else
 0677          {
 0678              $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
 0679                  SET folder_id = $dest_folder, pm_new = 0
 0680                  WHERE folder_id = " . PRIVMSGS_NO_BOX . "
 0681                      AND user_id = $user_id
 0682                      AND pm_new = 1
 0683                      AND " . $db->sql_in_set('msg_id', $msg_ary);
 0684              $db->sql_query($sql);
 0685   
 0686              if ($dest_folder != PRIVMSGS_INBOX)
 0687              {
 0688                  $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . '
 0689                      SET pm_count = pm_count + ' . (int) $db->sql_affectedrows() . "
 0690                      WHERE folder_id = $dest_folder
 0691                          AND user_id = $user_id";
 0692                  $db->sql_query($sql);
 0693              }
 0694          }
 0695      }
 0696   
 0697      if (sizeof($action_ary))
 0698      {
 0699          // Move from OUTBOX to SENTBOX
 0700          // We are not checking any full folder status here... SENTBOX is a special treatment (old messages get deleted)
 0701          $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 0702              SET folder_id = ' . PRIVMSGS_SENTBOX . '
 0703              WHERE folder_id = ' . PRIVMSGS_OUTBOX . '
 0704                  AND ' . $db->sql_in_set('msg_id', array_keys($action_ary));
 0705          $db->sql_query($sql);
 0706      }
 0707   
 0708      // Update new/unread count
 0709      update_pm_counts();
 0710   
 0711      // Now check how many messages got not moved...
 0712      $sql = 'SELECT COUNT(msg_id) as num_messages
 0713          FROM ' . PRIVMSGS_TO_TABLE . "
 0714          WHERE user_id = $user_id
 0715              AND folder_id = " . PRIVMSGS_HOLD_BOX;
 0716      $result = $db->sql_query($sql);
 0717      $num_not_moved = (int) $db->sql_fetchfield('num_messages');
 0718      $db->sql_freeresult($result);
 0719   
 0720      return array('not_moved' => $num_not_moved, 'removed' => $num_removed);
 0721  }
 0722   
 0723  /**
 0724  * Move PM from one to another folder
 0725  */
 0726  function move_pm($user_id, $message_limit, $move_msg_ids, $dest_folder, $cur_folder_id)
 0727  {
 0728      global $db, $user;
 0729      global $phpbb_root_path, $phpEx;
 0730   
 0731      $num_moved = 0;
 0732   
 0733      if (!is_array($move_msg_ids))
 0734      {
 0735          $move_msg_ids = array($move_msg_ids);
 0736      }
 0737   
 0738      if (sizeof($move_msg_ids) && !in_array($dest_folder, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX)) &&
 0739          !in_array($cur_folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)) && $cur_folder_id != $dest_folder)
 0740      {
 0741          // We have to check the destination folder ;)
 0742          if ($dest_folder != PRIVMSGS_INBOX)
 0743          {
 0744              $sql = 'SELECT folder_id, folder_name, pm_count
 0745                  FROM ' . PRIVMSGS_FOLDER_TABLE . "
 0746                  WHERE folder_id = $dest_folder
 0747                      AND user_id = $user_id";
 0748              $result = $db->sql_query($sql);
 0749              $row = $db->sql_fetchrow($result);
 0750              $db->sql_freeresult($result);
 0751   
 0752              if (!$row)
 0753              {
 0754                  trigger_error('NOT_AUTHORISED');
 0755              }
 0756   
 0757              if ($message_limit && $row['pm_count'] + sizeof($move_msg_ids) > $message_limit)
 0758              {
 0759                  $message = sprintf($user->lang['NOT_ENOUGH_SPACE_FOLDER'], $row['folder_name']) . '<br /><br />';
 0760                  $message .= sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $row['folder_id']) . '">', '</a>', $row['folder_name']);
 0761                  trigger_error($message);
 0762              }
 0763          }
 0764          else
 0765          {
 0766              $sql = 'SELECT COUNT(msg_id) as num_messages
 0767                  FROM ' . PRIVMSGS_TO_TABLE . '
 0768                  WHERE folder_id = ' . PRIVMSGS_INBOX . "
 0769                      AND user_id = $user_id";
 0770              $result = $db->sql_query($sql);
 0771              $num_messages = (int) $db->sql_fetchfield('num_messages');
 0772              $db->sql_freeresult($result);
 0773   
 0774              if ($message_limit && $num_messages + sizeof($move_msg_ids) > $message_limit)
 0775              {
 0776                  $message = sprintf($user->lang['NOT_ENOUGH_SPACE_FOLDER'], $user->lang['PM_INBOX']) . '<br /><br />';
 0777                  $message .= sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=inbox') . '">', '</a>', $user->lang['PM_INBOX']);
 0778                  trigger_error($message);
 0779              }
 0780          }
 0781   
 0782          $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
 0783              SET folder_id = $dest_folder
 0784              WHERE folder_id = $cur_folder_id
 0785                  AND user_id = $user_id
 0786                  AND " . $db->sql_in_set('msg_id', $move_msg_ids);
 0787          $db->sql_query($sql);
 0788          $num_moved = $db->sql_affectedrows();
 0789   
 0790          // Update pm counts
 0791          if ($num_moved)
 0792          {
 0793              if (!in_array($cur_folder_id, array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX)))
 0794              {
 0795                  $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
 0796                      SET pm_count = pm_count - $num_moved
 0797                      WHERE folder_id = $cur_folder_id
 0798                          AND user_id = $user_id";
 0799                  $db->sql_query($sql);
 0800              }
 0801   
 0802              if ($dest_folder != PRIVMSGS_INBOX)
 0803              {
 0804                  $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
 0805                      SET pm_count = pm_count + $num_moved
 0806                      WHERE folder_id = $dest_folder
 0807                          AND user_id = $user_id";
 0808                  $db->sql_query($sql);
 0809              }
 0810          }
 0811      }
 0812      else if (in_array($cur_folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)))
 0813      {
 0814          trigger_error('CANNOT_MOVE_SPECIAL');
 0815      }
 0816   
 0817      return $num_moved;
 0818  }
 0819   
 0820  /**
 0821  * Update unread message status
 0822  */
 0823  function update_unread_status($unread, $msg_id, $user_id, $folder_id)
 0824  {
 0825      if (!$unread)
 0826      {
 0827          return;
 0828      }
 0829   
 0830      global $db, $user;
 0831   
 0832      $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
 0833          SET pm_unread = 0
 0834          WHERE msg_id = $msg_id
 0835              AND user_id = $user_id
 0836              AND folder_id = $folder_id";
 0837      $db->sql_query($sql);
 0838   
 0839      $sql = 'UPDATE ' . USERS_TABLE . "
 0840          SET user_unread_privmsg = user_unread_privmsg - 1
 0841          WHERE user_id = $user_id";
 0842      $db->sql_query($sql);
 0843   
 0844      if ($user->data['user_id'] == $user_id)
 0845      {
 0846          $user->data['user_unread_privmsg']--;
 0847   
 0848          // Try to cope with previous wrong conversions...
 0849          if ($user->data['user_unread_privmsg'] < 0)
 0850          {
 0851              $sql = 'UPDATE ' . USERS_TABLE . "
 0852                  SET user_unread_privmsg = 0
 0853                  WHERE user_id = $user_id";
 0854              $db->sql_query($sql);
 0855   
 0856              $user->data['user_unread_privmsg'] = 0;
 0857          }
 0858      }
 0859  }
 0860   
 0861  /**
 0862  * Handle all actions possible with marked messages
 0863  */
 0864  function handle_mark_actions($user_id, $mark_action)
 0865  {
 0866      global $db, $user, $phpbb_root_path, $phpEx;
 0867   
 0868      $msg_ids        = request_var('marked_msg_id', array(0));
 0869      $cur_folder_id    = request_var('cur_folder_id', PRIVMSGS_NO_BOX);
 0870      $confirm        = (isset($_POST['confirm'])) ? true : false;
 0871   
 0872      if (!sizeof($msg_ids))
 0873      {
 0874          return false;
 0875      }
 0876   
 0877      switch ($mark_action)
 0878      {
 0879          case 'mark_important':
 0880   
 0881              $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
 0882                  SET pm_marked = 1 - pm_marked
 0883                  WHERE folder_id = $cur_folder_id
 0884                      AND user_id = $user_id
 0885                      AND " . $db->sql_in_set('msg_id', $msg_ids);
 0886              $db->sql_query($sql);
 0887   
 0888          break;
 0889   
 0890          case 'delete_marked':
 0891   
 0892              if (confirm_box(true))
 0893              {
 0894                  delete_pm($user_id, $msg_ids, $cur_folder_id);
 0895                  
 0896                  $success_msg = (sizeof($msg_ids) == 1) ? 'MESSAGE_DELETED' : 'MESSAGES_DELETED';
 0897                  $redirect = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;folder=' . $cur_folder_id);
 0898   
 0899                  meta_refresh(3, $redirect);
 0900                  trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_FOLDER'], '<a href="' . $redirect . '">', '</a>'));
 0901              }
 0902              else
 0903              {
 0904                  $s_hidden_fields = array(
 0905                      'cur_folder_id'    => $cur_folder_id,
 0906                      'mark_option'    => 'delete_marked',
 0907                      'submit_mark'    => true,
 0908                      'marked_msg_id'    => $msg_ids
 0909                  );
 0910   
 0911                  confirm_box(false, 'DELETE_MARKED_PM', build_hidden_fields($s_hidden_fields));
 0912              }
 0913   
 0914          break;
 0915   
 0916          default:
 0917              return false;
 0918      }
 0919   
 0920      return true;
 0921  }
 0922   
 0923  /**
 0924  * Delete PM(s)
 0925  */
 0926  function delete_pm($user_id, $msg_ids, $folder_id)
 0927  {
 0928      global $db, $user;
 0929   
 0930      $user_id    = (int) $user_id;
 0931      $folder_id    = (int) $folder_id;
 0932   
 0933      if (!$user_id)
 0934      {
 0935          return false;
 0936      }
 0937   
 0938      if (!is_array($msg_ids))
 0939      {
 0940          if (!$msg_ids)
 0941          {
 0942              return false;
 0943          }
 0944          $msg_ids = array($msg_ids);
 0945      }
 0946   
 0947      if (!sizeof($msg_ids))
 0948      {
 0949          return false;
 0950      }
 0951   
 0952      // Get PM Information for later deleting
 0953      $sql = 'SELECT msg_id, pm_unread, pm_new
 0954          FROM ' . PRIVMSGS_TO_TABLE . '
 0955          WHERE ' . $db->sql_in_set('msg_id', array_map('intval', $msg_ids)) . "
 0956              AND folder_id = $folder_id
 0957              AND user_id = $user_id";
 0958      $result = $db->sql_query($sql);
 0959   
 0960      $delete_rows = array();
 0961      $num_unread = $num_new = $num_deleted = 0;
 0962      while ($row = $db->sql_fetchrow($result))
 0963      {
 0964          $num_unread += (int) $row['pm_unread'];
 0965          $num_new += (int) $row['pm_new'];
 0966   
 0967          $delete_rows[$row['msg_id']] = 1;
 0968      }
 0969      $db->sql_freeresult($result);
 0970      unset($msg_ids);
 0971   
 0972      if (!sizeof($delete_rows))
 0973      {
 0974          return false;
 0975      }
 0976   
 0977      // if no one has read the message yet (meaning it is in users outbox)
 0978      // then mark the message as deleted...
 0979      if ($folder_id == PRIVMSGS_OUTBOX)
 0980      {
 0981          // Remove PM from Outbox
 0982          $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . "
 0983              WHERE user_id = $user_id AND folder_id = " . PRIVMSGS_OUTBOX . '
 0984                  AND ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
 0985          $db->sql_query($sql);
 0986   
 0987          // Update PM Information for safety
 0988          $sql = 'UPDATE ' . PRIVMSGS_TABLE . " SET message_text = ''
 0989              WHERE " . $db->sql_in_set('msg_id', array_keys($delete_rows));
 0990          $db->sql_query($sql);
 0991   
 0992          // Set delete flag for those intended to receive the PM
 0993          // We do not remove the message actually, to retain some basic information (sent time for example)
 0994          $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 0995              SET pm_deleted = 1
 0996              WHERE ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
 0997          $db->sql_query($sql);
 0998   
 0999          $num_deleted = $db->sql_affectedrows();
 1000      }
 1001      else
 1002      {
 1003          // Delete private message data
 1004          $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . "
 1005              WHERE user_id = $user_id
 1006                  AND folder_id = $folder_id
 1007                  AND " . $db->sql_in_set('msg_id', array_keys($delete_rows));
 1008          $db->sql_query($sql);
 1009          $num_deleted = $db->sql_affectedrows();
 1010      }
 1011   
 1012      // if folder id is user defined folder then decrease pm_count
 1013      if (!in_array($folder_id, array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX, PRIVMSGS_NO_BOX)))
 1014      {
 1015          $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
 1016              SET pm_count = pm_count - $num_deleted
 1017              WHERE folder_id = $folder_id";
 1018          $db->sql_query($sql);
 1019      }
 1020   
 1021      // Update unread and new status field
 1022      if ($num_unread || $num_new)
 1023      {
 1024          $set_sql = ($num_unread) ? 'user_unread_privmsg = user_unread_privmsg - ' . $num_unread : '';
 1025   
 1026          if ($num_new)
 1027          {
 1028              $set_sql .= ($set_sql != '') ? ', ' : '';
 1029              $set_sql .= 'user_new_privmsg = user_new_privmsg - ' . $num_new;
 1030          }
 1031   
 1032          $db->sql_query('UPDATE ' . USERS_TABLE . " SET $set_sql WHERE user_id = $user_id");
 1033   
 1034          $user->data['user_new_privmsg'] -= $num_new;
 1035          $user->data['user_unread_privmsg'] -= $num_unread;
 1036      }
 1037      
 1038      // Now we have to check which messages we can delete completely    
 1039      $sql = 'SELECT msg_id
 1040          FROM ' . PRIVMSGS_TO_TABLE . '
 1041          WHERE ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
 1042      $result = $db->sql_query($sql);
 1043   
 1044      while ($row = $db->sql_fetchrow($result))
 1045      {
 1046          unset($delete_rows[$row['msg_id']]);
 1047      }
 1048      $db->sql_freeresult($result);
 1049   
 1050      $delete_ids = array_keys($delete_rows);
 1051   
 1052      if (sizeof($delete_ids))
 1053      {
 1054          $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
 1055              WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
 1056          $db->sql_query($sql);
 1057      }
 1058   
 1059      return true;
 1060  }
 1061   
 1062  /**
 1063  * Rebuild message header
 1064  */
 1065  function rebuild_header($check_ary)
 1066  {
 1067      global $db;
 1068   
 1069      $address = array();
 1070   
 1071      foreach ($check_ary as $check_type => $address_field)
 1072      {
 1073          // Split Addresses into users and groups
 1074          preg_match_all('/:?(u|g)_([0-9]+):?/', $address_field, $match);
 1075   
 1076          $u = $g = array();
 1077          foreach ($match[1] as $id => $type)
 1078          {
 1079              ${$type}[] = (int) $match[2][$id];
 1080          }
 1081   
 1082          $_types = array('u', 'g');
 1083          foreach ($_types as $type)
 1084          {
 1085              if (sizeof($$type))
 1086              {
 1087                  foreach ($$type as $id)
 1088                  {
 1089                      $address[$type][$id] = $check_type;
 1090                  }
 1091              }
 1092          }
 1093      }
 1094   
 1095      return $address;
 1096  }
 1097   
 1098  /**
 1099  * Print out/assign recipient information
 1100  */
 1101  function write_pm_addresses($check_ary, $author_id, $plaintext = false)
 1102  {
 1103      global $db, $user, $template, $phpbb_root_path, $phpEx;
 1104   
 1105      $addresses = array();
 1106   
 1107      foreach ($check_ary as $check_type => $address_field)
 1108      {
 1109          if (!is_array($address_field))
 1110          {
 1111              // Split Addresses into users and groups
 1112              preg_match_all('/:?(u|g)_([0-9]+):?/', $address_field, $match);
 1113   
 1114              $u = $g = array();
 1115              foreach ($match[1] as $id => $type)
 1116              {
 1117                  ${$type}[] = (int) $match[2][$id];
 1118              }
 1119          }
 1120          else
 1121          {
 1122              $u = $address_field['u'];
 1123              $g = $address_field['g'];
 1124          }
 1125   
 1126          $address = array();
 1127          if (sizeof($u))
 1128          {
 1129              $sql = 'SELECT user_id, username, user_colour
 1130                  FROM ' . USERS_TABLE . '
 1131                  WHERE ' . $db->sql_in_set('user_id', $u) . '
 1132                      AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
 1133              $result = $db->sql_query($sql);
 1134   
 1135              while ($row = $db->sql_fetchrow($result))
 1136              {
 1137                  if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
 1138                  {
 1139                      if ($plaintext)
 1140                      {
 1141                          $address[] = $row['username'];
 1142                      }
 1143                      else
 1144                      {
 1145                          $address['user'][$row['user_id']] = array('name' => $row['username'], 'colour' => $row['user_colour']);
 1146                      }
 1147                  }
 1148              }
 1149              $db->sql_freeresult($result);
 1150          }
 1151   
 1152          if (sizeof($g))
 1153          {
 1154              if ($plaintext)
 1155              {
 1156                  $sql = 'SELECT group_name, group_type
 1157                      FROM ' . GROUPS_TABLE . '
 1158                          WHERE ' . $db->sql_in_set('group_id', $g);
 1159                  $result = $db->sql_query($sql);
 1160          
 1161                  while ($row = $db->sql_fetchrow($result))
 1162                  {
 1163                      if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
 1164                      {
 1165                          $address[] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
 1166                      }
 1167                  }
 1168                  $db->sql_freeresult($result);
 1169              }
 1170              else
 1171              {
 1172                  $sql = 'SELECT g.group_id, g.group_name, g.group_colour, g.group_type, ug.user_id
 1173                      FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
 1174                          WHERE ' . $db->sql_in_set('g.group_id', $g) . '
 1175                          AND g.group_id = ug.group_id
 1176                          AND ug.user_pending = 0';
 1177                  $result = $db->sql_query($sql);
 1178          
 1179                  while ($row = $db->sql_fetchrow($result))
 1180                  {
 1181                      if (!isset($address['group'][$row['group_id']]))
 1182                      {
 1183                          if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
 1184                          {
 1185                              $row['group_name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
 1186                              $address['group'][$row['group_id']] = array('name' => $row['group_name'], 'colour' => $row['group_colour']);
 1187                          }
 1188                      }
 1189   
 1190                      if (isset($address['user'][$row['user_id']]))
 1191                      {
 1192                          $address['user'][$row['user_id']]['in_group'] = $row['group_id'];
 1193                      }
 1194                  }
 1195                  $db->sql_freeresult($result);
 1196              }
 1197          }
 1198   
 1199          if (sizeof($address) && !$plaintext)
 1200          {
 1201              $template->assign_var('S_' . strtoupper($check_type) . '_RECIPIENT', true);
 1202   
 1203              foreach ($address as $type => $adr_ary)
 1204              {
 1205                  foreach ($adr_ary as $id => $row)
 1206                  {
 1207                      $tpl_ary = array(
 1208                          'IS_GROUP'    => ($type == 'group') ? true : false,
 1209                          'IS_USER'    => ($type == 'user') ? true : false,
 1210                          'UG_ID'        => $id,
 1211                          'NAME'        => $row['name'],
 1212                          'COLOUR'    => ($row['colour']) ? '#' . $row['colour'] : '',
 1213                          'TYPE'        => $type,
 1214                      );
 1215   
 1216                      if ($type == 'user')
 1217                      {
 1218                          $tpl_ary = array_merge($tpl_ary, array(
 1219                              'U_VIEW'        => get_username_string('profile', $id, $row['name'], $row['colour']),
 1220                              'NAME_FULL'        => get_username_string('full', $id, $row['name'], $row['colour']),
 1221                          ));
 1222                      }
 1223                      else
 1224                      {
 1225                          $tpl_ary = array_merge($tpl_ary, array(
 1226                              'U_VIEW'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp;g=' . $id),
 1227                          ));
 1228                      }
 1229   
 1230                      $template->assign_block_vars($check_type . '_recipient', $tpl_ary);
 1231                  }
 1232              }
 1233          }
 1234   
 1235          $addresses[$check_type] = $address;
 1236      }
 1237   
 1238      return $addresses;
 1239  }
 1240   
 1241  /**
 1242  * Get folder status
 1243  */
 1244  function get_folder_status($folder_id, $folder)
 1245  {
 1246      global $db, $user, $config;
 1247   
 1248      if (isset($folder[$folder_id]))
 1249      {
 1250          $folder = $folder[$folder_id];
 1251      }
 1252      else
 1253      {
 1254          return false;
 1255      }
 1256   
 1257      $return = array(
 1258          'folder_name'    => $folder['folder_name'],
 1259          'cur'            => $folder['num_messages'],
 1260          'remaining'        => ($user->data['message_limit']) ? $user->data['message_limit'] - $folder['num_messages'] : 0,
 1261          'max'            => $user->data['message_limit'],
 1262          'percent'        => ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? round(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0,
 1263      );
 1264   
 1265      $return['message']    = sprintf($user->lang['FOLDER_STATUS_MSG'], $return['percent'], $return['cur'], $return['max']);
 1266   
 1267      return $return;
 1268  }
 1269   
 1270  //
 1271  // COMPOSE MESSAGES
 1272  //
 1273   
 1274  /**
 1275  * Submit PM
 1276  */
 1277  function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
 1278  {
 1279      global $db, $auth, $config, $phpEx, $template, $user, $phpbb_root_path;
 1280   
 1281      // We do not handle erasing pms here
 1282      if ($mode == 'delete')
 1283      {
 1284          return false;
 1285      }
 1286   
 1287      $current_time = time();
 1288   
 1289      // Collect some basic information about which tables and which rows to update/insert
 1290      $sql_data = array();
 1291      $root_level = 0;
 1292   
 1293      // Recipient Information
 1294      $recipients = $to = $bcc = array();
 1295   
 1296      if ($mode != 'edit')
 1297      {
 1298          // Build Recipient List
 1299          // u|g => array($user_id => 'to'|'bcc')
 1300          $_types = array('u', 'g');
 1301          foreach ($_types as $ug_type)
 1302          {
 1303              if (isset($data['address_list'][$ug_type]) && sizeof($data['address_list'][$ug_type]))
 1304              {
 1305                  foreach ($data['address_list'][$ug_type] as $id => $field)
 1306                  {
 1307                      $id = (int) $id;
 1308   
 1309                      // Do not rely on the address list being "valid"
 1310                      if (!$id || ($ug_type == 'u' && $id == ANONYMOUS))
 1311                      {
 1312                          continue;
 1313                      }
 1314   
 1315                      $field = ($field == 'to') ? 'to' : 'bcc';
 1316                      if ($ug_type == 'u')
 1317                      {
 1318                          $recipients[$id] = $field;
 1319                      }
 1320                      ${$field}[] = $ug_type . '_' . $id;
 1321                  }
 1322              }
 1323          }
 1324   
 1325          if (isset($data['address_list']['g']) && sizeof($data['address_list']['g']))
 1326          {
 1327              $sql = 'SELECT u.user_type, ug.group_id, ug.user_id
 1328                  FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug
 1329                  WHERE ' . $db->sql_in_set('ug.group_id', array_keys($data['address_list']['g'])) . '
 1330                      AND ug.user_pending = 0
 1331                      AND u.user_id = ug.user_id
 1332                      AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
 1333              $result = $db->sql_query($sql);
 1334      
 1335              while ($row = $db->sql_fetchrow($result))
 1336              {
 1337                  $field = ($data['address_list']['g'][$row['group_id']] == 'to') ? 'to' : 'bcc';
 1338                  $recipients[$row['user_id']] = $field;
 1339              }
 1340              $db->sql_freeresult($result);
 1341          }
 1342   
 1343          if (!sizeof($recipients))
 1344          {
 1345              trigger_error('NO_RECIPIENT');
 1346          }
 1347      }
 1348   
 1349      $db->sql_transaction('begin');
 1350   
 1351      $sql = '';
 1352   
 1353      switch ($mode)
 1354      {
 1355          case 'reply':
 1356          case 'quote':
 1357              $root_level = ($data['reply_from_root_level']) ? $data['reply_from_root_level'] : $data['reply_from_msg_id'];
 1358   
 1359              // Set message_replied switch for this user
 1360              $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 1361                  SET pm_replied = 1
 1362                  WHERE user_id = ' . $data['from_user_id'] . '
 1363                      AND msg_id = ' . $data['reply_from_msg_id'];
 1364   
 1365          // no break
 1366   
 1367          case 'forward':
 1368          case 'post':
 1369          case 'quotepost':
 1370              $sql_data = array(
 1371                  'root_level'        => $root_level,
 1372                  'author_id'            => $data['from_user_id'],
 1373                  'icon_id'            => $data['icon_id'],
 1374                  'author_ip'            => $data['from_user_ip'],
 1375                  'message_time'        => $current_time,
 1376                  'enable_bbcode'        => $data['enable_bbcode'],
 1377                  'enable_smilies'    => $data['enable_smilies'],
 1378                  'enable_magic_url'    => $data['enable_urls'],
 1379                  'enable_sig'        => $data['enable_sig'],
 1380                  'message_subject'    => $subject,
 1381                  'message_text'        => $data['message'],
 1382                  'message_attachment'=> (!empty($data['attachment_data'])) ? 1 : 0,
 1383                  'bbcode_bitfield'    => $data['bbcode_bitfield'],
 1384                  'bbcode_uid'        => $data['bbcode_uid'],
 1385                  'to_address'        => implode(':', $to),
 1386                  'bcc_address'        => implode(':', $bcc)
 1387              );
 1388          break;
 1389   
 1390          case 'edit':
 1391              $sql_data = array(
 1392                  'icon_id'            => $data['icon_id'],
 1393                  'message_edit_time'    => $current_time,
 1394                  'enable_bbcode'        => $data['enable_bbcode'],
 1395                  'enable_smilies'    => $data['enable_smilies'],
 1396                  'enable_magic_url'    => $data['enable_urls'],
 1397                  'enable_sig'        => $data['enable_sig'],
 1398                  'message_subject'    => $subject,
 1399                  'message_text'        => $data['message'],
 1400                  'message_attachment'=> (!empty($data['attachment_data'])) ? 1 : 0,
 1401                  'bbcode_bitfield'    => $data['bbcode_bitfield'],
 1402                  'bbcode_uid'        => $data['bbcode_uid']
 1403              );
 1404          break;
 1405      }
 1406   
 1407      if (sizeof($sql_data))
 1408      {
 1409          $query = '';
 1410   
 1411          if ($mode == 'post' || $mode == 'reply' || $mode == 'quote' || $mode == 'quotepost' || $mode == 'forward')
 1412          {
 1413              $db->sql_query('INSERT INTO ' . PRIVMSGS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data));
 1414              $data['msg_id'] = $db->sql_nextid();
 1415          }
 1416          else if ($mode == 'edit')
 1417          {
 1418              $sql = 'UPDATE ' . PRIVMSGS_TABLE . '
 1419                  SET message_edit_count = message_edit_count + 1, ' . $db->sql_build_array('UPDATE', $sql_data) . '
 1420                  WHERE msg_id = ' . $data['msg_id'];
 1421              $db->sql_query($sql);
 1422          }
 1423      }
 1424   
 1425      if ($mode != 'edit')
 1426      {
 1427          if ($sql)
 1428          {
 1429              $db->sql_query($sql);
 1430          }
 1431          unset($sql);
 1432   
 1433          $sql_ary = array();
 1434          foreach ($recipients as $user_id => $type)
 1435          {
 1436              $sql_ary[] = array(
 1437                  'msg_id'        => (int) $data['msg_id'],
 1438                  'user_id'        => (int) $user_id,
 1439                  'author_id'        => (int) $data['from_user_id'],
 1440                  'folder_id'        => PRIVMSGS_NO_BOX,
 1441                  'pm_new'        => 1,
 1442                  'pm_unread'        => 1,
 1443                  'pm_forwarded'    => ($mode == 'forward') ? 1 : 0
 1444              );
 1445          }
 1446   
 1447          $db->sql_multi_insert(PRIVMSGS_TO_TABLE, $sql_ary);
 1448   
 1449          $sql = 'UPDATE ' . USERS_TABLE . '
 1450              SET user_new_privmsg = user_new_privmsg + 1, user_unread_privmsg = user_unread_privmsg + 1, user_last_privmsg = ' . time() . '
 1451              WHERE ' . $db->sql_in_set('user_id', array_keys($recipients));
 1452          $db->sql_query($sql);
 1453   
 1454          // Put PM into outbox
 1455          if ($put_in_outbox)
 1456          {
 1457              $db->sql_query('INSERT INTO ' . PRIVMSGS_TO_TABLE . ' ' . $db->sql_build_array('INSERT', array(
 1458                  'msg_id'        => (int) $data['msg_id'],
 1459                  'user_id'        => (int) $data['from_user_id'],
 1460                  'author_id'        => (int) $data['from_user_id'],
 1461                  'folder_id'        => PRIVMSGS_OUTBOX,
 1462                  'pm_new'        => 0,
 1463                  'pm_unread'        => 0,
 1464                  'pm_forwarded'    => ($mode == 'forward') ? 1 : 0))
 1465              );
 1466          }
 1467      }
 1468   
 1469      // Set user last post time
 1470      if ($mode == 'reply' || $mode == 'quote' || $mode == 'quotepost' || $mode == 'forward' || $mode == 'post')
 1471      {
 1472          $sql = 'UPDATE ' . USERS_TABLE . "
 1473              SET user_lastpost_time = $current_time
 1474              WHERE user_id = " . $data['from_user_id'];
 1475          $db->sql_query($sql);
 1476      }
 1477   
 1478      // Submit Attachments
 1479      if (!empty($data['attachment_data']) && $data['msg_id'] && in_array($mode, array('post', 'reply', 'quote', 'quotepost', 'edit', 'forward')))
 1480      {
 1481          $space_taken = $files_added = 0;
 1482          $orphan_rows = array();
 1483   
 1484          foreach ($data['attachment_data'] as $pos => $attach_row)
 1485          {
 1486              $orphan_rows[(int) $attach_row['attach_id']] = array();
 1487          }
 1488   
 1489          if (sizeof($orphan_rows))
 1490          {
 1491              $sql = 'SELECT attach_id, filesize, physical_filename
 1492                  FROM ' . ATTACHMENTS_TABLE . '
 1493                  WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan_rows)) . '
 1494                      AND in_message = 1
 1495                      AND is_orphan = 1
 1496                      AND poster_id = ' . $user->data['user_id'];
 1497              $result = $db->sql_query($sql);
 1498   
 1499              $orphan_rows = array();
 1500              while ($row = $db->sql_fetchrow($result))
 1501              {
 1502                  $orphan_rows[$row['attach_id']] = $row;
 1503              }
 1504              $db->sql_freeresult($result);
 1505          }
 1506   
 1507          foreach ($data['attachment_data'] as $pos => $attach_row)
 1508          {
 1509              if ($attach_row['is_orphan'] && !in_array($attach_row['attach_id'], array_keys($orphan_rows)))
 1510              {
 1511                  continue;
 1512              }
 1513   
 1514              if (!$attach_row['is_orphan'])
 1515              {
 1516                  // update entry in db if attachment already stored in db and filespace
 1517                  $sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
 1518                      SET attach_comment = '" . $db->sql_escape($attach_row['attach_comment']) . "'
 1519                      WHERE attach_id = " . (int) $attach_row['attach_id'] . '
 1520                          AND is_orphan = 0';
 1521                  $db->sql_query($sql);
 1522              }
 1523              else
 1524              {
 1525                  // insert attachment into db
 1526                  if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
 1527                  {
 1528                      continue;
 1529                  }
 1530   
 1531                  $space_taken += $orphan_rows[$attach_row['attach_id']]['filesize'];
 1532                  $files_added++;
 1533   
 1534                  $attach_sql = array(
 1535                      'post_msg_id'        => $data['msg_id'],
 1536                      'topic_id'            => 0,
 1537                      'is_orphan'            => 0,
 1538                      'poster_id'            => $data['from_user_id'],
 1539                      'attach_comment'    => $attach_row['attach_comment'],
 1540                  );
 1541   
 1542                  $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $attach_sql) . '
 1543                      WHERE attach_id = ' . $attach_row['attach_id'] . '
 1544                          AND is_orphan = 1
 1545                          AND poster_id = ' . $user->data['user_id'];
 1546                  $db->sql_query($sql);
 1547              }
 1548          }
 1549   
 1550          if ($space_taken && $files_added)
 1551          {
 1552              set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
 1553              set_config('num_files', $config['num_files'] + $files_added, true);
 1554          }
 1555      }
 1556   
 1557      // Delete draft if post was loaded...
 1558      $draft_id = request_var('draft_loaded', 0);
 1559      if ($draft_id)
 1560      {
 1561          $sql = 'DELETE FROM ' . DRAFTS_TABLE . "
 1562              WHERE draft_id = $draft_id
 1563                  AND user_id = " . $data['from_user_id'];
 1564          $db->sql_query($sql);
 1565      }
 1566   
 1567      $db->sql_transaction('commit');
 1568   
 1569      // Send Notifications
 1570      if ($mode != 'edit')
 1571      {
 1572          pm_notification($mode, $data['from_username'], $recipients, $subject, $data['message']);
 1573      }
 1574   
 1575      return $data['msg_id'];
 1576  }
 1577   
 1578  /**
 1579  * PM Notification
 1580  */
 1581  function pm_notification($mode, $author, $recipients, $subject, $message)
 1582  {
 1583      global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
 1584   
 1585      $subject = censor_text($subject);
 1586   
 1587      unset($recipients[ANONYMOUS], $recipients[$user->data['user_id']]);
 1588   
 1589      if (!sizeof($recipients))
 1590      {
 1591          return;
 1592      }
 1593   
 1594      // Get banned User ID's
 1595      $sql = 'SELECT ban_userid
 1596          FROM ' . BANLIST_TABLE . '
 1597          WHERE ' . $db->sql_in_set('ban_userid', array_map('intval', array_keys($recipients))) . '
 1598              AND ban_exclude = 0';
 1599      $result = $db->sql_query($sql);
 1600   
 1601      while ($row = $db->sql_fetchrow($result))
 1602      {
 1603          unset($recipients[$row['ban_userid']]);
 1604      }
 1605      $db->sql_freeresult($result);
 1606   
 1607      if (!sizeof($recipients))
 1608      {
 1609          return;
 1610      }
 1611   
 1612      $sql = 'SELECT user_id, username, user_email, user_lang, user_notify_pm, user_notify_type, user_jabber
 1613          FROM ' . USERS_TABLE . '
 1614          WHERE ' . $db->sql_in_set('user_id', array_map('intval', array_keys($recipients)));
 1615      $result = $db->sql_query($sql);
 1616   
 1617      $msg_list_ary = array();
 1618      while ($row = $db->sql_fetchrow($result))
 1619      {
 1620          if ($row['user_notify_pm'] == 1 && trim($row['user_email']))
 1621          {
 1622              $msg_list_ary[] = array(
 1623                  'method'    => $row['user_notify_type'],
 1624                  'email'        => $row['user_email'],
 1625                  'jabber'    => $row['user_jabber'],
 1626                  'name'        => $row['username'],
 1627                  'lang'        => $row['user_lang']
 1628              );
 1629          }
 1630      }
 1631      $db->sql_freeresult($result);
 1632   
 1633      if (!sizeof($msg_list_ary))
 1634      {
 1635          return;
 1636      }
 1637   
 1638      include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
 1639      $messenger = new messenger();
 1640   
 1641      foreach ($msg_list_ary as $pos => $addr)
 1642      {
 1643          $messenger->template('privmsg_notify', $addr['lang']);
 1644   
 1645          $messenger->to($addr['email'], $addr['name']);
 1646          $messenger->im($addr['jabber'], $addr['name']);
 1647   
 1648          $messenger->assign_vars(array(
 1649              'SUBJECT'        => htmlspecialchars_decode($subject),
 1650              'AUTHOR_NAME'    => htmlspecialchars_decode($author),
 1651              'USERNAME'        => htmlspecialchars_decode($addr['name']),
 1652   
 1653              'U_INBOX'        => generate_board_url() . "/ucp.$phpEx?i=pm&folder=inbox")
 1654          );
 1655   
 1656          $messenger->send($addr['method']);
 1657      }
 1658      unset($msg_list_ary);
 1659   
 1660      $messenger->save_queue();
 1661   
 1662      unset($messenger);
 1663  }
 1664   
 1665  /**
 1666  * Display Message History
 1667  */
 1668  function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode = false)
 1669  {
 1670      global $db, $user, $config, $template, $phpbb_root_path, $phpEx, $auth, $bbcode;
 1671   
 1672      // Get History Messages (could be newer)
 1673      $sql = 'SELECT t.*, p.*, u.*
 1674          FROM ' . PRIVMSGS_TABLE . ' p, ' . PRIVMSGS_TO_TABLE . ' t, ' . USERS_TABLE . ' u
 1675          WHERE t.msg_id = p.msg_id
 1676              AND p.author_id = u.user_id
 1677              AND t.folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ")
 1678              AND t.user_id = $user_id";
 1679   
 1680      if (!$message_row['root_level'])
 1681      {
 1682          $sql .= " AND (p.root_level = $msg_id OR (p.root_level = 0 AND p.msg_id = $msg_id))";
 1683      }
 1684      else
 1685      {
 1686          $sql .= " AND (p.root_level = " . $message_row['root_level'] . ' OR p.msg_id = ' . $message_row['root_level'] . ')';
 1687      }
 1688      $sql .= ' ORDER BY p.message_time DESC';
 1689   
 1690      $result = $db->sql_query($sql);
 1691      $row = $db->sql_fetchrow($result);
 1692   
 1693      if (!$row)
 1694      {
 1695          $db->sql_freeresult($result);
 1696          return false;
 1697      }
 1698   
 1699      $rowset = array();
 1700      $bbcode_bitfield = '';
 1701      $folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm') . '&amp;folder=';
 1702   
 1703      do
 1704      {
 1705          $folder_id = (int) $row['folder_id'];
 1706   
 1707          $row['folder'][] = (isset($folder[$folder_id])) ? '<a href="' . $folder_url . $folder_id . '">' . $folder[$folder_id]['folder_name'] . '</a>' : $user->lang['UNKNOWN_FOLDER'];
 1708   
 1709          if (isset($rowset[$row['msg_id']]))
 1710          {
 1711              $rowset[$row['msg_id']]['folder'][] = (isset($folder[$folder_id])) ? '<a href="' . $folder_url . $folder_id . '">' . $folder[$folder_id]['folder_name'] . '</a>' : $user->lang['UNKNOWN_FOLDER'];
 1712          }
 1713          else
 1714          {
 1715              $rowset[$row['msg_id']] = $row;
 1716              $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
 1717          }
 1718      }
 1719      while ($row = $db->sql_fetchrow($result));
 1720      $db->sql_freeresult($result);
 1721   
 1722      $title = $row['message_subject'];
 1723   
 1724      if (sizeof($rowset) == 1 && !$in_post_mode)
 1725      {
 1726          return false;
 1727      }
 1728   
 1729      // Instantiate BBCode class
 1730      if ((empty($bbcode) || $bbcode === false) && $bbcode_bitfield !== '')
 1731      {
 1732          if (!class_exists('bbcode'))
 1733          {
 1734              include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
 1735          }
 1736          $bbcode = new bbcode(base64_encode($bbcode_bitfield));
 1737      }
 1738   
 1739      $title = censor_text($title);
 1740   
 1741      $url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm');
 1742      $next_history_pm = $previous_history_pm = $prev_id = 0;
 1743   
 1744      foreach ($rowset as $id => $row)
 1745      {
 1746          $author_id    = $row['author_id'];
 1747          $folder_id    = (int) $row['folder_id'];
 1748   
 1749          $subject    = $row['message_subject'];
 1750          $message    = $row['message_text'];
 1751   
 1752          $message = censor_text($message);
 1753   
 1754          if ($row['bbcode_bitfield'])
 1755          {
 1756              $bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
 1757          }
 1758   
 1759          $message = bbcode_nl2br($message);
 1760          $message = smiley_text($message, !$row['enable_smilies']);
 1761   
 1762          $subject = censor_text($subject);
 1763   
 1764          if ($id == $msg_id)
 1765          {
 1766              $next_history_pm = next($rowset);
 1767              $next_history_pm = (sizeof($next_history_pm)) ? (int) $next_history_pm['msg_id'] : 0;
 1768              $previous_history_pm = $prev_id;
 1769          }
 1770   
 1771          $template->assign_block_vars('history_row', array(
 1772              'MESSAGE_AUTHOR_FULL'        => get_username_string('full', $author_id, $row['username'], $row['user_colour'], $row['username']),
 1773              'MESSAGE_AUTHOR_COLOUR'        => get_username_string('colour', $author_id, $row['username'], $row['user_colour'], $row['username']),
 1774              'MESSAGE_AUTHOR'            => get_username_string('username', $author_id, $row['username'], $row['user_colour'], $row['username']),
 1775              'U_MESSAGE_AUTHOR'            => get_username_string('profile', $author_id, $row['username'], $row['user_colour'], $row['username']),
 1776   
 1777              'SUBJECT'        => $subject,
 1778              'SENT_DATE'        => $user->format_date($row['message_time']),
 1779              'MESSAGE'        => $message,
 1780              'FOLDER'        => implode(', ', $row['folder']),
 1781   
 1782              'S_CURRENT_MSG'        => ($row['msg_id'] == $msg_id),
 1783              'S_AUTHOR_DELETED'    => ($author_id == ANONYMOUS) ? true : false,
 1784              'S_IN_POST_MODE'    => $in_post_mode,
 1785   
 1786              'MSG_ID'            => $row['msg_id'],
 1787              'U_VIEW_MESSAGE'    => "$url&amp;f=$folder_id&amp;p=" . $row['msg_id'],
 1788              'U_QUOTE'            => (!$in_post_mode && $auth->acl_get('u_sendpm') && $author_id != ANONYMOUS && $author_id != $user->data['user_id']) ? "$url&amp;mode=compose&amp;action=quote&amp;f=" . $folder_id . "&amp;p=" . $row['msg_id'] : '',
 1789              'U_POST_REPLY_PM'    => ($author_id != $user->data['user_id'] && $author_id != ANONYMOUS && $auth->acl_get('u_sendpm')) ? "$url&amp;mode=compose&amp;action=reply&amp;f=$folder_id&amp;p=" . $row['msg_id'] : '')
 1790          );
 1791          unset($rowset[$id]);
 1792          $prev_id = $id;
 1793      }
 1794   
 1795      $template->assign_vars(array(
 1796          'QUOTE_IMG'            => $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE']),
 1797          'HISTORY_TITLE'        => $title,
 1798   
 1799          'U_VIEW_NEXT_HISTORY'        => ($next_history_pm) ? "$url&amp;p=" . $next_history_pm : '',
 1800          'U_VIEW_PREVIOUS_HISTORY'    => ($previous_history_pm) ? "$url&amp;p=" . $previous_history_pm : '',
 1801      ));
 1802   
 1803      return true;
 1804  }
 1805   
 1806  ?>