1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-07-30 21:40:43 +02:00

Merge remote-tracking branch 'upstream/develop' into feature/prune-users

* upstream/develop: (2171 commits)
  [ticket/11164] Update composer.phar
  [ticket/10933] Use inheritDoc, eliminate copy pasted docblocks.
  [ticket/10933] Dependency inject template context.
  [ticket/10933] Expanded prose documentation for phpbb_extension_provider.
  [ticket/10933] Specify empty template path for absolute includephp test.
  [ticket/10933] Useful documentation for template locate function
  [ticket/10933] Typo fixes
  [ticket/10933] Initialize template context when template is constructed.
  [ticket/11099] Mark acp_ban::display_ban_options() as static.
  [ticket/11158] Require acl_u_sig for ucp signature module.
  [ticket/11158] Revert old fix in PHPBB3-10186.
  [ticket/11159] static public is the currently approved order.
  [ticket/11157] static public is the currently approved order.
  [ticket/11157] Fix remaining captcha spam.
  [ticket/11157] get_captcha_types is an instance method.
  [ticket/11156] Delete "Misc" tab of forum based permissions + move items
  [ticket/10848] Move include up.
  [ticket/11014] Fix old pagination assignment
  [ticket/11018] Fix several paginations in ACP
  [ticket/11014] Fix IF statements for new template pagination
  ...

Conflicts:
	phpBB/includes/functions_user.php
This commit is contained in:
Oleg Pudeyev
2012-11-06 11:11:27 -05:00
1002 changed files with 35913 additions and 19014 deletions

View File

