Blame Identity/Webenv/App/phpBB/3.0.4/includes/functions_privmsgs.php

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

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

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

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