diff options
-rw-r--r-- | phpBB/includes/constants.php | 8 | ||||
-rw-r--r-- | phpBB/includes/functions_user.php | 26 | ||||
-rw-r--r-- | phpBB/includes/ucp/ucp_pm_compose.php | 84 | ||||
-rw-r--r-- | phpBB/language/en/ucp.php | 1 | ||||
-rw-r--r-- | phpBB/memberlist.php | 25 | ||||
-rw-r--r-- | phpBB/viewtopic.php | 31 | ||||
-rw-r--r-- | tests/functions/fixtures/banned_users.xml | 38 | ||||
-rw-r--r-- | tests/functions/phpbb_get_banned_user_ids.php | 58 |
8 files changed, 246 insertions, 25 deletions
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index a59b4a8add..66d2e4bd81 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -46,10 +46,10 @@ define('USER_INACTIVE', 1); define('USER_IGNORE', 2); define('USER_FOUNDER', 3); -define('INACTIVE_REGISTER', 1); -define('INACTIVE_PROFILE', 2); -define('INACTIVE_MANUAL', 3); -define('INACTIVE_REMIND', 4); +define('INACTIVE_REGISTER', 1); // Newly registered account +define('INACTIVE_PROFILE', 2); // Profile details changed +define('INACTIVE_MANUAL', 3); // Account deactivated by administrator +define('INACTIVE_REMIND', 4); // Forced user account reactivation // ACL define('ACL_NEVER', 0); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index dcc0d727a1..0dd1708c55 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -3455,9 +3455,12 @@ function remove_newly_registered($user_id, $user_data = false) * * @param array $user_ids Array of users' ids to check for banning, * leave empty to get complete list of banned ids +* @param bool|int $ban_end Bool True to get users currently banned +* Bool False to only get permanently banned users +* Int Unix timestamp to get users banned until that time * @return array Array of banned users' ids if any, empty array otherwise */ -function phpbb_get_banned_user_ids($user_ids = array()) +function phpbb_get_banned_user_ids($user_ids = array(), $ban_end = true) { global $db; @@ -3469,9 +3472,26 @@ function phpbb_get_banned_user_ids($user_ids = array()) $sql = 'SELECT ban_userid FROM ' . BANLIST_TABLE . " WHERE $sql_user_ids - AND ban_exclude <> 1 - AND (ban_end > " . time() . ' + AND ban_exclude <> 1"; + + if ($ban_end === true) + { + // Banned currently + $sql .= " AND (ban_end > " . time() . ' + OR ban_end = 0)'; + } + else if ($ban_end === false) + { + // Permanently banned + $sql .= " AND ban_end = 0"; + } + else + { + // Banned until a specified time + $sql .= " AND (ban_end > " . (int) $ban_end . ' OR ban_end = 0)'; + } + $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index e5a1c1b915..3219771c93 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -1226,29 +1226,81 @@ function handle_message_list_actions(&$address_list, &$error, $remove_u, $remove // Check for disallowed recipients if (!empty($address_list['u'])) { - // We need to check their PM status (do they want to receive PM's?) - // Only check if not a moderator or admin, since they are allowed to override this user setting - if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) + // Administrator deactivated users check and we need to check their + // PM status (do they want to receive PM's?) + // Only check PM status if not a moderator or admin, since they + // are allowed to override this user setting + $sql = 'SELECT user_id, user_allow_pm + FROM ' . USERS_TABLE . ' + WHERE ' . $db->sql_in_set('user_id', array_keys($address_list['u'])) . ' + AND (user_type = ' . USER_INACTIVE . ' + AND user_inactive_reason = ' . INACTIVE_MANUAL . ')'; + + $can_ignore_allow_pm = ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_')); + if (!$can_ignore_allow_pm) { - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . ' - WHERE ' . $db->sql_in_set('user_id', array_keys($address_list['u'])) . ' - AND user_allow_pm = 0'; - $result = $db->sql_query($sql); + $sql .= ' OR user_allow_pm = 0'; + } - $removed = false; - while ($row = $db->sql_fetchrow($result)) + $result = $db->sql_query($sql); + + $removed_no_pm = $removed_no_permission = false; + while ($row = $db->sql_fetchrow($result)) + { + if (!$can_ignore_allow_pm && !$row['user_allow_pm']) { - $removed = true; - unset($address_list['u'][$row['user_id']]); + $removed_no_pm = true; } - $db->sql_freeresult($result); + else + { + $removed_no_permission = true; + } + + unset($address_list['u'][$row['user_id']]); + } + $db->sql_freeresult($result); - // print a notice about users not being added who do not want to receive pms - if ($removed) + // print a notice about users not being added who do not want to receive pms + if ($removed_no_pm) + { + $error[] = $user->lang['PM_USERS_REMOVED_NO_PM']; + } + + // print a notice about users not being added who do not have permission to receive PMs + if ($removed_no_permission) + { + $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION']; + } + + if (!sizeof(array_keys($address_list['u']))) + { + return; + } + + // Check if users have permission to read PMs + $can_read = $auth->acl_get_list(array_keys($address_list['u']), 'u_readpm'); + $can_read = (empty($can_read) || !isset($can_read[0]['u_readpm'])) ? array() : $can_read[0]['u_readpm']; + $cannot_read_list = array_diff(array_keys($address_list['u']), $can_read); + if (!empty($cannot_read_list)) + { + foreach ($cannot_read_list as $cannot_read) { - $error[] = $user->lang['PM_USERS_REMOVED_NO_PM']; + unset($address_list['u'][$cannot_read]); } + + $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION']; + } + + // Check if users are banned + $banned_user_list = phpbb_get_banned_user_ids(array_keys($address_list['u']), false); + if (!empty($banned_user_list)) + { + foreach ($banned_user_list as $banned_user) + { + unset($address_list['u'][$banned_user]); + } + + $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION']; } } } diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 79d2b9fa3a..3419d34e7a 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -413,6 +413,7 @@ $lang = array_merge($lang, array( 'PM_SUBJECT' => 'Message subject', 'PM_TO' => 'Send to', 'PM_TOOLS' => 'Message tools', + 'PM_USERS_REMOVED_NO_PERMISSION' => 'Some users couldn’t be added as they do not have permission to read private messages.', 'PM_USERS_REMOVED_NO_PM' => 'Some users couldn’t be added as they have disabled private message receipt.', 'POST_EDIT_PM' => 'Edit message', 'POST_FORWARD_PM' => 'Forward message', diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 63c8dc0c08..9c6b3d278f 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1720,6 +1720,29 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f } } + if (!function_exists('phpbb_get_banned_user_ids')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + // Can this user receive a Private Message? + $can_receive_pm = ( + // They must be a "normal" user + $data['user_type'] != USER_IGNORE && + + // They must not be deactivated by the administrator + ($data['user_type'] != USER_INACTIVE && $data['user_inactive_reason'] == INACTIVE_MANUAL) && + + // They must be able to read PMs + sizeof($auth->acl_get_list($user_id, 'u_readpm')) && + + // They must not be permanently banned + !sizeof(phpbb_get_banned_user_ids($user_id, false)) && + + // They must allow users to contact via PM + (($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_')) || $data['user_allow_pm']) + ); + // Dump it out to the template $template_data = array( 'AGE' => $age, @@ -1748,7 +1771,7 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f 'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$user_id&sr=posts") : '', 'U_NOTES' => ($user_notes_enabled && $auth->acl_getf_global('m_')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $user_id, true, $user->session_id) : '', 'U_WARN' => ($warn_user_enabled && $auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&mode=warn_user&u=' . $user_id, true, $user->session_id) : '', - 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($data['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&u=' . $user_id) : '', + 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && $can_receive_pm) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&u=' . $user_id) : '', 'U_EMAIL' => $email, 'U_JABBER' => ($data['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=jabber&u=' . $user_id) : '', diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 36d7533254..fc40dd65bb 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -16,6 +16,7 @@ $phpEx = substr(strrchr(__FILE__, '.'), 1); include($phpbb_root_path . 'common.' . $phpEx); include($phpbb_root_path . 'includes/functions_display.' . $phpEx); include($phpbb_root_path . 'includes/bbcode.' . $phpEx); +include($phpbb_root_path . 'includes/functions_user.' . $phpEx); // Start session management $user->session_begin(); @@ -1163,6 +1164,9 @@ while ($row = $db->sql_fetchrow($result)) $id_cache[] = $poster_id; $user_cache_data = array( + 'user_type' => $row['user_type'], + 'user_inactive_reason' => $row['user_inactive_reason'], + 'joined' => $user->format_date($row['user_regdate']), 'posts' => $row['user_posts'], 'warnings' => (isset($row['user_warnings'])) ? $row['user_warnings'] : 0, @@ -1374,6 +1378,13 @@ if ($bbcode_bitfield !== '') $bbcode = new bbcode(base64_encode($bbcode_bitfield)); } +// Get the list of users who can receive private messages +$can_receive_pm_list = $auth->acl_get_list(array_keys($user_cache), 'u_readpm'); +$can_receive_pm_list = (empty($can_receive_pm_list) || !isset($can_receive_pm_list[0]['u_readpm'])) ? array() : $can_receive_pm_list[0]['u_readpm']; + +// Get the list of permanently banned users +$permanently_banned_users = phpbb_get_banned_user_ids(array_keys($user_cache), false); + $i_total = sizeof($rowset) - 1; $prev_post_id = ''; @@ -1592,6 +1603,24 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) !$row['post_edit_locked'] ))); + // Can this user receive a Private Message? + $can_receive_pm = ( + // They must be a "normal" user + $user_cache[$poster_id]['user_type'] != USER_IGNORE && + + // They must not be deactivated by the administrator + ($user_cache[$poster_id]['user_type'] != USER_INACTIVE && $user_cache[$poster_id]['user_inactive_reason'] == INACTIVE_MANUAL) && + + // They must be able to read PMs + in_array($poster_id, $can_receive_pm_list) && + + // They must not be permanently banned + !in_array($poster_id, $permanently_banned_users) && + + // They must allow users to contact via PM + (($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_')) || $data['user_allow_pm']) + ); + // $post_row = array( 'POST_AUTHOR_FULL' => ($poster_id != ANONYMOUS) ? $user_cache[$poster_id]['author_full'] : get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), @@ -1631,7 +1660,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'U_DELETE' => ($delete_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=delete&f=$forum_id&p={$row['post_id']}") : '', 'U_SEARCH' => $user_cache[$poster_id]['search'], - 'U_PM' => ($poster_id != ANONYMOUS && $config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($user_cache[$poster_id]['allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&action=quotepost&p=' . $row['post_id']) : '', + 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && $can_receive_pm) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&action=quotepost&p=' . $row['post_id']) : '', 'U_EMAIL' => $user_cache[$poster_id]['email'], 'U_JABBER' => $user_cache[$poster_id]['jabber'], diff --git a/tests/functions/fixtures/banned_users.xml b/tests/functions/fixtures/banned_users.xml new file mode 100644 index 0000000000..cec3f4e51f --- /dev/null +++ b/tests/functions/fixtures/banned_users.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_banlist"> + <column>ban_userid</column> + <column>ban_exclude</column> + <column>ban_end</column> + <row> + <value>1</value> + <value>1</value> + <value>0</value> + </row> + <row> + <value>2</value> + <value>0</value> + <value>0</value> + </row> + <row> + <value>3</value> + <value>0</value> + <value>0</value> + </row> + <row> + <value>4</value> + <value>0</value> + <value>2</value> + </row> + <row> + <value>5</value> + <value>0</value> + <value>999999999999999999999</value> + </row> + <row> + <value>6</value> + <value>0</value> + <value>3</value> + </row> + </table> +</dataset> diff --git a/tests/functions/phpbb_get_banned_user_ids.php b/tests/functions/phpbb_get_banned_user_ids.php new file mode 100644 index 0000000000..96de5c5767 --- /dev/null +++ b/tests/functions/phpbb_get_banned_user_ids.php @@ -0,0 +1,58 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php'; + +class phpbb_get_banned_user_ids_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/banned_users.xml'); + } + + public function phpbb_get_banned_user_ids_data() + { + return array( + // Input to phpbb_get_banned_user_ids (user_id list, ban_end) + // Expected output + array( + // True to get users currently banned + array(array(1, 2, 4, 5, 6), true), + array(2 => 2, 5 => 5), + ), + array( + // False to only get permanently banned users + array(array(1, 2, 4, 5, 6), false), + array(2 => 2), + ), + array( + // Unix timestamp to get users banned until that time + array(array(1, 2, 4, 5, 6), 2), + array(2 => 2, 5 => 5, 6 => 6), + ), + ); + } + + public function setUp() + { + global $db; + + $db = $this->new_dbal(); + + return parent::setUp(); + } + + /** + * @dataProvider phpbb_get_banned_user_ids_data + */ + public function test_phpbb_get_banned_user_ids($input, $expected) + { + $this->assertEquals($expected, call_user_func_array('phpbb_get_banned_user_ids', $input)); + } +} |