@@ -2,9 +2,8 @@
/**
*
* @package phpBB3
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
@@ -19,7 +18,8 @@ if (!defined('IN_PHPBB'))
Ability to simply add own rules by doing three things:
1) Add an appropriate constant
2) Add a new check array to the global_privmsgs_rules variable and the condition array (if one is required)
3) Add a new language variable to ucp.php
3) Implement the rule logic in the check_rule() function
4) Add a new language variable to ucp.php
The user is then able to select the new rule. It will be checked against and handled as specified.
To add new actions (yes, checks can be added here too) to the rule management, the core code has to be modified.
@@ -57,42 +57,42 @@ define('CHECK_TO', 5);
*/
$global_privmsgs_rules = array(
CHECK_SUBJECT => array(
RULE_IS_LIKE => array('check0' => 'message_subject', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
RULE_IS_NOT_LIKE => array('check0' => 'message_subject', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
RULE_IS => array('check0' => 'message_subject', 'function' => '{CHECK0} == {STRING}'),
RULE_IS_NOT => array('check0' => 'message_subject', 'function' => '{CHECK0} != {STRING}'),
RULE_BEGINS_WITH => array('check0' => 'message_subject', 'function' => 'preg_match("/^" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
RULE_ENDS_WITH => array('check0' => 'message_subject', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "$/i", {CHECK0})'),
RULE_IS_LIKE => array('check0' => 'message_subject'),
RULE_IS_NOT_LIKE => array('check0' => 'message_subject'),
RULE_IS => array('check0' => 'message_subject'),
RULE_IS_NOT => array('check0' => 'message_subject'),
RULE_BEGINS_WITH => array('check0' => 'message_subject'),
RULE_ENDS_WITH => array('check0' => 'message_subject'),
),
CHECK_SENDER => array(
RULE_IS_LIKE => array('check0' => 'username', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
RULE_IS_NOT_LIKE => array('check0' => 'username', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
RULE_IS => array('check0' => 'username', 'function' => '{CHECK0} == {STRING}'),
RULE_IS_NOT => array('check0' => 'username', 'function' => '{CHECK0} != {STRING}'),
RULE_BEGINS_WITH => array('check0' => 'username', 'function' => 'preg_match("/^" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
RULE_ENDS_WITH => array('check0' => 'username', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "$/i", {CHECK0})'),
RULE_IS_FRIEND => array('check0' => 'friend', 'function' => '{CHECK0} == 1'),
RULE_IS_FOE => array('check0' => 'foe', 'function' => '{CHECK0} == 1'),
RULE_IS_USER => array('check0' => 'author_id', 'function' => '{CHECK0} == {USER_ID}'),
RULE_IS_GROUP => array('check0' => 'author_in_group', 'function' => 'in_array({GROUP_ID}, {CHECK0})'),
RULE_IS_LIKE => array('check0' => 'username'),
RULE_IS_NOT_LIKE => array('check0' => 'username'),
RULE_IS => array('check0' => 'username'),
RULE_IS_NOT => array('check0' => 'username'),
RULE_BEGINS_WITH => array('check0' => 'username'),
RULE_ENDS_WITH => array('check0' => 'username'),
RULE_IS_FRIEND => array('check0' => 'friend'),
RULE_IS_FOE => array('check0' => 'foe'),
RULE_IS_USER => array('check0' => 'author_id'),
RULE_IS_GROUP => array('check0' => 'author_in_group'),
),
CHECK_MESSAGE => array(
RULE_IS_LIKE => array('check0' => 'message_text', 'function' => 'preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0})'),
RULE_IS_NOT_LIKE => array('check0' => 'message_text', 'function' => '!(preg_match("/" . preg_quote({STRING}, "/") . "/i", {CHECK0}))'),
RULE_IS => array('check0' => 'message_text', 'function' => '{CHECK0} == {STRING}'),
RULE_IS_NOT => array('check0' => 'message_text', 'function' => '{CHECK0} != {STRING}'),
RULE_IS_LIKE => array('check0' => 'message_text'),
RULE_IS_NOT_LIKE => array('check0' => 'message_text'),
RULE_IS => array('check0' => 'message_text'),
RULE_IS_NOT => array('check0' => 'message_text'),
),
CHECK_STATUS => array(
RULE_ANSWERED => array('check0' => 'pm_replied', 'function' => '{CHECK0} == 1'),
RULE_FORWARDED => array('check0' => 'pm_forwarded', 'function' => '{CHECK0} == 1'),
RULE_ANSWERED => array('check0' => 'pm_replied'),
RULE_FORWARDED => array('check0' => 'pm_forwarded'),
),
CHECK_TO => array(
RULE_TO_GROUP => array('check0' => 'to', 'check1' => 'bcc', 'check2' => 'user_in_group', 'function' => 'in_array("g_" . {CHECK2}, {CHECK0}) || in_array("g_" . {CHECK2}, {CHECK1})'),
RULE_TO_ME => array('check0' => 'to', 'check1' => 'bcc', 'function' => 'in_array("u_" . $user_id, {CHECK0}) || in_array("u_" . $user_id, {CHECK1})'),
RULE_TO_GROUP => array('check0' => 'to', 'check1' => 'bcc', 'check2' => 'user_in_group'),
RULE_TO_ME => array('check0' => 'to', 'check1' => 'bcc'),
)
);
@@ -260,16 +260,60 @@ function check_rule(&$rules, &$rule_row, &$message_row, $user_id)
$check_ary = $rules[$rule_row['rule_check']][$rule_row['rule_connection']];
// Replace Check Literals
$evaluate = $check_ary['function'];
$evaluate = preg_replace('/{(CHECK[0-9])}/', '$message_row[$check_ary[strtolower("\1")]]', $evaluate);
// Replace Rule Literals
$evaluate = preg_replace('/{(STRING|USER_ID|GROUP_ID)}/', '$rule_row["rule_" . strtolower("\1")]', $evaluate);
// Evil Statement
$result = false;
eval('$result = (' . $evaluate . ') ? true : false;');
$check0 = $message_row[$check_ary['check0']];
switch ($rule_row['rule_connection'])
{
case RULE_IS_LIKE:
$result = preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0);
break;
case RULE_IS_NOT_LIKE:
$result = !preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0);
break;
case RULE_IS:
$result = ($check0 == $rule_row['rule_string']);
break;
case RULE_IS_NOT:
$result = ($check0 != $rule_row['rule_string']);
break;
case RULE_BEGINS_WITH:
$result = preg_match("/^" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0);
break;
case RULE_ENDS_WITH:
$result = preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '$/i', $check0);
break;
case RULE_IS_FRIEND:
case RULE_IS_FOE:
case RULE_ANSWERED:
case RULE_FORWARDED:
$result = ($check0 == 1);
break;
case RULE_IS_USER:
$result = ($check0 == $rule_row['rule_user_id']);
break;
case RULE_IS_GROUP:
$result = in_array($rule_row['rule_group_id'], $check0);
break;
case RULE_TO_GROUP:
$result = (in_array('g_' . $message_row[$check_ary['check2']], $check0) || in_array('g_' . $message_row[$check_ary['check2']], $message_row[$check_ary['check1']]));
break;
case RULE_TO_ME:
$result = (in_array('u_' . $user_id, $check0) || in_array('u_' . $user_id, $message_row[$check_ary['check1']]));
break;
}
if (!$result)
{
@@ -299,7 +343,7 @@ function check_rule(&$rules, &$rule_row, &$message_row, $user_id)
$userdata = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$auth2 = new auth();
$auth2 = new phpbb_auth();
$auth2->acl($userdata);
if (!$auth2->acl_get('a_') && !$auth2->acl_get('m_') && !$auth2->acl_getf_global('m_'))
@@ -1083,6 +1127,222 @@ function delete_pm($user_id, $msg_ids, $folder_id)
return true;
}
/**
* Delete all PM(s) for a given user and delete the ones without references
*
* @param int $user_id ID of the user whose private messages we want to delete
*
* @return boolean False if there were no pms found, true otherwise.
*/
function phpbb_delete_user_pms($user_id)
{
global $db, $user, $phpbb_root_path, $phpEx;
$user_id = (int) $user_id;
if (!$user_id)
{
return false;
}
return phpbb_delete_users_pms(array($user_id));
}
/**
* Delete all PM(s) for given users and delete the ones without references
*
* @param array $user_ids IDs of the users whose private messages we want to delete
*
* @return boolean False if there were no pms found, true otherwise.
*/
function phpbb_delete_users_pms($user_ids)
{
global $db, $user, $phpbb_root_path, $phpEx;
$user_id_sql = $db->sql_in_set('user_id', $user_ids);
$author_id_sql = $db->sql_in_set('author_id', $user_ids);
// Get PM Information for later deleting
// The two queries where split, so we can use our indexes
$undelivered_msg = $delete_ids = array();
// Part 1: get PMs the user received
$sql = 'SELECT msg_id
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE ' . $user_id_sql;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$msg_id = (int) $row['msg_id'];
$delete_ids[$msg_id] = $msg_id;
}
$db->sql_freeresult($result);
// Part 2: get PMs the users sent, but are yet to be received.
// We cannot simply delete them. First we have to check
// whether another user already received and read the message.
$sql = 'SELECT msg_id
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE ' . $author_id_sql . '
AND folder_id = ' . PRIVMSGS_NO_BOX;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$msg_id = (int) $row['msg_id'];
$undelivered_msg[$msg_id] = $msg_id;
}
$db->sql_freeresult($result);
if (empty($delete_ids) && empty($undelivered_msg))
{
return false;
}
$db->sql_transaction('begin');
if (!empty($undelivered_msg))
{
// A pm is delivered, if for any recipient the message was moved
// from their NO_BOX to another folder. We do not delete such
// messages, but only delete them for users, who have not yet
// received them.
$sql = 'SELECT msg_id
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE ' . $author_id_sql . '
AND folder_id <> ' . PRIVMSGS_NO_BOX . '
AND folder_id <> ' . PRIVMSGS_OUTBOX . '
AND folder_id <> ' . PRIVMSGS_SENTBOX;
$result = $db->sql_query($sql);
$delivered_msg = array();
while ($row = $db->sql_fetchrow($result))
{
$msg_id = (int) $row['msg_id'];
$delivered_msg[$msg_id] = $msg_id;
unset($undelivered_msg[$msg_id]);
}
$db->sql_freeresult($result);
$undelivered_user = array();
// Count the messages we delete, so we can correct the user pm data
$sql = 'SELECT user_id, COUNT(msg_id) as num_undelivered_privmsgs
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE ' . $author_id_sql . '
AND folder_id = ' . PRIVMSGS_NO_BOX . '
AND ' . $db->sql_in_set('msg_id', array_merge($undelivered_msg, $delivered_msg)) . '
GROUP BY user_id';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$num_pms = (int) $row['num_undelivered_privmsgs'];
$undelivered_user[$num_pms][] = (int) $row['user_id'];
if (sizeof($undelivered_user[$num_pms]) > 50)
{
// If there are too many users affected the query might get
// too long, so we update the value for the first bunch here.
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_new_privmsg = user_new_privmsg - ' . $num_pms . ',
user_unread_privmsg = user_unread_privmsg - ' . $num_pms . '
WHERE ' . $db->sql_in_set('user_id', $undelivered_user[$num_pms]);
$db->sql_query($sql);
unset($undelivered_user[$num_pms]);
}
}
$db->sql_freeresult($result);
foreach ($undelivered_user as $num_pms => $undelivered_user_set)
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_new_privmsg = user_new_privmsg - ' . $num_pms . ',
user_unread_privmsg = user_unread_privmsg - ' . $num_pms . '
WHERE ' . $db->sql_in_set('user_id', $undelivered_user_set);
$db->sql_query($sql);
}
if (!empty($delivered_msg))
{
$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
WHERE folder_id = ' . PRIVMSGS_NO_BOX . '
AND ' . $db->sql_in_set('msg_id', $delivered_msg);
$db->sql_query($sql);
}
if (!empty($undelivered_msg))
{
$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg);
$db->sql_query($sql);
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg);
$db->sql_query($sql);
}
}
// Reset the user's pm count to 0
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_new_privmsg = 0,
user_unread_privmsg = 0
WHERE ' . $user_id_sql;
$db->sql_query($sql);
// Delete private message data of the user
$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
WHERE ' . $user_id_sql;
$db->sql_query($sql);
if (!empty($delete_ids))
{
// Now we have to check which messages we can delete completely
$sql = 'SELECT msg_id
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
unset($delete_ids[$row['msg_id']]);
}
$db->sql_freeresult($result);
if (!empty($delete_ids))
{
// Check if there are any attachments we need to remove
if (!function_exists('delete_attachments'))
{
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
}
delete_attachments('message', $delete_ids, false);
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
$db->sql_query($sql);
}
}
// Set the remaining author id to anonymous
// This way users are still able to read messages from users being removed
$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
SET author_id = ' . ANONYMOUS . '
WHERE ' . $author_id_sql;
$db->sql_query($sql);
$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
SET author_id = ' . ANONYMOUS . '
WHERE ' . $author_id_sql;
$db->sql_query($sql);
$db->sql_transaction('commit');
return true;
}
/**
* Rebuild message header
*/
@@ -1285,7 +1545,7 @@ function get_folder_status($folder_id, $folder)
'percent' => ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? round(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0,
);
$return['message'] = sprintf($user->lang['FOLDER_STATUS_MSG'], $return['percent'], $return['cur'], $return['max']);
$return['message'] = $user->lang('FOLDER_STATUS_MSG', (int) $return['max'], $return['cur'], $return['percent']);
return $return;
}
@@ -1362,12 +1622,6 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
while ($row = $db->sql_fetchrow($result))
{
// Additionally, do not include the sender if he is in the group he wants to send to. ;)
if ($row['user_id'] === $user->data['user_id'])
{
continue;
}
$field = ($data['address_list']['g'][$row['group_id']] == 'to') ? 'to' : 'bcc';
$recipients[$row['user_id']] = $field;
}
@@ -1607,7 +1861,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
// Send Notifications
if ($mode != 'edit')
{
pm_notification($mode, $data['from_username'], $recipients, $subject, $data['message']);
pm_notification($mode, $data['from_username'], $recipients, $subject, $data['message'], $data['msg_id']);
}
return $data['msg_id'];
@@ -1616,12 +1870,13 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
/**
* PM Notification
*/
function pm_notification($mode, $author, $recipients, $subject, $message)
function pm_notification($mode, $author, $recipients, $subject, $message, $msg_id)
{
global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
$subject = censor_text($subject);
// Exclude guests, current user and banned users from notifications
unset($recipients[ANONYMOUS], $recipients[$user->data['user_id']]);
if (!sizeof($recipients))
@@ -1629,18 +1884,12 @@ function pm_notification($mode, $author, $recipients, $subject, $message)
return;
}
// Get banned User ID's
$sql = 'SELECT ban_userid
FROM ' . BANLIST_TABLE . '
WHERE ' . $db->sql_in_set('ban_userid', array_map('intval', array_keys($recipients))) . '
AND ban_exclude = 0';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
if (!function_exists('phpbb_get_banned_user_ids'))
{
unset($recipients[$row['ban_userid']]);
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
}
$db->sql_freeresult($result);
$banned_users = phpbb_get_banned_user_ids(array_keys($recipients));
$recipients = array_diff(array_keys($recipients), $banned_users);
if (!sizeof($recipients))
{
@@ -1649,7 +1898,7 @@ function pm_notification($mode, $author, $recipients, $subject, $message)
$sql = 'SELECT user_id, username, user_email, user_lang, user_notify_pm, user_notify_type, user_jabber
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', array_map('intval', array_keys($recipients)));
WHERE ' . $db->sql_in_set('user_id', $recipients);
$result = $db->sql_query($sql);
$msg_list_ary = array();
@@ -1688,8 +1937,9 @@ function pm_notification($mode, $author, $recipients, $subject, $message)
'AUTHOR_NAME' => htmlspecialchars_decode($author),
'USERNAME' => htmlspecialchars_decode($addr['name']),
'U_INBOX' => generate_board_url() . "/ucp.$phpEx?i=pm&folder=inbox")
);
'U_INBOX' => generate_board_url() . "/ucp.$phpEx?i=pm&folder=inbox",
'U_VIEW_MESSAGE' => generate_board_url() . "/ucp.$phpEx?i=pm&mode=view&p=$msg_id",
));
$messenger->send($addr['method']);
}
@@ -1851,7 +2101,7 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode
'SUBJECT' => $subject,
'SENT_DATE' => $user->format_date($row['message_time']),
'MESSAGE' => $message,
'FOLDER' => implode(', ', $row['folder']),
'FOLDER' => implode($user->lang['COMMA_SEPARATOR'], $row['folder']),
'DECODED_MESSAGE' => $decoded_message,
'S_CURRENT_MSG' => ($row['msg_id'] == $msg_id),