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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
functions_privmsgs.php
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&folder=' . $f_id) : append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&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&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&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&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&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') . '&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&f=$folder_id&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&mode=compose&action=quote&f=" . $folder_id . "&p=" . $row['msg_id'] : '',
1789 'U_POST_REPLY_PM' => ($author_id != $user->data['user_id'] && $author_id != ANONYMOUS && $auth->acl_get('u_sendpm')) ? "$url&mode=compose&action=reply&f=$folder_id&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&p=" . $next_history_pm : '',
1800 'U_VIEW_PREVIOUS_HISTORY' => ($previous_history_pm) ? "$url&p=" . $previous_history_pm : '',
1801 ));
1802
1803 return true;
1804 }
1805
1806 ?>