Blame Identity/Models/Html/phpBB/3.0.4/includes/functions_privmsgs.php

d6e8d8
d6e8d8
/**
d6e8d8
*
d6e8d8
* @package phpBB3
d6e8d8
* @version $Id: functions_privmsgs.php 8993 2008-10-10 17:38:17Z toonarmy $
d6e8d8
* @copyright (c) 2005 phpBB Group
d6e8d8
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
d6e8d8
*
d6e8d8
*/
d6e8d8
d6e8d8
/**
d6e8d8
*/
d6e8d8
if (!defined('IN_PHPBB'))
d6e8d8
{
d6e8d8
	exit;
d6e8d8
}
d6e8d8
d6e8d8
/*
d6e8d8
	Ability to simply add own rules by doing three things:
d6e8d8
		1) Add an appropriate constant
d6e8d8
		2) Add a new check array to the global_privmsgs_rules variable and the condition array (if one is required)
d6e8d8
		3) Add a new language variable to ucp.php
d6e8d8
d6e8d8
		The user is then able to select the new rule. It will be checked against and handled as specified.
d6e8d8
		To add new actions (yes, checks can be added here too) to the rule management, the core code has to be modified.
d6e8d8
*/
d6e8d8
d6e8d8
define('RULE_IS_LIKE', 1);		// Is Like
d6e8d8
define('RULE_IS_NOT_LIKE', 2);	// Is Not Like
d6e8d8
define('RULE_IS', 3);			// Is
d6e8d8
define('RULE_IS_NOT', 4);		// Is Not
d6e8d8
define('RULE_BEGINS_WITH', 5);	// Begins with
d6e8d8
define('RULE_ENDS_WITH', 6);	// Ends with
d6e8d8
define('RULE_IS_FRIEND', 7);	// Is Friend
d6e8d8
define('RULE_IS_FOE', 8);		// Is Foe
d6e8d8
define('RULE_IS_USER', 9);		// Is User
d6e8d8
define('RULE_IS_GROUP', 10);	// Is In Usergroup
d6e8d8
define('RULE_ANSWERED', 11);	// Answered
d6e8d8
define('RULE_FORWARDED', 12);	// Forwarded
d6e8d8
define('RULE_TO_GROUP', 14);	// Usergroup
d6e8d8
define('RULE_TO_ME', 15);		// Me
d6e8d8
d6e8d8
define('ACTION_PLACE_INTO_FOLDER', 1);
d6e8d8
define('ACTION_MARK_AS_READ', 2);
d6e8d8
define('ACTION_MARK_AS_IMPORTANT', 3);
d6e8d8
define('ACTION_DELETE_MESSAGE', 4);
d6e8d8
d6e8d8
define('CHECK_SUBJECT', 1);
d6e8d8
define('CHECK_SENDER', 2);
d6e8d8
define('CHECK_MESSAGE', 3);
d6e8d8
define('CHECK_STATUS', 4);
d6e8d8
define('CHECK_TO', 5);
d6e8d8
d6e8d8
/**
d6e8d8
* Global private message rules
d6e8d8
* These rules define what to do if a rule is hit
d6e8d8
*/
d6e8d8
$global_privmsgs_rules = array(
d6e8d8
	CHECK_SUBJECT	=> array(
d6e8d8
		RULE_IS_LIKE		=> array('check0' => 'message_subject', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
d6e8d8
		RULE_IS_NOT_LIKE	=> array('check0' => 'message_subject', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
d6e8d8
		RULE_IS				=> array('check0' => 'message_subject', 'function' => '{CHECK0} == {STRING}'),
d6e8d8
		RULE_IS_NOT			=> array('check0' => 'message_subject', 'function' => '{CHECK0} != {STRING}'),
d6e8d8
		RULE_BEGINS_WITH	=> array('check0' => 'message_subject', 'function' => 'preg_match("/^" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
d6e8d8
		RULE_ENDS_WITH		=> array('check0' => 'message_subject', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "$/i", {CHECK0})'),
d6e8d8
	),
d6e8d8
d6e8d8
	CHECK_SENDER	=> array(
d6e8d8
		RULE_IS_LIKE		=> array('check0' => 'username', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
d6e8d8
		RULE_IS_NOT_LIKE	=> array('check0' => 'username', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
d6e8d8
		RULE_IS				=> array('check0' => 'username', 'function' => '{CHECK0} == {STRING}'),
d6e8d8
		RULE_IS_NOT			=> array('check0' => 'username', 'function' => '{CHECK0} != {STRING}'),
d6e8d8
		RULE_BEGINS_WITH	=> array('check0' => 'username', 'function' => 'preg_match("/^" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
d6e8d8
		RULE_ENDS_WITH		=> array('check0' => 'username', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "$/i", {CHECK0})'),
d6e8d8
		RULE_IS_FRIEND		=> array('check0' => 'friend', 'function' => '{CHECK0} == 1'),
d6e8d8
		RULE_IS_FOE			=> array('check0' => 'foe', 'function' => '{CHECK0} == 1'),
d6e8d8
		RULE_IS_USER		=> array('check0' => 'author_id', 'function' => '{CHECK0} == {USER_ID}'),
d6e8d8
		RULE_IS_GROUP		=> array('check0' => 'author_in_group', 'function' => 'in_array({GROUP_ID}, {CHECK0})'),
d6e8d8
	),
d6e8d8
d6e8d8
	CHECK_MESSAGE	=> array(
d6e8d8
		RULE_IS_LIKE		=> array('check0' => 'message_text', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
d6e8d8
		RULE_IS_NOT_LIKE	=> array('check0' => 'message_text', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
d6e8d8
		RULE_IS				=> array('check0' => 'message_text', 'function' => '{CHECK0} == {STRING}'),
d6e8d8
		RULE_IS_NOT			=> array('check0' => 'message_text', 'function' => '{CHECK0} != {STRING}'),
d6e8d8
	),
d6e8d8
d6e8d8
	CHECK_STATUS	=> array(
d6e8d8
		RULE_ANSWERED		=> array('check0' => 'pm_replied', 'function' => '{CHECK0} == 1'),
d6e8d8
		RULE_FORWARDED		=> array('check0' => 'pm_forwarded', 'function' => '{CHECK0} == 1'),
d6e8d8
	),
d6e8d8
d6e8d8
	CHECK_TO		=> array(
d6e8d8
		RULE_TO_GROUP		=> array('check0' => 'to', 'check1' => 'bcc', 'check2' => 'user_in_group', 'function' => 'in_array("g_" . {CHECK2}, {CHECK0}) || in_array("g_" . {CHECK2}, {CHECK1})'),
d6e8d8
		RULE_TO_ME			=> array('check0' => 'to', 'check1' => 'bcc', 'function' => 'in_array("u_" . $user_id, {CHECK0}) || in_array("u_" . $user_id, {CHECK1})'),
d6e8d8
	)
d6e8d8
);
d6e8d8
d6e8d8
/**
d6e8d8
* This is for defining which condition fields to show for which Rule
d6e8d8
*/
d6e8d8
$global_rule_conditions = array(
d6e8d8
	RULE_IS_LIKE		=> 'text',
d6e8d8
	RULE_IS_NOT_LIKE	=> 'text',
d6e8d8
	RULE_IS				=> 'text',
d6e8d8
	RULE_IS_NOT			=> 'text',
d6e8d8
	RULE_BEGINS_WITH	=> 'text',
d6e8d8
	RULE_ENDS_WITH		=> 'text',
d6e8d8
	RULE_IS_USER		=> 'user',
d6e8d8
	RULE_IS_GROUP		=> 'group'
d6e8d8
);
d6e8d8
d6e8d8
/**
d6e8d8
* Get all folder
d6e8d8
*/
d6e8d8
function get_folder($user_id, $folder_id = false)
d6e8d8
{
d6e8d8
	global $db, $user, $template;
d6e8d8
	global $phpbb_root_path, $phpEx;
d6e8d8
d6e8d8
	$folder = array();
d6e8d8
d6e8d8
	// Get folder information
d6e8d8
	$sql = 'SELECT folder_id, COUNT(msg_id) as num_messages, SUM(pm_unread) as num_unread
d6e8d8
		FROM ' . PRIVMSGS_TO_TABLE . "
d6e8d8
		WHERE user_id = $user_id
d6e8d8
			AND folder_id <> " . PRIVMSGS_NO_BOX . '
d6e8d8
		GROUP BY folder_id';
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
d6e8d8
	$num_messages = $num_unread = array();
d6e8d8
	while ($row = $db->sql_fetchrow($result))
d6e8d8
	{
d6e8d8
		$num_messages[(int) $row['folder_id']] = $row['num_messages'];
d6e8d8
		$num_unread[(int) $row['folder_id']] = $row['num_unread'];
d6e8d8
	}
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	// Make sure the default boxes are defined
d6e8d8
	$available_folder = array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX);
d6e8d8
d6e8d8
	foreach ($available_folder as $default_folder)
d6e8d8
	{
d6e8d8
		if (!isset($num_messages[$default_folder]))
d6e8d8
		{
d6e8d8
			$num_messages[$default_folder] = 0;
d6e8d8
		}
d6e8d8
d6e8d8
		if (!isset($num_unread[$default_folder]))
d6e8d8
		{
d6e8d8
			$num_unread[$default_folder] = 0;
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	// Adjust unread status for outbox
d6e8d8
	$num_unread[PRIVMSGS_OUTBOX] = $num_messages[PRIVMSGS_OUTBOX];
d6e8d8
d6e8d8
	$folder[PRIVMSGS_INBOX] = array(
d6e8d8
		'folder_name'		=> $user->lang['PM_INBOX'],
d6e8d8
		'num_messages'		=> $num_messages[PRIVMSGS_INBOX],
d6e8d8
		'unread_messages'	=> $num_unread[PRIVMSGS_INBOX]
d6e8d8
	);
d6e8d8
d6e8d8
	// Custom Folder
d6e8d8
	$sql = 'SELECT folder_id, folder_name, pm_count
d6e8d8
		FROM ' . PRIVMSGS_FOLDER_TABLE . "
d6e8d8
			WHERE user_id = $user_id";
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
d6e8d8
	while ($row = $db->sql_fetchrow($result))
d6e8d8
	{
d6e8d8
		$folder[$row['folder_id']] = array(
d6e8d8
			'folder_name'		=> $row['folder_name'],
d6e8d8
			'num_messages'		=> $row['pm_count'],
d6e8d8
			'unread_messages'	=> ((isset($num_unread[$row['folder_id']])) ? $num_unread[$row['folder_id']] : 0)
d6e8d8
		);
d6e8d8
	}
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	$folder[PRIVMSGS_OUTBOX] = array(
d6e8d8
		'folder_name'		=> $user->lang['PM_OUTBOX'],
d6e8d8
		'num_messages'		=> $num_messages[PRIVMSGS_OUTBOX],
d6e8d8
		'unread_messages'	=> $num_unread[PRIVMSGS_OUTBOX]
d6e8d8
	);
d6e8d8
d6e8d8
	$folder[PRIVMSGS_SENTBOX] = array(
d6e8d8
		'folder_name'		=> $user->lang['PM_SENTBOX'],
d6e8d8
		'num_messages'		=> $num_messages[PRIVMSGS_SENTBOX],
d6e8d8
		'unread_messages'	=> $num_unread[PRIVMSGS_SENTBOX]
d6e8d8
	);
d6e8d8
d6e8d8
	// Define Folder Array for template designers (and for making custom folders usable by the template too)
d6e8d8
	foreach ($folder as $f_id => $folder_ary)
d6e8d8
	{
d6e8d8
		$folder_id_name = ($f_id == PRIVMSGS_INBOX) ? 'inbox' : (($f_id == PRIVMSGS_OUTBOX) ? 'outbox' : 'sentbox');
d6e8d8
d6e8d8
		$template->assign_block_vars('folder', array(
d6e8d8
			'FOLDER_ID'			=> $f_id,
d6e8d8
			'FOLDER_NAME'		=> $folder_ary['folder_name'],
d6e8d8
			'NUM_MESSAGES'		=> $folder_ary['num_messages'],
d6e8d8
			'UNREAD_MESSAGES'	=> $folder_ary['unread_messages'],
d6e8d8
d6e8d8
			'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),
d6e8d8
d6e8d8
			'S_CUR_FOLDER'		=> ($f_id === $folder_id) ? true : false,
d6e8d8
			'S_UNREAD_MESSAGES'	=> ($folder_ary['unread_messages']) ? true : false,
d6e8d8
			'S_CUSTOM_FOLDER'	=> ($f_id > 0) ? true : false)
d6e8d8
		);
d6e8d8
	}
d6e8d8
d6e8d8
	if ($folder_id !== false && !isset($folder[$folder_id]))
d6e8d8
	{
d6e8d8
		trigger_error('UNKNOWN_FOLDER');
d6e8d8
	}
d6e8d8
d6e8d8
	return $folder;
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Delete Messages From Sentbox
d6e8d8
* we are doing this here because this saves us a bunch of checks and queries
d6e8d8
*/
d6e8d8
function clean_sentbox($num_sentbox_messages)
d6e8d8
{
d6e8d8
	global $db, $user, $config;
d6e8d8
d6e8d8
	// Check Message Limit
d6e8d8
	if ($user->data['message_limit'] && $num_sentbox_messages > $user->data['message_limit'])
d6e8d8
	{
d6e8d8
		// Delete old messages
d6e8d8
		$sql = 'SELECT t.msg_id
d6e8d8
			FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p
d6e8d8
			WHERE t.msg_id = p.msg_id
d6e8d8
				AND t.user_id = ' . $user->data['user_id'] . '
d6e8d8
				AND t.folder_id = ' . PRIVMSGS_SENTBOX . '
d6e8d8
			ORDER BY p.message_time ASC';
d6e8d8
		$result = $db->sql_query_limit($sql, ($num_sentbox_messages - $user->data['message_limit']));
d6e8d8
d6e8d8
		$delete_ids = array();
d6e8d8
		while ($row = $db->sql_fetchrow($result))
d6e8d8
		{
d6e8d8
			$delete_ids[] = $row['msg_id'];
d6e8d8
		}
d6e8d8
		$db->sql_freeresult($result);
d6e8d8
		delete_pm($user->data['user_id'], $delete_ids, PRIVMSGS_SENTBOX);
d6e8d8
	}
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Check Rule against Message Information
d6e8d8
*/
d6e8d8
function check_rule(&$rules, &$rule_row, &$message_row, $user_id)
d6e8d8
{
d6e8d8
	global $user, $config;
d6e8d8
d6e8d8
	if (!isset($rules[$rule_row['rule_check']][$rule_row['rule_connection']]))
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	$check_ary = $rules[$rule_row['rule_check']][$rule_row['rule_connection']];
d6e8d8
d6e8d8
	// Replace Check Literals
d6e8d8
	$evaluate = $check_ary['function'];
d6e8d8
	$evaluate = preg_replace('/{(CHECK[0-9])}/', '$message_row[$check_ary[strtolower("\1")]]', $evaluate);
d6e8d8
d6e8d8
	// Replace Rule Literals
d6e8d8
	$evaluate = preg_replace('/{(STRING|USER_ID|GROUP_ID)}/', '$rule_row["rule_" . strtolower("\1")]', $evaluate);
d6e8d8
d6e8d8
	// Evil Statement
d6e8d8
	$result = false;
d6e8d8
	eval('$result = (' . $evaluate . ') ? true : false;');
d6e8d8
d6e8d8
	if (!$result)
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	switch ($rule_row['rule_action'])
d6e8d8
	{
d6e8d8
		case ACTION_PLACE_INTO_FOLDER:
d6e8d8
			return array('action' => $rule_row['rule_action'], 'folder_id' => $rule_row['rule_folder_id']);
d6e8d8
		break;
d6e8d8
d6e8d8
		case ACTION_MARK_AS_READ:
d6e8d8
		case ACTION_MARK_AS_IMPORTANT:
d6e8d8
			return array('action' => $rule_row['rule_action'], 'pm_unread' => $message_row['pm_unread'], 'pm_marked' => $message_row['pm_marked']);
d6e8d8
		break;
d6e8d8
d6e8d8
		case ACTION_DELETE_MESSAGE:
d6e8d8
			global $db, $auth;
d6e8d8
d6e8d8
			// Check for admins/mods - users are not allowed to remove those messages...
d6e8d8
			// We do the check here to make sure the data we use is consistent
d6e8d8
			$sql = 'SELECT user_id, user_type, user_permissions
d6e8d8
				FROM ' . USERS_TABLE . '
d6e8d8
				WHERE user_id = ' . (int) $message_row['author_id'];
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
			$userdata = $db->sql_fetchrow($result);
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
d6e8d8
			$auth2 = new auth();
d6e8d8
			$auth2->acl($userdata);
d6e8d8
d6e8d8
			if (!$auth2->acl_get('a_') && !$auth2->acl_get('m_') && !$auth2->acl_getf_global('m_'))
d6e8d8
			{
d6e8d8
				return array('action' => $rule_row['rule_action'], 'pm_unread' => $message_row['pm_unread'], 'pm_marked' => $message_row['pm_marked']);
d6e8d8
			}
d6e8d8
d6e8d8
			return false;
d6e8d8
		break;
d6e8d8
d6e8d8
		default:
d6e8d8
			return false;
d6e8d8
	}
d6e8d8
d6e8d8
	return false;
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Update user PM count
d6e8d8
*/
d6e8d8
function update_pm_counts()
d6e8d8
{
d6e8d8
	global $user, $db;
d6e8d8
d6e8d8
	// Update unread count
d6e8d8
	$sql = 'SELECT COUNT(msg_id) as num_messages
d6e8d8
		FROM ' . PRIVMSGS_TO_TABLE . '
d6e8d8
		WHERE pm_unread = 1
d6e8d8
			AND folder_id <> ' . PRIVMSGS_OUTBOX . '
d6e8d8
			AND user_id = ' . $user->data['user_id'];
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
	$user->data['user_unread_privmsg'] = (int) $db->sql_fetchfield('num_messages');
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	// Update new pm count
d6e8d8
	$sql = 'SELECT COUNT(msg_id) as num_messages
d6e8d8
		FROM ' . PRIVMSGS_TO_TABLE . '
d6e8d8
		WHERE pm_new = 1
d6e8d8
			AND folder_id IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ')
d6e8d8
			AND user_id = ' . $user->data['user_id'];
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
	$user->data['user_new_privmsg'] = (int) $db->sql_fetchfield('num_messages');
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	$db->sql_query('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
d6e8d8
		'user_unread_privmsg'	=> (int) $user->data['user_unread_privmsg'],
d6e8d8
		'user_new_privmsg'		=> (int) $user->data['user_new_privmsg'],
d6e8d8
	)) . ' WHERE user_id = ' . $user->data['user_id']);
d6e8d8
d6e8d8
	// Ok, here we need to repair something, other boxes than privmsgs_no_box and privmsgs_hold_box should not carry the pm_new flag.
d6e8d8
	if (!$user->data['user_new_privmsg'])
d6e8d8
	{
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
d6e8d8
			SET pm_new = 0
d6e8d8
			WHERE pm_new = 1
d6e8d8
				AND folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ')
d6e8d8
				AND user_id = ' . $user->data['user_id'];
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Place new messages into appropriate folder
d6e8d8
*/
d6e8d8
function place_pm_into_folder(&$global_privmsgs_rules, $release = false)
d6e8d8
{
d6e8d8
	global $db, $user, $config;
d6e8d8
d6e8d8
	if (!$user->data['user_new_privmsg'])
d6e8d8
	{
d6e8d8
		return array('not_moved' => 0, 'removed' => 0);
d6e8d8
	}
d6e8d8
d6e8d8
	$user_message_rules = (int) $user->data['user_message_rules'];
d6e8d8
	$user_id = (int) $user->data['user_id'];
d6e8d8
d6e8d8
	$action_ary = $move_into_folder = array();
d6e8d8
	$num_removed = 0;
d6e8d8
d6e8d8
	// Newly processing on-hold messages
d6e8d8
	if ($release)
d6e8d8
	{
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
d6e8d8
			SET folder_id = ' . PRIVMSGS_NO_BOX . '
d6e8d8
			WHERE folder_id = ' . PRIVMSGS_HOLD_BOX . "
d6e8d8
				AND user_id = $user_id";
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
d6e8d8
	// Get those messages not yet placed into any box
d6e8d8
	$retrieve_sql = 'SELECT t.*, p.*, u.username, u.user_id, u.group_id
d6e8d8
		FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . " u
d6e8d8
		WHERE t.user_id = $user_id
d6e8d8
			AND p.author_id = u.user_id
d6e8d8
			AND t.folder_id = " . PRIVMSGS_NO_BOX . '
d6e8d8
			AND t.msg_id = p.msg_id';
d6e8d8
d6e8d8
	// Just place into the appropriate arrays if no rules need to be checked
d6e8d8
	if (!$user_message_rules)
d6e8d8
	{
d6e8d8
		$result = $db->sql_query($retrieve_sql);
d6e8d8
d6e8d8
		while ($row = $db->sql_fetchrow($result))
d6e8d8
		{
d6e8d8
			$action_ary[$row['msg_id']][] = array('action' => false);
d6e8d8
		}
d6e8d8
		$db->sql_freeresult($result);
d6e8d8
	}
d6e8d8
	else
d6e8d8
	{
d6e8d8
		$user_rules = $zebra = $check_rows = array();
d6e8d8
		$user_ids = $memberships = array();
d6e8d8
d6e8d8
		// First of all, grab all rules and retrieve friends/foes
d6e8d8
		$sql = 'SELECT *
d6e8d8
			FROM ' . PRIVMSGS_RULES_TABLE . "
d6e8d8
			WHERE user_id = $user_id";
d6e8d8
		$result = $db->sql_query($sql);
d6e8d8
		$user_rules = $db->sql_fetchrowset($result);
d6e8d8
		$db->sql_freeresult($result);
d6e8d8
d6e8d8
		if (sizeof($user_rules))
d6e8d8
		{
d6e8d8
			$sql = 'SELECT zebra_id, friend, foe
d6e8d8
				FROM ' . ZEBRA_TABLE . "
d6e8d8
				WHERE user_id = $user_id";
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
d6e8d8
			while ($row = $db->sql_fetchrow($result))
d6e8d8
			{
d6e8d8
				$zebra[$row['zebra_id']] = $row;
d6e8d8
			}
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
		}
d6e8d8
d6e8d8
		// Now build a bare-bone check_row array
d6e8d8
		$result = $db->sql_query($retrieve_sql);
d6e8d8
d6e8d8
		while ($row = $db->sql_fetchrow($result))
d6e8d8
		{
d6e8d8
			$check_rows[] = array_merge($row, array(
d6e8d8
				'to'				=> explode(':', $row['to_address']),
d6e8d8
				'bcc'				=> explode(':', $row['bcc_address']),
d6e8d8
				'friend'			=> (isset($zebra[$row['author_id']])) ? $zebra[$row['author_id']]['friend'] : 0,
d6e8d8
				'foe'				=> (isset($zebra[$row['author_id']])) ? $zebra[$row['author_id']]['foe'] : 0,
d6e8d8
				'user_in_group'		=> array($user->data['group_id']),
d6e8d8
				'author_in_group'	=> array())
d6e8d8
			);
d6e8d8
d6e8d8
			$user_ids[] = $row['user_id'];
d6e8d8
		}
d6e8d8
		$db->sql_freeresult($result);
d6e8d8
d6e8d8
		// Retrieve user memberships
d6e8d8
		if (sizeof($user_ids))
d6e8d8
		{
d6e8d8
			$sql = 'SELECT *
d6e8d8
				FROM ' . USER_GROUP_TABLE . '
d6e8d8
				WHERE ' . $db->sql_in_set('user_id', $user_ids) . '
d6e8d8
					AND user_pending = 0';
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
d6e8d8
			while ($row = $db->sql_fetchrow($result))
d6e8d8
			{
d6e8d8
				$memberships[$row['user_id']][] = $row['group_id'];
d6e8d8
			}
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
		}
d6e8d8
d6e8d8
		// Now place into the appropriate folder
d6e8d8
		foreach ($check_rows as $row)
d6e8d8
		{
d6e8d8
			// Add membership if set
d6e8d8
			if (isset($memberships[$row['author_id']]))
d6e8d8
			{
d6e8d8
				$row['author_in_group'] = $memberships[$row['user_id']];
d6e8d8
			}
d6e8d8
d6e8d8
			// Check Rule - this should be very quick since we have all information we need
d6e8d8
			$is_match = false;
d6e8d8
			foreach ($user_rules as $rule_row)
d6e8d8
			{
d6e8d8
				if (($action = check_rule($global_privmsgs_rules, $rule_row, $row, $user_id)) !== false)
d6e8d8
				{
d6e8d8
					$is_match = true;
d6e8d8
					$action_ary[$row['msg_id']][] = $action;
d6e8d8
				}
d6e8d8
			}
d6e8d8
d6e8d8
			if (!$is_match)
d6e8d8
			{
d6e8d8
				$action_ary[$row['msg_id']][] = array('action' => false);
d6e8d8
			}
d6e8d8
		}
d6e8d8
d6e8d8
		unset($user_rules, $zebra, $check_rows, $user_ids, $memberships);
d6e8d8
	}
d6e8d8
d6e8d8
	// We place actions into arrays, to save queries.
d6e8d8
	$sql = $unread_ids = $delete_ids = $important_ids = array();
d6e8d8
d6e8d8
	foreach ($action_ary as $msg_id => $msg_ary)
d6e8d8
	{
d6e8d8
		// It is allowed to execute actions more than once, except placing messages into folder
d6e8d8
		$folder_action = $message_removed = false;
d6e8d8
d6e8d8
		foreach ($msg_ary as $pos => $rule_ary)
d6e8d8
		{
d6e8d8
			if ($folder_action && $rule_ary['action'] == ACTION_PLACE_INTO_FOLDER)
d6e8d8
			{
d6e8d8
				continue;
d6e8d8
			}
d6e8d8
d6e8d8
			switch ($rule_ary['action'])
d6e8d8
			{
d6e8d8
				case ACTION_PLACE_INTO_FOLDER:
d6e8d8
					// Folder actions have precedence, so we will remove any other ones
d6e8d8
					$folder_action = true;
d6e8d8
					$move_into_folder[(int) $rule_ary['folder_id']][] = $msg_id;
d6e8d8
				break;
d6e8d8
d6e8d8
				case ACTION_MARK_AS_READ:
d6e8d8
					if ($rule_ary['pm_unread'])
d6e8d8
					{
d6e8d8
						$unread_ids[] = $msg_id;
d6e8d8
					}
d6e8d8
				break;
d6e8d8
d6e8d8
				case ACTION_DELETE_MESSAGE:
d6e8d8
					$delete_ids[] = $msg_id;
d6e8d8
					$message_removed = true;
d6e8d8
				break;
d6e8d8
d6e8d8
				case ACTION_MARK_AS_IMPORTANT:
d6e8d8
					if (!$rule_ary['pm_marked'])
d6e8d8
					{
d6e8d8
						$important_ids[] = $msg_id;
d6e8d8
					}
d6e8d8
				break;
d6e8d8
			}
d6e8d8
		}
d6e8d8
d6e8d8
		// 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
d6e8d8
		// folder. Here we simply move the message into the INBOX if it gets not removed and also not put into a custom folder.
d6e8d8
		if (!$folder_action && !$message_removed)
d6e8d8
		{
d6e8d8
			$move_into_folder[PRIVMSGS_INBOX][] = $msg_id;
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	// Do not change the order of processing
d6e8d8
	// The number of queries needed to be executed here highly depends on the defined rules and are
d6e8d8
	// only gone through if new messages arrive.
d6e8d8
d6e8d8
	// Delete messages
d6e8d8
	if (sizeof($delete_ids))
d6e8d8
	{
d6e8d8
		$num_removed += sizeof($delete_ids);
d6e8d8
		delete_pm($user_id, $delete_ids, PRIVMSGS_NO_BOX);
d6e8d8
	}
d6e8d8
d6e8d8
	// Set messages to Unread
d6e8d8
	if (sizeof($unread_ids))
d6e8d8
	{
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
d6e8d8
			SET pm_unread = 0
d6e8d8
			WHERE ' . $db->sql_in_set('msg_id', $unread_ids) . "
d6e8d8
				AND user_id = $user_id
d6e8d8
				AND folder_id = " . PRIVMSGS_NO_BOX;
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
d6e8d8
	// mark messages as important
d6e8d8
	if (sizeof($important_ids))
d6e8d8
	{
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
d6e8d8
			SET pm_marked = 1 - pm_marked
d6e8d8
			WHERE folder_id = ' . PRIVMSGS_NO_BOX . "
d6e8d8
				AND user_id = $user_id
d6e8d8
				AND " . $db->sql_in_set('msg_id', $important_ids);
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
d6e8d8
	// Move into folder
d6e8d8
	$folder = array();
d6e8d8
d6e8d8
	if (sizeof($move_into_folder))
d6e8d8
	{
d6e8d8
		// Determine Full Folder Action - we need the move to folder id later eventually
d6e8d8
		$full_folder_action = ($user->data['user_full_folder'] == FULL_FOLDER_NONE) ? ($config['full_folder_action'] - (FULL_FOLDER_NONE*(-1))) : $user->data['user_full_folder'];
d6e8d8
d6e8d8
		$sql_folder = array_keys($move_into_folder);
d6e8d8
		if ($full_folder_action >= 0)
d6e8d8
		{
d6e8d8
			$sql_folder[] = $full_folder_action;
d6e8d8
		}
d6e8d8
d6e8d8
		$sql = 'SELECT folder_id, pm_count
d6e8d8
			FROM ' . PRIVMSGS_FOLDER_TABLE . '
d6e8d8
			WHERE ' . $db->sql_in_set('folder_id', $sql_folder) . "
d6e8d8
				AND user_id = $user_id";
d6e8d8
		$result = $db->sql_query($sql);
d6e8d8
d6e8d8
		while ($row = $db->sql_fetchrow($result))
d6e8d8
		{
d6e8d8
			$folder[(int) $row['folder_id']] = (int) $row['pm_count'];
d6e8d8
		}
d6e8d8
		$db->sql_freeresult($result);
d6e8d8
d6e8d8
		unset($sql_folder);
d6e8d8
d6e8d8
		if (isset($move_into_folder[PRIVMSGS_INBOX]))
d6e8d8
		{
d6e8d8
			$sql = 'SELECT COUNT(msg_id) as num_messages
d6e8d8
				FROM ' . PRIVMSGS_TO_TABLE . "
d6e8d8
				WHERE user_id = $user_id
d6e8d8
					AND folder_id = " . PRIVMSGS_INBOX;
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
			$folder[PRIVMSGS_INBOX] = (int) $db->sql_fetchfield('num_messages');
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	// Here we have ideally only one folder to move into
d6e8d8
	foreach ($move_into_folder as $folder_id => $msg_ary)
d6e8d8
	{
d6e8d8
		$dest_folder = $folder_id;
d6e8d8
		$full_folder_action = FULL_FOLDER_NONE;
d6e8d8
d6e8d8
		// Check Message Limit - we calculate with the complete array, most of the time it is one message
d6e8d8
		// But we are making sure that the other way around works too (more messages in queue than allowed to be stored)
d6e8d8
		if ($user->data['message_limit'] && $folder[$folder_id] && ($folder[$folder_id] + sizeof($msg_ary)) > $user->data['message_limit'])
d6e8d8
		{
d6e8d8
			$full_folder_action = ($user->data['user_full_folder'] == FULL_FOLDER_NONE) ? ($config['full_folder_action'] - (FULL_FOLDER_NONE*(-1))) : $user->data['user_full_folder'];
d6e8d8
d6e8d8
			// If destination folder itself is full...
d6e8d8
			if ($full_folder_action >= 0 && ($folder[$full_folder_action] + sizeof($msg_ary)) > $user->data['message_limit'])
d6e8d8
			{
d6e8d8
				$full_folder_action = $config['full_folder_action'] - (FULL_FOLDER_NONE*(-1));
d6e8d8
			}
d6e8d8
d6e8d8
			// If Full Folder Action is to move to another folder, we simply adjust the destination folder
d6e8d8
			if ($full_folder_action >= 0)
d6e8d8
			{
d6e8d8
				$dest_folder = $full_folder_action;
d6e8d8
			}
d6e8d8
			else if ($full_folder_action == FULL_FOLDER_DELETE)
d6e8d8
			{
d6e8d8
				// Delete some messages. NOTE: Ordered by msg_id here instead of message_time!
d6e8d8
				$sql = 'SELECT msg_id
d6e8d8
					FROM ' . PRIVMSGS_TO_TABLE . "
d6e8d8
					WHERE user_id = $user_id
d6e8d8
						AND folder_id = $dest_folder
d6e8d8
					ORDER BY msg_id ASC";
d6e8d8
				$result = $db->sql_query_limit($sql, (($folder[$dest_folder] + sizeof($msg_ary)) - $user->data['message_limit']));
d6e8d8
d6e8d8
				$delete_ids = array();
d6e8d8
				while ($row = $db->sql_fetchrow($result))
d6e8d8
				{
d6e8d8
					$delete_ids[] = $row['msg_id'];
d6e8d8
				}
d6e8d8
				$db->sql_freeresult($result);
d6e8d8
d6e8d8
				$num_removed += sizeof($delete_ids);
d6e8d8
				delete_pm($user_id, $delete_ids, $dest_folder);
d6e8d8
			}
d6e8d8
		}
d6e8d8
d6e8d8
		//
d6e8d8
		if ($full_folder_action == FULL_FOLDER_HOLD)
d6e8d8
		{
d6e8d8
			$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
d6e8d8
				SET folder_id = ' . PRIVMSGS_HOLD_BOX . '
d6e8d8
				WHERE folder_id = ' . PRIVMSGS_NO_BOX . "
d6e8d8
					AND user_id = $user_id
d6e8d8
					AND " . $db->sql_in_set('msg_id', $msg_ary);
d6e8d8
			$db->sql_query($sql);
d6e8d8
		}
d6e8d8
		else
d6e8d8
		{
d6e8d8
			$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
d6e8d8
				SET folder_id = $dest_folder, pm_new = 0
d6e8d8
				WHERE folder_id = " . PRIVMSGS_NO_BOX . "
d6e8d8
					AND user_id = $user_id
d6e8d8
					AND pm_new = 1
d6e8d8
					AND " . $db->sql_in_set('msg_id', $msg_ary);
d6e8d8
			$db->sql_query($sql);
d6e8d8
d6e8d8
			if ($dest_folder != PRIVMSGS_INBOX)
d6e8d8
			{
d6e8d8
				$sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . '
d6e8d8
					SET pm_count = pm_count + ' . (int) $db->sql_affectedrows() . "
d6e8d8
					WHERE folder_id = $dest_folder
d6e8d8
						AND user_id = $user_id";
d6e8d8
				$db->sql_query($sql);
d6e8d8
			}
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	if (sizeof($action_ary))
d6e8d8
	{
d6e8d8
		// Move from OUTBOX to SENTBOX
d6e8d8
		// We are not checking any full folder status here... SENTBOX is a special treatment (old messages get deleted)
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
d6e8d8
			SET folder_id = ' . PRIVMSGS_SENTBOX . '
d6e8d8
			WHERE folder_id = ' . PRIVMSGS_OUTBOX . '
d6e8d8
				AND ' . $db->sql_in_set('msg_id', array_keys($action_ary));
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
d6e8d8
	// Update new/unread count
d6e8d8
	update_pm_counts();
d6e8d8
d6e8d8
	// Now check how many messages got not moved...
d6e8d8
	$sql = 'SELECT COUNT(msg_id) as num_messages
d6e8d8
		FROM ' . PRIVMSGS_TO_TABLE . "
d6e8d8
		WHERE user_id = $user_id
d6e8d8
			AND folder_id = " . PRIVMSGS_HOLD_BOX;
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
	$num_not_moved = (int) $db->sql_fetchfield('num_messages');
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	return array('not_moved' => $num_not_moved, 'removed' => $num_removed);
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Move PM from one to another folder
d6e8d8
*/
d6e8d8
function move_pm($user_id, $message_limit, $move_msg_ids, $dest_folder, $cur_folder_id)
d6e8d8
{
d6e8d8
	global $db, $user;
d6e8d8
	global $phpbb_root_path, $phpEx;
d6e8d8
d6e8d8
	$num_moved = 0;
d6e8d8
d6e8d8
	if (!is_array($move_msg_ids))
d6e8d8
	{
d6e8d8
		$move_msg_ids = array($move_msg_ids);
d6e8d8
	}
d6e8d8
d6e8d8
	if (sizeof($move_msg_ids) && !in_array($dest_folder, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX)) &&
d6e8d8
		!in_array($cur_folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)) && $cur_folder_id != $dest_folder)
d6e8d8
	{
d6e8d8
		// We have to check the destination folder ;)
d6e8d8
		if ($dest_folder != PRIVMSGS_INBOX)
d6e8d8
		{
d6e8d8
			$sql = 'SELECT folder_id, folder_name, pm_count
d6e8d8
				FROM ' . PRIVMSGS_FOLDER_TABLE . "
d6e8d8
				WHERE folder_id = $dest_folder
d6e8d8
					AND user_id = $user_id";
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
			$row = $db->sql_fetchrow($result);
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
d6e8d8
			if (!$row)
d6e8d8
			{
d6e8d8
				trigger_error('NOT_AUTHORISED');
d6e8d8
			}
d6e8d8
d6e8d8
			if ($message_limit && $row['pm_count'] + sizeof($move_msg_ids) > $message_limit)
d6e8d8
			{
d6e8d8
				$message = sprintf($user->lang['NOT_ENOUGH_SPACE_FOLDER'], $row['folder_name']) . '

';
d6e8d8
				$message .= sprintf($user->lang['CLICK_RETURN_FOLDER'], '', '', $row['folder_name']);
d6e8d8
				trigger_error($message);
d6e8d8
			}
d6e8d8
		}
d6e8d8
		else
d6e8d8
		{
d6e8d8
			$sql = 'SELECT COUNT(msg_id) as num_messages
d6e8d8
				FROM ' . PRIVMSGS_TO_TABLE . '
d6e8d8
				WHERE folder_id = ' . PRIVMSGS_INBOX . "
d6e8d8
					AND user_id = $user_id";
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
			$num_messages = (int) $db->sql_fetchfield('num_messages');
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
d6e8d8
			if ($message_limit && $num_messages + sizeof($move_msg_ids) > $message_limit)
d6e8d8
			{
d6e8d8
				$message = sprintf($user->lang['NOT_ENOUGH_SPACE_FOLDER'], $user->lang['PM_INBOX']) . '

';
d6e8d8
				$message .= sprintf($user->lang['CLICK_RETURN_FOLDER'], '', '', $user->lang['PM_INBOX']);
d6e8d8
				trigger_error($message);
d6e8d8
			}
d6e8d8
		}
d6e8d8
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
d6e8d8
			SET folder_id = $dest_folder
d6e8d8
			WHERE folder_id = $cur_folder_id
d6e8d8
				AND user_id = $user_id
d6e8d8
				AND " . $db->sql_in_set('msg_id', $move_msg_ids);
d6e8d8
		$db->sql_query($sql);
d6e8d8
		$num_moved = $db->sql_affectedrows();
d6e8d8
d6e8d8
		// Update pm counts
d6e8d8
		if ($num_moved)
d6e8d8
		{
d6e8d8
			if (!in_array($cur_folder_id, array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX)))
d6e8d8
			{
d6e8d8
				$sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
d6e8d8
					SET pm_count = pm_count - $num_moved
d6e8d8
					WHERE folder_id = $cur_folder_id
d6e8d8
						AND user_id = $user_id";
d6e8d8
				$db->sql_query($sql);
d6e8d8
			}
d6e8d8
d6e8d8
			if ($dest_folder != PRIVMSGS_INBOX)
d6e8d8
			{
d6e8d8
				$sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
d6e8d8
					SET pm_count = pm_count + $num_moved
d6e8d8
					WHERE folder_id = $dest_folder
d6e8d8
						AND user_id = $user_id";
d6e8d8
				$db->sql_query($sql);
d6e8d8
			}
d6e8d8
		}
d6e8d8
	}
d6e8d8
	else if (in_array($cur_folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)))
d6e8d8
	{
d6e8d8
		trigger_error('CANNOT_MOVE_SPECIAL');
d6e8d8
	}
d6e8d8
d6e8d8
	return $num_moved;
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Update unread message status
d6e8d8
*/
d6e8d8
function update_unread_status($unread, $msg_id, $user_id, $folder_id)
d6e8d8
{
d6e8d8
	if (!$unread)
d6e8d8
	{
d6e8d8
		return;
d6e8d8
	}
d6e8d8
d6e8d8
	global $db, $user;
d6e8d8
d6e8d8
	$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
d6e8d8
		SET pm_unread = 0
d6e8d8
		WHERE msg_id = $msg_id
d6e8d8
			AND user_id = $user_id
d6e8d8
			AND folder_id = $folder_id";
d6e8d8
	$db->sql_query($sql);
d6e8d8
d6e8d8
	$sql = 'UPDATE ' . USERS_TABLE . "
d6e8d8
		SET user_unread_privmsg = user_unread_privmsg - 1
d6e8d8
		WHERE user_id = $user_id";
d6e8d8
	$db->sql_query($sql);
d6e8d8
d6e8d8
	if ($user->data['user_id'] == $user_id)
d6e8d8
	{
d6e8d8
		$user->data['user_unread_privmsg']--;
d6e8d8
d6e8d8
		// Try to cope with previous wrong conversions...
d6e8d8
		if ($user->data['user_unread_privmsg'] < 0)
d6e8d8
		{
d6e8d8
			$sql = 'UPDATE ' . USERS_TABLE . "
d6e8d8
				SET user_unread_privmsg = 0
d6e8d8
				WHERE user_id = $user_id";
d6e8d8
			$db->sql_query($sql);
d6e8d8
d6e8d8
			$user->data['user_unread_privmsg'] = 0;
d6e8d8
		}
d6e8d8
	}
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Handle all actions possible with marked messages
d6e8d8
*/
d6e8d8
function handle_mark_actions($user_id, $mark_action)
d6e8d8
{
d6e8d8
	global $db, $user, $phpbb_root_path, $phpEx;
d6e8d8
d6e8d8
	$msg_ids		= request_var('marked_msg_id', array(0));
d6e8d8
	$cur_folder_id	= request_var('cur_folder_id', PRIVMSGS_NO_BOX);
d6e8d8
	$confirm		= (isset($_POST['confirm'])) ? true : false;
d6e8d8
d6e8d8
	if (!sizeof($msg_ids))
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	switch ($mark_action)
d6e8d8
	{
d6e8d8
		case 'mark_important':
d6e8d8
d6e8d8
			$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
d6e8d8
				SET pm_marked = 1 - pm_marked
d6e8d8
				WHERE folder_id = $cur_folder_id
d6e8d8
					AND user_id = $user_id
d6e8d8
					AND " . $db->sql_in_set('msg_id', $msg_ids);
d6e8d8
			$db->sql_query($sql);
d6e8d8
d6e8d8
		break;
d6e8d8
d6e8d8
		case 'delete_marked':
d6e8d8
d6e8d8
			if (confirm_box(true))
d6e8d8
			{
d6e8d8
				delete_pm($user_id, $msg_ids, $cur_folder_id);
d6e8d8
d6e8d8
				$success_msg = (sizeof($msg_ids) == 1) ? 'MESSAGE_DELETED' : 'MESSAGES_DELETED';
d6e8d8
				$redirect = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=' . $cur_folder_id);
d6e8d8
d6e8d8
				meta_refresh(3, $redirect);
d6e8d8
				trigger_error($user->lang[$success_msg] . '

' . sprintf($user->lang['RETURN_FOLDER'], '', ''));
d6e8d8
			}
d6e8d8
			else
d6e8d8
			{
d6e8d8
				$s_hidden_fields = array(
d6e8d8
					'cur_folder_id'	=> $cur_folder_id,
d6e8d8
					'mark_option'	=> 'delete_marked',
d6e8d8
					'submit_mark'	=> true,
d6e8d8
					'marked_msg_id'	=> $msg_ids
d6e8d8
				);
d6e8d8
d6e8d8
				confirm_box(false, 'DELETE_MARKED_PM', build_hidden_fields($s_hidden_fields));
d6e8d8
			}
d6e8d8
d6e8d8
		break;
d6e8d8
d6e8d8
		default:
d6e8d8
			return false;
d6e8d8
	}
d6e8d8
d6e8d8
	return true;
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Delete PM(s)
d6e8d8
*/
d6e8d8
function delete_pm($user_id, $msg_ids, $folder_id)
d6e8d8
{
d6e8d8
	global $db, $user, $phpbb_root_path, $phpEx;
d6e8d8
d6e8d8
	$user_id	= (int) $user_id;
d6e8d8
	$folder_id	= (int) $folder_id;
d6e8d8
d6e8d8
	if (!$user_id)
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	if (!is_array($msg_ids))
d6e8d8
	{
d6e8d8
		if (!$msg_ids)
d6e8d8
		{
d6e8d8
			return false;
d6e8d8
		}
d6e8d8
		$msg_ids = array($msg_ids);
d6e8d8
	}
d6e8d8
d6e8d8
	if (!sizeof($msg_ids))
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	// Get PM Information for later deleting
d6e8d8
	$sql = 'SELECT msg_id, pm_unread, pm_new
d6e8d8
		FROM ' . PRIVMSGS_TO_TABLE . '
d6e8d8
		WHERE ' . $db->sql_in_set('msg_id', array_map('intval', $msg_ids)) . "
d6e8d8
			AND folder_id = $folder_id
d6e8d8
			AND user_id = $user_id";
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
d6e8d8
	$delete_rows = array();
d6e8d8
	$num_unread = $num_new = $num_deleted = 0;
d6e8d8
	while ($row = $db->sql_fetchrow($result))
d6e8d8
	{
d6e8d8
		$num_unread += (int) $row['pm_unread'];
d6e8d8
		$num_new += (int) $row['pm_new'];
d6e8d8
d6e8d8
		$delete_rows[$row['msg_id']] = 1;
d6e8d8
	}
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
	unset($msg_ids);
d6e8d8
d6e8d8
	if (!sizeof($delete_rows))
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	$db->sql_transaction('begin');
d6e8d8
d6e8d8
	// if no one has read the message yet (meaning it is in users outbox)
d6e8d8
	// then mark the message as deleted...
d6e8d8
	if ($folder_id == PRIVMSGS_OUTBOX)
d6e8d8
	{
d6e8d8
		// Remove PM from Outbox
d6e8d8
		$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . "
d6e8d8
			WHERE user_id = $user_id AND folder_id = " . PRIVMSGS_OUTBOX . '
d6e8d8
				AND ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
d6e8d8
		$db->sql_query($sql);
d6e8d8
d6e8d8
		// Update PM Information for safety
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_TABLE . " SET message_text = ''
d6e8d8
			WHERE " . $db->sql_in_set('msg_id', array_keys($delete_rows));
d6e8d8
		$db->sql_query($sql);
d6e8d8
d6e8d8
		// Set delete flag for those intended to receive the PM
d6e8d8
		// We do not remove the message actually, to retain some basic information (sent time for example)
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
d6e8d8
			SET pm_deleted = 1
d6e8d8
			WHERE ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
d6e8d8
		$db->sql_query($sql);
d6e8d8
d6e8d8
		$num_deleted = $db->sql_affectedrows();
d6e8d8
	}
d6e8d8
	else
d6e8d8
	{
d6e8d8
		// Delete private message data
d6e8d8
		$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . "
d6e8d8
			WHERE user_id = $user_id
d6e8d8
				AND folder_id = $folder_id
d6e8d8
				AND " . $db->sql_in_set('msg_id', array_keys($delete_rows));
d6e8d8
		$db->sql_query($sql);
d6e8d8
		$num_deleted = $db->sql_affectedrows();
d6e8d8
	}
d6e8d8
d6e8d8
	// if folder id is user defined folder then decrease pm_count
d6e8d8
	if (!in_array($folder_id, array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX, PRIVMSGS_NO_BOX)))
d6e8d8
	{
d6e8d8
		$sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . "
d6e8d8
			SET pm_count = pm_count - $num_deleted
d6e8d8
			WHERE folder_id = $folder_id";
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
d6e8d8
	// Update unread and new status field
d6e8d8
	if ($num_unread || $num_new)
d6e8d8
	{
d6e8d8
		$set_sql = ($num_unread) ? 'user_unread_privmsg = user_unread_privmsg - ' . $num_unread : '';
d6e8d8
d6e8d8
		if ($num_new)
d6e8d8
		{
d6e8d8
			$set_sql .= ($set_sql != '') ? ', ' : '';
d6e8d8
			$set_sql .= 'user_new_privmsg = user_new_privmsg - ' . $num_new;
d6e8d8
		}
d6e8d8
d6e8d8
		$db->sql_query('UPDATE ' . USERS_TABLE . " SET $set_sql WHERE user_id = $user_id");
d6e8d8
d6e8d8
		$user->data['user_new_privmsg'] -= $num_new;
d6e8d8
		$user->data['user_unread_privmsg'] -= $num_unread;
d6e8d8
	}
d6e8d8
d6e8d8
	// Now we have to check which messages we can delete completely
d6e8d8
	$sql = 'SELECT msg_id
d6e8d8
		FROM ' . PRIVMSGS_TO_TABLE . '
d6e8d8
		WHERE ' . $db->sql_in_set('msg_id', array_keys($delete_rows));
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
d6e8d8
	while ($row = $db->sql_fetchrow($result))
d6e8d8
	{
d6e8d8
		unset($delete_rows[$row['msg_id']]);
d6e8d8
	}
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	$delete_ids = array_keys($delete_rows);
d6e8d8
d6e8d8
	if (sizeof($delete_ids))
d6e8d8
	{
d6e8d8
		// Check if there are any attachments we need to remove
d6e8d8
		if (!function_exists('delete_attachments'))
d6e8d8
		{
d6e8d8
			include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
d6e8d8
		}
d6e8d8
d6e8d8
		delete_attachments('message', $delete_ids, false);
d6e8d8
d6e8d8
		$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
d6e8d8
			WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
d6e8d8
	$db->sql_transaction('commit');
d6e8d8
d6e8d8
	return true;
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Rebuild message header
d6e8d8
*/
d6e8d8
function rebuild_header($check_ary)
d6e8d8
{
d6e8d8
	global $db;
d6e8d8
d6e8d8
	$address = array();
d6e8d8
d6e8d8
	foreach ($check_ary as $check_type => $address_field)
d6e8d8
	{
d6e8d8
		// Split Addresses into users and groups
d6e8d8
		preg_match_all('/:?(u|g)_([0-9]+):?/', $address_field, $match);
d6e8d8
d6e8d8
		$u = $g = array();
d6e8d8
		foreach ($match[1] as $id => $type)
d6e8d8
		{
d6e8d8
			${$type}[] = (int) $match[2][$id];
d6e8d8
		}
d6e8d8
d6e8d8
		$_types = array('u', 'g');
d6e8d8
		foreach ($_types as $type)
d6e8d8
		{
d6e8d8
			if (sizeof($$type))
d6e8d8
			{
d6e8d8
				foreach ($$type as $id)
d6e8d8
				{
d6e8d8
					$address[$type][$id] = $check_type;
d6e8d8
				}
d6e8d8
			}
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	return $address;
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Print out/assign recipient information
d6e8d8
*/
d6e8d8
function write_pm_addresses($check_ary, $author_id, $plaintext = false)
d6e8d8
{
d6e8d8
	global $db, $user, $template, $phpbb_root_path, $phpEx;
d6e8d8
d6e8d8
	$addresses = array();
d6e8d8
d6e8d8
	foreach ($check_ary as $check_type => $address_field)
d6e8d8
	{
d6e8d8
		if (!is_array($address_field))
d6e8d8
		{
d6e8d8
			// Split Addresses into users and groups
d6e8d8
			preg_match_all('/:?(u|g)_([0-9]+):?/', $address_field, $match);
d6e8d8
d6e8d8
			$u = $g = array();
d6e8d8
			foreach ($match[1] as $id => $type)
d6e8d8
			{
d6e8d8
				${$type}[] = (int) $match[2][$id];
d6e8d8
			}
d6e8d8
		}
d6e8d8
		else
d6e8d8
		{
d6e8d8
			$u = $address_field['u'];
d6e8d8
			$g = $address_field['g'];
d6e8d8
		}
d6e8d8
d6e8d8
		$address = array();
d6e8d8
		if (sizeof($u))
d6e8d8
		{
d6e8d8
			$sql = 'SELECT user_id, username, user_colour
d6e8d8
				FROM ' . USERS_TABLE . '
d6e8d8
				WHERE ' . $db->sql_in_set('user_id', $u) . '
d6e8d8
					AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
d6e8d8
			while ($row = $db->sql_fetchrow($result))
d6e8d8
			{
d6e8d8
				if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
d6e8d8
				{
d6e8d8
					if ($plaintext)
d6e8d8
					{
d6e8d8
						$address[] = $row['username'];
d6e8d8
					}
d6e8d8
					else
d6e8d8
					{
d6e8d8
						$address['user'][$row['user_id']] = array('name' => $row['username'], 'colour' => $row['user_colour']);
d6e8d8
					}
d6e8d8
				}
d6e8d8
			}
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
		}
d6e8d8
d6e8d8
		if (sizeof($g))
d6e8d8
		{
d6e8d8
			if ($plaintext)
d6e8d8
			{
d6e8d8
				$sql = 'SELECT group_name, group_type
d6e8d8
					FROM ' . GROUPS_TABLE . '
d6e8d8
						WHERE ' . $db->sql_in_set('group_id', $g);
d6e8d8
				$result = $db->sql_query($sql);
d6e8d8
d6e8d8
				while ($row = $db->sql_fetchrow($result))
d6e8d8
				{
d6e8d8
					if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
d6e8d8
					{
d6e8d8
						$address[] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
d6e8d8
					}
d6e8d8
				}
d6e8d8
				$db->sql_freeresult($result);
d6e8d8
			}
d6e8d8
			else
d6e8d8
			{
d6e8d8
				$sql = 'SELECT g.group_id, g.group_name, g.group_colour, g.group_type, ug.user_id
d6e8d8
					FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
d6e8d8
						WHERE ' . $db->sql_in_set('g.group_id', $g) . '
d6e8d8
						AND g.group_id = ug.group_id
d6e8d8
						AND ug.user_pending = 0';
d6e8d8
				$result = $db->sql_query($sql);
d6e8d8
d6e8d8
				while ($row = $db->sql_fetchrow($result))
d6e8d8
				{
d6e8d8
					if (!isset($address['group'][$row['group_id']]))
d6e8d8
					{
d6e8d8
						if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
d6e8d8
						{
d6e8d8
							$row['group_name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
d6e8d8
							$address['group'][$row['group_id']] = array('name' => $row['group_name'], 'colour' => $row['group_colour']);
d6e8d8
						}
d6e8d8
					}
d6e8d8
d6e8d8
					if (isset($address['user'][$row['user_id']]))
d6e8d8
					{
d6e8d8
						$address['user'][$row['user_id']]['in_group'] = $row['group_id'];
d6e8d8
					}
d6e8d8
				}
d6e8d8
				$db->sql_freeresult($result);
d6e8d8
			}
d6e8d8
		}
d6e8d8
d6e8d8
		if (sizeof($address) && !$plaintext)
d6e8d8
		{
d6e8d8
			$template->assign_var('S_' . strtoupper($check_type) . '_RECIPIENT', true);
d6e8d8
d6e8d8
			foreach ($address as $type => $adr_ary)
d6e8d8
			{
d6e8d8
				foreach ($adr_ary as $id => $row)
d6e8d8
				{
d6e8d8
					$tpl_ary = array(
d6e8d8
						'IS_GROUP'	=> ($type == 'group') ? true : false,
d6e8d8
						'IS_USER'	=> ($type == 'user') ? true : false,
d6e8d8
						'UG_ID'		=> $id,
d6e8d8
						'NAME'		=> $row['name'],
d6e8d8
						'COLOUR'	=> ($row['colour']) ? '#' . $row['colour'] : '',
d6e8d8
						'TYPE'		=> $type,
d6e8d8
					);
d6e8d8
d6e8d8
					if ($type == 'user')
d6e8d8
					{
d6e8d8
						$tpl_ary = array_merge($tpl_ary, array(
d6e8d8
							'U_VIEW'		=> get_username_string('profile', $id, $row['name'], $row['colour']),
d6e8d8
							'NAME_FULL'		=> get_username_string('full', $id, $row['name'], $row['colour']),
d6e8d8
						));
d6e8d8
					}
d6e8d8
					else
d6e8d8
					{
d6e8d8
						$tpl_ary = array_merge($tpl_ary, array(
d6e8d8
							'U_VIEW'		=> append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&g=' . $id),
d6e8d8
						));
d6e8d8
					}
d6e8d8
d6e8d8
					$template->assign_block_vars($check_type . '_recipient', $tpl_ary);
d6e8d8
				}
d6e8d8
			}
d6e8d8
		}
d6e8d8
d6e8d8
		$addresses[$check_type] = $address;
d6e8d8
	}
d6e8d8
d6e8d8
	return $addresses;
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Get folder status
d6e8d8
*/
d6e8d8
function get_folder_status($folder_id, $folder)
d6e8d8
{
d6e8d8
	global $db, $user, $config;
d6e8d8
d6e8d8
	if (isset($folder[$folder_id]))
d6e8d8
	{
d6e8d8
		$folder = $folder[$folder_id];
d6e8d8
	}
d6e8d8
	else
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	$return = array(
d6e8d8
		'folder_name'	=> $folder['folder_name'],
d6e8d8
		'cur'			=> $folder['num_messages'],
d6e8d8
		'remaining'		=> ($user->data['message_limit']) ? $user->data['message_limit'] - $folder['num_messages'] : 0,
d6e8d8
		'max'			=> $user->data['message_limit'],
d6e8d8
		'percent'		=> ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? round(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0,
d6e8d8
	);
d6e8d8
d6e8d8
	$return['message']	= sprintf($user->lang['FOLDER_STATUS_MSG'], $return['percent'], $return['cur'], $return['max']);
d6e8d8
d6e8d8
	return $return;
d6e8d8
}
d6e8d8
d6e8d8
//
d6e8d8
// COMPOSE MESSAGES
d6e8d8
//
d6e8d8
d6e8d8
/**
d6e8d8
* Submit PM
d6e8d8
*/
d6e8d8
function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
d6e8d8
{
d6e8d8
	global $db, $auth, $config, $phpEx, $template, $user, $phpbb_root_path;
d6e8d8
d6e8d8
	// We do not handle erasing pms here
d6e8d8
	if ($mode == 'delete')
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	$current_time = time();
d6e8d8
d6e8d8
	// Collect some basic information about which tables and which rows to update/insert
d6e8d8
	$sql_data = array();
d6e8d8
	$root_level = 0;
d6e8d8
d6e8d8
	// Recipient Information
d6e8d8
	$recipients = $to = $bcc = array();
d6e8d8
d6e8d8
	if ($mode != 'edit')
d6e8d8
	{
d6e8d8
		// Build Recipient List
d6e8d8
		// u|g => array($user_id => 'to'|'bcc')
d6e8d8
		$_types = array('u', 'g');
d6e8d8
		foreach ($_types as $ug_type)
d6e8d8
		{
d6e8d8
			if (isset($data['address_list'][$ug_type]) && sizeof($data['address_list'][$ug_type]))
d6e8d8
			{
d6e8d8
				foreach ($data['address_list'][$ug_type] as $id => $field)
d6e8d8
				{
d6e8d8
					$id = (int) $id;
d6e8d8
d6e8d8
					// Do not rely on the address list being "valid"
d6e8d8
					if (!$id || ($ug_type == 'u' && $id == ANONYMOUS))
d6e8d8
					{
d6e8d8
						continue;
d6e8d8
					}
d6e8d8
d6e8d8
					$field = ($field == 'to') ? 'to' : 'bcc';
d6e8d8
					if ($ug_type == 'u')
d6e8d8
					{
d6e8d8
						$recipients[$id] = $field;
d6e8d8
					}
d6e8d8
					${$field}[] = $ug_type . '_' . $id;
d6e8d8
				}
d6e8d8
			}
d6e8d8
		}
d6e8d8
d6e8d8
		if (isset($data['address_list']['g']) && sizeof($data['address_list']['g']))
d6e8d8
		{
d6e8d8
			// We need to check the PM status of group members (do they want to receive PM's?)
d6e8d8
			// Only check if not a moderator or admin, since they are allowed to override this user setting
d6e8d8
			$sql_allow_pm = (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) ? ' AND u.user_allow_pm = 1' : '';
d6e8d8
d6e8d8
			$sql = 'SELECT u.user_type, ug.group_id, ug.user_id
d6e8d8
				FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug
d6e8d8
				WHERE ' . $db->sql_in_set('ug.group_id', array_keys($data['address_list']['g'])) . '
d6e8d8
					AND ug.user_pending = 0
d6e8d8
					AND u.user_id = ug.user_id
d6e8d8
					AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')' . 
d6e8d8
					$sql_allow_pm;
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
d6e8d8
			while ($row = $db->sql_fetchrow($result))
d6e8d8
			{
d6e8d8
				$field = ($data['address_list']['g'][$row['group_id']] == 'to') ? 'to' : 'bcc';
d6e8d8
				$recipients[$row['user_id']] = $field;
d6e8d8
			}
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
		}
d6e8d8
d6e8d8
		if (!sizeof($recipients))
d6e8d8
		{
d6e8d8
			trigger_error('NO_RECIPIENT');
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	$db->sql_transaction('begin');
d6e8d8
d6e8d8
	$sql = '';
d6e8d8
d6e8d8
	switch ($mode)
d6e8d8
	{
d6e8d8
		case 'reply':
d6e8d8
		case 'quote':
d6e8d8
			$root_level = ($data['reply_from_root_level']) ? $data['reply_from_root_level'] : $data['reply_from_msg_id'];
d6e8d8
d6e8d8
			// Set message_replied switch for this user
d6e8d8
			$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
d6e8d8
				SET pm_replied = 1
d6e8d8
				WHERE user_id = ' . $data['from_user_id'] . '
d6e8d8
					AND msg_id = ' . $data['reply_from_msg_id'];
d6e8d8
d6e8d8
		// no break
d6e8d8
d6e8d8
		case 'forward':
d6e8d8
		case 'post':
d6e8d8
		case 'quotepost':
d6e8d8
			$sql_data = array(
d6e8d8
				'root_level'		=> $root_level,
d6e8d8
				'author_id'			=> $data['from_user_id'],
d6e8d8
				'icon_id'			=> $data['icon_id'],
d6e8d8
				'author_ip'			=> $data['from_user_ip'],
d6e8d8
				'message_time'		=> $current_time,
d6e8d8
				'enable_bbcode'		=> $data['enable_bbcode'],
d6e8d8
				'enable_smilies'	=> $data['enable_smilies'],
d6e8d8
				'enable_magic_url'	=> $data['enable_urls'],
d6e8d8
				'enable_sig'		=> $data['enable_sig'],
d6e8d8
				'message_subject'	=> $subject,
d6e8d8
				'message_text'		=> $data['message'],
d6e8d8
				'message_attachment'=> (!empty($data['attachment_data'])) ? 1 : 0,
d6e8d8
				'bbcode_bitfield'	=> $data['bbcode_bitfield'],
d6e8d8
				'bbcode_uid'		=> $data['bbcode_uid'],
d6e8d8
				'to_address'		=> implode(':', $to),
d6e8d8
				'bcc_address'		=> implode(':', $bcc)
d6e8d8
			);
d6e8d8
		break;
d6e8d8
d6e8d8
		case 'edit':
d6e8d8
			$sql_data = array(
d6e8d8
				'icon_id'			=> $data['icon_id'],
d6e8d8
				'message_edit_time'	=> $current_time,
d6e8d8
				'enable_bbcode'		=> $data['enable_bbcode'],
d6e8d8
				'enable_smilies'	=> $data['enable_smilies'],
d6e8d8
				'enable_magic_url'	=> $data['enable_urls'],
d6e8d8
				'enable_sig'		=> $data['enable_sig'],
d6e8d8
				'message_subject'	=> $subject,
d6e8d8
				'message_text'		=> $data['message'],
d6e8d8
				'message_attachment'=> (!empty($data['attachment_data'])) ? 1 : 0,
d6e8d8
				'bbcode_bitfield'	=> $data['bbcode_bitfield'],
d6e8d8
				'bbcode_uid'		=> $data['bbcode_uid']
d6e8d8
			);
d6e8d8
		break;
d6e8d8
	}
d6e8d8
d6e8d8
	if (sizeof($sql_data))
d6e8d8
	{
d6e8d8
		$query = '';
d6e8d8
d6e8d8
		if ($mode == 'post' || $mode == 'reply' || $mode == 'quote' || $mode == 'quotepost' || $mode == 'forward')
d6e8d8
		{
d6e8d8
			$db->sql_query('INSERT INTO ' . PRIVMSGS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data));
d6e8d8
			$data['msg_id'] = $db->sql_nextid();
d6e8d8
		}
d6e8d8
		else if ($mode == 'edit')
d6e8d8
		{
d6e8d8
			$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
d6e8d8
				SET message_edit_count = message_edit_count + 1, ' . $db->sql_build_array('UPDATE', $sql_data) . '
d6e8d8
				WHERE msg_id = ' . $data['msg_id'];
d6e8d8
			$db->sql_query($sql);
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	if ($mode != 'edit')
d6e8d8
	{
d6e8d8
		if ($sql)
d6e8d8
		{
d6e8d8
			$db->sql_query($sql);
d6e8d8
		}
d6e8d8
		unset($sql);
d6e8d8
d6e8d8
		$sql_ary = array();
d6e8d8
		foreach ($recipients as $user_id => $type)
d6e8d8
		{
d6e8d8
			$sql_ary[] = array(
d6e8d8
				'msg_id'		=> (int) $data['msg_id'],
d6e8d8
				'user_id'		=> (int) $user_id,
d6e8d8
				'author_id'		=> (int) $data['from_user_id'],
d6e8d8
				'folder_id'		=> PRIVMSGS_NO_BOX,
d6e8d8
				'pm_new'		=> 1,
d6e8d8
				'pm_unread'		=> 1,
d6e8d8
				'pm_forwarded'	=> ($mode == 'forward') ? 1 : 0
d6e8d8
			);
d6e8d8
		}
d6e8d8
d6e8d8
		$db->sql_multi_insert(PRIVMSGS_TO_TABLE, $sql_ary);
d6e8d8
d6e8d8
		$sql = 'UPDATE ' . USERS_TABLE . '
d6e8d8
			SET user_new_privmsg = user_new_privmsg + 1, user_unread_privmsg = user_unread_privmsg + 1, user_last_privmsg = ' . time() . '
d6e8d8
			WHERE ' . $db->sql_in_set('user_id', array_keys($recipients));
d6e8d8
		$db->sql_query($sql);
d6e8d8
d6e8d8
		// Put PM into outbox
d6e8d8
		if ($put_in_outbox)
d6e8d8
		{
d6e8d8
			$db->sql_query('INSERT INTO ' . PRIVMSGS_TO_TABLE . ' ' . $db->sql_build_array('INSERT', array(
d6e8d8
				'msg_id'		=> (int) $data['msg_id'],
d6e8d8
				'user_id'		=> (int) $data['from_user_id'],
d6e8d8
				'author_id'		=> (int) $data['from_user_id'],
d6e8d8
				'folder_id'		=> PRIVMSGS_OUTBOX,
d6e8d8
				'pm_new'		=> 0,
d6e8d8
				'pm_unread'		=> 0,
d6e8d8
				'pm_forwarded'	=> ($mode == 'forward') ? 1 : 0))
d6e8d8
			);
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	// Set user last post time
d6e8d8
	if ($mode == 'reply' || $mode == 'quote' || $mode == 'quotepost' || $mode == 'forward' || $mode == 'post')
d6e8d8
	{
d6e8d8
		$sql = 'UPDATE ' . USERS_TABLE . "
d6e8d8
			SET user_lastpost_time = $current_time
d6e8d8
			WHERE user_id = " . $data['from_user_id'];
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
d6e8d8
	// Submit Attachments
d6e8d8
	if (!empty($data['attachment_data']) && $data['msg_id'] && in_array($mode, array('post', 'reply', 'quote', 'quotepost', 'edit', 'forward')))
d6e8d8
	{
d6e8d8
		$space_taken = $files_added = 0;
d6e8d8
		$orphan_rows = array();
d6e8d8
d6e8d8
		foreach ($data['attachment_data'] as $pos => $attach_row)
d6e8d8
		{
d6e8d8
			$orphan_rows[(int) $attach_row['attach_id']] = array();
d6e8d8
		}
d6e8d8
d6e8d8
		if (sizeof($orphan_rows))
d6e8d8
		{
d6e8d8
			$sql = 'SELECT attach_id, filesize, physical_filename
d6e8d8
				FROM ' . ATTACHMENTS_TABLE . '
d6e8d8
				WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan_rows)) . '
d6e8d8
					AND in_message = 1
d6e8d8
					AND is_orphan = 1
d6e8d8
					AND poster_id = ' . $user->data['user_id'];
d6e8d8
			$result = $db->sql_query($sql);
d6e8d8
d6e8d8
			$orphan_rows = array();
d6e8d8
			while ($row = $db->sql_fetchrow($result))
d6e8d8
			{
d6e8d8
				$orphan_rows[$row['attach_id']] = $row;
d6e8d8
			}
d6e8d8
			$db->sql_freeresult($result);
d6e8d8
		}
d6e8d8
d6e8d8
		foreach ($data['attachment_data'] as $pos => $attach_row)
d6e8d8
		{
d6e8d8
			if ($attach_row['is_orphan'] && !isset($orphan_rows[$attach_row['attach_id']]))
d6e8d8
			{
d6e8d8
				continue;
d6e8d8
			}
d6e8d8
d6e8d8
			if (!$attach_row['is_orphan'])
d6e8d8
			{
d6e8d8
				// update entry in db if attachment already stored in db and filespace
d6e8d8
				$sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
d6e8d8
					SET attach_comment = '" . $db->sql_escape($attach_row['attach_comment']) . "'
d6e8d8
					WHERE attach_id = " . (int) $attach_row['attach_id'] . '
d6e8d8
						AND is_orphan = 0';
d6e8d8
				$db->sql_query($sql);
d6e8d8
			}
d6e8d8
			else
d6e8d8
			{
d6e8d8
				// insert attachment into db
d6e8d8
				if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
d6e8d8
				{
d6e8d8
					continue;
d6e8d8
				}
d6e8d8
d6e8d8
				$space_taken += $orphan_rows[$attach_row['attach_id']]['filesize'];
d6e8d8
				$files_added++;
d6e8d8
d6e8d8
				$attach_sql = array(
d6e8d8
					'post_msg_id'		=> $data['msg_id'],
d6e8d8
					'topic_id'			=> 0,
d6e8d8
					'is_orphan'			=> 0,
d6e8d8
					'poster_id'			=> $data['from_user_id'],
d6e8d8
					'attach_comment'	=> $attach_row['attach_comment'],
d6e8d8
				);
d6e8d8
d6e8d8
				$sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $attach_sql) . '
d6e8d8
					WHERE attach_id = ' . $attach_row['attach_id'] . '
d6e8d8
						AND is_orphan = 1
d6e8d8
						AND poster_id = ' . $user->data['user_id'];
d6e8d8
				$db->sql_query($sql);
d6e8d8
			}
d6e8d8
		}
d6e8d8
d6e8d8
		if ($space_taken && $files_added)
d6e8d8
		{
d6e8d8
			set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
d6e8d8
			set_config('num_files', $config['num_files'] + $files_added, true);
d6e8d8
		}
d6e8d8
	}
d6e8d8
d6e8d8
	// Delete draft if post was loaded...
d6e8d8
	$draft_id = request_var('draft_loaded', 0);
d6e8d8
	if ($draft_id)
d6e8d8
	{
d6e8d8
		$sql = 'DELETE FROM ' . DRAFTS_TABLE . "
d6e8d8
			WHERE draft_id = $draft_id
d6e8d8
				AND user_id = " . $data['from_user_id'];
d6e8d8
		$db->sql_query($sql);
d6e8d8
	}
d6e8d8
d6e8d8
	$db->sql_transaction('commit');
d6e8d8
d6e8d8
	// Send Notifications
d6e8d8
	if ($mode != 'edit')
d6e8d8
	{
d6e8d8
		pm_notification($mode, $data['from_username'], $recipients, $subject, $data['message']);
d6e8d8
	}
d6e8d8
d6e8d8
	return $data['msg_id'];
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* PM Notification
d6e8d8
*/
d6e8d8
function pm_notification($mode, $author, $recipients, $subject, $message)
d6e8d8
{
d6e8d8
	global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
d6e8d8
d6e8d8
	$subject = censor_text($subject);
d6e8d8
d6e8d8
	unset($recipients[ANONYMOUS], $recipients[$user->data['user_id']]);
d6e8d8
d6e8d8
	if (!sizeof($recipients))
d6e8d8
	{
d6e8d8
		return;
d6e8d8
	}
d6e8d8
d6e8d8
	// Get banned User ID's
d6e8d8
	$sql = 'SELECT ban_userid
d6e8d8
		FROM ' . BANLIST_TABLE . '
d6e8d8
		WHERE ' . $db->sql_in_set('ban_userid', array_map('intval', array_keys($recipients))) . '
d6e8d8
			AND ban_exclude = 0';
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
d6e8d8
	while ($row = $db->sql_fetchrow($result))
d6e8d8
	{
d6e8d8
		unset($recipients[$row['ban_userid']]);
d6e8d8
	}
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	if (!sizeof($recipients))
d6e8d8
	{
d6e8d8
		return;
d6e8d8
	}
d6e8d8
d6e8d8
	$sql = 'SELECT user_id, username, user_email, user_lang, user_notify_pm, user_notify_type, user_jabber
d6e8d8
		FROM ' . USERS_TABLE . '
d6e8d8
		WHERE ' . $db->sql_in_set('user_id', array_map('intval', array_keys($recipients)));
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
d6e8d8
	$msg_list_ary = array();
d6e8d8
	while ($row = $db->sql_fetchrow($result))
d6e8d8
	{
d6e8d8
		if ($row['user_notify_pm'] == 1 && trim($row['user_email']))
d6e8d8
		{
d6e8d8
			$msg_list_ary[] = array(
d6e8d8
				'method'	=> $row['user_notify_type'],
d6e8d8
				'email'		=> $row['user_email'],
d6e8d8
				'jabber'	=> $row['user_jabber'],
d6e8d8
				'name'		=> $row['username'],
d6e8d8
				'lang'		=> $row['user_lang']
d6e8d8
			);
d6e8d8
		}
d6e8d8
	}
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	if (!sizeof($msg_list_ary))
d6e8d8
	{
d6e8d8
		return;
d6e8d8
	}
d6e8d8
d6e8d8
	include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
d6e8d8
	$messenger = new messenger();
d6e8d8
d6e8d8
	foreach ($msg_list_ary as $pos => $addr)
d6e8d8
	{
d6e8d8
		$messenger->template('privmsg_notify', $addr['lang']);
d6e8d8
d6e8d8
		$messenger->to($addr['email'], $addr['name']);
d6e8d8
		$messenger->im($addr['jabber'], $addr['name']);
d6e8d8
d6e8d8
		$messenger->assign_vars(array(
d6e8d8
			'SUBJECT'		=> htmlspecialchars_decode($subject),
d6e8d8
			'AUTHOR_NAME'	=> htmlspecialchars_decode($author),
d6e8d8
			'USERNAME'		=> htmlspecialchars_decode($addr['name']),
d6e8d8
d6e8d8
			'U_INBOX'		=> generate_board_url() . "/ucp.$phpEx?i=pm&folder=inbox")
d6e8d8
		);
d6e8d8
d6e8d8
		$messenger->send($addr['method']);
d6e8d8
	}
d6e8d8
	unset($msg_list_ary);
d6e8d8
d6e8d8
	$messenger->save_queue();
d6e8d8
d6e8d8
	unset($messenger);
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Display Message History
d6e8d8
*/
d6e8d8
function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode = false)
d6e8d8
{
d6e8d8
	global $db, $user, $config, $template, $phpbb_root_path, $phpEx, $auth, $bbcode;
d6e8d8
d6e8d8
	// Get History Messages (could be newer)
d6e8d8
	$sql = 'SELECT t.*, p.*, u.*
d6e8d8
		FROM ' . PRIVMSGS_TABLE . ' p, ' . PRIVMSGS_TO_TABLE . ' t, ' . USERS_TABLE . ' u
d6e8d8
		WHERE t.msg_id = p.msg_id
d6e8d8
			AND p.author_id = u.user_id
d6e8d8
			AND t.folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ")
d6e8d8
			AND t.user_id = $user_id";
d6e8d8
d6e8d8
	if (!$message_row['root_level'])
d6e8d8
	{
d6e8d8
		$sql .= " AND (p.root_level = $msg_id OR (p.root_level = 0 AND p.msg_id = $msg_id))";
d6e8d8
	}
d6e8d8
	else
d6e8d8
	{
d6e8d8
		$sql .= " AND (p.root_level = " . $message_row['root_level'] . ' OR p.msg_id = ' . $message_row['root_level'] . ')';
d6e8d8
	}
d6e8d8
	$sql .= ' ORDER BY p.message_time DESC';
d6e8d8
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
	$row = $db->sql_fetchrow($result);
d6e8d8
d6e8d8
	if (!$row)
d6e8d8
	{
d6e8d8
		$db->sql_freeresult($result);
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	$rowset = array();
d6e8d8
	$bbcode_bitfield = '';
d6e8d8
	$folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm') . '&folder=';
d6e8d8
d6e8d8
	do
d6e8d8
	{
d6e8d8
		$folder_id = (int) $row['folder_id'];
d6e8d8
d6e8d8
		$row['folder'][] = (isset($folder[$folder_id])) ? '' . $folder[$folder_id]['folder_name'] . '' : $user->lang['UNKNOWN_FOLDER'];
d6e8d8
d6e8d8
		if (isset($rowset[$row['msg_id']]))
d6e8d8
		{
d6e8d8
			$rowset[$row['msg_id']]['folder'][] = (isset($folder[$folder_id])) ? '' . $folder[$folder_id]['folder_name'] . '' : $user->lang['UNKNOWN_FOLDER'];
d6e8d8
		}
d6e8d8
		else
d6e8d8
		{
d6e8d8
			$rowset[$row['msg_id']] = $row;
d6e8d8
			$bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
d6e8d8
		}
d6e8d8
	}
d6e8d8
	while ($row = $db->sql_fetchrow($result));
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	$title = $row['message_subject'];
d6e8d8
d6e8d8
	if (sizeof($rowset) == 1 && !$in_post_mode)
d6e8d8
	{
d6e8d8
		return false;
d6e8d8
	}
d6e8d8
d6e8d8
	// Instantiate BBCode class
d6e8d8
	if ((empty($bbcode) || $bbcode === false) && $bbcode_bitfield !== '')
d6e8d8
	{
d6e8d8
		if (!class_exists('bbcode'))
d6e8d8
		{
d6e8d8
			include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
d6e8d8
		}
d6e8d8
		$bbcode = new bbcode(base64_encode($bbcode_bitfield));
d6e8d8
	}
d6e8d8
d6e8d8
	$title = censor_text($title);
d6e8d8
d6e8d8
	$url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm');
d6e8d8
	$next_history_pm = $previous_history_pm = $prev_id = 0;
d6e8d8
d6e8d8
	foreach ($rowset as $id => $row)
d6e8d8
	{
d6e8d8
		$author_id	= $row['author_id'];
d6e8d8
		$folder_id	= (int) $row['folder_id'];
d6e8d8
d6e8d8
		$subject	= $row['message_subject'];
d6e8d8
		$message	= $row['message_text'];
d6e8d8
d6e8d8
		$message = censor_text($message);
d6e8d8
d6e8d8
		$decoded_message = false;
d6e8d8
d6e8d8
		if ($in_post_mode && $auth->acl_get('u_sendpm') && $author_id != ANONYMOUS && $author_id != $user->data['user_id'])
d6e8d8
		{
d6e8d8
			$decoded_message = $message;
d6e8d8
			decode_message($decoded_message, $row['bbcode_uid']);
d6e8d8
d6e8d8
			$decoded_message = bbcode_nl2br($decoded_message);
d6e8d8
		}
d6e8d8
d6e8d8
		if ($row['bbcode_bitfield'])
d6e8d8
		{
d6e8d8
			$bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
d6e8d8
		}
d6e8d8
d6e8d8
		$message = bbcode_nl2br($message);
d6e8d8
		$message = smiley_text($message, !$row['enable_smilies']);
d6e8d8
d6e8d8
		$subject = censor_text($subject);
d6e8d8
d6e8d8
		if ($id == $msg_id)
d6e8d8
		{
d6e8d8
			$next_history_pm = next($rowset);
d6e8d8
			$next_history_pm = (sizeof($next_history_pm)) ? (int) $next_history_pm['msg_id'] : 0;
d6e8d8
			$previous_history_pm = $prev_id;
d6e8d8
		}
d6e8d8
d6e8d8
		$template->assign_block_vars('history_row', array(
d6e8d8
			'MESSAGE_AUTHOR_QUOTE'		=> (($decoded_message) ? addslashes(get_username_string('username', $author_id, $row['username'], $row['user_colour'], $row['username'])) : ''),
d6e8d8
			'MESSAGE_AUTHOR_FULL'		=> get_username_string('full', $author_id, $row['username'], $row['user_colour'], $row['username']),
d6e8d8
			'MESSAGE_AUTHOR_COLOUR'		=> get_username_string('colour', $author_id, $row['username'], $row['user_colour'], $row['username']),
d6e8d8
			'MESSAGE_AUTHOR'			=> get_username_string('username', $author_id, $row['username'], $row['user_colour'], $row['username']),
d6e8d8
			'U_MESSAGE_AUTHOR'			=> get_username_string('profile', $author_id, $row['username'], $row['user_colour'], $row['username']),
d6e8d8
d6e8d8
			'SUBJECT'			=> $subject,
d6e8d8
			'SENT_DATE'			=> $user->format_date($row['message_time']),
d6e8d8
			'MESSAGE'			=> $message,
d6e8d8
			'FOLDER'			=> implode(', ', $row['folder']),
d6e8d8
			'DECODED_MESSAGE'	=> $decoded_message,
d6e8d8
d6e8d8
			'S_CURRENT_MSG'		=> ($row['msg_id'] == $msg_id),
d6e8d8
			'S_AUTHOR_DELETED'	=> ($author_id == ANONYMOUS) ? true : false,
d6e8d8
			'S_IN_POST_MODE'	=> $in_post_mode,
d6e8d8
d6e8d8
			'MSG_ID'			=> $row['msg_id'],
d6e8d8
			'U_VIEW_MESSAGE'	=> "$url&f=$folder_id&p=" . $row['msg_id'],
d6e8d8
			'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'] : '',
d6e8d8
			'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'] : '')
d6e8d8
		);
d6e8d8
		unset($rowset[$id]);
d6e8d8
		$prev_id = $id;
d6e8d8
	}
d6e8d8
d6e8d8
	$template->assign_vars(array(
d6e8d8
		'QUOTE_IMG'			=> $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE']),
d6e8d8
		'HISTORY_TITLE'		=> $title,
d6e8d8
d6e8d8
		'U_VIEW_NEXT_HISTORY'		=> ($next_history_pm) ? "$url&p=" . $next_history_pm : '',
d6e8d8
		'U_VIEW_PREVIOUS_HISTORY'	=> ($previous_history_pm) ? "$url&p=" . $previous_history_pm : '',
d6e8d8
	));
d6e8d8
d6e8d8
	return true;
d6e8d8
}
d6e8d8
d6e8d8
/**
d6e8d8
* Set correct users max messages in PM folder.
d6e8d8
* If several group memberships define different amount of messages, the highest will be chosen.
d6e8d8
*/
d6e8d8
function set_user_message_limit()
d6e8d8
{
d6e8d8
	global $user, $db, $config;
d6e8d8
d6e8d8
	// Get maximum about from user memberships - if it is 0, there is no limit set and we use the maximum value within the config.
d6e8d8
	$sql = 'SELECT MAX(g.group_message_limit) as max_message_limit
d6e8d8
		FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
d6e8d8
		WHERE ug.user_id = ' . $user->data['user_id'] . '
d6e8d8
			AND ug.user_pending = 0
d6e8d8
			AND ug.group_id = g.group_id';
d6e8d8
	$result = $db->sql_query($sql);
d6e8d8
	$message_limit = (int) $db->sql_fetchfield('max_message_limit');
d6e8d8
	$db->sql_freeresult($result);
d6e8d8
d6e8d8
	$user->data['message_limit'] = (!$message_limit) ? $config['pm_max_msgs'] : $message_limit;
d6e8d8
}
d6e8d8
d6e8d8
?>