Try this --> http://yourboard.com/phpBB3/install/safekyle wrote:Tried again,
using this domain, as it is uploaded on my FTP
http://scooternations.com/public_html/phpBB3/install
Still no luck, is there some sort of non viewing from hostgator?
Code: Select all
[phpBB Debug] PHP Warning: in file [ROOT]/install/convertors/functions_phpbb20.php on line 414: include(./../../language/lang_/lang_main.php) [function.include]: failed to open stream: No such file or directory
[phpBB Debug] PHP Warning: in file [ROOT]/install/convertors/functions_phpbb20.php on line 414: include(./../../language/lang_/lang_main.php) [function.include]: failed to open stream: No such file or directory
[phpBB Debug] PHP Warning: in file [ROOT]/install/convertors/functions_phpbb20.php on line 414: include() [function.include]: Failed opening './../../language/lang_/lang_main.php' for inclusion (include_path='.:/usr/lib64/php:/usr/lib/php:/usr/share/pear')
[phpBB Debug] PHP Warning: in file [ROOT]/install/convertors/functions_phpbb20.php on line 414: include(./../../language/lang_/lang_main.php) [function.include]: failed to open stream: No such file or directory
[phpBB Debug] PHP Warning: in file [ROOT]/install/convertors/functions_phpbb20.php on line 414: include(./../../language/lang_/lang_main.php) [function.include]: failed to open stream: No such file or directory
[phpBB Debug] PHP Warning: in file [ROOT]/install/convertors/functions_phpbb20.php on line 414: include() [function.include]: Failed opening './../../language/lang_/lang_main.php' for inclusion (include_path='.:/usr/lib64/php:/usr/lib/php:/usr/share/pear')
Return to the index page
General Error
SQL ERROR [ mysql4 ]
Table 'bikesje1_bikes_je.USERCONV_TABLE' doesn't exist [1146]
SQL
SELECT username_clean FROM USERCONV_TABLE GROUP BY username_clean HAVING COUNT(user_id) > 1
BACKTRACE
FILE: (not given by php)
LINE: (not given by php)
CALL: msg_handler()
FILE: [ROOT]/includes/db/dbal.php
LINE: 757
CALL: trigger_error()
FILE: [ROOT]/includes/db/mysql.php
LINE: 175
CALL: dbal->sql_error()
FILE: [ROOT]/install/convertors/functions_phpbb20.php
LINE: 1810
CALL: dbal_mysql->sql_query()
FILE: [ROOT]/install/install_convert.php(1003) : eval()'d code
LINE: 3
CALL: phpbb_check_username_collisions()
FILE: [ROOT]/install/install_convert.php
LINE: 1003
CALL: eval()
FILE: [ROOT]/install/install_convert.php
LINE: 203
CALL: install_convert->convert_data()
FILE: [ROOT]/install/index.php
LINE: 326
CALL: install_convert->main()
FILE: [ROOT]/install/index.php
LINE: 203
CALL: module->load()
[ROOT]/install/convertors/functions_phpbb20.php
suggests that you're using the phpBB2 convertor.convert_vb30_THIS DOES vb4.02.php
and rename that to convert_vb30.php
and thus overwriting the old convert_vb30.php
with the new one. Then move the install and includes directories to the phpBB board root. Once you click on the Convert tab in the installer, you will be provided with two options: phpBB 2.0.x and vBulletin 3.x.Code: Select all
<?php
/**
*
* @package phpBB3
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Obtain user_ids from usernames or vice versa. Returns false on
* success else the error string
*
* @param array &$user_id_ary The user ids to check or empty if usernames used
* @param array &$username_ary The usernames to check or empty if user ids used
* @param mixed $user_type Array of user types to check, false if not restricting by user type
*/
function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false)
{
global $db;
// Are both arrays already filled? Yep, return else
// are neither array filled?
if ($user_id_ary && $username_ary)
{
return false;
}
else if (!$user_id_ary && !$username_ary)
{
return 'NO_USERS';
}
$which_ary = ($user_id_ary) ? 'user_id_ary' : 'username_ary';
if ($$which_ary && !is_array($$which_ary))
{
$$which_ary = array($$which_ary);
}
$sql_in = ($which_ary == 'user_id_ary') ? array_map('intval', $$which_ary) : array_map('utf8_clean_string', $$which_ary);
unset($$which_ary);
$user_id_ary = $username_ary = array();
// Grab the user id/username records
$sql_where = ($which_ary == 'user_id_ary') ? 'user_id' : 'username_clean';
$sql = 'SELECT user_id, username
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set($sql_where, $sql_in);
if ($user_type !== false && !empty($user_type))
{
$sql .= ' AND ' . $db->sql_in_set('user_type', $user_type);
}
$result = $db->sql_query($sql);
if (!($row = $db->sql_fetchrow($result)))
{
$db->sql_freeresult($result);
return 'NO_USERS';
}
do
{
$username_ary[$row['user_id']] = $row['username'];
$user_id_ary[] = $row['user_id'];
}
while ($row = $db->sql_fetchrow($result));
$db->sql_freeresult($result);
return false;
}
/**
* Get latest registered username and update database to reflect it
*/
function update_last_username()
{
global $db;
// Get latest username
$sql = 'SELECT user_id, username, user_colour
FROM ' . USERS_TABLE . '
WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')
ORDER BY user_id DESC';
$result = $db->sql_query_limit($sql, 1);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
set_config('newest_user_id', $row['user_id'], true);
set_config('newest_username', $row['username'], true);
set_config('newest_user_colour', $row['user_colour'], true);
}
}
/**
* Updates a username across all relevant tables/fields
*
* @param string $old_name the old/current username
* @param string $new_name the new username
*/
function user_update_name($old_name, $new_name)
{
global $config, $db, $cache;
$update_ary = array(
FORUMS_TABLE => array('forum_last_poster_name'),
MODERATOR_CACHE_TABLE => array('username'),
POSTS_TABLE => array('post_username'),
TOPICS_TABLE => array('topic_first_poster_name', 'topic_last_poster_name'),
);
foreach ($update_ary as $table => $field_ary)
{
foreach ($field_ary as $field)
{
$sql = "UPDATE $table
SET $field = '" . $db->sql_escape($new_name) . "'
WHERE $field = '" . $db->sql_escape($old_name) . "'";
$db->sql_query($sql);
}
}
if ($config['newest_username'] == $old_name)
{
set_config('newest_username', $new_name, true);
}
// Because some tables/caches use username-specific data we need to purge this here.
$cache->destroy('sql', MODERATOR_CACHE_TABLE);
}
/**
* Adds an user
*
* @param mixed $user_row An array containing the following keys (and the appropriate values): username, group_id (the group to place the user in), user_email and the user_type(usually 0). Additional entries not overridden by defaults will be forwarded.
* @param string $cp_data custom profile fields, see custom_profile::build_insert_sql_array
* @return the new user's ID.
*/
function user_add($user_row, $cp_data = false)
{
global $db, $user, $auth, $config, $phpbb_root_path, $phpEx;
if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type']))
{
return false;
}
$username_clean = utf8_clean_string($user_row['username']);
if (empty($username_clean))
{
return false;
}
$sql_ary = array(
'username' => $user_row['username'],
'username_clean' => $username_clean,
'user_password' => (isset($user_row['user_password'])) ? $user_row['user_password'] : '',
'user_pass_convert' => 0,
'user_email' => strtolower($user_row['user_email']),
'user_email_hash' => phpbb_email_hash($user_row['user_email']),
'group_id' => $user_row['group_id'],
'user_type' => $user_row['user_type'],
);
// These are the additional vars able to be specified
$additional_vars = array(
'user_permissions' => '',
'user_timezone' => $config['board_timezone'],
'user_dateformat' => $config['default_dateformat'],
'user_lang' => $config['default_lang'],
'user_style' => (int) $config['default_style'],
'user_actkey' => '',
'user_ip' => '',
'user_regdate' => time(),
'user_passchg' => time(),
'user_options' => 230271,
// We do not set the new flag here - registration scripts need to specify it
'user_new' => 0,
'user_inactive_reason' => 0,
'user_inactive_time' => 0,
'user_lastmark' => time(),
'user_lastvisit' => 0,
'user_lastpost_time' => 0,
'user_lastpage' => '',
'user_posts' => 0,
'user_dst' => (int) $config['board_dst'],
'user_colour' => '',
'user_occ' => '',
'user_interests' => '',
'user_avatar' => '',
'user_avatar_type' => 0,
'user_avatar_width' => 0,
'user_avatar_height' => 0,
'user_new_privmsg' => 0,
'user_unread_privmsg' => 0,
'user_last_privmsg' => 0,
'user_message_rules' => 0,
'user_full_folder' => PRIVMSGS_NO_BOX,
'user_emailtime' => 0,
'user_notify' => 0,
'user_notify_pm' => 1,
'user_notify_type' => NOTIFY_EMAIL,
'user_allow_pm' => 1,
'user_allow_viewonline' => 1,
'user_allow_viewemail' => 1,
'user_allow_massemail' => 1,
'user_sig' => '',
'user_sig_bbcode_uid' => '',
'user_sig_bbcode_bitfield' => '',
'user_form_salt' => unique_id(),
);
// Now fill the sql array with not required variables
foreach ($additional_vars as $key => $default_value)
{
$sql_ary[$key] = (isset($user_row[$key])) ? $user_row[$key] : $default_value;
}
// Any additional variables in $user_row not covered above?
$remaining_vars = array_diff(array_keys($user_row), array_keys($sql_ary));
// Now fill our sql array with the remaining vars
if (sizeof($remaining_vars))
{
foreach ($remaining_vars as $key)
{
$sql_ary[$key] = $user_row[$key];
}
}
$sql = 'INSERT INTO ' . USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_query($sql);
$user_id = $db->sql_nextid();
// Insert Custom Profile Fields
if ($cp_data !== false && sizeof($cp_data))
{
$cp_data['user_id'] = (int) $user_id;
if (!class_exists('custom_profile'))
{
include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx);
}
$sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' .
$db->sql_build_array('INSERT', custom_profile::build_insert_sql_array($cp_data));
$db->sql_query($sql);
}
// Place into appropriate group...
$sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' ' . $db->sql_build_array('INSERT', array(
'user_id' => (int) $user_id,
'group_id' => (int) $user_row['group_id'],
'user_pending' => 0)
);
$db->sql_query($sql);
// Now make it the users default group...
group_set_user_default($user_row['group_id'], array($user_id), false);
// Add to newly registered users group if user_new is 1
if ($config['new_member_post_limit'] && $sql_ary['user_new'])
{
$sql = 'SELECT group_id
FROM ' . GROUPS_TABLE . "
WHERE group_name = 'NEWLY_REGISTERED'
AND group_type = " . GROUP_SPECIAL;
$result = $db->sql_query($sql);
$add_group_id = (int) $db->sql_fetchfield('group_id');
$db->sql_freeresult($result);
if ($add_group_id)
{
// Because these actions only fill the log unneccessarily we skip the add_log() entry with a little hack. :/
$GLOBALS['skip_add_log'] = true;
// Add user to "newly registered users" group and set to default group if admin specified so.
if ($config['new_member_group_default'])
{
group_user_add($add_group_id, $user_id, false, false, true);
$user_row['group_id'] = $add_group_id;
}
else
{
group_user_add($add_group_id, $user_id);
}
unset($GLOBALS['skip_add_log']);
}
}
// set the newest user and adjust the user count if the user is a normal user and no activation mail is sent
if ($user_row['user_type'] == USER_NORMAL || $user_row['user_type'] == USER_FOUNDER)
{
set_config('newest_user_id', $user_id, true);
set_config('newest_username', $user_row['username'], true);
set_config_count('num_users', 1, true);
$sql = 'SELECT group_colour
FROM ' . GROUPS_TABLE . '
WHERE group_id = ' . (int) $user_row['group_id'];
$result = $db->sql_query_limit($sql, 1);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
set_config('newest_user_colour', $row['group_colour'], true);
}
return $user_id;
}
/**
* Remove User
*/
function user_delete($mode, $user_id, $post_username = false)
{
global $cache, $config, $db, $user, $auth;
global $phpbb_root_path, $phpEx;
$sql = 'SELECT *
FROM ' . USERS_TABLE . '
WHERE user_id = ' . $user_id;
$result = $db->sql_query($sql);
$user_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$user_row)
{
return false;
}
// Before we begin, we will remove the reports the user issued.
$sql = 'SELECT r.post_id, p.topic_id
FROM ' . REPORTS_TABLE . ' r, ' . POSTS_TABLE . ' p
WHERE r.user_id = ' . $user_id . '
AND p.post_id = r.post_id';
$result = $db->sql_query($sql);
$report_posts = $report_topics = array();
while ($row = $db->sql_fetchrow($result))
{
$report_posts[] = $row['post_id'];
$report_topics[] = $row['topic_id'];
}
$db->sql_freeresult($result);
if (sizeof($report_posts))
{
$report_posts = array_unique($report_posts);
$report_topics = array_unique($report_topics);
// Get a list of topics that still contain reported posts
$sql = 'SELECT DISTINCT topic_id
FROM ' . POSTS_TABLE . '
WHERE ' . $db->sql_in_set('topic_id', $report_topics) . '
AND post_reported = 1
AND ' . $db->sql_in_set('post_id', $report_posts, true);
$result = $db->sql_query($sql);
$keep_report_topics = array();
while ($row = $db->sql_fetchrow($result))
{
$keep_report_topics[] = $row['topic_id'];
}
$db->sql_freeresult($result);
if (sizeof($keep_report_topics))
{
$report_topics = array_diff($report_topics, $keep_report_topics);
}
unset($keep_report_topics);
// Now set the flags back
$sql = 'UPDATE ' . POSTS_TABLE . '
SET post_reported = 0
WHERE ' . $db->sql_in_set('post_id', $report_posts);
$db->sql_query($sql);
if (sizeof($report_topics))
{
$sql = 'UPDATE ' . TOPICS_TABLE . '
SET topic_reported = 0
WHERE ' . $db->sql_in_set('topic_id', $report_topics);
$db->sql_query($sql);
}
}
// Remove reports
$db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE user_id = ' . $user_id);
if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD)
{
avatar_delete('user', $user_row);
}
switch ($mode)
{
case 'retain':
$db->sql_transaction('begin');
if ($post_username === false)
{
$post_username = $user->lang['GUEST'];
}
// If the user is inactive and newly registered we assume no posts from this user being there...
if ($user_row['user_type'] == USER_INACTIVE && $user_row['user_inactive_reason'] == INACTIVE_REGISTER && !$user_row['user_posts'])
{
}
else
{
$sql = 'UPDATE ' . FORUMS_TABLE . '
SET forum_last_poster_id = ' . ANONYMOUS . ", forum_last_poster_name = '" . $db->sql_escape($post_username) . "', forum_last_poster_colour = ''
WHERE forum_last_poster_id = $user_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . POSTS_TABLE . '
SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "'
WHERE poster_id = $user_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . POSTS_TABLE . '
SET post_edit_user = ' . ANONYMOUS . "
WHERE post_edit_user = $user_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . TOPICS_TABLE . '
SET topic_poster = ' . ANONYMOUS . ", topic_first_poster_name = '" . $db->sql_escape($post_username) . "', topic_first_poster_colour = ''
WHERE topic_poster = $user_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . TOPICS_TABLE . '
SET topic_last_poster_id = ' . ANONYMOUS . ", topic_last_poster_name = '" . $db->sql_escape($post_username) . "', topic_last_poster_colour = ''
WHERE topic_last_poster_id = $user_id";
$db->sql_query($sql);
$sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
SET poster_id = ' . ANONYMOUS . "
WHERE poster_id = $user_id";
$db->sql_query($sql);
// Since we change every post by this author, we need to count this amount towards the anonymous user
// Update the post count for the anonymous user
if ($user_row['user_posts'])
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_posts = user_posts + ' . $user_row['user_posts'] . '
WHERE user_id = ' . ANONYMOUS;
$db->sql_query($sql);
}
}
$db->sql_transaction('commit');
break;
case 'remove':
if (!function_exists('delete_posts'))
{
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
}
// Delete posts, attachments, etc.
delete_posts('poster_id', $user_id);
break;
}
$db->sql_transaction('begin');
$table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE, DRAFTS_TABLE, BOOKMARKS_TABLE, SESSIONS_KEYS_TABLE, PRIVMSGS_FOLDER_TABLE, PRIVMSGS_RULES_TABLE);
foreach ($table_ary as $table)
{
$sql = "DELETE FROM $table
WHERE user_id = $user_id";
$db->sql_query($sql);
}
$cache->destroy('sql', MODERATOR_CACHE_TABLE);
// Delete user log entries about this user
$sql = 'DELETE FROM ' . LOG_TABLE . '
WHERE reportee_id = ' . $user_id;
$db->sql_query($sql);
// Change user_id to anonymous for this users triggered events
$sql = 'UPDATE ' . LOG_TABLE . '
SET user_id = ' . ANONYMOUS . '
WHERE user_id = ' . $user_id;
$db->sql_query($sql);
// Delete the user_id from the zebra table
$sql = 'DELETE FROM ' . ZEBRA_TABLE . '
WHERE user_id = ' . $user_id . '
OR zebra_id = ' . $user_id;
$db->sql_query($sql);
// Delete the user_id from the banlist
$sql = 'DELETE FROM ' . BANLIST_TABLE . '
WHERE ban_userid = ' . $user_id;
$db->sql_query($sql);
// Delete the user_id from the session table
$sql = 'DELETE FROM ' . SESSIONS_TABLE . '
WHERE session_user_id = ' . $user_id;
$db->sql_query($sql);
// Clean the private messages tables from the user
if (!function_exists('phpbb_delete_user_pms'))
{
include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
}
phpbb_delete_user_pms($user_id);
$db->sql_transaction('commit');
// Reset newest user info if appropriate
if ($config['newest_user_id'] == $user_id)
{
update_last_username();
}
// Decrement number of users if this user is active
if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE)
{
set_config_count('num_users', -1, true);
}
return false;
}
/**
* Flips user_type from active to inactive and vice versa, handles group membership updates
*
* @param string $mode can be flip for flipping from active/inactive, activate or deactivate
*/
function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)
{
global $config, $db, $user, $auth;
$deactivated = $activated = 0;
$sql_statements = array();
if (!is_array($user_id_ary))
{
$user_id_ary = array($user_id_ary);
}
if (!sizeof($user_id_ary))
{
return;
}
$sql = 'SELECT user_id, group_id, user_type, user_inactive_reason
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$sql_ary = array();
if ($row['user_type'] == USER_IGNORE || $row['user_type'] == USER_FOUNDER ||
($mode == 'activate' && $row['user_type'] != USER_INACTIVE) ||
($mode == 'deactivate' && $row['user_type'] == USER_INACTIVE))
{
continue;
}
if ($row['user_type'] == USER_INACTIVE)
{
$activated++;
}
else
{
$deactivated++;
// Remove the users session key...
$user->reset_login_keys($row['user_id']);
}
$sql_ary += array(
'user_type' => ($row['user_type'] == USER_NORMAL) ? USER_INACTIVE : USER_NORMAL,
'user_inactive_time' => ($row['user_type'] == USER_NORMAL) ? time() : 0,
'user_inactive_reason' => ($row['user_type'] == USER_NORMAL) ? $reason : 0,
);
$sql_statements[$row['user_id']] = $sql_ary;
}
$db->sql_freeresult($result);
if (sizeof($sql_statements))
{
foreach ($sql_statements as $user_id => $sql_ary)
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE user_id = ' . $user_id;
$db->sql_query($sql);
}
$auth->acl_clear_prefetch(array_keys($sql_statements));
}
if ($deactivated)
{
set_config_count('num_users', $deactivated * (-1), true);
}
if ($activated)
{
set_config_count('num_users', $activated, true);
}
// Update latest username
update_last_username();
}
/**
* Add a ban or ban exclusion to the banlist. Bans either a user, an IP or an email address
*
* @param string $mode Type of ban. One of the following: user, ip, email
* @param mixed $ban Banned entity. Either string or array with usernames, ips or email addresses
* @param int $ban_len Ban length in minutes
* @param string $ban_len_other Ban length as a date (YYYY-MM-DD)
* @param boolean $ban_exclude Exclude these entities from banning?
* @param string $ban_reason String describing the reason for this ban
* @return boolean
*/
function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reason, $ban_give_reason = '')
{
global $db, $user, $auth, $cache;
// Delete stale bans
$sql = 'DELETE FROM ' . BANLIST_TABLE . '
WHERE ban_end < ' . time() . '
AND ban_end <> 0';
$db->sql_query($sql);
$ban_list = (!is_array($ban)) ? array_unique(explode("\n", $ban)) : $ban;
$ban_list_log = implode(', ', $ban_list);
$current_time = time();
// Set $ban_end to the unix time when the ban should end. 0 is a permanent ban.
if ($ban_len)
{
if ($ban_len != -1 || !$ban_len_other)
{
$ban_end = max($current_time, $current_time + ($ban_len) * 60);
}
else
{
$ban_other = explode('-', $ban_len_other);
if (sizeof($ban_other) == 3 && ((int)$ban_other[0] < 9999) &&
(strlen($ban_other[0]) == 4) && (strlen($ban_other[1]) == 2) && (strlen($ban_other[2]) == 2))
{
$time_offset = (isset($user->timezone) && isset($user->dst)) ? (int) $user->timezone + (int) $user->dst : 0;
$ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0]) - $time_offset);
}
else
{
trigger_error('LENGTH_BAN_INVALID', E_USER_WARNING);
}
}
}
else
{
$ban_end = 0;
}
$founder = $founder_names = array();
if (!$ban_exclude)
{
// Create a list of founder...
$sql = 'SELECT user_id, user_email, username_clean
FROM ' . USERS_TABLE . '
WHERE user_type = ' . USER_FOUNDER;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$founder[$row['user_id']] = $row['user_email'];
$founder_names[$row['user_id']] = $row['username_clean'];
}
$db->sql_freeresult($result);
}
$banlist_ary = array();
switch ($mode)
{
case 'user':
$type = 'ban_userid';
// At the moment we do not support wildcard username banning
// Select the relevant user_ids.
$sql_usernames = array();
foreach ($ban_list as $username)
{
$username = trim($username);
if ($username != '')
{
$clean_name = utf8_clean_string($username);
if ($clean_name == $user->data['username_clean'])
{
trigger_error('CANNOT_BAN_YOURSELF', E_USER_WARNING);
}
if (in_array($clean_name, $founder_names))
{
trigger_error('CANNOT_BAN_FOUNDER', E_USER_WARNING);
}
$sql_usernames[] = $clean_name;
}
}
// Make sure we have been given someone to ban
if (!sizeof($sql_usernames))
{
trigger_error('NO_USER_SPECIFIED', E_USER_WARNING);
}
$sql = 'SELECT user_id
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('username_clean', $sql_usernames);
// Do not allow banning yourself, the guest account, or founders.
$non_bannable = array($user->data['user_id'], ANONYMOUS);
if (sizeof($founder))
{
$sql .= ' AND ' . $db->sql_in_set('user_id', array_merge(array_keys($founder), $non_bannable), true);
}
else
{
$sql .= ' AND ' . $db->sql_in_set('user_id', $non_bannable, true);
}
$result = $db->sql_query($sql);
if ($row = $db->sql_fetchrow($result))
{
do
{
$banlist_ary[] = (int) $row['user_id'];
}
while ($row = $db->sql_fetchrow($result));
}
else
{
$db->sql_freeresult($result);
trigger_error('NO_USERS', E_USER_WARNING);
}
$db->sql_freeresult($result);
break;
case 'ip':
$type = 'ban_ip';
foreach ($ban_list as $ban_item)
{
if (preg_match('#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})[ ]*\-[ ]*([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#', trim($ban_item), $ip_range_explode))
{
// This is an IP range
// Don't ask about all this, just don't ask ... !
$ip_1_counter = $ip_range_explode[1];
$ip_1_end = $ip_range_explode[5];
while ($ip_1_counter <= $ip_1_end)
{
$ip_2_counter = ($ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[2] : 0;
$ip_2_end = ($ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[6];
if ($ip_2_counter == 0 && $ip_2_end == 254)
{
$ip_2_counter = 256;
$ip_2_fragment = 256;
$banlist_ary[] = "$ip_1_counter.*";
}
while ($ip_2_counter <= $ip_2_end)
{
$ip_3_counter = ($ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[3] : 0;
$ip_3_end = ($ip_2_counter < $ip_2_end || $ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[7];
if ($ip_3_counter == 0 && $ip_3_end == 254)
{
$ip_3_counter = 256;
$ip_3_fragment = 256;
$banlist_ary[] = "$ip_1_counter.$ip_2_counter.*";
}
while ($ip_3_counter <= $ip_3_end)
{
$ip_4_counter = ($ip_3_counter == $ip_range_explode[3] && $ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[4] : 0;
$ip_4_end = ($ip_3_counter < $ip_3_end || $ip_2_counter < $ip_2_end) ? 254 : $ip_range_explode[8];
if ($ip_4_counter == 0 && $ip_4_end == 254)
{
$ip_4_counter = 256;
$ip_4_fragment = 256;
$banlist_ary[] = "$ip_1_counter.$ip_2_counter.$ip_3_counter.*";
}
while ($ip_4_counter <= $ip_4_end)
{
$banlist_ary[] = "$ip_1_counter.$ip_2_counter.$ip_3_counter.$ip_4_counter";
$ip_4_counter++;
}
$ip_3_counter++;
}
$ip_2_counter++;
}
$ip_1_counter++;
}
}
else if (preg_match('#^([0-9]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})$#', trim($ban_item)) || preg_match('#^[a-f0-9:]+\*?$#i', trim($ban_item)))
{
// Normal IP address
$banlist_ary[] = trim($ban_item);
}
else if (preg_match('#^\*$#', trim($ban_item)))
{
// Ban all IPs
$banlist_ary[] = '*';
}
else if (preg_match('#^([\w\-_]\.?){2,}$#is', trim($ban_item)))
{
// hostname
$ip_ary = gethostbynamel(trim($ban_item));
if (!empty($ip_ary))
{
foreach ($ip_ary as $ip)
{
if ($ip)
{
if (strlen($ip) > 40)
{
continue;
}
$banlist_ary[] = $ip;
}
}
}
}
if (empty($banlist_ary))
{
trigger_error('NO_IPS_DEFINED', E_USER_WARNING);
}
}
break;
case 'email':
$type = 'ban_email';
foreach ($ban_list as $ban_item)
{
$ban_item = trim($ban_item);
if (preg_match('#^.*?@*|(([a-z0-9\-]+\.)+([a-z]{2,3}))$#i', $ban_item))
{
if (strlen($ban_item) > 100)
{
continue;
}
if (!sizeof($founder) || !in_array($ban_item, $founder))
{
$banlist_ary[] = $ban_item;
}
}
}
if (sizeof($ban_list) == 0)
{
trigger_error('NO_EMAILS_DEFINED', E_USER_WARNING);
}
break;
default:
trigger_error('NO_MODE', E_USER_WARNING);
break;
}
// Fetch currently set bans of the specified type and exclude state. Prevent duplicate bans.
$sql_where = ($type == 'ban_userid') ? 'ban_userid <> 0' : "$type <> ''";
$sql = "SELECT $type
FROM " . BANLIST_TABLE . "
WHERE $sql_where
AND ban_exclude = " . (int) $ban_exclude;
$result = $db->sql_query($sql);
// Reset $sql_where, because we use it later...
$sql_where = '';
if ($row = $db->sql_fetchrow($result))
{
$banlist_ary_tmp = array();
do
{
switch ($mode)
{
case 'user':
$banlist_ary_tmp[] = $row['ban_userid'];
break;
case 'ip':
$banlist_ary_tmp[] = $row['ban_ip'];
break;
case 'email':
$banlist_ary_tmp[] = $row['ban_email'];
break;
}
}
while ($row = $db->sql_fetchrow($result));
$banlist_ary_tmp = array_intersect($banlist_ary, $banlist_ary_tmp);
if (sizeof($banlist_ary_tmp))
{
// One or more entities are already banned/excluded, delete the existing bans, so they can be re-inserted with the given new length
$sql = 'DELETE FROM ' . BANLIST_TABLE . '
WHERE ' . $db->sql_in_set($type, $banlist_ary_tmp) . '
AND ban_exclude = ' . (int) $ban_exclude;
$db->sql_query($sql);
}
unset($banlist_ary_tmp);
}
$db->sql_freeresult($result);
// We have some entities to ban
if (sizeof($banlist_ary))
{
$sql_ary = array();
foreach ($banlist_ary as $ban_entry)
{
$sql_ary[] = array(
$type => $ban_entry,
'ban_start' => (int) $current_time,
'ban_end' => (int) $ban_end,
'ban_exclude' => (int) $ban_exclude,
'ban_reason' => (string) $ban_reason,
'ban_give_reason' => (string) $ban_give_reason,
);
}
$db->sql_multi_insert(BANLIST_TABLE, $sql_ary);
// If we are banning we want to logout anyone matching the ban
if (!$ban_exclude)
{
switch ($mode)
{
case 'user':
$sql_where = 'WHERE ' . $db->sql_in_set('session_user_id', $banlist_ary);
break;
case 'ip':
$sql_where = 'WHERE ' . $db->sql_in_set('session_ip', $banlist_ary);
break;
case 'email':
$banlist_ary_sql = array();
foreach ($banlist_ary as $ban_entry)
{
$banlist_ary_sql[] = (string) str_replace('*', '%', $ban_entry);
}
$sql = 'SELECT user_id
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_email', $banlist_ary_sql);
$result = $db->sql_query($sql);
$sql_in = array();
if ($row = $db->sql_fetchrow($result))
{
do
{
$sql_in[] = $row['user_id'];
}
while ($row = $db->sql_fetchrow($result));
$sql_where = 'WHERE ' . $db->sql_in_set('session_user_id', $sql_in);
}
$db->sql_freeresult($result);
break;
}
if (isset($sql_where) && $sql_where)
{
$sql = 'DELETE FROM ' . SESSIONS_TABLE . "
$sql_where";
$db->sql_query($sql);
if ($mode == 'user')
{
$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' ' . ((in_array('*', $banlist_ary)) ? '' : 'WHERE ' . $db->sql_in_set('user_id', $banlist_ary));
$db->sql_query($sql);
}
}
}
// Update log
$log_entry = ($ban_exclude) ? 'LOG_BAN_EXCLUDE_' : 'LOG_BAN_';
// Add to moderator log, admin log and user notes
add_log('admin', $log_entry . strtoupper($mode), $ban_reason, $ban_list_log);
add_log('mod', 0, 0, $log_entry . strtoupper($mode), $ban_reason, $ban_list_log);
if ($mode == 'user')
{
foreach ($banlist_ary as $user_id)
{
add_log('user', $user_id, $log_entry . strtoupper($mode), $ban_reason, $ban_list_log);
}
}
$cache->destroy('sql', BANLIST_TABLE);
return true;
}
// There was nothing to ban/exclude. But destroying the cache because of the removal of stale bans.
$cache->destroy('sql', BANLIST_TABLE);
return false;
}
/**
* Unban User
*/
function user_unban($mode, $ban)
{
global $db, $user, $auth, $cache;
// Delete stale bans
$sql = 'DELETE FROM ' . BANLIST_TABLE . '
WHERE ban_end < ' . time() . '
AND ban_end <> 0';
$db->sql_query($sql);
if (!is_array($ban))
{
$ban = array($ban);
}
$unban_sql = array_map('intval', $ban);
if (sizeof($unban_sql))
{
// Grab details of bans for logging information later
switch ($mode)
{
case 'user':
$sql = 'SELECT u.username AS unban_info, u.user_id
FROM ' . USERS_TABLE . ' u, ' . BANLIST_TABLE . ' b
WHERE ' . $db->sql_in_set('b.ban_id', $unban_sql) . '
AND u.user_id = b.ban_userid';
break;
case 'email':
$sql = 'SELECT ban_email AS unban_info
FROM ' . BANLIST_TABLE . '
WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
break;
case 'ip':
$sql = 'SELECT ban_ip AS unban_info
FROM ' . BANLIST_TABLE . '
WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
break;
}
$result = $db->sql_query($sql);
$l_unban_list = '';
$user_ids_ary = array();
while ($row = $db->sql_fetchrow($result))
{
$l_unban_list .= (($l_unban_list != '') ? ', ' : '') . $row['unban_info'];
if ($mode == 'user')
{
$user_ids_ary[] = $row['user_id'];
}
}
$db->sql_freeresult($result);
$sql = 'DELETE FROM ' . BANLIST_TABLE . '
WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
$db->sql_query($sql);
// Add to moderator log, admin log and user notes
add_log('admin', 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list);
add_log('mod', 0, 0, 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list);
if ($mode == 'user')
{
foreach ($user_ids_ary as $user_id)
{
add_log('user', $user_id, 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list);
}
}
}
$cache->destroy('sql', BANLIST_TABLE);
return false;
}
/**
* Internet Protocol Address Whois
* RFC3912: WHOIS Protocol Specification
*
* @param string $ip Ip address, either IPv4 or IPv6.
*
* @return string Empty string if not a valid ip address.
* Otherwise make_clickable()'ed whois result.
*/
function user_ipwhois($ip)
{
if (empty($ip))
{
return '';
}
if (preg_match(get_preg_expression('ipv4'), $ip))
{
// IPv4 address
$whois_host = 'whois.arin.net.';
}
else if (preg_match(get_preg_expression('ipv6'), $ip))
{
// IPv6 address
$whois_host = 'whois.sixxs.net.';
}
else
{
return '';
}
$ipwhois = '';
if (($fsk = @fsockopen($whois_host, 43)))
{
// CRLF as per RFC3912
fputs($fsk, "$ip\r\n");
while (!feof($fsk))
{
$ipwhois .= fgets($fsk, 1024);
}
@fclose($fsk);
}
$match = array();
// Test for referrals from $whois_host to other whois databases, roll on rwhois
if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match))
{
if (strpos($match[1], ':') !== false)
{
$pos = strrpos($match[1], ':');
$server = substr($match[1], 0, $pos);
$port = (int) substr($match[1], $pos + 1);
unset($pos);
}
else
{
$server = $match[1];
$port = 43;
}
$buffer = '';
if (($fsk = @fsockopen($server, $port)))
{
fputs($fsk, "$ip\r\n");
while (!feof($fsk))
{
$buffer .= fgets($fsk, 1024);
}
@fclose($fsk);
}
// Use the result from $whois_host if we don't get any result here
$ipwhois = (empty($buffer)) ? $ipwhois : $buffer;
}
$ipwhois = htmlspecialchars($ipwhois);
// Magic URL ;)
return trim(make_clickable($ipwhois, false, ''));
}
/**
* Data validation ... used primarily but not exclusively by ucp modules
*
* "Master" function for validating a range of data types
*/
function validate_data($data, $val_ary)
{
global $user;
$error = array();
foreach ($val_ary as $var => $val_seq)
{
if (!is_array($val_seq[0]))
{
$val_seq = array($val_seq);
}
foreach ($val_seq as $validate)
{
$function = array_shift($validate);
array_unshift($validate, $data[$var]);
if ($result = call_user_func_array('validate_' . $function, $validate))
{
// Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted.
$error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var);
}
}
}
return $error;
}
/**
* Validate String
*
* @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_string($string, $optional = false, $min = 0, $max = 0)
{
if (empty($string) && $optional)
{
return false;
}
if ($min && utf8_strlen(htmlspecialchars_decode($string)) < $min)
{
return 'TOO_SHORT';
}
else if ($max && utf8_strlen(htmlspecialchars_decode($string)) > $max)
{
return 'TOO_LONG';
}
return false;
}
/**
* Validate Number
*
* @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_num($num, $optional = false, $min = 0, $max = 1E99)
{
if (empty($num) && $optional)
{
return false;
}
if ($num < $min)
{
return 'TOO_SMALL';
}
else if ($num > $max)
{
return 'TOO_LARGE';
}
return false;
}
/**
* Validate Date
* @param String $string a date in the dd-mm-yyyy format
* @return boolean
*/
function validate_date($date_string, $optional = false)
{
$date = explode('-', $date_string);
if ((empty($date) || sizeof($date) != 3) && $optional)
{
return false;
}
else if ($optional)
{
for ($field = 0; $field <= 1; $field++)
{
$date[$field] = (int) $date[$field];
if (empty($date[$field]))
{
$date[$field] = 1;
}
}
$date[2] = (int) $date[2];
// assume an arbitrary leap year
if (empty($date[2]))
{
$date[2] = 1980;
}
}
if (sizeof($date) != 3 || !checkdate($date[1], $date[0], $date[2]))
{
return 'INVALID';
}
return false;
}
/**
* Validate Match
*
* @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_match($string, $optional = false, $match = '')
{
if (empty($string) && $optional)
{
return false;
}
if (empty($match))
{
return false;
}
if (!preg_match($match, $string))
{
return 'WRONG_DATA';
}
return false;
}
/**
* Validate Language Pack ISO Name
*
* Tests whether a language name is valid and installed
*
* @param string $lang_iso The language string to test
*
* @return bool|string Either false if validation succeeded or
* a string which will be used as the error message
* (with the variable name appended)
*/
function validate_language_iso_name($lang_iso)
{
global $db;
$sql = 'SELECT lang_id
FROM ' . LANG_TABLE . "
WHERE lang_iso = '" . $db->sql_escape($lang_iso) . "'";
$result = $db->sql_query($sql);
$lang_id = (int) $db->sql_fetchfield('lang_id');
$db->sql_freeresult($result);
return ($lang_id) ? false : 'WRONG_DATA';
}
/**
* Check to see if the username has been taken, or if it is disallowed.
* Also checks if it includes the " character, which we don't allow in usernames.
* Used for registering, changing names, and posting anonymously with a username
*
* @param string $username The username to check
* @param string $allowed_username An allowed username, default being $user->data['username']
*
* @return mixed Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_username($username, $allowed_username = false)
{
global $config, $db, $user, $cache;
$clean_username = utf8_clean_string($username);
$allowed_username = ($allowed_username === false) ? $user->data['username_clean'] : utf8_clean_string($allowed_username);
if ($allowed_username == $clean_username)
{
return false;
}
// ... fast checks first.
if (strpos($username, '"') !== false || strpos($username, '"') !== false || empty($clean_username))
{
return 'INVALID_CHARS';
}
$mbstring = $pcre = false;
// generic UTF-8 character types supported?
if ((version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.0', '>='))) && @preg_match('/\p{L}/u', 'a') !== false)
{
$pcre = true;
}
else if (function_exists('mb_ereg_match'))
{
mb_regex_encoding('UTF-8');
$mbstring = true;
}
switch ($config['allow_name_chars'])
{
case 'USERNAME_CHARS_ANY':
$pcre = true;
$regex = '.+';
break;
case 'USERNAME_ALPHA_ONLY':
$pcre = true;
$regex = '[A-Za-z0-9]+';
break;
case 'USERNAME_ALPHA_SPACERS':
$pcre = true;
$regex = '[A-Za-z0-9-[\]_+ ]+';
break;
case 'USERNAME_LETTER_NUM':
if ($pcre)
{
$regex = '[\p{Lu}\p{Ll}\p{N}]+';
}
else if ($mbstring)
{
$regex = '[[:upper:][:lower:][:digit:]]+';
}
else
{
$pcre = true;
$regex = '[a-zA-Z0-9]+';
}
break;
case 'USERNAME_LETTER_NUM_SPACERS':
if ($pcre)
{
$regex = '[-\]_+ [\p{Lu}\p{Ll}\p{N}]+';
}
else if ($mbstring)
{
$regex = '[-\]_+ \[[:upper:][:lower:][:digit:]]+';
}
else
{
$pcre = true;
$regex = '[-\]_+ [a-zA-Z0-9]+';
}
break;
case 'USERNAME_ASCII':
default:
$pcre = true;
$regex = '[\x01-\x7F]+';
break;
}
if ($pcre)
{
if (!preg_match('#^' . $regex . '$#u', $username))
{
return 'INVALID_CHARS';
}
}
else if ($mbstring)
{
mb_ereg_search_init($username, '^' . $regex . '$');
if (!mb_ereg_search())
{
return 'INVALID_CHARS';
}
}
$sql = 'SELECT username
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $db->sql_escape($clean_username) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
return 'USERNAME_TAKEN';
}
$sql = 'SELECT group_name
FROM ' . GROUPS_TABLE . "
WHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($username)) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
return 'USERNAME_TAKEN';
}
$bad_usernames = $cache->obtain_disallowed_usernames();
foreach ($bad_usernames as $bad_username)
{
if (preg_match('#^' . $bad_username . '$#', $clean_username))
{
return 'USERNAME_DISALLOWED';
}
}
return false;
}
/**
* Check to see if the password meets the complexity settings
*
* @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_password($password)
{
global $config, $db, $user;
if ($password === '' || $config['pass_complex'] === 'PASS_TYPE_ANY')
{
// Password empty or no password complexity required.
return false;
}
$pcre = $mbstring = false;
// generic UTF-8 character types supported?
if ((version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.0', '>='))) && @preg_match('/\p{L}/u', 'a') !== false)
{
$upp = '\p{Lu}';
$low = '\p{Ll}';
$num = '\p{N}';
$sym = '[^\p{Lu}\p{Ll}\p{N}]';
$pcre = true;
}
else if (function_exists('mb_ereg_match'))
{
mb_regex_encoding('UTF-8');
$upp = '[[:upper:]]';
$low = '[[:lower:]]';
$num = '[[:digit:]]';
$sym = '[^[:upper:][:lower:][:digit:]]';
$mbstring = true;
}
else
{
$upp = '[A-Z]';
$low = '[a-z]';
$num = '[0-9]';
$sym = '[^A-Za-z0-9]';
$pcre = true;
}
$chars = array();
switch ($config['pass_complex'])
{
// No break statements below ...
// We require strong passwords in case pass_complex is not set or is invalid
default:
// Require mixed case letters, numbers and symbols
case 'PASS_TYPE_SYMBOL':
$chars[] = $sym;
// Require mixed case letters and numbers
case 'PASS_TYPE_ALPHA':
$chars[] = $num;
// Require mixed case letters
case 'PASS_TYPE_CASE':
$chars[] = $low;
$chars[] = $upp;
}
if ($pcre)
{
foreach ($chars as $char)
{
if (!preg_match('#' . $char . '#u', $password))
{
return 'INVALID_CHARS';
}
}
}
else if ($mbstring)
{
foreach ($chars as $char)
{
if (mb_ereg($char, $password) === false)
{
return 'INVALID_CHARS';
}
}
}
return false;
}
/**
* Check to see if email address is banned or already present in the DB
*
* @param string $email The email to check
* @param string $allowed_email An allowed email, default being $user->data['user_email']
*
* @return mixed Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_email($email, $allowed_email = false)
{
global $config, $db, $user;
$email = strtolower($email);
$allowed_email = ($allowed_email === false) ? strtolower($user->data['user_email']) : strtolower($allowed_email);
if ($allowed_email == $email)
{
return false;
}
if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))
{
return 'EMAIL_INVALID';
}
// Check MX record.
// The idea for this is from reading the UseBB blog/announcement. :)
if ($config['email_check_mx'])
{
list(, $domain) = explode('@', $email);
if (phpbb_checkdnsrr($domain, 'A') === false && phpbb_checkdnsrr($domain, 'MX') === false)
{
return 'DOMAIN_NO_MX_RECORD';
}
}
if (($ban_reason = $user->check_ban(false, false, $email, true)) !== false)
{
return ($ban_reason === true) ? 'EMAIL_BANNED' : $ban_reason;
}
if (!$config['allow_emailreuse'])
{
$sql = 'SELECT user_email_hash
FROM ' . USERS_TABLE . "
WHERE user_email_hash = " . $db->sql_escape(phpbb_email_hash($email));
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
return 'EMAIL_TAKEN';
}
}
return false;
}
/**
* Validate jabber address
* Taken from the jabber class within flyspray (see author notes)
*
* @author flyspray.org
*/
function validate_jabber($jid)
{
if (!$jid)
{
return false;
}
$seperator_pos = strpos($jid, '@');
if ($seperator_pos === false)
{
return 'WRONG_DATA';
}
$username = substr($jid, 0, $seperator_pos);
$realm = substr($jid, $seperator_pos + 1);
if (strlen($username) == 0 || strlen($realm) < 3)
{
return 'WRONG_DATA';
}
$arr = explode('.', $realm);
if (sizeof($arr) == 0)
{
return 'WRONG_DATA';
}
foreach ($arr as $part)
{
if (substr($part, 0, 1) == '-' || substr($part, -1, 1) == '-')
{
return 'WRONG_DATA';
}
if (!preg_match("@^[a-zA-Z0-9-.]+$@", $part))
{
return 'WRONG_DATA';
}
}
$boundary = array(array(0, 127), array(192, 223), array(224, 239), array(240, 247), array(248, 251), array(252, 253));
// Prohibited Characters RFC3454 + RFC3920
$prohibited = array(
// Table C.1.1
array(0x0020, 0x0020), // SPACE
// Table C.1.2
array(0x00A0, 0x00A0), // NO-BREAK SPACE
array(0x1680, 0x1680), // OGHAM SPACE MARK
array(0x2000, 0x2001), // EN QUAD
array(0x2001, 0x2001), // EM QUAD
array(0x2002, 0x2002), // EN SPACE
array(0x2003, 0x2003), // EM SPACE
array(0x2004, 0x2004), // THREE-PER-EM SPACE
array(0x2005, 0x2005), // FOUR-PER-EM SPACE
array(0x2006, 0x2006), // SIX-PER-EM SPACE
array(0x2007, 0x2007), // FIGURE SPACE
array(0x2008, 0x2008), // PUNCTUATION SPACE
array(0x2009, 0x2009), // THIN SPACE
array(0x200A, 0x200A), // HAIR SPACE
array(0x200B, 0x200B), // ZERO WIDTH SPACE
array(0x202F, 0x202F), // NARROW NO-BREAK SPACE
array(0x205F, 0x205F), // MEDIUM MATHEMATICAL SPACE
array(0x3000, 0x3000), // IDEOGRAPHIC SPACE
// Table C.2.1
array(0x0000, 0x001F), // [CONTROL CHARACTERS]
array(0x007F, 0x007F), // DELETE
// Table C.2.2
array(0x0080, 0x009F), // [CONTROL CHARACTERS]
array(0x06DD, 0x06DD), // ARABIC END OF AYAH
array(0x070F, 0x070F), // SYRIAC ABBREVIATION MARK
array(0x180E, 0x180E), // MONGOLIAN VOWEL SEPARATOR
array(0x200C, 0x200C), // ZERO WIDTH NON-JOINER
array(0x200D, 0x200D), // ZERO WIDTH JOINER
array(0x2028, 0x2028), // LINE SEPARATOR
array(0x2029, 0x2029), // PARAGRAPH SEPARATOR
array(0x2060, 0x2060), // WORD JOINER
array(0x2061, 0x2061), // FUNCTION APPLICATION
array(0x2062, 0x2062), // INVISIBLE TIMES
array(0x2063, 0x2063), // INVISIBLE SEPARATOR
array(0x206A, 0x206F), // [CONTROL CHARACTERS]
array(0xFEFF, 0xFEFF), // ZERO WIDTH NO-BREAK SPACE
array(0xFFF9, 0xFFFC), // [CONTROL CHARACTERS]
array(0x1D173, 0x1D17A), // [MUSICAL CONTROL CHARACTERS]
// Table C.3
array(0xE000, 0xF8FF), // [PRIVATE USE, PLANE 0]
array(0xF0000, 0xFFFFD), // [PRIVATE USE, PLANE 15]
array(0x100000, 0x10FFFD), // [PRIVATE USE, PLANE 16]
// Table C.4
array(0xFDD0, 0xFDEF), // [NONCHARACTER CODE POINTS]
array(0xFFFE, 0xFFFF), // [NONCHARACTER CODE POINTS]
array(0x1FFFE, 0x1FFFF), // [NONCHARACTER CODE POINTS]
array(0x2FFFE, 0x2FFFF), // [NONCHARACTER CODE POINTS]
array(0x3FFFE, 0x3FFFF), // [NONCHARACTER CODE POINTS]
array(0x4FFFE, 0x4FFFF), // [NONCHARACTER CODE POINTS]
array(0x5FFFE, 0x5FFFF), // [NONCHARACTER CODE POINTS]
array(0x6FFFE, 0x6FFFF), // [NONCHARACTER CODE POINTS]
array(0x7FFFE, 0x7FFFF), // [NONCHARACTER CODE POINTS]
array(0x8FFFE, 0x8FFFF), // [NONCHARACTER CODE POINTS]
array(0x9FFFE, 0x9FFFF), // [NONCHARACTER CODE POINTS]
array(0xAFFFE, 0xAFFFF), // [NONCHARACTER CODE POINTS]
array(0xBFFFE, 0xBFFFF), // [NONCHARACTER CODE POINTS]
array(0xCFFFE, 0xCFFFF), // [NONCHARACTER CODE POINTS]
array(0xDFFFE, 0xDFFFF), // [NONCHARACTER CODE POINTS]
array(0xEFFFE, 0xEFFFF), // [NONCHARACTER CODE POINTS]
array(0xFFFFE, 0xFFFFF), // [NONCHARACTER CODE POINTS]
array(0x10FFFE, 0x10FFFF), // [NONCHARACTER CODE POINTS]
// Table C.5
array(0xD800, 0xDFFF), // [SURROGATE CODES]
// Table C.6
array(0xFFF9, 0xFFF9), // INTERLINEAR ANNOTATION ANCHOR
array(0xFFFA, 0xFFFA), // INTERLINEAR ANNOTATION SEPARATOR
array(0xFFFB, 0xFFFB), // INTERLINEAR ANNOTATION TERMINATOR
array(0xFFFC, 0xFFFC), // OBJECT REPLACEMENT CHARACTER
array(0xFFFD, 0xFFFD), // REPLACEMENT CHARACTER
// Table C.7
array(0x2FF0, 0x2FFB), // [IDEOGRAPHIC DESCRIPTION CHARACTERS]
// Table C.8
array(0x0340, 0x0340), // COMBINING GRAVE TONE MARK
array(0x0341, 0x0341), // COMBINING ACUTE TONE MARK
array(0x200E, 0x200E), // LEFT-TO-RIGHT MARK
array(0x200F, 0x200F), // RIGHT-TO-LEFT MARK
array(0x202A, 0x202A), // LEFT-TO-RIGHT EMBEDDING
array(0x202B, 0x202B), // RIGHT-TO-LEFT EMBEDDING
array(0x202C, 0x202C), // POP DIRECTIONAL FORMATTING
array(0x202D, 0x202D), // LEFT-TO-RIGHT OVERRIDE
array(0x202E, 0x202E), // RIGHT-TO-LEFT OVERRIDE
array(0x206A, 0x206A), // INHIBIT SYMMETRIC SWAPPING
array(0x206B, 0x206B), // ACTIVATE SYMMETRIC SWAPPING
array(0x206C, 0x206C), // INHIBIT ARABIC FORM SHAPING
array(0x206D, 0x206D), // ACTIVATE ARABIC FORM SHAPING
array(0x206E, 0x206E), // NATIONAL DIGIT SHAPES
array(0x206F, 0x206F), // NOMINAL DIGIT SHAPES
// Table C.9
array(0xE0001, 0xE0001), // LANGUAGE TAG
array(0xE0020, 0xE007F), // [TAGGING CHARACTERS]
// RFC3920
array(0x22, 0x22), // "
array(0x26, 0x26), // &
array(0x27, 0x27), // '
array(0x2F, 0x2F), // /
array(0x3A, 0x3A), // :
array(0x3C, 0x3C), // <
array(0x3E, 0x3E), // >
array(0x40, 0x40) // @
);
$pos = 0;
$result = true;
while ($pos < strlen($username))
{
$len = $uni = 0;
for ($i = 0; $i <= 5; $i++)
{
if (ord($username[$pos]) >= $boundary[$i][0] && ord($username[$pos]) <= $boundary[$i][1])
{
$len = $i + 1;
$uni = (ord($username[$pos]) - $boundary[$i][0]) * pow(2, $i * 6);
for ($k = 1; $k < $len; $k++)
{
$uni += (ord($username[$pos + $k]) - 128) * pow(2, ($i - $k) * 6);
}
break;
}
}
if ($len == 0)
{
return 'WRONG_DATA';
}
foreach ($prohibited as $pval)
{
if ($uni >= $pval[0] && $uni <= $pval[1])
{
$result = false;
break 2;
}
}
$pos = $pos + $len;
}
if (!$result)
{
return 'WRONG_DATA';
}
return false;
}
/**
* Verifies whether a style ID corresponds to an active style.
*
* @param int $style_id The style_id of a style which should be checked if activated or not.
* @return boolean
*/
function phpbb_style_is_active($style_id)
{
global $db;
$sql = 'SELECT style_active
FROM ' . STYLES_TABLE . '
WHERE style_id = '. (int) $style_id;
$result = $db->sql_query($sql);
$style_is_active = (bool) $db->sql_fetchfield('style_active');
$db->sql_freeresult($result);
return $style_is_active;
}
/**
* Remove avatar
*/
function avatar_delete($mode, $row, $clean_db = false)
{
global $phpbb_root_path, $config, $db, $user;
// Check if the users avatar is actually *not* a group avatar
if ($mode == 'user')
{
if (strpos($row['user_avatar'], 'g') === 0 || (((int)$row['user_avatar'] !== 0) && ((int)$row['user_avatar'] !== (int)$row['user_id'])))
{
return false;
}
}
if ($clean_db)
{
avatar_remove_db($row[$mode . '_avatar']);
}
$filename = get_avatar_filename($row[$mode . '_avatar']);
if (file_exists($phpbb_root_path . $config['avatar_path'] . '/' . $filename))
{
@unlink($phpbb_root_path . $config['avatar_path'] . '/' . $filename);
return true;
}
return false;
}
/**
* Remote avatar linkage
*/
function avatar_remote($data, &$error)
{
global $config, $db, $user, $phpbb_root_path, $phpEx;
if (!preg_match('#^(http|https|ftp)://#i', $data['remotelink']))
{
$data['remotelink'] = 'http://' . $data['remotelink'];
}
if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.(gif|jpg|jpeg|png)$#i', $data['remotelink']))
{
$error[] = $user->lang['AVATAR_URL_INVALID'];
return false;
}
// Make sure getimagesize works...
if (($image_data = @getimagesize($data['remotelink'])) === false && (empty($data['width']) || empty($data['height'])))
{
$error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
return false;
}
if (!empty($image_data) && ($image_data[0] < 2 || $image_data[1] < 2))
{
$error[] = $user->lang['AVATAR_NO_SIZE'];
return false;
}
$width = ($data['width'] && $data['height']) ? $data['width'] : $image_data[0];
$height = ($data['width'] && $data['height']) ? $data['height'] : $image_data[1];
if ($width < 2 || $height < 2)
{
$error[] = $user->lang['AVATAR_NO_SIZE'];
return false;
}
// Check image type
include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
$types = fileupload::image_types();
$extension = strtolower(filespec::get_extension($data['remotelink']));
if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]])))
{
if (!isset($types[$image_data[2]]))
{
$error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
}
else
{
$error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$image_data[2]][0], $extension);
}
return false;
}
if ($config['avatar_max_width'] || $config['avatar_max_height'])
{
if ($width > $config['avatar_max_width'] || $height > $config['avatar_max_height'])
{
$error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height);
return false;
}
}
if ($config['avatar_min_width'] || $config['avatar_min_height'])
{
if ($width < $config['avatar_min_width'] || $height < $config['avatar_min_height'])
{
$error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height);
return false;
}
}
return array(AVATAR_REMOTE, $data['remotelink'], $width, $height);
}
/**
* Avatar upload using the upload class
*/
function avatar_upload($data, &$error)
{
global $phpbb_root_path, $config, $db, $user, $phpEx;
// Init upload class
include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
$upload = new fileupload('AVATAR_', array('jpg', 'jpeg', 'gif', 'png'), $config['avatar_filesize'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], (isset($config['mime_triggers']) ? explode('|', $config['mime_triggers']) : false));
if (!empty($_FILES['uploadfile']['name']))
{
$file = $upload->form_upload('uploadfile');
}
else
{
$file = $upload->remote_upload($data['uploadurl']);
}
$prefix = $config['avatar_salt'] . '_';
$file->clean_filename('avatar', $prefix, $data['user_id']);
$destination = $config['avatar_path'];
// Adjust destination path (no trailing slash)
if (substr($destination, -1, 1) == '/' || substr($destination, -1, 1) == '\\')
{
$destination = substr($destination, 0, -1);
}
$destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination);
if ($destination && ($destination[0] == '/' || $destination[0] == "\\"))
{
$destination = '';
}
// Move file and overwrite any existing image
$file->move_file($destination, true);
if (sizeof($file->error))
{
$file->remove();
$error = array_merge($error, $file->error);
}
return array(AVATAR_UPLOAD, $data['user_id'] . '_' . time() . '.' . $file->get('extension'), $file->get('width'), $file->get('height'));
}
/**
* Generates avatar filename from the database entry
*/
function get_avatar_filename($avatar_entry)
{
global $config;
if ($avatar_entry[0] === 'g')
{
$avatar_group = true;
$avatar_entry = substr($avatar_entry, 1);
}
else
{
$avatar_group = false;
}
$ext = substr(strrchr($avatar_entry, '.'), 1);
$avatar_entry = intval($avatar_entry);
return $config['avatar_salt'] . '_' . (($avatar_group) ? 'g' : '') . $avatar_entry . '.' . $ext;
}
/**
* Avatar Gallery
*/
function avatar_gallery($category, $avatar_select, $items_per_column, $block_var = 'avatar_row')
{
global $user, $cache, $template;
global $config, $phpbb_root_path;
$avatar_list = array();
$path = $phpbb_root_path . $config['avatar_gallery_path'];
if (!file_exists($path) || !is_dir($path))
{
$avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array());
}
else
{
// Collect images
$dp = @opendir($path);
if (!$dp)
{
return array($user->lang['NO_AVATAR_CATEGORY'] => array());
}
while (($file = readdir($dp)) !== false)
{
if ($file[0] != '.' && preg_match('#^[^&"\'<>]+$#i', $file) && is_dir("$path/$file"))
{
$avatar_row_count = $avatar_col_count = 0;
if ($dp2 = @opendir("$path/$file"))
{
while (($sub_file = readdir($dp2)) !== false)
{
if (preg_match('#^[^&\'"<>]+\.(?:gif|png|jpe?g)$#i', $sub_file))
{
$avatar_list[$file][$avatar_row_count][$avatar_col_count] = array(
'file' => rawurlencode($file) . '/' . rawurlencode($sub_file),
'filename' => rawurlencode($sub_file),
'name' => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $sub_file))),
);
$avatar_col_count++;
if ($avatar_col_count == $items_per_column)
{
$avatar_row_count++;
$avatar_col_count = 0;
}
}
}
closedir($dp2);
}
}
}
closedir($dp);
}
if (!sizeof($avatar_list))
{
$avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array());
}
@ksort($avatar_list);
$category = (!$category) ? key($avatar_list) : $category;
$avatar_categories = array_keys($avatar_list);
$s_category_options = '';
foreach ($avatar_categories as $cat)
{
$s_category_options .= '<option value="' . $cat . '"' . (($cat == $category) ? ' selected="selected"' : '') . '>' . $cat . '</option>';
}
$template->assign_vars(array(
'S_AVATARS_ENABLED' => true,
'S_IN_AVATAR_GALLERY' => true,
'S_CAT_OPTIONS' => $s_category_options)
);
$avatar_list = (isset($avatar_list[$category])) ? $avatar_list[$category] : array();
foreach ($avatar_list as $avatar_row_ary)
{
$template->assign_block_vars($block_var, array());
foreach ($avatar_row_ary as $avatar_col_ary)
{
$template->assign_block_vars($block_var . '.avatar_column', array(
'AVATAR_IMAGE' => $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'],
'AVATAR_NAME' => $avatar_col_ary['name'],
'AVATAR_FILE' => $avatar_col_ary['filename'])
);
$template->assign_block_vars($block_var . '.avatar_option_column', array(
'AVATAR_IMAGE' => $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'],
'S_OPTIONS_AVATAR' => $avatar_col_ary['filename'])
);
}
}
return $avatar_list;
}
/**
* Tries to (re-)establish avatar dimensions
*/
function avatar_get_dimensions($avatar, $avatar_type, &$error, $current_x = 0, $current_y = 0)
{
global $config, $phpbb_root_path, $user;
switch ($avatar_type)
{
case AVATAR_REMOTE :
break;
case AVATAR_UPLOAD :
$avatar = $phpbb_root_path . $config['avatar_path'] . '/' . get_avatar_filename($avatar);
break;
case AVATAR_GALLERY :
$avatar = $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar ;
break;
}
// Make sure getimagesize works...
if (($image_data = @getimagesize($avatar)) === false)
{
$error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
return false;
}
if ($image_data[0] < 2 || $image_data[1] < 2)
{
$error[] = $user->lang['AVATAR_NO_SIZE'];
return false;
}
// try to maintain ratio
if (!(empty($current_x) && empty($current_y)))
{
if ($current_x != 0)
{
$image_data[1] = (int) floor(($current_x / $image_data[0]) * $image_data[1]);
$image_data[1] = min($config['avatar_max_height'], $image_data[1]);
$image_data[1] = max($config['avatar_min_height'], $image_data[1]);
}
if ($current_y != 0)
{
$image_data[0] = (int) floor(($current_y / $image_data[1]) * $image_data[0]);
$image_data[0] = min($config['avatar_max_width'], $image_data[1]);
$image_data[0] = max($config['avatar_min_width'], $image_data[1]);
}
}
return array($image_data[0], $image_data[1]);
}
/**
* Uploading/Changing user avatar
*/
function avatar_process_user(&$error, $custom_userdata = false, $can_upload = null)
{
global $config, $phpbb_root_path, $auth, $user, $db;
$data = array(
'uploadurl' => request_var('uploadurl', ''),
'remotelink' => request_var('remotelink', ''),
'width' => request_var('width', 0),
'height' => request_var('height', 0),
);
$error = validate_data($data, array(
'uploadurl' => array('string', true, 5, 255),
'remotelink' => array('string', true, 5, 255),
'width' => array('string', true, 1, 3),
'height' => array('string', true, 1, 3),
));
if (sizeof($error))
{
return false;
}
$sql_ary = array();
if ($custom_userdata === false)
{
$userdata = &$user->data;
}
else
{
$userdata = &$custom_userdata;
}
$data['user_id'] = $userdata['user_id'];
$change_avatar = ($custom_userdata === false) ? $auth->acl_get('u_chgavatar') : true;
$avatar_select = basename(request_var('avatar_select', ''));
// Can we upload?
if (is_null($can_upload))
{
$can_upload = ($config['allow_avatar_upload'] && file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $change_avatar && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
}
if ((!empty($_FILES['uploadfile']['name']) || $data['uploadurl']) && $can_upload)
{
list($sql_ary['user_avatar_type'], $sql_ary['user_avatar'], $sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = avatar_upload($data, $error);
}
else if ($data['remotelink'] && $change_avatar && $config['allow_avatar_remote'])
{
list($sql_ary['user_avatar_type'], $sql_ary['user_avatar'], $sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = avatar_remote($data, $error);
}
else if ($avatar_select && $change_avatar && $config['allow_avatar_local'])
{
$category = basename(request_var('category', ''));
$sql_ary['user_avatar_type'] = AVATAR_GALLERY;
$sql_ary['user_avatar'] = $avatar_select;
// check avatar gallery
if (!is_dir($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category))
{
$sql_ary['user_avatar'] = '';
$sql_ary['user_avatar_type'] = $sql_ary['user_avatar_width'] = $sql_ary['user_avatar_height'] = 0;
}
else
{
list($sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = getimagesize($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category . '/' . urldecode($sql_ary['user_avatar']));
$sql_ary['user_avatar'] = $category . '/' . $sql_ary['user_avatar'];
}
}
else if (isset($_POST['delete']) && $change_avatar)
{
$sql_ary['user_avatar'] = '';
$sql_ary['user_avatar_type'] = $sql_ary['user_avatar_width'] = $sql_ary['user_avatar_height'] = 0;
}
else if (!empty($userdata['user_avatar']))
{
// Only update the dimensions
if (empty($data['width']) || empty($data['height']))
{
if ($dims = avatar_get_dimensions($userdata['user_avatar'], $userdata['user_avatar_type'], $error, $data['width'], $data['height']))
{
list($guessed_x, $guessed_y) = $dims;
if (empty($data['width']))
{
$data['width'] = $guessed_x;
}
if (empty($data['height']))
{
$data['height'] = $guessed_y;
}
}
}
if (($config['avatar_max_width'] || $config['avatar_max_height']) &&
(($data['width'] != $userdata['user_avatar_width']) || $data['height'] != $userdata['user_avatar_height']))
{
if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height'])
{
$error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
}
}
if (!sizeof($error))
{
if ($config['avatar_min_width'] || $config['avatar_min_height'])
{
if ($data['width'] < $config['avatar_min_width'] || $data['height'] < $config['avatar_min_height'])
{
$error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
}
}
}
if (!sizeof($error))
{
$sql_ary['user_avatar_width'] = $data['width'];
$sql_ary['user_avatar_height'] = $data['height'];
}
}
if (!sizeof($error))
{
// Do we actually have any data to update?
if (sizeof($sql_ary))
{
$ext_new = $ext_old = '';
if (isset($sql_ary['user_avatar']))
{
$userdata = ($custom_userdata === false) ? $user->data : $custom_userdata;
$ext_new = (empty($sql_ary['user_avatar'])) ? '' : substr(strrchr($sql_ary['user_avatar'], '.'), 1);
$ext_old = (empty($userdata['user_avatar'])) ? '' : substr(strrchr($userdata['user_avatar'], '.'), 1);
if ($userdata['user_avatar_type'] == AVATAR_UPLOAD)
{
// Delete old avatar if present
if ((!empty($userdata['user_avatar']) && empty($sql_ary['user_avatar']))
|| ( !empty($userdata['user_avatar']) && !empty($sql_ary['user_avatar']) && $ext_new !== $ext_old))
{
avatar_delete('user', $userdata);
}
}
}
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE user_id = ' . (($custom_userdata === false) ? $user->data['user_id'] : $custom_userdata['user_id']);
$db->sql_query($sql);
}
}
return (sizeof($error)) ? false : true;
}
//
// Usergroup functions
//
/**
* Add or edit a group. If we're editing a group we only update user
* parameters such as rank, etc. if they are changed
*/
function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow_desc_bbcode = false, $allow_desc_urls = false, $allow_desc_smilies = false)
{
global $phpbb_root_path, $config, $db, $user, $file_upload;
$error = array();
// Attributes which also affect the users table
$user_attribute_ary = array('group_colour', 'group_rank', 'group_avatar', 'group_avatar_type', 'group_avatar_width', 'group_avatar_height');
// Check data. Limit group name length.
if (!utf8_strlen($name) || utf8_strlen($name) > 60)
{
$error[] = (!utf8_strlen($name)) ? $user->lang['GROUP_ERR_USERNAME'] : $user->lang['GROUP_ERR_USER_LONG'];
}
$err = group_validate_groupname($group_id, $name);
if (!empty($err))
{
$error[] = $user->lang[$err];
}
if (!in_array($type, array(GROUP_OPEN, GROUP_CLOSED, GROUP_HIDDEN, GROUP_SPECIAL, GROUP_FREE)))
{
$error[] = $user->lang['GROUP_ERR_TYPE'];
}
if (!sizeof($error))
{
$user_ary = array();
$sql_ary = array(
'group_name' => (string) $name,
'group_desc' => (string) $desc,
'group_desc_uid' => '',
'group_desc_bitfield' => '',
'group_type' => (int) $type,
);
// Parse description
if ($desc)
{
generate_text_for_storage($sql_ary['group_desc'], $sql_ary['group_desc_uid'], $sql_ary['group_desc_bitfield'], $sql_ary['group_desc_options'], $allow_desc_bbcode, $allow_desc_urls, $allow_desc_smilies);
}
if (sizeof($group_attributes))
{
// Merge them with $sql_ary to properly update the group
$sql_ary = array_merge($sql_ary, $group_attributes);
}
// Setting the log message before we set the group id (if group gets added)
$log = ($group_id) ? 'LOG_GROUP_UPDATED' : 'LOG_GROUP_CREATED';
$query = '';
if ($group_id)
{
$sql = 'SELECT user_id
FROM ' . USERS_TABLE . '
WHERE group_id = ' . $group_id;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$user_ary[] = $row['user_id'];
}
$db->sql_freeresult($result);
if (isset($sql_ary['group_avatar']) && !$sql_ary['group_avatar'])
{
remove_default_avatar($group_id, $user_ary);
}
if (isset($sql_ary['group_rank']) && !$sql_ary['group_rank'])
{
remove_default_rank($group_id, $user_ary);
}
$sql = 'UPDATE ' . GROUPS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE group_id = $group_id";
$db->sql_query($sql);
// Since we may update the name too, we need to do this on other tables too...
$sql = 'UPDATE ' . MODERATOR_CACHE_TABLE . "
SET group_name = '" . $db->sql_escape($sql_ary['group_name']) . "'
WHERE group_id = $group_id";
$db->sql_query($sql);
// One special case is the group skip auth setting. If this was changed we need to purge permissions for this group
if (isset($group_attributes['group_skip_auth']))
{
// Get users within this group...
$sql = 'SELECT user_id
FROM ' . USER_GROUP_TABLE . '
WHERE group_id = ' . $group_id . '
AND user_pending = 0';
$result = $db->sql_query($sql);
$user_id_ary = array();
while ($row = $db->sql_fetchrow($result))
{
$user_id_ary[] = $row['user_id'];
}
$db->sql_freeresult($result);
if (!empty($user_id_ary))
{
global $auth;
// Clear permissions cache of relevant users
$auth->acl_clear_prefetch($user_id_ary);
}
}
}
else
{
$sql = 'INSERT INTO ' . GROUPS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_query($sql);
}
if (!$group_id)
{
$group_id = $db->sql_nextid();
if (isset($sql_ary['group_avatar_type']) && $sql_ary['group_avatar_type'] == AVATAR_UPLOAD)
{
group_correct_avatar($group_id, $sql_ary['group_avatar']);
}
}
// Set user attributes
$sql_ary = array();
if (sizeof($group_attributes))
{
// Go through the user attributes array, check if a group attribute matches it and then set it. ;)
foreach ($user_attribute_ary as $attribute)
{
if (!isset($group_attributes[$attribute]))
{
continue;
}
// If we are about to set an avatar, we will not overwrite user avatars if no group avatar is set...
if (strpos($attribute, 'group_avatar') === 0 && !$group_attributes[$attribute])
{
continue;
}
$sql_ary[$attribute] = $group_attributes[$attribute];
}
}
if (sizeof($sql_ary) && sizeof($user_ary))
{
group_set_user_default($group_id, $user_ary, $sql_ary);
}
$name = ($type == GROUP_SPECIAL) ? $user->lang['G_' . $name] : $name;
add_log('admin', $log, $name);
group_update_listings($group_id);
}
return (sizeof($error)) ? $error : false;
}
/**
* Changes a group avatar's filename to conform to the naming scheme
*/
function group_correct_avatar($group_id, $old_entry)
{
global $config, $db, $phpbb_root_path;
$group_id = (int)$group_id;
$ext = substr(strrchr($old_entry, '.'), 1);
$old_filename = get_avatar_filename($old_entry);
$new_filename = $config['avatar_salt'] . "_g$group_id.$ext";
$new_entry = 'g' . $group_id . '_' . substr(time(), -5) . ".$ext";
$avatar_path = $phpbb_root_path . $config['avatar_path'];
if (@rename($avatar_path . '/'. $old_filename, $avatar_path . '/' . $new_filename))
{
$sql = 'UPDATE ' . GROUPS_TABLE . '
SET group_avatar = \'' . $db->sql_escape($new_entry) . "'
WHERE group_id = $group_id";
$db->sql_query($sql);
}
}
/**
* Remove avatar also for users not having the group as default
*/
function avatar_remove_db($avatar_name)
{
global $config, $db;
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_avatar = '',
user_avatar_type = 0
WHERE user_avatar = '" . $db->sql_escape($avatar_name) . '\'';
$db->sql_query($sql);
}
/**
* Group Delete
*/
function group_delete($group_id, $group_name = false)
{
global $db, $phpbb_root_path, $phpEx;
if (!$group_name)
{
$group_name = get_group_name($group_id);
}
$start = 0;
do
{
$user_id_ary = $username_ary = array();
// Batch query for group members, call group_user_del
$sql = 'SELECT u.user_id, u.username
FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . " u
WHERE ug.group_id = $group_id
AND u.user_id = ug.user_id";
$result = $db->sql_query_limit($sql, 200, $start);
if ($row = $db->sql_fetchrow($result))
{
do
{
$user_id_ary[] = $row['user_id'];
$username_ary[] = $row['username'];
$start++;
}
while ($row = $db->sql_fetchrow($result));
group_user_del($group_id, $user_id_ary, $username_ary, $group_name);
}
else
{
$start = 0;
}
$db->sql_freeresult($result);
}
while ($start);
// Delete group
$sql = 'DELETE FROM ' . GROUPS_TABLE . "
WHERE group_id = $group_id";
$db->sql_query($sql);
// Delete auth entries from the groups table
$sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . "
WHERE group_id = $group_id";
$db->sql_query($sql);
// Re-cache moderators
if (!function_exists('cache_moderators'))
{
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
}
cache_moderators();
add_log('admin', 'LOG_GROUP_DELETE', $group_name);
// Return false - no error
return false;
}
/**
* Add user(s) to group
*
* @return mixed false if no errors occurred, else the user lang string for the relevant error, for example 'NO_USER'
*/
function group_user_add($group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $default = false, $leader = 0, $pending = 0, $group_attributes = false)
{
global $db, $auth;
// We need both username and user_id info
$result = user_get_id_name($user_id_ary, $username_ary);
if (!sizeof($user_id_ary) || $result !== false)
{
return 'NO_USER';
}
// Remove users who are already members of this group
$sql = 'SELECT user_id, group_leader
FROM ' . USER_GROUP_TABLE . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . "
AND group_id = $group_id";
$result = $db->sql_query($sql);
$add_id_ary = $update_id_ary = array();
while ($row = $db->sql_fetchrow($result))
{
$add_id_ary[] = (int) $row['user_id'];
if ($leader && !$row['group_leader'])
{
$update_id_ary[] = (int) $row['user_id'];
}
}
$db->sql_freeresult($result);
// Do all the users exist in this group?
$add_id_ary = array_diff($user_id_ary, $add_id_ary);
// If we have no users
if (!sizeof($add_id_ary) && !sizeof($update_id_ary))
{
return 'GROUP_USERS_EXIST';
}
$db->sql_transaction('begin');
// Insert the new users
if (sizeof($add_id_ary))
{
$sql_ary = array();
foreach ($add_id_ary as $user_id)
{
$sql_ary[] = array(
'user_id' => (int) $user_id,
'group_id' => (int) $group_id,
'group_leader' => (int) $leader,
'user_pending' => (int) $pending,
);
}
$db->sql_multi_insert(USER_GROUP_TABLE, $sql_ary);
}
if (sizeof($update_id_ary))
{
$sql = 'UPDATE ' . USER_GROUP_TABLE . '
SET group_leader = 1
WHERE ' . $db->sql_in_set('user_id', $update_id_ary) . "
AND group_id = $group_id";
$db->sql_query($sql);
}
if ($default)
{
group_user_attributes('default', $group_id, $user_id_ary, false, $group_name, $group_attributes);
}
$db->sql_transaction('commit');
// Clear permissions cache of relevant users
$auth->acl_clear_prefetch($user_id_ary);
if (!$group_name)
{
$group_name = get_group_name($group_id);
}
$log = ($leader) ? 'LOG_MODS_ADDED' : (($pending) ? 'LOG_USERS_PENDING' : 'LOG_USERS_ADDED');
add_log('admin', $log, $group_name, implode(', ', $username_ary));
group_update_listings($group_id);
// Return false - no error
return false;
}
/**
* Remove a user/s from a given group. When we remove users we update their
* default group_id. We do this by examining which "special" groups they belong
* to. The selection is made based on a reasonable priority system
*
* @return false if no errors occurred, else the user lang string for the relevant error, for example 'NO_USER'
*/
function group_user_del($group_id, $user_id_ary = false, $username_ary = false, $group_name = false)
{
global $db, $auth, $config;
if ($config['coppa_enable'])
{
$group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'NEWLY_REGISTERED', 'REGISTERED_COPPA', 'REGISTERED', 'BOTS', 'GUESTS');
}
else
{
$group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'NEWLY_REGISTERED', 'REGISTERED', 'BOTS', 'GUESTS');
}
// We need both username and user_id info
$result = user_get_id_name($user_id_ary, $username_ary);
if (!sizeof($user_id_ary) || $result !== false)
{
return 'NO_USER';
}
$sql = 'SELECT *
FROM ' . GROUPS_TABLE . '
WHERE ' . $db->sql_in_set('group_name', $group_order);
$result = $db->sql_query($sql);
$group_order_id = $special_group_data = array();
while ($row = $db->sql_fetchrow($result))
{
$group_order_id[$row['group_name']] = $row['group_id'];
$special_group_data[$row['group_id']] = array(
'group_colour' => $row['group_colour'],
'group_rank' => $row['group_rank'],
);
// Only set the group avatar if one is defined...
if ($row['group_avatar'])
{
$special_group_data[$row['group_id']] = array_merge($special_group_data[$row['group_id']], array(
'group_avatar' => $row['group_avatar'],
'group_avatar_type' => $row['group_avatar_type'],
'group_avatar_width' => $row['group_avatar_width'],
'group_avatar_height' => $row['group_avatar_height'])
);
}
}
$db->sql_freeresult($result);
// Get users default groups - we only need to reset default group membership if the group from which the user gets removed is set as default
$sql = 'SELECT user_id, group_id
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
$result = $db->sql_query($sql);
$default_groups = array();
while ($row = $db->sql_fetchrow($result))
{
$default_groups[$row['user_id']] = $row['group_id'];
}
$db->sql_freeresult($result);
// What special group memberships exist for these users?
$sql = 'SELECT g.group_id, g.group_name, ug.user_id
FROM ' . USER_GROUP_TABLE . ' ug, ' . GROUPS_TABLE . ' g
WHERE ' . $db->sql_in_set('ug.user_id', $user_id_ary) . "
AND g.group_id = ug.group_id
AND g.group_id <> $group_id
AND g.group_type = " . GROUP_SPECIAL . '
ORDER BY ug.user_id, g.group_id';
$result = $db->sql_query($sql);
$temp_ary = array();
while ($row = $db->sql_fetchrow($result))
{
if ($default_groups[$row['user_id']] == $group_id && (!isset($temp_ary[$row['user_id']]) || $group_order_id[$row['group_name']] < $temp_ary[$row['user_id']]))
{
$temp_ary[$row['user_id']] = $row['group_id'];
}
}
$db->sql_freeresult($result);
// sql_where_ary holds the new default groups and their users
$sql_where_ary = array();
foreach ($temp_ary as $uid => $gid)
{
$sql_where_ary[$gid][] = $uid;
}
unset($temp_ary);
foreach ($special_group_data as $gid => $default_data_ary)
{
if (isset($sql_where_ary[$gid]) && sizeof($sql_where_ary[$gid]))
{
remove_default_rank($group_id, $sql_where_ary[$gid]);
remove_default_avatar($group_id, $sql_where_ary[$gid]);
group_set_user_default($gid, $sql_where_ary[$gid], $default_data_ary);
}
}
unset($special_group_data);
$sql = 'DELETE FROM ' . USER_GROUP_TABLE . "
WHERE group_id = $group_id
AND " . $db->sql_in_set('user_id', $user_id_ary);
$db->sql_query($sql);
// Clear permissions cache of relevant users
$auth->acl_clear_prefetch($user_id_ary);
if (!$group_name)
{
$group_name = get_group_name($group_id);
}
$log = 'LOG_GROUP_REMOVE';
if ($group_name)
{
add_log('admin', $log, $group_name, implode(', ', $username_ary));
}
group_update_listings($group_id);
// Return false - no error
return false;
}
/**
* Removes the group avatar of the default group from the users in user_ids who have that group as default.
*/
function remove_default_avatar($group_id, $user_ids)
{
global $db;
if (!is_array($user_ids))
{
$user_ids = array($user_ids);
}
if (empty($user_ids))
{
return false;
}
$user_ids = array_map('intval', $user_ids);
$sql = 'SELECT *
FROM ' . GROUPS_TABLE . '
WHERE group_id = ' . (int)$group_id;
$result = $db->sql_query($sql);
if (!$row = $db->sql_fetchrow($result))
{
$db->sql_freeresult($result);
return false;
}
$db->sql_freeresult($result);
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_avatar = '',
user_avatar_type = 0,
user_avatar_width = 0,
user_avatar_height = 0
WHERE group_id = " . (int) $group_id . "
AND user_avatar = '" . $db->sql_escape($row['group_avatar']) . "'
AND " . $db->sql_in_set('user_id', $user_ids);
$db->sql_query($sql);
}
/**
* Removes the group rank of the default group from the users in user_ids who have that group as default.
*/
function remove_default_rank($group_id, $user_ids)
{
global $db;
if (!is_array($user_ids))
{
$user_ids = array($user_ids);
}
if (empty($user_ids))
{
return false;
}
$user_ids = array_map('intval', $user_ids);
$sql = 'SELECT *
FROM ' . GROUPS_TABLE . '
WHERE group_id = ' . (int)$group_id;
$result = $db->sql_query($sql);
if (!$row = $db->sql_fetchrow($result))
{
$db->sql_freeresult($result);
return false;
}
$db->sql_freeresult($result);
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_rank = 0
WHERE group_id = ' . (int)$group_id . '
AND user_rank <> 0
AND user_rank = ' . (int)$row['group_rank'] . '
AND ' . $db->sql_in_set('user_id', $user_ids);
$db->sql_query($sql);
}
/**
* This is used to promote (to leader), demote or set as default a member/s
*/
function group_user_attributes($action, $group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $group_attributes = false)
{
global $db, $auth, $phpbb_root_path, $phpEx, $config;
// We need both username and user_id info
$result = user_get_id_name($user_id_ary, $username_ary);
if (!sizeof($user_id_ary) || $result !== false)
{
return 'NO_USERS';
}
if (!$group_name)
{
$group_name = get_group_name($group_id);
}
switch ($action)
{
case 'demote':
case 'promote':
$sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . "
WHERE group_id = $group_id
AND user_pending = 1
AND " . $db->sql_in_set('user_id', $user_id_ary);
$result = $db->sql_query_limit($sql, 1);
$not_empty = ($db->sql_fetchrow($result));
$db->sql_freeresult($result);
if ($not_empty)
{
return 'NO_VALID_USERS';
}
$sql = 'UPDATE ' . USER_GROUP_TABLE . '
SET group_leader = ' . (($action == 'promote') ? 1 : 0) . "
WHERE group_id = $group_id
AND user_pending = 0
AND " . $db->sql_in_set('user_id', $user_id_ary);
$db->sql_query($sql);
$log = ($action == 'promote') ? 'LOG_GROUP_PROMOTED' : 'LOG_GROUP_DEMOTED';
break;
case 'approve':
// Make sure we only approve those which are pending ;)
$sql = 'SELECT u.user_id, u.user_email, u.username, u.username_clean, u.user_notify_type, u.user_jabber, u.user_lang
FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug
WHERE ug.group_id = ' . $group_id . '
AND ug.user_pending = 1
AND ug.user_id = u.user_id
AND ' . $db->sql_in_set('ug.user_id', $user_id_ary);
$result = $db->sql_query($sql);
$user_id_ary = $email_users = array();
while ($row = $db->sql_fetchrow($result))
{
$user_id_ary[] = $row['user_id'];
$email_users[] = $row;
}
$db->sql_freeresult($result);
if (!sizeof($user_id_ary))
{
return false;
}
$sql = 'UPDATE ' . USER_GROUP_TABLE . "
SET user_pending = 0
WHERE group_id = $group_id
AND " . $db->sql_in_set('user_id', $user_id_ary);
$db->sql_query($sql);
// Send approved email to users...
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
$messenger = new messenger();
foreach ($email_users as $row)
{
$messenger->template('group_approved', $row['user_lang']);
$messenger->to($row['user_email'], $row['username']);
$messenger->im($row['user_jabber'], $row['username']);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($row['username']),
'GROUP_NAME' => htmlspecialchars_decode($group_name),
'U_GROUP' => generate_board_url() . "/ucp.$phpEx?i=groups&mode=membership")
);
$messenger->send($row['user_notify_type']);
}
$messenger->save_queue();
$log = 'LOG_USERS_APPROVED';
break;
case 'default':
// We only set default group for approved members of the group
$sql = 'SELECT user_id
FROM ' . USER_GROUP_TABLE . "
WHERE group_id = $group_id
AND user_pending = 0
AND " . $db->sql_in_set('user_id', $user_id_ary);
$result = $db->sql_query($sql);
$user_id_ary = $username_ary = array();
while ($row = $db->sql_fetchrow($result))
{
$user_id_ary[] = $row['user_id'];
}
$db->sql_freeresult($result);
$result = user_get_id_name($user_id_ary, $username_ary);
if (!sizeof($user_id_ary) || $result !== false)
{
return 'NO_USERS';
}
$sql = 'SELECT user_id, group_id FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary, false, true);
$result = $db->sql_query($sql);
$groups = array();
while ($row = $db->sql_fetchrow($result))
{
if (!isset($groups[$row['group_id']]))
{
$groups[$row['group_id']] = array();
}
$groups[$row['group_id']][] = $row['user_id'];
}
$db->sql_freeresult($result);
foreach ($groups as $gid => $uids)
{
remove_default_rank($gid, $uids);
remove_default_avatar($gid, $uids);
}
group_set_user_default($group_id, $user_id_ary, $group_attributes);
$log = 'LOG_GROUP_DEFAULTS';
break;
}
// Clear permissions cache of relevant users
$auth->acl_clear_prefetch($user_id_ary);
add_log('admin', $log, $group_name, implode(', ', $username_ary));
group_update_listings($group_id);
return false;
}
/**
* A small version of validate_username to check for a group name's existence. To be called directly.
*/
function group_validate_groupname($group_id, $group_name)
{
global $config, $db;
$group_name = utf8_clean_string($group_name);
if (!empty($group_id))
{
$sql = 'SELECT group_name
FROM ' . GROUPS_TABLE . '
WHERE group_id = ' . (int) $group_id;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$row)
{
return false;
}
$allowed_groupname = utf8_clean_string($row['group_name']);
if ($allowed_groupname == $group_name)
{
return false;
}
}
$sql = 'SELECT group_name
FROM ' . GROUPS_TABLE . "
WHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($group_name)) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
return 'GROUP_NAME_TAKEN';
}
return false;
}
/**
* Set users default group
*
* @access private
*/
function group_set_user_default($group_id, $user_id_ary, $group_attributes = false, $update_listing = false)
{
global $cache, $db;
if (empty($user_id_ary))
{
return;
}
$attribute_ary = array(
'group_colour' => 'string',
'group_rank' => 'int',
'group_avatar' => 'string',
'group_avatar_type' => 'int',
'group_avatar_width' => 'int',
'group_avatar_height' => 'int',
);
$sql_ary = array(
'group_id' => $group_id
);
// Were group attributes passed to the function? If not we need to obtain them
if ($group_attributes === false)
{
$sql = 'SELECT ' . implode(', ', array_keys($attribute_ary)) . '
FROM ' . GROUPS_TABLE . "
WHERE group_id = $group_id";
$result = $db->sql_query($sql);
$group_attributes = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
}
foreach ($attribute_ary as $attribute => $type)
{
if (isset($group_attributes[$attribute]))
{
// If we are about to set an avatar or rank, we will not overwrite with empty, unless we are not actually changing the default group
if ((strpos($attribute, 'group_avatar') === 0 || strpos($attribute, 'group_rank') === 0) && !$group_attributes[$attribute])
{
continue;
}
settype($group_attributes[$attribute], $type);
$sql_ary[str_replace('group_', 'user_', $attribute)] = $group_attributes[$attribute];
}
}
// Before we update the user attributes, we will make a list of those having now the group avatar assigned
if (isset($sql_ary['user_avatar']))
{
// Ok, get the original avatar data from users having an uploaded one (we need to remove these from the filesystem)
$sql = 'SELECT user_id, group_id, user_avatar
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . '
AND user_avatar_type = ' . AVATAR_UPLOAD;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
avatar_delete('user', $row);
}
$db->sql_freeresult($result);
}
else
{
unset($sql_ary['user_avatar_type']);
unset($sql_ary['user_avatar_height']);
unset($sql_ary['user_avatar_width']);
}
$sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
$db->sql_query($sql);
if (isset($sql_ary['user_colour']))
{
// Update any cached colour information for these users
$sql = 'UPDATE ' . FORUMS_TABLE . " SET forum_last_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
WHERE " . $db->sql_in_set('forum_last_poster_id', $user_id_ary);
$db->sql_query($sql);
$sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_first_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
WHERE " . $db->sql_in_set('topic_poster', $user_id_ary);
$db->sql_query($sql);
$sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_last_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
WHERE " . $db->sql_in_set('topic_last_poster_id', $user_id_ary);
$db->sql_query($sql);
global $config;
if (in_array($config['newest_user_id'], $user_id_ary))
{
set_config('newest_user_colour', $sql_ary['user_colour'], true);
}
}
if ($update_listing)
{
group_update_listings($group_id);
}
// Because some tables/caches use usercolour-specific data we need to purge this here.
$cache->destroy('sql', MODERATOR_CACHE_TABLE);
}
/**
* Get group name
*/
function get_group_name($group_id)
{
global $db, $user;
$sql = 'SELECT group_name, group_type
FROM ' . GROUPS_TABLE . '
WHERE group_id = ' . (int) $group_id;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$row || ($row['group_type'] == GROUP_SPECIAL && empty($user->lang)))
{
return '';
}
return ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
}
/**
* Obtain either the members of a specified group, the groups the specified user is subscribed to
* or checking if a specified user is in a specified group. This function does not return pending memberships.
*
* Note: Never use this more than once... first group your users/groups
*/
function group_memberships($group_id_ary = false, $user_id_ary = false, $return_bool = false)
{
global $db;
if (!$group_id_ary && !$user_id_ary)
{
return true;
}
if ($user_id_ary)
{
$user_id_ary = (!is_array($user_id_ary)) ? array($user_id_ary) : $user_id_ary;
}
if ($group_id_ary)
{
$group_id_ary = (!is_array($group_id_ary)) ? array($group_id_ary) : $group_id_ary;
}
$sql = 'SELECT ug.*, u.username, u.username_clean, u.user_email
FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u
WHERE ug.user_id = u.user_id
AND ug.user_pending = 0 AND ';
if ($group_id_ary)
{
$sql .= ' ' . $db->sql_in_set('ug.group_id', $group_id_ary);
}
if ($user_id_ary)
{
$sql .= ($group_id_ary) ? ' AND ' : ' ';
$sql .= $db->sql_in_set('ug.user_id', $user_id_ary);
}
$result = ($return_bool) ? $db->sql_query_limit($sql, 1) : $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
if ($return_bool)
{
$db->sql_freeresult($result);
return ($row) ? true : false;
}
if (!$row)
{
return false;
}
$return = array();
do
{
$return[] = $row;
}
while ($row = $db->sql_fetchrow($result));
$db->sql_freeresult($result);
return $return;
}
/**
* Re-cache moderators and foes if group has a_ or m_ permissions
*/
function group_update_listings($group_id)
{
global $auth;
$hold_ary = $auth->acl_group_raw_data($group_id, array('a_', 'm_'));
if (!sizeof($hold_ary))
{
return;
}
$mod_permissions = $admin_permissions = false;
foreach ($hold_ary as $g_id => $forum_ary)
{
foreach ($forum_ary as $forum_id => $auth_ary)
{
foreach ($auth_ary as $auth_option => $setting)
{
if ($mod_permissions && $admin_permissions)
{
break 3;
}
if ($setting != ACL_YES)
{
continue;
}
if ($auth_option == 'm_')
{
$mod_permissions = true;
}
if ($auth_option == 'a_')
{
$admin_permissions = true;
}
}
}
}
if ($mod_permissions)
{
if (!function_exists('cache_moderators'))
{
global $phpbb_root_path, $phpEx;
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
}
cache_moderators();
}
if ($mod_permissions || $admin_permissions)
{
if (!function_exists('update_foes'))
{
global $phpbb_root_path, $phpEx;
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
}
update_foes(array($group_id));
}
}
/**
* Funtion to make a user leave the NEWLY_REGISTERED system group.
* @access public
* @param $user_id The id of the user to remove from the group
*/
function remove_newly_registered($user_id, $user_data = false)
{
global $db;
if ($user_data === false)
{
$sql = 'SELECT *
FROM ' . USERS_TABLE . '
WHERE user_id = ' . $user_id;
$result = $db->sql_query($sql);
$user_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$user_row)
{
return false;
}
else
{
$user_data = $user_row;
}
}
if (empty($user_data['user_new']))
{
return false;
}
$sql = 'SELECT group_id
FROM ' . GROUPS_TABLE . "
WHERE group_name = 'NEWLY_REGISTERED'
AND group_type = " . GROUP_SPECIAL;
$result = $db->sql_query($sql);
$group_id = (int) $db->sql_fetchfield('group_id');
$db->sql_freeresult($result);
if (!$group_id)
{
return false;
}
// We need to call group_user_del here, because this function makes sure everything is correctly changed.
// A downside for a call within the session handler is that the language is not set up yet - so no log entry
group_user_del($group_id, $user_id);
// Set user_new to 0 to let this not be triggered again
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_new = 0
WHERE user_id = ' . $user_id;
$db->sql_query($sql);
// The new users group was the users default group?
if ($user_data['group_id'] == $group_id)
{
// Which group is now the users default one?
$sql = 'SELECT group_id
FROM ' . USERS_TABLE . '
WHERE user_id = ' . $user_id;
$result = $db->sql_query($sql);
$user_data['group_id'] = $db->sql_fetchfield('group_id');
$db->sql_freeresult($result);
}
return $user_data['group_id'];
}
/**
* Gets user ids of currently banned registered users.
*
* @param array $user_ids Array of users' ids to check for banning,
* leave empty to get complete list of banned ids
* @return array Array of banned users' ids if any, empty array otherwise
*/
function phpbb_get_banned_user_ids($user_ids = array())
{
global $db;
$sql_user_ids = (!empty($user_ids)) ? $db->sql_in_set('ban_userid', $user_ids) : 'ban_userid <> 0';
// Get banned User ID's
// Ignore stale bans which were not wiped yet
$banned_ids_list = array();
$sql = 'SELECT ban_userid
FROM ' . BANLIST_TABLE . "
WHERE $sql_user_ids
AND ban_exclude <> 1
AND (ban_end > " . time() . '
OR ban_end = 0)';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$user_id = (int) $row['ban_userid'];
$banned_ids_list[$user_id] = $user_id;
}
$db->sql_freeresult($result);
return $banned_ids_list;
}
?>
I don't have access to a vBulletin board, so can you send a dump of a few of the rows from the vBulletin attachments table via PM, please?yamahar wrote:Thanks a lot for your help with that, conversion now works, however any attachments are now lost, is there any way to keep them too ?
Is that the complete error? Can you post your includes/acp/acp_users.php, please?yamahar wrote: however in the ACP when I go to a user or a group I get the following message.
Code: Select all
1;"18";"6";"1";"1294838337";"1";"visible";"4";"af829414d0344c360813e9041549e3f5";"37236.jpg";NULL;"0";NULL;"0";"0"
2;"18";"7";"1";"1294838337";"2";"visible";"1";"af829414d0344c360813e9041549e3f5";"37237.jpg";NULL;"0";NULL;"0";"0"
3;"18";"8";"1";"1294838337";"3";"visible";"1";"af829414d0344c360813e9041549e3f5";"37238.jpg";NULL;"0";NULL;"0";"0"
4;"18";"9";"1";"1294838337";"4";"visible";"2";"af829414d0344c360813e9041549e3f5";"37254.jpg";NULL;"0";NULL;"0";"0"
5;"18";"9";"1";"1294838337";"5";"visible";"1";"af829414d0344c360813e9041549e3f5";"37256.jpg";NULL;"0";NULL;"0";"0"
6;"18";"10";"1";"1294838337";"6";"visible";"19";"af829414d0344c360813e9041549e3f5";"37242.jpg";NULL;"0";NULL;"0";"0"
7;"18";"10";"1";"1294838337";"7";"visible";"2";"af829414d0344c360813e9041549e3f5";"37243.jpg";NULL;"0";NULL;"0";"0"
8;"18";"13";"1";"1294838337";"8";"visible";"1";"af829414d0344c360813e9041549e3f5";"37245.jpg";NULL;"0";NULL;"0";"0"
9;"18";"14";"1";"1294838337";"9";"visible";"12";"af829414d0344c360813e9041549e3f5";"37244.jpg";NULL;"0";NULL;"0";"0"
10;"18";"18";"1";"1294838337";"10";"visible";"0";"af829414d0344c360813e9041549e3f5";"37246.jpg";NULL;"0";NULL;"0";"0"
11;"18";"19";"1";"1294838337";"11";"visible";"0";"af829414d0344c360813e9041549e3f5";"37247.jpg";NULL;"0";NULL;"0";"0"
12;"18";"20";"1";"1294838337";"12";"visible";"3";"af829414d0344c360813e9041549e3f5";"37248.jpg";NULL;"0";NULL;"0";"0"
13;"18";"21";"1";"1294838337";"13";"visible";"3";"af829414d0344c360813e9041549e3f5";"37249.jpg";NULL;"0";NULL;"0";"0"
14;"18";"22";"1";"1294838337";"14";"visible";"17";"af829414d0344c360813e9041549e3f5";"37250.jpg";NULL;"0";NULL;"0";"0"
15;"18";"25";"1";"1294838337";"15";"visible";"2";"af829414d0344c360813e9041549e3f5";"37251.jpg";NULL;"0";NULL;"0";"0"
16;"18";"33";"1";"1294838337";"16";"visible";"0";"af829414d0344c360813e9041549e3f5";"37253.jpg";NULL;"0";NULL;"0";"0"
17;"18";"40";"1";"1294838337";"17";"visible";"14";"af829414d0344c360813e9041549e3f5";"37258.jpg";NULL;"0";NULL;"0";"0"
18;"18";"43";"1";"1294838337";"18";"visible";"5";"af829414d0344c360813e9041549e3f5";"37264.png";NULL;"0";NULL;"0";"0"
19;"18";"43";"1";"1294838337";"19";"visible";"5";"af829414d0344c360813e9041549e3f5";"37265.jpg";NULL;"0";NULL;"0";"0"
20;"18";"43";"1";"1294838337";"20";"visible";"21";"af829414d0344c360813e9041549e3f5";"37266.jpg";NULL;"0";NULL;"0";"0"
21;"18";"43";"1";"1294838337";"21";"visible";"5";"af829414d0344c360813e9041549e3f5";"37267.png";NULL;"0";NULL;"0";"0"
27;"18";"93";"1";"1294838337";"27";"visible";"5";"af829414d0344c360813e9041549e3f5";"37536.png";NULL;"0";NULL;"0";"0"
28;"18";"93";"1";"1294838337";"28";"visible";"5";"af829414d0344c360813e9041549e3f5";"37609.png";NULL;"0";NULL;"0";"0"
29;"18";"93";"1";"1294838337";"29";"visible";"5";"af829414d0344c360813e9041549e3f5";"37539.png";NULL;"0";NULL;"0";"0"
30;"18";"93";"1";"1294838337";"30";"visible";"32";"af829414d0344c360813e9041549e3f5";"37538.png";NULL;"0";NULL;"0";"0"
31;"18";"93";"1";"1294838337";"31";"visible";"4";"af829414d0344c360813e9041549e3f5";"37540.png";NULL;"0";NULL;"0";"0"
32;"18";"93";"1";"1294838337";"32";"visible";"4";"af829414d0344c360813e9041549e3f5";"37615.png";NULL;"0";NULL;"0";"0"
33;"18";"93";"1";"1294838337";"33";"visible";"4";"af829414d0344c360813e9041549e3f5";"37614.png";NULL;"0";NULL;"0";"0"
985;"1";"47186";"489";"1335551667";"878";"visible";"12";;"DSCN0702sml.jpg";NULL;"0";NULL;"0";"0"
40;"8";"1";"301";"1295521872";"38";"visible";"15";;"IMAG0101.jpg";"IMAG0101";"0";NULL;"40";"0"
41;"8";"1";"301";"1295521874";"39";"visible";"5";;"Bikesje LOGO.jpg";"Bikesje LOGO";"0";NULL;"41";"0"
44;"8";"1";"301";"1295616399";"41";"visible";"5";;"Resized.jpg";"Greve";"0";NULL;"44";"0"
45;"8";"1";"301";"1295616523";"42";"visible";"8";;"Greve2.jpg";"Greve2";"0";NULL;"0";"0"
46;"8";"1";"301";"1295616642";"43";"visible";"346";;"Greve.jpg";"Greve";"0";NULL;"0";"0"
47;"1";"31335";"3";"1295821095";"44";"visible";"28";;"fried_friend-img-817.jpg";NULL;"0";NULL;"0";"0"
48;"1";"31341";"301";"1295877513";"45";"visible";"1";;"TSHIRTS.JPG";NULL;"0";NULL;"0";"0"
49;"1";"31341";"301";"1295877643";"46";"visible";"0";;"Email signature copy.jpg";NULL;"0";NULL;"0";"0"
50;"8";"2";"201";"1296254398";"47";"visible";"20";;"South of France 2004 048.jpg";"South of France 2004 048";"0";NULL;"0";"0"
51;"8";"2";"201";"1296254398";"48";"visible";"18";;"100B1630.jpg";"100B1630";"0";NULL;"0";"0"
53;"8";"3";"201";"1296255471";"50";"visible";"18";;"chris_cameron_916gse_rep.jpg";"1998 916 BP HODGSON REP";"0";NULL;"0";"0"
52;"8";"2";"201";"1296254398";"49";"visible";"16";;"Hair styles Tracy 021.jpg";"Hair styles Tracy 021";"0";NULL;"0";"0"
63;"8";"3";"201";"1296301414";"57";"visible";"15";;"IMG_0419.jpg";"1998 CR250";"0";NULL;"0";"0"
54;"8";"3";"201";"1296255471";"51";"visible";"13";;"South of France 2004 011.jpg";"2001 FAZER 600";"0";NULL;"0";"0"
55;"8";"3";"201";"1296255471";"52";"visible";"12";;"Chris Photo's 006.jpg";"2002 GSXR1000";"0";NULL;"0";"0"
65;"8";"3";"201";"1296302050";"59";"visible";"9";;"IMG_0254.jpg";"2005 METAL X 100";"0";NULL;"0";"0"
62;"8";"3";"201";"1296301414";"56";"visible";"11";;"CIMG3725.jpg";"1994 XT600E";"0";NULL;"0";"0"
59;"8";"3";"201";"1296255854";"55";"visible";"14";;"IMG_0516.jpg";"2001 GSXR1000";"0";NULL;"0";"0"
60;"8";"3";"201";"1296255854";"53";"visible";"14";;"100_1461.jpg";"2004 SPEED TRIPLE";"0";NULL;"0";"0"
61;"8";"3";"201";"1296255854";"54";"visible";"15";;"IMG_1273.jpg";"2005 SM510R";"0";NULL;"0";"0"
64;"8";"3";"201";"1296301414";"58";"visible";"15";;"CIMG3957.jpg";"2010 SPEED TRIPLE";"0";NULL;"0";"0"
66;"8";"3";"201";"1296302050";"60";"visible";"11";;"TDR.jpg";"TDR 250";"0";NULL;"0";"0"
67;"8";"3";"201";"1296302050";"61";"visible";"10";;"IMG_0473.jpg";"1998 DT 125";"0";NULL;"0";"0"
68;"8";"3";"201";"1296302356";"62";"visible";"11";;"Chris Photo's 079.jpg";"DT 125";"0";NULL;"0";"0"
69;"8";"3";"201";"1296302356";"63";"visible";"13";;"Chris Photo's 081.jpg";"IT 250";"0";NULL;"0";"0"
70;"8";"3";"201";"1296302356";"64";"visible";"12";;"Chris Photo's 088.jpg";"DUKE 620 MK1";"0";NULL;"0";"0"
71;"8";"3";"201";"1296302798";"65";"visible";"11";;"CIMG2379.jpg";"2006 TXT 300";"0";NULL;"0";"0"
Code: Select all
<?php
/**
*
* @package acp
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* @package acp
*/
class acp_users
{
var $u_action;
var $p_master;
function acp_users(&$p_master)
{
$this->p_master = &$p_master;
}
function main($id, $mode)
{
global $config, $db, $user, $auth, $template, $cache;
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $file_uploads;
$user->add_lang(array('posting', 'ucp', 'acp/users'));
$this->tpl_name = 'acp_users';
$this->page_title = 'ACP_USER_' . strtoupper($mode);
$error = array();
$username = utf8_normalize_nfc(request_var('username', '', true));
$user_id = request_var('u', 0);
$action = request_var('action', '');
$submit = (isset($_POST['update']) && !isset($_POST['cancel'])) ? true : false;
$form_name = 'acp_users';
add_form_key($form_name);
// Whois (special case)
if ($action == 'whois')
{
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
$this->page_title = 'WHOIS';
$this->tpl_name = 'simple_body';
$user_ip = request_var('user_ip', '');
$domain = gethostbyaddr($user_ip);
$ipwhois = user_ipwhois($user_ip);
$template->assign_vars(array(
'MESSAGE_TITLE' => sprintf($user->lang['IP_WHOIS_FOR'], $domain),
'MESSAGE_TEXT' => nl2br($ipwhois))
);
return;
}
// Show user selection mask
if (!$username && !$user_id)
{
$this->page_title = 'SELECT_USER';
$template->assign_vars(array(
'U_ACTION' => $this->u_action,
'ANONYMOUS_USER_ID' => ANONYMOUS,
'S_SELECT_USER' => true,
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=select_user&field=username&select_single=true'),
));
return;
}
if (!$user_id)
{
$sql = 'SELECT user_id
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
$result = $db->sql_query($sql);
$user_id = (int) $db->sql_fetchfield('user_id');
$db->sql_freeresult($result);
if (!$user_id)
{
trigger_error($user->lang['NO_USER'] . adm_back_link($this->u_action), E_USER_WARNING);
}
}
// Generate content for all modes
$sql = 'SELECT u.*, s.*
FROM ' . USERS_TABLE . ' u
LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id)
WHERE u.user_id = ' . $user_id . '
ORDER BY s.session_time DESC';
$result = $db->sql_query_limit($sql, 1);
$user_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$user_row)
{
trigger_error($user->lang['NO_USER'] . adm_back_link($this->u_action), E_USER_WARNING);
}
// Generate overall "header" for user admin
$s_form_options = '';
// Build modes dropdown list
$sql = 'SELECT module_mode, module_auth
FROM ' . MODULES_TABLE . "
WHERE module_basename = 'users'
AND module_enabled = 1
AND module_class = 'acp'
ORDER BY left_id, module_mode";
$result = $db->sql_query($sql);
$dropdown_modes = array();
while ($row = $db->sql_fetchrow($result))
{
if (!$this->p_master->module_auth($row['module_auth']))
{
continue;
}
$dropdown_modes[$row['module_mode']] = true;
}
$db->sql_freeresult($result);
foreach ($dropdown_modes as $module_mode => $null)
{
$selected = ($mode == $module_mode) ? ' selected="selected"' : '';
$s_form_options .= '<option value="' . $module_mode . '"' . $selected . '>' . $user->lang['ACP_USER_' . strtoupper($module_mode)] . '</option>';
}
$template->assign_vars(array(
'U_BACK' => $this->u_action,
'U_MODE_SELECT' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&u=$user_id"),
'U_ACTION' => $this->u_action . '&u=' . $user_id,
'S_FORM_OPTIONS' => $s_form_options,
'MANAGED_USERNAME' => $user_row['username'])
);
// Prevent normal users/admins change/view founders if they are not a founder by themselves
if ($user->data['user_type'] != USER_FOUNDER && $user_row['user_type'] == USER_FOUNDER)
{
trigger_error($user->lang['NOT_MANAGE_FOUNDER'] . adm_back_link($this->u_action), E_USER_WARNING);
}
switch ($mode)
{
case 'overview':
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
$user->add_lang('acp/ban');
$delete = request_var('delete', 0);
$delete_type = request_var('delete_type', '');
$ip = request_var('ip', 'ip');
if ($submit)
{
// You can't delete the founder
if ($delete && $user_row['user_type'] != USER_FOUNDER)
{
if (!$auth->acl_get('a_userdel'))
{
trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
// Check if the user wants to remove himself or the guest user account
if ($user_id == ANONYMOUS)
{
trigger_error($user->lang['CANNOT_REMOVE_ANONYMOUS'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($user_id == $user->data['user_id'])
{
trigger_error($user->lang['CANNOT_REMOVE_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($delete_type)
{
if (confirm_box(true))
{
user_delete($delete_type, $user_id, $user_row['username']);
add_log('admin', 'LOG_USER_DELETED', $user_row['username']);
trigger_error($user->lang['USER_DELETED'] . adm_back_link($this->u_action));
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'update' => true,
'delete' => 1,
'delete_type' => $delete_type))
);
}
}
else
{
trigger_error($user->lang['NO_MODE'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
}
// Handle quicktool actions
switch ($action)
{
case 'banuser':
case 'banemail':
case 'banip':
if ($user_id == $user->data['user_id'])
{
trigger_error($user->lang['CANNOT_BAN_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($user_id == ANONYMOUS)
{
trigger_error($user->lang['CANNOT_BAN_ANONYMOUS'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($user_row['user_type'] == USER_FOUNDER)
{
trigger_error($user->lang['CANNOT_BAN_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$ban = array();
switch ($action)
{
case 'banuser':
$ban[] = $user_row['username'];
$reason = 'USER_ADMIN_BAN_NAME_REASON';
$log = 'LOG_USER_BAN_USER';
break;
case 'banemail':
$ban[] = $user_row['user_email'];
$reason = 'USER_ADMIN_BAN_EMAIL_REASON';
$log = 'LOG_USER_BAN_EMAIL';
break;
case 'banip':
$ban[] = $user_row['user_ip'];
$sql = 'SELECT DISTINCT poster_ip
FROM ' . POSTS_TABLE . "
WHERE poster_id = $user_id";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$ban[] = $row['poster_ip'];
}
$db->sql_freeresult($result);
$reason = 'USER_ADMIN_BAN_IP_REASON';
$log = 'LOG_USER_BAN_IP';
break;
}
$ban_reason = utf8_normalize_nfc(request_var('ban_reason', $user->lang[$reason], true));
$ban_give_reason = utf8_normalize_nfc(request_var('ban_give_reason', '', true));
// Log not used at the moment, we simply utilize the ban function.
$result = user_ban(substr($action, 3), $ban, 0, 0, 0, $ban_reason, $ban_give_reason);
trigger_error((($result === false) ? $user->lang['BAN_ALREADY_ENTERED'] : $user->lang['BAN_SUCCESSFUL']) . adm_back_link($this->u_action . '&u=' . $user_id));
break;
case 'reactivate':
if ($user_id == $user->data['user_id'])
{
trigger_error($user->lang['CANNOT_FORCE_REACT_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($user_row['user_type'] == USER_FOUNDER)
{
trigger_error($user->lang['CANNOT_FORCE_REACT_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($user_row['user_type'] == USER_IGNORE)
{
trigger_error($user->lang['CANNOT_FORCE_REACT_BOT'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($config['email_enable'])
{
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
$server_url = generate_board_url();
$user_actkey = gen_rand_string(mt_rand(6, 10));
$email_template = ($user_row['user_type'] == USER_NORMAL) ? 'user_reactivate_account' : 'user_resend_inactive';
if ($user_row['user_type'] == USER_NORMAL)
{
user_active_flip('deactivate', $user_id, INACTIVE_REMIND);
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_actkey = '" . $db->sql_escape($user_actkey) . "'
WHERE user_id = $user_id";
$db->sql_query($sql);
}
else
{
// Grabbing the last confirm key - we only send a reminder
$sql = 'SELECT user_actkey
FROM ' . USERS_TABLE . '
WHERE user_id = ' . $user_id;
$result = $db->sql_query($sql);
$user_actkey = (string) $db->sql_fetchfield('user_actkey');
$db->sql_freeresult($result);
}
$messenger = new messenger(false);
$messenger->template($email_template, $user_row['user_lang']);
$messenger->to($user_row['user_email'], $user_row['username']);
$messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'WELCOME_MSG' => htmlspecialchars_decode(sprintf($user->lang['WELCOME_SUBJECT'], $config['sitename'])),
'USERNAME' => htmlspecialchars_decode($user_row['username']),
'U_ACTIVATE' => "$server_url/ucp.$phpEx?mode=activate&u={$user_row['user_id']}&k=$user_actkey")
);
$messenger->send(NOTIFY_EMAIL);
add_log('admin', 'LOG_USER_REACTIVATE', $user_row['username']);
add_log('user', $user_id, 'LOG_USER_REACTIVATE_USER');
trigger_error($user->lang['FORCE_REACTIVATION_SUCCESS'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
break;
case 'active':
if ($user_id == $user->data['user_id'])
{
// It is only deactivation since the user is already activated (else he would not have reached this page)
trigger_error($user->lang['CANNOT_DEACTIVATE_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($user_row['user_type'] == USER_FOUNDER)
{
trigger_error($user->lang['CANNOT_DEACTIVATE_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($user_row['user_type'] == USER_IGNORE)
{
trigger_error($user->lang['CANNOT_DEACTIVATE_BOT'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
user_active_flip('flip', $user_id);
if ($user_row['user_type'] == USER_INACTIVE)
{
if ($config['require_activation'] == USER_ACTIVATION_ADMIN)
{
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
$messenger = new messenger(false);
$messenger->template('admin_welcome_activated', $user_row['user_lang']);
$messenger->to($user_row['user_email'], $user_row['username']);
$messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($user_row['username']))
);
$messenger->send(NOTIFY_EMAIL);
}
}
$message = ($user_row['user_type'] == USER_INACTIVE) ? 'USER_ADMIN_ACTIVATED' : 'USER_ADMIN_DEACTIVED';
$log = ($user_row['user_type'] == USER_INACTIVE) ? 'LOG_USER_ACTIVE' : 'LOG_USER_INACTIVE';
add_log('admin', $log, $user_row['username']);
add_log('user', $user_id, $log . '_USER');
trigger_error($user->lang[$message] . adm_back_link($this->u_action . '&u=' . $user_id));
break;
case 'delsig':
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$sql_ary = array(
'user_sig' => '',
'user_sig_bbcode_uid' => '',
'user_sig_bbcode_bitfield' => ''
);
$sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE user_id = $user_id";
$db->sql_query($sql);
add_log('admin', 'LOG_USER_DEL_SIG', $user_row['username']);
add_log('user', $user_id, 'LOG_USER_DEL_SIG_USER');
trigger_error($user->lang['USER_ADMIN_SIG_REMOVED'] . adm_back_link($this->u_action . '&u=' . $user_id));
break;
case 'delavatar':
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$sql_ary = array(
'user_avatar' => '',
'user_avatar_type' => 0,
'user_avatar_width' => 0,
'user_avatar_height' => 0,
);
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE user_id = $user_id";
$db->sql_query($sql);
// Delete old avatar if present
if ($user_row['user_avatar'] && $user_row['user_avatar_type'] != AVATAR_GALLERY)
{
avatar_delete('user', $user_row);
}
add_log('admin', 'LOG_USER_DEL_AVATAR', $user_row['username']);
add_log('user', $user_id, 'LOG_USER_DEL_AVATAR_USER');
trigger_error($user->lang['USER_ADMIN_AVATAR_REMOVED'] . adm_back_link($this->u_action . '&u=' . $user_id));
break;
case 'delposts':
if (confirm_box(true))
{
// Delete posts, attachments, etc.
delete_posts('poster_id', $user_id);
add_log('admin', 'LOG_USER_DEL_POSTS', $user_row['username']);
trigger_error($user->lang['USER_POSTS_DELETED'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'update' => true))
);
}
break;
case 'delattach':
if (confirm_box(true))
{
delete_attachments('user', $user_id);
add_log('admin', 'LOG_USER_DEL_ATTACH', $user_row['username']);
trigger_error($user->lang['USER_ATTACHMENTS_REMOVED'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'update' => true))
);
}
break;
case 'deloutbox':
if (confirm_box(true))
{
$msg_ids = array();
$lang = 'EMPTY';
$sql = 'SELECT msg_id
FROM ' . PRIVMSGS_TO_TABLE . "
WHERE author_id = $user_id
AND folder_id = " . PRIVMSGS_OUTBOX;
$result = $db->sql_query($sql);
if ($row = $db->sql_fetchrow($result))
{
if (!function_exists('delete_pm'))
{
include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
}
do
{
$msg_ids[] = (int) $row['msg_id'];
}
while ($row = $db->sql_fetchrow($result));
$db->sql_freeresult($result);
delete_pm($user_id, $msg_ids, PRIVMSGS_OUTBOX);
add_log('admin', 'LOG_USER_DEL_OUTBOX', $user_row['username']);
$lang = 'EMPTIED';
}
$db->sql_freeresult($result);
trigger_error($user->lang['USER_OUTBOX_' . $lang] . adm_back_link($this->u_action . '&u=' . $user_id));
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'update' => true))
);
}
break;
case 'moveposts':
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$user->add_lang('acp/forums');
$new_forum_id = request_var('new_f', 0);
if (!$new_forum_id)
{
$this->page_title = 'USER_ADMIN_MOVE_POSTS';
$template->assign_vars(array(
'S_SELECT_FORUM' => true,
'U_ACTION' => $this->u_action . "&action=$action&u=$user_id",
'U_BACK' => $this->u_action . "&u=$user_id",
'S_FORUM_OPTIONS' => make_forum_select(false, false, false, true))
);
return;
}
// Is the new forum postable to?
$sql = 'SELECT forum_name, forum_type
FROM ' . FORUMS_TABLE . "
WHERE forum_id = $new_forum_id";
$result = $db->sql_query($sql);
$forum_info = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$forum_info)
{
trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($forum_info['forum_type'] != FORUM_POST)
{
trigger_error($user->lang['MOVE_POSTS_NO_POSTABLE_FORUM'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
// Two stage?
// Move topics comprising only posts from this user
$topic_id_ary = $move_topic_ary = $move_post_ary = $new_topic_id_ary = array();
$forum_id_ary = array($new_forum_id);
$sql = 'SELECT topic_id, COUNT(post_id) AS total_posts
FROM ' . POSTS_TABLE . "
WHERE poster_id = $user_id
AND forum_id <> $new_forum_id
GROUP BY topic_id";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$topic_id_ary[$row['topic_id']] = $row['total_posts'];
}
$db->sql_freeresult($result);
if (sizeof($topic_id_ary))
{
$sql = 'SELECT topic_id, forum_id, topic_title, topic_replies, topic_replies_real, topic_attachment
FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_id', array_keys($topic_id_ary));
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (max($row['topic_replies'], $row['topic_replies_real']) + 1 == $topic_id_ary[$row['topic_id']])
{
$move_topic_ary[] = $row['topic_id'];
}
else
{
$move_post_ary[$row['topic_id']]['title'] = $row['topic_title'];
$move_post_ary[$row['topic_id']]['attach'] = ($row['topic_attachment']) ? 1 : 0;
}
$forum_id_ary[] = $row['forum_id'];
}
$db->sql_freeresult($result);
}
// Entire topic comprises posts by this user, move these topics
if (sizeof($move_topic_ary))
{
move_topics($move_topic_ary, $new_forum_id, false);
}
if (sizeof($move_post_ary))
{
// Create new topic
// Update post_ids, report_ids, attachment_ids
foreach ($move_post_ary as $topic_id => $post_ary)
{
// Create new topic
$sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
'topic_poster' => $user_id,
'topic_time' => time(),
'forum_id' => $new_forum_id,
'icon_id' => 0,
'topic_approved' => 1,
'topic_title' => $post_ary['title'],
'topic_first_poster_name' => $user_row['username'],
'topic_type' => POST_NORMAL,
'topic_time_limit' => 0,
'topic_attachment' => $post_ary['attach'])
);
$db->sql_query($sql);
$new_topic_id = $db->sql_nextid();
// Move posts
$sql = 'UPDATE ' . POSTS_TABLE . "
SET forum_id = $new_forum_id, topic_id = $new_topic_id
WHERE topic_id = $topic_id
AND poster_id = $user_id";
$db->sql_query($sql);
if ($post_ary['attach'])
{
$sql = 'UPDATE ' . ATTACHMENTS_TABLE . "
SET topic_id = $new_topic_id
WHERE topic_id = $topic_id
AND poster_id = $user_id";
$db->sql_query($sql);
}
$new_topic_id_ary[] = $new_topic_id;
}
}
$forum_id_ary = array_unique($forum_id_ary);
$topic_id_ary = array_unique(array_merge(array_keys($topic_id_ary), $new_topic_id_ary));
if (sizeof($topic_id_ary))
{
sync('topic_reported', 'topic_id', $topic_id_ary);
sync('topic', 'topic_id', $topic_id_ary);
}
if (sizeof($forum_id_ary))
{
sync('forum', 'forum_id', $forum_id_ary, false, true);
}
add_log('admin', 'LOG_USER_MOVE_POSTS', $user_row['username'], $forum_info['forum_name']);
add_log('user', $user_id, 'LOG_USER_MOVE_POSTS_USER', $forum_info['forum_name']);
trigger_error($user->lang['USER_POSTS_MOVED'] . adm_back_link($this->u_action . '&u=' . $user_id));
break;
case 'leave_nr':
if (confirm_box(true))
{
remove_newly_registered($user_id, $user_row);
add_log('admin', 'LOG_USER_REMOVED_NR', $user_row['username']);
trigger_error($user->lang['USER_LIFTED_NR'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'update' => true))
);
}
break;
}
// Handle registration info updates
$data = array(
'username' => utf8_normalize_nfc(request_var('user', $user_row['username'], true)),
'user_founder' => request_var('user_founder', ($user_row['user_type'] == USER_FOUNDER) ? 1 : 0),
'email' => strtolower(request_var('user_email', $user_row['user_email'])),
'email_confirm' => strtolower(request_var('email_confirm', '')),
'new_password' => request_var('new_password', '', true),
'password_confirm' => request_var('password_confirm', '', true),
);
// Validation data - we do not check the password complexity setting here
$check_ary = array(
'new_password' => array(
array('string', true, $config['min_pass_chars'], $config['max_pass_chars']),
array('password')),
'password_confirm' => array('string', true, $config['min_pass_chars'], $config['max_pass_chars']),
);
// Check username if altered
if ($data['username'] != $user_row['username'])
{
$check_ary += array(
'username' => array(
array('string', false, $config['min_name_chars'], $config['max_name_chars']),
array('username', $user_row['username'])
),
);
}
// Check email if altered
if ($data['email'] != $user_row['user_email'])
{
$check_ary += array(
'email' => array(
array('string', false, 6, 60),
array('email', $user_row['user_email'])
),
'email_confirm' => array('string', true, 6, 60)
);
}
$error = validate_data($data, $check_ary);
if ($data['new_password'] && $data['password_confirm'] != $data['new_password'])
{
$error[] = 'NEW_PASSWORD_ERROR';
}
if ($data['email'] != $user_row['user_email'] && $data['email_confirm'] != $data['email'])
{
$error[] = 'NEW_EMAIL_ERROR';
}
if (!check_form_key($form_name))
{
$error[] = 'FORM_INVALID';
}
// Which updates do we need to do?
$update_username = ($user_row['username'] != $data['username']) ? $data['username'] : false;
$update_password = ($data['new_password'] && !phpbb_check_hash($data['new_password'], $user_row['user_password'])) ? true : false;
$update_email = ($data['email'] != $user_row['user_email']) ? $data['email'] : false;
if (!sizeof($error))
{
$sql_ary = array();
if ($user_row['user_type'] != USER_FOUNDER || $user->data['user_type'] == USER_FOUNDER)
{
// Only allow founders updating the founder status...
if ($user->data['user_type'] == USER_FOUNDER)
{
// Setting a normal member to be a founder
if ($data['user_founder'] && $user_row['user_type'] != USER_FOUNDER)
{
// Make sure the user is not setting an Inactive or ignored user to be a founder
if ($user_row['user_type'] == USER_IGNORE)
{
trigger_error($user->lang['CANNOT_SET_FOUNDER_IGNORED'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($user_row['user_type'] == USER_INACTIVE)
{
trigger_error($user->lang['CANNOT_SET_FOUNDER_INACTIVE'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$sql_ary['user_type'] = USER_FOUNDER;
}
else if (!$data['user_founder'] && $user_row['user_type'] == USER_FOUNDER)
{
// Check if at least one founder is present
$sql = 'SELECT user_id
FROM ' . USERS_TABLE . '
WHERE user_type = ' . USER_FOUNDER . '
AND user_id <> ' . $user_id;
$result = $db->sql_query_limit($sql, 1);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
$sql_ary['user_type'] = USER_NORMAL;
}
else
{
trigger_error($user->lang['AT_LEAST_ONE_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
}
}
}
if ($update_username !== false)
{
$sql_ary['username'] = $update_username;
$sql_ary['username_clean'] = utf8_clean_string($update_username);
add_log('user', $user_id, 'LOG_USER_UPDATE_NAME', $user_row['username'], $update_username);
}
if ($update_email !== false)
{
$sql_ary += array(
'user_email' => $update_email,
'user_email_hash' => phpbb_email_hash($update_email),
);
add_log('user', $user_id, 'LOG_USER_UPDATE_EMAIL', $user_row['username'], $user_row['user_email'], $update_email);
}
if ($update_password)
{
$sql_ary += array(
'user_password' => phpbb_hash($data['new_password']),
'user_passchg' => time(),
'user_pass_convert' => 0,
);
$user->reset_login_keys($user_id);
add_log('user', $user_id, 'LOG_USER_NEW_PASSWORD', $user_row['username']);
}
if (sizeof($sql_ary))
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE user_id = ' . $user_id;
$db->sql_query($sql);
}
if ($update_username)
{
user_update_name($user_row['username'], $update_username);
}
// Let the users permissions being updated
$auth->acl_clear_prefetch($user_id);
add_log('admin', 'LOG_USER_USER_UPDATE', $data['username']);
trigger_error($user->lang['USER_OVERVIEW_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
// Replace "error" strings with their real, localised form
$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
}
if ($user_id == $user->data['user_id'])
{
$quick_tool_ary = array('delsig' => 'DEL_SIG', 'delavatar' => 'DEL_AVATAR', 'moveposts' => 'MOVE_POSTS', 'delposts' => 'DEL_POSTS', 'delattach' => 'DEL_ATTACH', 'deloutbox' => 'DEL_OUTBOX');
if ($user_row['user_new'])
{
$quick_tool_ary['leave_nr'] = 'LEAVE_NR';
}
}
else
{
$quick_tool_ary = array();
if ($user_row['user_type'] != USER_FOUNDER)
{
$quick_tool_ary += array('banuser' => 'BAN_USER', 'banemail' => 'BAN_EMAIL', 'banip' => 'BAN_IP');
}
if ($user_row['user_type'] != USER_FOUNDER && $user_row['user_type'] != USER_IGNORE)
{
$quick_tool_ary += array('active' => (($user_row['user_type'] == USER_INACTIVE) ? 'ACTIVATE' : 'DEACTIVATE'));
}
$quick_tool_ary += array('delsig' => 'DEL_SIG', 'delavatar' => 'DEL_AVATAR', 'moveposts' => 'MOVE_POSTS', 'delposts' => 'DEL_POSTS', 'delattach' => 'DEL_ATTACH', 'deloutbox' => 'DEL_OUTBOX');
if ($config['email_enable'] && ($user_row['user_type'] == USER_NORMAL || $user_row['user_type'] == USER_INACTIVE))
{
$quick_tool_ary['reactivate'] = 'FORCE';
}
if ($user_row['user_new'])
{
$quick_tool_ary['leave_nr'] = 'LEAVE_NR';
}
}
$s_action_options = '<option class="sep" value="">' . $user->lang['SELECT_OPTION'] . '</option>';
foreach ($quick_tool_ary as $value => $lang)
{
$s_action_options .= '<option value="' . $value . '">' . $user->lang['USER_ADMIN_' . $lang] . '</option>';
}
if ($config['load_onlinetrack'])
{
$sql = 'SELECT MAX(session_time) AS session_time, MIN(session_viewonline) AS session_viewonline
FROM ' . SESSIONS_TABLE . "
WHERE session_user_id = $user_id";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$user_row['session_time'] = (isset($row['session_time'])) ? $row['session_time'] : 0;
$user_row['session_viewonline'] = (isset($row['session_viewonline'])) ? $row['session_viewonline'] : 0;
unset($row);
}
$last_visit = (!empty($user_row['session_time'])) ? $user_row['session_time'] : $user_row['user_lastvisit'];
$inactive_reason = '';
if ($user_row['user_type'] == USER_INACTIVE)
{
$inactive_reason = $user->lang['INACTIVE_REASON_UNKNOWN'];
switch ($user_row['user_inactive_reason'])
{
case INACTIVE_REGISTER:
$inactive_reason = $user->lang['INACTIVE_REASON_REGISTER'];
break;
case INACTIVE_PROFILE:
$inactive_reason = $user->lang['INACTIVE_REASON_PROFILE'];
break;
case INACTIVE_MANUAL:
$inactive_reason = $user->lang['INACTIVE_REASON_MANUAL'];
break;
case INACTIVE_REMIND:
$inactive_reason = $user->lang['INACTIVE_REASON_REMIND'];
break;
}
}
// Posts in Queue
$sql = 'SELECT COUNT(post_id) as posts_in_queue
FROM ' . POSTS_TABLE . '
WHERE poster_id = ' . $user_id . '
AND post_approved = 0';
$result = $db->sql_query($sql);
$user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue');
$db->sql_freeresult($result);
$sql = 'SELECT post_id
FROM ' . POSTS_TABLE . '
WHERE poster_id = '. $user_id;
$result = $db->sql_query_limit($sql, 1);
$user_row['user_has_posts'] = (bool) $db->sql_fetchfield('post_id');
$db->sql_freeresult($result);
$template->assign_vars(array(
'L_NAME_CHARS_EXPLAIN' => sprintf($user->lang[$config['allow_name_chars'] . '_EXPLAIN'], $config['min_name_chars'], $config['max_name_chars']),
'L_CHANGE_PASSWORD_EXPLAIN' => sprintf($user->lang[$config['pass_complex'] . '_EXPLAIN'], $config['min_pass_chars'], $config['max_pass_chars']),
'L_POSTS_IN_QUEUE' => $user->lang('NUM_POSTS_IN_QUEUE', $user_row['posts_in_queue']),
'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false,
'S_OVERVIEW' => true,
'S_USER_IP' => ($user_row['user_ip']) ? true : false,
'S_USER_FOUNDER' => ($user_row['user_type'] == USER_FOUNDER) ? true : false,
'S_ACTION_OPTIONS' => $s_action_options,
'S_OWN_ACCOUNT' => ($user_id == $user->data['user_id']) ? true : false,
'S_USER_INACTIVE' => ($user_row['user_type'] == USER_INACTIVE) ? true : false,
'U_SHOW_IP' => $this->u_action . "&u=$user_id&ip=" . (($ip == 'ip') ? 'hostname' : 'ip'),
'U_WHOIS' => $this->u_action . "&action=whois&user_ip={$user_row['user_ip']}",
'U_MCP_QUEUE' => ($auth->acl_getf_global('m_approve')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue', true, $user->session_id) : '',
'U_SWITCH_PERMISSIONS' => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_row['user_id']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&u={$user_row['user_id']}&hash=" . generate_link_hash('switchperm')) : '',
'POSTS_IN_QUEUE' => $user_row['posts_in_queue'],
'USER' => $user_row['username'],
'USER_REGISTERED' => $user->format_date($user_row['user_regdate']),
'REGISTERED_IP' => ($ip == 'hostname') ? gethostbyaddr($user_row['user_ip']) : $user_row['user_ip'],
'USER_LASTACTIVE' => ($last_visit) ? $user->format_date($last_visit) : ' - ',
'USER_EMAIL' => $user_row['user_email'],
'USER_WARNINGS' => $user_row['user_warnings'],
'USER_POSTS' => $user_row['user_posts'],
'USER_HAS_POSTS' => $user_row['user_has_posts'],
'USER_INACTIVE_REASON' => $inactive_reason,
));
break;
case 'feedback':
$user->add_lang('mcp');
// Set up general vars
$start = request_var('start', 0);
$deletemark = (isset($_POST['delmarked'])) ? true : false;
$deleteall = (isset($_POST['delall'])) ? true : false;
$marked = request_var('mark', array(0));
$message = utf8_normalize_nfc(request_var('message', '', true));
// Sort keys
$sort_days = request_var('st', 0);
$sort_key = request_var('sk', 't');
$sort_dir = request_var('sd', 'd');
// Delete entries if requested and able
if (($deletemark || $deleteall) && $auth->acl_get('a_clearlogs'))
{
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$where_sql = '';
if ($deletemark && $marked)
{
$sql_in = array();
foreach ($marked as $mark)
{
$sql_in[] = $mark;
}
$where_sql = ' AND ' . $db->sql_in_set('log_id', $sql_in);
unset($sql_in);
}
if ($where_sql || $deleteall)
{
$sql = 'DELETE FROM ' . LOG_TABLE . '
WHERE log_type = ' . LOG_USERS . "
AND reportee_id = $user_id
$where_sql";
$db->sql_query($sql);
add_log('admin', 'LOG_CLEAR_USER', $user_row['username']);
}
}
if ($submit && $message)
{
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
add_log('admin', 'LOG_USER_FEEDBACK', $user_row['username']);
add_log('mod', 0, 0, 'LOG_USER_FEEDBACK', $user_row['username']);
add_log('user', $user_id, 'LOG_USER_GENERAL', $message);
trigger_error($user->lang['USER_FEEDBACK_ADDED'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
// Sorting
$limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
$sort_by_text = array('u' => $user->lang['SORT_USERNAME'], 't' => $user->lang['SORT_DATE'], 'i' => $user->lang['SORT_IP'], 'o' => $user->lang['SORT_ACTION']);
$sort_by_sql = array('u' => 'u.username_clean', 't' => 'l.log_time', 'i' => 'l.log_ip', 'o' => 'l.log_operation');
$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
// Define where and sort sql for use in displaying logs
$sql_where = ($sort_days) ? (time() - ($sort_days * 86400)) : 0;
$sql_sort = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
// Grab log data
$log_data = array();
$log_count = 0;
$start = view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort);
$template->assign_vars(array(
'S_FEEDBACK' => true,
'S_ON_PAGE' => on_page($log_count, $config['topics_per_page'], $start),
'PAGINATION' => generate_pagination($this->u_action . "&u=$user_id&$u_sort_param", $log_count, $config['topics_per_page'], $start, true),
'S_LIMIT_DAYS' => $s_limit_days,
'S_SORT_KEY' => $s_sort_key,
'S_SORT_DIR' => $s_sort_dir,
'S_CLEARLOGS' => $auth->acl_get('a_clearlogs'))
);
foreach ($log_data as $row)
{
$template->assign_block_vars('log', array(
'USERNAME' => $row['username_full'],
'IP' => $row['ip'],
'DATE' => $user->format_date($row['time']),
'ACTION' => nl2br($row['action']),
'ID' => $row['id'])
);
}
break;
case 'warnings':
$user->add_lang('mcp');
// Set up general vars
$start = request_var('start', 0);
$deletemark = (isset($_POST['delmarked'])) ? true : false;
$deleteall = (isset($_POST['delall'])) ? true : false;
$confirm = (isset($_POST['confirm'])) ? true : false;
$marked = request_var('mark', array(0));
$message = utf8_normalize_nfc(request_var('message', '', true));
// Sort keys
$sort_days = request_var('st', 0);
$sort_key = request_var('sk', 't');
$sort_dir = request_var('sd', 'd');
// Delete entries if requested and able
if ($deletemark || $deleteall || $confirm)
{
if (confirm_box(true))
{
$where_sql = '';
$deletemark = request_var('delmarked', 0);
$deleteall = request_var('delall', 0);
if ($deletemark && $marked)
{
$where_sql = ' AND ' . $db->sql_in_set('warning_id', array_values($marked));
}
if ($where_sql || $deleteall)
{
$sql = 'DELETE FROM ' . WARNINGS_TABLE . "
WHERE user_id = $user_id
$where_sql";
$db->sql_query($sql);
if ($deleteall)
{
$log_warnings = $deleted_warnings = 0;
}
else
{
$num_warnings = (int) $db->sql_affectedrows();
$deleted_warnings = ' user_warnings - ' . $num_warnings;
$log_warnings = ($num_warnings > 2) ? 2 : $num_warnings;
}
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_warnings = $deleted_warnings
WHERE user_id = $user_id";
$db->sql_query($sql);
switch ($log_warnings)
{
case 2:
add_log('admin', 'LOG_WARNINGS_DELETED', $user_row['username'], $num_warnings);
break;
case 1:
add_log('admin', 'LOG_WARNING_DELETED', $user_row['username']);
break;
default:
add_log('admin', 'LOG_WARNINGS_DELETED_ALL', $user_row['username']);
break;
}
}
}
else
{
$s_hidden_fields = array(
'i' => $id,
'mode' => $mode,
'u' => $user_id,
'mark' => $marked,
);
if (isset($_POST['delmarked']))
{
$s_hidden_fields['delmarked'] = 1;
}
if (isset($_POST['delall']))
{
$s_hidden_fields['delall'] = 1;
}
if (isset($_POST['delall']) || (isset($_POST['delmarked']) && sizeof($marked)))
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields));
}
}
}
$sql = 'SELECT w.warning_id, w.warning_time, w.post_id, l.log_operation, l.log_data, l.user_id AS mod_user_id, m.username AS mod_username, m.user_colour AS mod_user_colour
FROM ' . WARNINGS_TABLE . ' w
LEFT JOIN ' . LOG_TABLE . ' l
ON (w.log_id = l.log_id)
LEFT JOIN ' . USERS_TABLE . ' m
ON (l.user_id = m.user_id)
WHERE w.user_id = ' . $user_id . '
ORDER BY w.warning_time DESC';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (!$row['log_operation'])
{
// We do not have a log-entry anymore, so there is no data available
$row['action'] = $user->lang['USER_WARNING_LOG_DELETED'];
}
else
{
$row['action'] = (isset($user->lang[$row['log_operation']])) ? $user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}';
if (!empty($row['log_data']))
{
$log_data_ary = @unserialize($row['log_data']);
$log_data_ary = ($log_data_ary === false) ? array() : $log_data_ary;
if (isset($user->lang[$row['log_operation']]))
{
// Check if there are more occurrences of % than arguments, if there are we fill out the arguments array
// It doesn't matter if we add more arguments than placeholders
if ((substr_count($row['action'], '%') - sizeof($log_data_ary)) > 0)
{
$log_data_ary = array_merge($log_data_ary, array_fill(0, substr_count($row['action'], '%') - sizeof($log_data_ary), ''));
}
$row['action'] = vsprintf($row['action'], $log_data_ary);
$row['action'] = bbcode_nl2br(censor_text($row['action']));
}
else if (!empty($log_data_ary))
{
$row['action'] .= '<br />' . implode('', $log_data_ary);
}
}
}
$template->assign_block_vars('warn', array(
'ID' => $row['warning_id'],
'USERNAME' => ($row['log_operation']) ? get_username_string('full', $row['mod_user_id'], $row['mod_username'], $row['mod_user_colour']) : '-',
'ACTION' => make_clickable($row['action']),
'DATE' => $user->format_date($row['warning_time']),
));
}
$db->sql_freeresult($result);
$template->assign_vars(array(
'S_WARNINGS' => true,
));
break;
case 'profile':
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx);
$cp = new custom_profile();
$cp_data = $cp_error = array();
$sql = 'SELECT lang_id
FROM ' . LANG_TABLE . "
WHERE lang_iso = '" . $db->sql_escape($user->data['user_lang']) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$user_row['iso_lang_id'] = $row['lang_id'];
$data = array(
'icq' => request_var('icq', $user_row['user_icq']),
'aim' => request_var('aim', $user_row['user_aim']),
'msn' => request_var('msn', $user_row['user_msnm']),
'yim' => request_var('yim', $user_row['user_yim']),
'jabber' => utf8_normalize_nfc(request_var('jabber', $user_row['user_jabber'], true)),
'website' => request_var('website', $user_row['user_website']),
'location' => utf8_normalize_nfc(request_var('location', $user_row['user_from'], true)),
'occupation' => utf8_normalize_nfc(request_var('occupation', $user_row['user_occ'], true)),
'interests' => utf8_normalize_nfc(request_var('interests', $user_row['user_interests'], true)),
'bday_day' => 0,
'bday_month' => 0,
'bday_year' => 0,
);
if ($user_row['user_birthday'])
{
list($data['bday_day'], $data['bday_month'], $data['bday_year']) = explode('-', $user_row['user_birthday']);
}
$data['bday_day'] = request_var('bday_day', $data['bday_day']);
$data['bday_month'] = request_var('bday_month', $data['bday_month']);
$data['bday_year'] = request_var('bday_year', $data['bday_year']);
$data['user_birthday'] = sprintf('%2d-%2d-%4d', $data['bday_day'], $data['bday_month'], $data['bday_year']);
if ($submit)
{
$error = validate_data($data, array(
'icq' => array(
array('string', true, 3, 15),
array('match', true, '#^[0-9]+$#i')),
'aim' => array('string', true, 3, 255),
'msn' => array('string', true, 5, 255),
'jabber' => array(
array('string', true, 5, 255),
array('jabber')),
'yim' => array('string', true, 5, 255),
'website' => array(
array('string', true, 12, 255),
array('match', true, '#^http[s]?://(.*?\.)*?[a-z0-9\-]+\.[a-z]{2,4}#i')),
'location' => array('string', true, 2, 100),
'occupation' => array('string', true, 2, 500),
'interests' => array('string', true, 2, 500),
'bday_day' => array('num', true, 1, 31),
'bday_month' => array('num', true, 1, 12),
'bday_year' => array('num', true, 1901, gmdate('Y', time())),
'user_birthday' => array('date', true),
));
// validate custom profile fields
$cp->submit_cp_field('profile', $user_row['iso_lang_id'], $cp_data, $cp_error);
if (sizeof($cp_error))
{
$error = array_merge($error, $cp_error);
}
if (!check_form_key($form_name))
{
$error[] = 'FORM_INVALID';
}
if (!sizeof($error))
{
$sql_ary = array(
'user_icq' => $data['icq'],
'user_aim' => $data['aim'],
'user_msnm' => $data['msn'],
'user_yim' => $data['yim'],
'user_jabber' => $data['jabber'],
'user_website' => $data['website'],
'user_from' => $data['location'],
'user_occ' => $data['occupation'],
'user_interests'=> $data['interests'],
'user_birthday' => $data['user_birthday'],
);
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE user_id = $user_id";
$db->sql_query($sql);
// Update Custom Fields
$cp->update_profile_field_data($user_id, $cp_data);
trigger_error($user->lang['USER_PROFILE_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
// Replace "error" strings with their real, localised form
$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
}
$s_birthday_day_options = '<option value="0"' . ((!$data['bday_day']) ? ' selected="selected"' : '') . '>--</option>';
for ($i = 1; $i < 32; $i++)
{
$selected = ($i == $data['bday_day']) ? ' selected="selected"' : '';
$s_birthday_day_options .= "<option value=\"$i\"$selected>$i</option>";
}
$s_birthday_month_options = '<option value="0"' . ((!$data['bday_month']) ? ' selected="selected"' : '') . '>--</option>';
for ($i = 1; $i < 13; $i++)
{
$selected = ($i == $data['bday_month']) ? ' selected="selected"' : '';
$s_birthday_month_options .= "<option value=\"$i\"$selected>$i</option>";
}
$s_birthday_year_options = '';
$now = getdate();
$s_birthday_year_options = '<option value="0"' . ((!$data['bday_year']) ? ' selected="selected"' : '') . '>--</option>';
for ($i = $now['year'] - 100; $i <= $now['year']; $i++)
{
$selected = ($i == $data['bday_year']) ? ' selected="selected"' : '';
$s_birthday_year_options .= "<option value=\"$i\"$selected>$i</option>";
}
unset($now);
$template->assign_vars(array(
'ICQ' => $data['icq'],
'YIM' => $data['yim'],
'AIM' => $data['aim'],
'MSN' => $data['msn'],
'JABBER' => $data['jabber'],
'WEBSITE' => $data['website'],
'LOCATION' => $data['location'],
'OCCUPATION' => $data['occupation'],
'INTERESTS' => $data['interests'],
'S_BIRTHDAY_DAY_OPTIONS' => $s_birthday_day_options,
'S_BIRTHDAY_MONTH_OPTIONS' => $s_birthday_month_options,
'S_BIRTHDAY_YEAR_OPTIONS' => $s_birthday_year_options,
'S_PROFILE' => true)
);
// Get additional profile fields and assign them to the template block var 'profile_fields'
$user->get_profile_fields($user_id);
$cp->generate_profile_fields('profile', $user_row['iso_lang_id']);
break;
case 'prefs':
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
$data = array(
'dateformat' => utf8_normalize_nfc(request_var('dateformat', $user_row['user_dateformat'], true)),
'lang' => basename(request_var('lang', $user_row['user_lang'])),
'tz' => request_var('tz', (float) $user_row['user_timezone']),
'style' => request_var('style', $user_row['user_style']),
'dst' => request_var('dst', $user_row['user_dst']),
'viewemail' => request_var('viewemail', $user_row['user_allow_viewemail']),
'massemail' => request_var('massemail', $user_row['user_allow_massemail']),
'hideonline' => request_var('hideonline', !$user_row['user_allow_viewonline']),
'notifymethod' => request_var('notifymethod', $user_row['user_notify_type']),
'notifypm' => request_var('notifypm', $user_row['user_notify_pm']),
'popuppm' => request_var('popuppm', $this->optionget($user_row, 'popuppm')),
'allowpm' => request_var('allowpm', $user_row['user_allow_pm']),
'topic_sk' => request_var('topic_sk', ($user_row['user_topic_sortby_type']) ? $user_row['user_topic_sortby_type'] : 't'),
'topic_sd' => request_var('topic_sd', ($user_row['user_topic_sortby_dir']) ? $user_row['user_topic_sortby_dir'] : 'd'),
'topic_st' => request_var('topic_st', ($user_row['user_topic_show_days']) ? $user_row['user_topic_show_days'] : 0),
'post_sk' => request_var('post_sk', ($user_row['user_post_sortby_type']) ? $user_row['user_post_sortby_type'] : 't'),
'post_sd' => request_var('post_sd', ($user_row['user_post_sortby_dir']) ? $user_row['user_post_sortby_dir'] : 'a'),
'post_st' => request_var('post_st', ($user_row['user_post_show_days']) ? $user_row['user_post_show_days'] : 0),
'view_images' => request_var('view_images', $this->optionget($user_row, 'viewimg')),
'view_flash' => request_var('view_flash', $this->optionget($user_row, 'viewflash')),
'view_smilies' => request_var('view_smilies', $this->optionget($user_row, 'viewsmilies')),
'view_sigs' => request_var('view_sigs', $this->optionget($user_row, 'viewsigs')),
'view_avatars' => request_var('view_avatars', $this->optionget($user_row, 'viewavatars')),
'view_wordcensor' => request_var('view_wordcensor', $this->optionget($user_row, 'viewcensors')),
'bbcode' => request_var('bbcode', $this->optionget($user_row, 'bbcode')),
'smilies' => request_var('smilies', $this->optionget($user_row, 'smilies')),
'sig' => request_var('sig', $this->optionget($user_row, 'attachsig')),
'notify' => request_var('notify', $user_row['user_notify']),
);
if ($submit)
{
$error = validate_data($data, array(
'dateformat' => array('string', false, 1, 30),
'lang' => array('match', false, '#^[a-z_\-]{2,}$#i'),
'tz' => array('num', false, -14, 14),
'topic_sk' => array('string', false, 1, 1),
'topic_sd' => array('string', false, 1, 1),
'post_sk' => array('string', false, 1, 1),
'post_sd' => array('string', false, 1, 1),
));
if (!check_form_key($form_name))
{
$error[] = 'FORM_INVALID';
}
if (!sizeof($error))
{
$this->optionset($user_row, 'popuppm', $data['popuppm']);
$this->optionset($user_row, 'viewimg', $data['view_images']);
$this->optionset($user_row, 'viewflash', $data['view_flash']);
$this->optionset($user_row, 'viewsmilies', $data['view_smilies']);
$this->optionset($user_row, 'viewsigs', $data['view_sigs']);
$this->optionset($user_row, 'viewavatars', $data['view_avatars']);
$this->optionset($user_row, 'viewcensors', $data['view_wordcensor']);
$this->optionset($user_row, 'bbcode', $data['bbcode']);
$this->optionset($user_row, 'smilies', $data['smilies']);
$this->optionset($user_row, 'attachsig', $data['sig']);
$sql_ary = array(
'user_options' => $user_row['user_options'],
'user_allow_pm' => $data['allowpm'],
'user_allow_viewemail' => $data['viewemail'],
'user_allow_massemail' => $data['massemail'],
'user_allow_viewonline' => !$data['hideonline'],
'user_notify_type' => $data['notifymethod'],
'user_notify_pm' => $data['notifypm'],
'user_dst' => $data['dst'],
'user_dateformat' => $data['dateformat'],
'user_lang' => $data['lang'],
'user_timezone' => $data['tz'],
'user_style' => $data['style'],
'user_topic_sortby_type' => $data['topic_sk'],
'user_post_sortby_type' => $data['post_sk'],
'user_topic_sortby_dir' => $data['topic_sd'],
'user_post_sortby_dir' => $data['post_sd'],
'user_topic_show_days' => $data['topic_st'],
'user_post_show_days' => $data['post_st'],
'user_notify' => $data['notify'],
);
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE user_id = $user_id";
$db->sql_query($sql);
// Check if user has an active session
if ($user_row['session_id'])
{
// We'll update the session if user_allow_viewonline has changed and the user is a bot
// Or if it's a regular user and the admin set it to hide the session
if ($user_row['user_allow_viewonline'] != $sql_ary['user_allow_viewonline'] && $user_row['user_type'] == USER_IGNORE
|| $user_row['user_allow_viewonline'] && !$sql_ary['user_allow_viewonline'])
{
// We also need to check if the user has the permission to cloak.
$user_auth = new auth();
$user_auth->acl($user_row);
$session_sql_ary = array(
'session_viewonline' => ($user_auth->acl_get('u_hideonline')) ? $sql_ary['user_allow_viewonline'] : true,
);
$sql = 'UPDATE ' . SESSIONS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $session_sql_ary) . "
WHERE session_user_id = $user_id";
$db->sql_query($sql);
unset($user_auth);
}
}
trigger_error($user->lang['USER_PREFS_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
// Replace "error" strings with their real, localised form
$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
}
$dateformat_options = '';
foreach ($user->lang['dateformats'] as $format => $null)
{
$dateformat_options .= '<option value="' . $format . '"' . (($format == $data['dateformat']) ? ' selected="selected"' : '') . '>';
$dateformat_options .= $user->format_date(time(), $format, false) . ((strpos($format, '|') !== false) ? $user->lang['VARIANT_DATE_SEPARATOR'] . $user->format_date(time(), $format, true) : '');
$dateformat_options .= '</option>';
}
$s_custom = false;
$dateformat_options .= '<option value="custom"';
if (!isset($user->lang['dateformats'][$data['dateformat']]))
{
$dateformat_options .= ' selected="selected"';
$s_custom = true;
}
$dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . '</option>';
$sort_dir_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']);
// Topic ordering options
$limit_topic_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
$sort_by_topic_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']);
// Post ordering options
$limit_post_days = array(0 => $user->lang['ALL_POSTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
$sort_by_post_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 's' => $user->lang['SUBJECT']);
$_options = array('topic', 'post');
foreach ($_options as $sort_option)
{
${'s_limit_' . $sort_option . '_days'} = '<select name="' . $sort_option . '_st">';
foreach (${'limit_' . $sort_option . '_days'} as $day => $text)
{
$selected = ($data[$sort_option . '_st'] == $day) ? ' selected="selected"' : '';
${'s_limit_' . $sort_option . '_days'} .= '<option value="' . $day . '"' . $selected . '>' . $text . '</option>';
}
${'s_limit_' . $sort_option . '_days'} .= '</select>';
${'s_sort_' . $sort_option . '_key'} = '<select name="' . $sort_option . '_sk">';
foreach (${'sort_by_' . $sort_option . '_text'} as $key => $text)
{
$selected = ($data[$sort_option . '_sk'] == $key) ? ' selected="selected"' : '';
${'s_sort_' . $sort_option . '_key'} .= '<option value="' . $key . '"' . $selected . '>' . $text . '</option>';
}
${'s_sort_' . $sort_option . '_key'} .= '</select>';
${'s_sort_' . $sort_option . '_dir'} = '<select name="' . $sort_option . '_sd">';
foreach ($sort_dir_text as $key => $value)
{
$selected = ($data[$sort_option . '_sd'] == $key) ? ' selected="selected"' : '';
${'s_sort_' . $sort_option . '_dir'} .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
}
${'s_sort_' . $sort_option . '_dir'} .= '</select>';
}
$template->assign_vars(array(
'S_PREFS' => true,
'S_JABBER_DISABLED' => ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true,
'VIEW_EMAIL' => $data['viewemail'],
'MASS_EMAIL' => $data['massemail'],
'ALLOW_PM' => $data['allowpm'],
'HIDE_ONLINE' => $data['hideonline'],
'NOTIFY_EMAIL' => ($data['notifymethod'] == NOTIFY_EMAIL) ? true : false,
'NOTIFY_IM' => ($data['notifymethod'] == NOTIFY_IM) ? true : false,
'NOTIFY_BOTH' => ($data['notifymethod'] == NOTIFY_BOTH) ? true : false,
'NOTIFY_PM' => $data['notifypm'],
'POPUP_PM' => $data['popuppm'],
'DST' => $data['dst'],
'BBCODE' => $data['bbcode'],
'SMILIES' => $data['smilies'],
'ATTACH_SIG' => $data['sig'],
'NOTIFY' => $data['notify'],
'VIEW_IMAGES' => $data['view_images'],
'VIEW_FLASH' => $data['view_flash'],
'VIEW_SMILIES' => $data['view_smilies'],
'VIEW_SIGS' => $data['view_sigs'],
'VIEW_AVATARS' => $data['view_avatars'],
'VIEW_WORDCENSOR' => $data['view_wordcensor'],
'S_TOPIC_SORT_DAYS' => $s_limit_topic_days,
'S_TOPIC_SORT_KEY' => $s_sort_topic_key,
'S_TOPIC_SORT_DIR' => $s_sort_topic_dir,
'S_POST_SORT_DAYS' => $s_limit_post_days,
'S_POST_SORT_KEY' => $s_sort_post_key,
'S_POST_SORT_DIR' => $s_sort_post_dir,
'DATE_FORMAT' => $data['dateformat'],
'S_DATEFORMAT_OPTIONS' => $dateformat_options,
'S_CUSTOM_DATEFORMAT' => $s_custom,
'DEFAULT_DATEFORMAT' => $config['default_dateformat'],
'A_DEFAULT_DATEFORMAT' => addslashes($config['default_dateformat']),
'S_LANG_OPTIONS' => language_select($data['lang']),
'S_STYLE_OPTIONS' => style_select($data['style']),
'S_TZ_OPTIONS' => tz_select($data['tz'], true),
)
);
break;
case 'avatar':
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
$can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
if ($submit)
{
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if (avatar_process_user($error, $user_row, $can_upload))
{
trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_row['user_id']));
}
// Replace "error" strings with their real, localised form
$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
}
if (!$config['allow_avatar'] && $user_row['user_avatar_type'])
{
$error[] = $user->lang['USER_AVATAR_NOT_ALLOWED'];
}
else if ((($user_row['user_avatar_type'] == AVATAR_UPLOAD) && !$config['allow_avatar_upload']) ||
(($user_row['user_avatar_type'] == AVATAR_REMOTE) && !$config['allow_avatar_remote']) ||
(($user_row['user_avatar_type'] == AVATAR_GALLERY) && !$config['allow_avatar_local']))
{
$error[] = $user->lang['USER_AVATAR_TYPE_NOT_ALLOWED'];
}
// Generate users avatar
$avatar_img = ($user_row['user_avatar']) ? get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height'], 'USER_AVATAR', true) : '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />';
$display_gallery = (isset($_POST['display_gallery'])) ? true : false;
$avatar_select = basename(request_var('avatar_select', ''));
$category = basename(request_var('category', ''));
if ($config['allow_avatar_local'] && $display_gallery)
{
avatar_gallery($category, $avatar_select, 4);
}
$template->assign_vars(array(
'S_AVATAR' => true,
'S_CAN_UPLOAD' => $can_upload,
'S_UPLOAD_FILE' => ($config['allow_avatar'] && $can_upload && $config['allow_avatar_upload']) ? true : false,
'S_REMOTE_UPLOAD' => ($config['allow_avatar'] && $can_upload && $config['allow_avatar_remote_upload']) ? true : false,
'S_ALLOW_REMOTE' => ($config['allow_avatar'] && $config['allow_avatar_remote']) ? true : false,
'S_DISPLAY_GALLERY' => ($config['allow_avatar'] && $config['allow_avatar_local'] && !$display_gallery) ? true : false,
'S_IN_GALLERY' => ($config['allow_avatar'] && $config['allow_avatar_local'] && $display_gallery) ? true : false,
'AVATAR_IMAGE' => $avatar_img,
'AVATAR_MAX_FILESIZE' => $config['avatar_filesize'],
'USER_AVATAR_WIDTH' => $user_row['user_avatar_width'],
'USER_AVATAR_HEIGHT' => $user_row['user_avatar_height'],
'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], round($config['avatar_filesize'] / 1024)))
);
break;
case 'rank':
if ($submit)
{
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$rank_id = request_var('user_rank', 0);
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_rank = $rank_id
WHERE user_id = $user_id";
$db->sql_query($sql);
trigger_error($user->lang['USER_RANK_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
$sql = 'SELECT *
FROM ' . RANKS_TABLE . '
WHERE rank_special = 1
ORDER BY rank_title';
$result = $db->sql_query($sql);
$s_rank_options = '<option value="0"' . ((!$user_row['user_rank']) ? ' selected="selected"' : '') . '>' . $user->lang['NO_SPECIAL_RANK'] . '</option>';
while ($row = $db->sql_fetchrow($result))
{
$selected = ($user_row['user_rank'] && $row['rank_id'] == $user_row['user_rank']) ? ' selected="selected"' : '';
$s_rank_options .= '<option value="' . $row['rank_id'] . '"' . $selected . '>' . $row['rank_title'] . '</option>';
}
$db->sql_freeresult($result);
$template->assign_vars(array(
'S_RANK' => true,
'S_RANK_OPTIONS' => $s_rank_options)
);
break;
case 'sig':
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
include_once($phpbb_root_path . 'includes/functions_display.' . $phpEx);
$enable_bbcode = ($config['allow_sig_bbcode']) ? (bool) $this->optionget($user_row, 'sig_bbcode') : false;
$enable_smilies = ($config['allow_sig_smilies']) ? (bool) $this->optionget($user_row, 'sig_smilies') : false;
$enable_urls = ($config['allow_sig_links']) ? (bool) $this->optionget($user_row, 'sig_links') : false;
$signature = utf8_normalize_nfc(request_var('signature', (string) $user_row['user_sig'], true));
$preview = (isset($_POST['preview'])) ? true : false;
if ($submit || $preview)
{
include_once($phpbb_root_path . 'includes/message_parser.' . $phpEx);
$enable_bbcode = ($config['allow_sig_bbcode']) ? ((request_var('disable_bbcode', false)) ? false : true) : false;
$enable_smilies = ($config['allow_sig_smilies']) ? ((request_var('disable_smilies', false)) ? false : true) : false;
$enable_urls = ($config['allow_sig_links']) ? ((request_var('disable_magic_url', false)) ? false : true) : false;
$message_parser = new parse_message($signature);
// Allowing Quote BBCode
$message_parser->parse($enable_bbcode, $enable_urls, $enable_smilies, $config['allow_sig_img'], $config['allow_sig_flash'], true, $config['allow_sig_links'], true, 'sig');
if (sizeof($message_parser->warn_msg))
{
$error[] = implode('<br />', $message_parser->warn_msg);
}
if (!check_form_key($form_name))
{
$error = 'FORM_INVALID';
}
if (!sizeof($error) && $submit)
{
$this->optionset($user_row, 'sig_bbcode', $enable_bbcode);
$this->optionset($user_row, 'sig_smilies', $enable_smilies);
$this->optionset($user_row, 'sig_links', $enable_urls);
$sql_ary = array(
'user_sig' => (string) $message_parser->message,
'user_options' => $user_row['user_options'],
'user_sig_bbcode_uid' => (string) $message_parser->bbcode_uid,
'user_sig_bbcode_bitfield' => (string) $message_parser->bbcode_bitfield
);
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE user_id = ' . $user_id;
$db->sql_query($sql);
trigger_error($user->lang['USER_SIG_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id));
}
// Replace "error" strings with their real, localised form
$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
}
$signature_preview = '';
if ($preview)
{
// Now parse it for displaying
$signature_preview = $message_parser->format_display($enable_bbcode, $enable_urls, $enable_smilies, false);
unset($message_parser);
}
decode_message($signature, $user_row['user_sig_bbcode_uid']);
$template->assign_vars(array(
'S_SIGNATURE' => true,
'SIGNATURE' => $signature,
'SIGNATURE_PREVIEW' => $signature_preview,
'S_BBCODE_CHECKED' => (!$enable_bbcode) ? ' checked="checked"' : '',
'S_SMILIES_CHECKED' => (!$enable_smilies) ? ' checked="checked"' : '',
'S_MAGIC_URL_CHECKED' => (!$enable_urls) ? ' checked="checked"' : '',
'BBCODE_STATUS' => ($config['allow_sig_bbcode']) ? sprintf($user->lang['BBCODE_IS_ON'], '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>') : sprintf($user->lang['BBCODE_IS_OFF'], '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>'),
'SMILIES_STATUS' => ($config['allow_sig_smilies']) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'],
'IMG_STATUS' => ($config['allow_sig_img']) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'],
'FLASH_STATUS' => ($config['allow_sig_flash']) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'],
'URL_STATUS' => ($config['allow_sig_links']) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'],
'L_SIGNATURE_EXPLAIN' => sprintf($user->lang['SIGNATURE_EXPLAIN'], $config['max_sig_chars']),
'S_BBCODE_ALLOWED' => $config['allow_sig_bbcode'],
'S_SMILIES_ALLOWED' => $config['allow_sig_smilies'],
'S_BBCODE_IMG' => ($config['allow_sig_img']) ? true : false,
'S_BBCODE_FLASH' => ($config['allow_sig_flash']) ? true : false,
'S_LINKS_ALLOWED' => ($config['allow_sig_links']) ? true : false)
);
// Assigning custom bbcodes
display_custom_bbcodes();
break;
case 'attach':
$start = request_var('start', 0);
$deletemark = (isset($_POST['delmarked'])) ? true : false;
$marked = request_var('mark', array(0));
// Sort keys
$sort_key = request_var('sk', 'a');
$sort_dir = request_var('sd', 'd');
if ($deletemark && sizeof($marked))
{
$sql = 'SELECT attach_id
FROM ' . ATTACHMENTS_TABLE . '
WHERE poster_id = ' . $user_id . '
AND is_orphan = 0
AND ' . $db->sql_in_set('attach_id', $marked);
$result = $db->sql_query($sql);
$marked = array();
while ($row = $db->sql_fetchrow($result))
{
$marked[] = $row['attach_id'];
}
$db->sql_freeresult($result);
}
if ($deletemark && sizeof($marked))
{
if (confirm_box(true))
{
$sql = 'SELECT real_filename
FROM ' . ATTACHMENTS_TABLE . '
WHERE ' . $db->sql_in_set('attach_id', $marked);
$result = $db->sql_query($sql);
$log_attachments = array();
while ($row = $db->sql_fetchrow($result))
{
$log_attachments[] = $row['real_filename'];
}
$db->sql_freeresult($result);
delete_attachments('attach', $marked);
$message = (sizeof($log_attachments) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED'];
add_log('admin', 'LOG_ATTACHMENTS_DELETED', implode(', ', $log_attachments));
trigger_error($message . adm_back_link($this->u_action . '&u=' . $user_id));
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'delmarked' => true,
'mark' => $marked))
);
}
}
$sk_text = array('a' => $user->lang['SORT_FILENAME'], 'c' => $user->lang['SORT_EXTENSION'], 'd' => $user->lang['SORT_SIZE'], 'e' => $user->lang['SORT_DOWNLOADS'], 'f' => $user->lang['SORT_POST_TIME'], 'g' => $user->lang['SORT_TOPIC_TITLE']);
$sk_sql = array('a' => 'a.real_filename', 'c' => 'a.extension', 'd' => 'a.filesize', 'e' => 'a.download_count', 'f' => 'a.filetime', 'g' => 't.topic_title');
$sd_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']);
$s_sort_key = '';
foreach ($sk_text as $key => $value)
{
$selected = ($sort_key == $key) ? ' selected="selected"' : '';
$s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
}
$s_sort_dir = '';
foreach ($sd_text as $key => $value)
{
$selected = ($sort_dir == $key) ? ' selected="selected"' : '';
$s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
}
if (!isset($sk_sql[$sort_key]))
{
$sort_key = 'a';
}
$order_by = $sk_sql[$sort_key] . ' ' . (($sort_dir == 'a') ? 'ASC' : 'DESC');
$sql = 'SELECT COUNT(attach_id) as num_attachments
FROM ' . ATTACHMENTS_TABLE . "
WHERE poster_id = $user_id
AND is_orphan = 0";
$result = $db->sql_query_limit($sql, 1);
$num_attachments = (int) $db->sql_fetchfield('num_attachments');
$db->sql_freeresult($result);
$sql = 'SELECT a.*, t.topic_title, p.message_subject as message_title
FROM ' . ATTACHMENTS_TABLE . ' a
LEFT JOIN ' . TOPICS_TABLE . ' t ON (a.topic_id = t.topic_id
AND a.in_message = 0)
LEFT JOIN ' . PRIVMSGS_TABLE . ' p ON (a.post_msg_id = p.msg_id
AND a.in_message = 1)
WHERE a.poster_id = ' . $user_id . "
AND a.is_orphan = 0
ORDER BY $order_by";
$result = $db->sql_query_limit($sql, $config['posts_per_page'], $start);
while ($row = $db->sql_fetchrow($result))
{
if ($row['in_message'])
{
$view_topic = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&p={$row['post_msg_id']}");
}
else
{
$view_topic = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t={$row['topic_id']}&p={$row['post_msg_id']}") . '#p' . $row['post_msg_id'];
}
$template->assign_block_vars('attach', array(
'REAL_FILENAME' => $row['real_filename'],
'COMMENT' => nl2br($row['attach_comment']),
'EXTENSION' => $row['extension'],
'SIZE' => get_formatted_filesize($row['filesize']),
'DOWNLOAD_COUNT' => $row['download_count'],
'POST_TIME' => $user->format_date($row['filetime']),
'TOPIC_TITLE' => ($row['in_message']) ? $row['message_title'] : $row['topic_title'],
'ATTACH_ID' => $row['attach_id'],
'POST_ID' => $row['post_msg_id'],
'TOPIC_ID' => $row['topic_id'],
'S_IN_MESSAGE' => $row['in_message'],
'U_DOWNLOAD' => append_sid("{$phpbb_root_path}download/file.$phpEx", 'mode=view&id=' . $row['attach_id']),
'U_VIEW_TOPIC' => $view_topic)
);
}
$db->sql_freeresult($result);
$template->assign_vars(array(
'S_ATTACHMENTS' => true,
'S_ON_PAGE' => on_page($num_attachments, $config['topics_per_page'], $start),
'S_SORT_KEY' => $s_sort_key,
'S_SORT_DIR' => $s_sort_dir,
'PAGINATION' => generate_pagination($this->u_action . "&u=$user_id&sk=$sort_key&sd=$sort_dir", $num_attachments, $config['topics_per_page'], $start, true))
);
break;
case 'groups':
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
$user->add_lang(array('groups', 'acp/groups'));
$group_id = request_var('g', 0);
if ($group_id)
{
// Check the founder only entry for this group to make sure everything is well
$sql = 'SELECT group_founder_manage
FROM ' . GROUPS_TABLE . '
WHERE group_id = ' . $group_id;
$result = $db->sql_query($sql);
$founder_manage = (int) $db->sql_fetchfield('group_founder_manage');
$db->sql_freeresult($result);
if ($user->data['user_type'] != USER_FOUNDER && $founder_manage)
{
trigger_error($user->lang['NOT_ALLOWED_MANAGE_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
}
else
{
$founder_manage = 0;
}
switch ($action)
{
case 'demote':
case 'promote':
case 'default':
if (!$group_id)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
group_user_attributes($action, $group_id, $user_id);
if ($action == 'default')
{
$user_row['group_id'] = $group_id;
}
break;
case 'delete':
if (confirm_box(true))
{
if (!$group_id)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if ($error = group_user_del($group_id, $user_id))
{
trigger_error($user->lang[$error] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$error = array();
// The delete action was successful - therefore update the user row...
$sql = 'SELECT u.*, s.*
FROM ' . USERS_TABLE . ' u
LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id)
WHERE u.user_id = ' . $user_id . '
ORDER BY s.session_time DESC';
$result = $db->sql_query_limit($sql, 1);
$user_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'g' => $group_id))
);
}
break;
case 'approve':
if (confirm_box(true))
{
if (!$group_id)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
group_user_attributes($action, $group_id, $user_id);
}
else
{
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'g' => $group_id))
);
}
break;
}
// Add user to group?
if ($submit)
{
if (!check_form_key($form_name))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
if (!$group_id)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
// Add user/s to group
if ($error = group_user_add($group_id, $user_id))
{
trigger_error($user->lang[$error] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
$error = array();
}
$sql = 'SELECT ug.*, g.*
FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . " ug
WHERE ug.user_id = $user_id
AND g.group_id = ug.group_id
ORDER BY g.group_type DESC, ug.user_pending ASC, g.group_name";
$result = $db->sql_query($sql);
$i = 0;
$group_data = $id_ary = array();
while ($row = $db->sql_fetchrow($result))
{
$type = ($row['group_type'] == GROUP_SPECIAL) ? 'special' : (($row['user_pending']) ? 'pending' : 'normal');
$group_data[$type][$i]['group_id'] = $row['group_id'];
$group_data[$type][$i]['group_name'] = $row['group_name'];
$group_data[$type][$i]['group_leader'] = ($row['group_leader']) ? 1 : 0;
$id_ary[] = $row['group_id'];
$i++;
}
$db->sql_freeresult($result);
// Select box for other groups
$sql = 'SELECT group_id, group_name, group_type, group_founder_manage
FROM ' . GROUPS_TABLE . '
' . ((sizeof($id_ary)) ? 'WHERE ' . $db->sql_in_set('group_id', $id_ary, true) : '') . '
ORDER BY group_type DESC, group_name ASC';
$result = $db->sql_query($sql);
$s_group_options = '';
while ($row = $db->sql_fetchrow($result))
{
if (!$config['coppa_enable'] && $row['group_name'] == 'REGISTERED_COPPA')
{
continue;
}
// Do not display those groups not allowed to be managed
if ($user->data['user_type'] != USER_FOUNDER && $row['group_founder_manage'])
{
continue;
}
$s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
}
$db->sql_freeresult($result);
$current_type = '';
foreach ($group_data as $group_type => $data_ary)
{
if ($current_type != $group_type)
{
$template->assign_block_vars('group', array(
'S_NEW_GROUP_TYPE' => true,
'GROUP_TYPE' => $user->lang['USER_GROUP_' . strtoupper($group_type)])
);
}
foreach ($data_ary as $data)
{
$template->assign_block_vars('group', array(
'U_EDIT_GROUP' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=groups&mode=manage&action=edit&u=$user_id&g={$data['group_id']}&back_link=acp_users_groups"),
'U_DEFAULT' => $this->u_action . "&action=default&u=$user_id&g=" . $data['group_id'],
'U_DEMOTE_PROMOTE' => $this->u_action . '&action=' . (($data['group_leader']) ? 'demote' : 'promote') . "&u=$user_id&g=" . $data['group_id'],
'U_DELETE' => $this->u_action . "&action=delete&u=$user_id&g=" . $data['group_id'],
'U_APPROVE' => ($group_type == 'pending') ? $this->u_action . "&action=approve&u=$user_id&g=" . $data['group_id'] : '',
'GROUP_NAME' => ($group_type == 'special') ? $user->lang['G_' . $data['group_name']] : $data['group_name'],
'L_DEMOTE_PROMOTE' => ($data['group_leader']) ? $user->lang['GROUP_DEMOTE'] : $user->lang['GROUP_PROMOTE'],
'S_IS_MEMBER' => ($group_type != 'pending') ? true : false,
'S_NO_DEFAULT' => ($user_row['group_id'] != $data['group_id']) ? true : false,
'S_SPECIAL_GROUP' => ($group_type == 'special') ? true : false,
)
);
}
}
$template->assign_vars(array(
'S_GROUPS' => true,
'S_GROUP_OPTIONS' => $s_group_options)
);
break;
case 'perm':
include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
$auth_admin = new auth_admin();
$user->add_lang('acp/permissions');
add_permission_language();
$forum_id = request_var('f', 0);
// Global Permissions
if (!$forum_id)
{
// Select auth options
$sql = 'SELECT auth_option, is_local, is_global
FROM ' . ACL_OPTIONS_TABLE . '
WHERE auth_option ' . $db->sql_like_expression($db->any_char . '_') . '
AND is_global = 1
ORDER BY auth_option';
$result = $db->sql_query($sql);
$hold_ary = array();
while ($row = $db->sql_fetchrow($result))
{
$hold_ary = $auth_admin->get_mask('view', $user_id, false, false, $row['auth_option'], 'global', ACL_NEVER);
$auth_admin->display_mask('view', $row['auth_option'], $hold_ary, 'user', false, false);
}
$db->sql_freeresult($result);
unset($hold_ary);
}
else
{
$sql = 'SELECT auth_option, is_local, is_global
FROM ' . ACL_OPTIONS_TABLE . "
WHERE auth_option " . $db->sql_like_expression($db->any_char . '_') . "
AND is_local = 1
ORDER BY is_global DESC, auth_option";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$hold_ary = $auth_admin->get_mask('view', $user_id, false, $forum_id, $row['auth_option'], 'local', ACL_NEVER);
$auth_admin->display_mask('view', $row['auth_option'], $hold_ary, 'user', true, false);
}
$db->sql_freeresult($result);
}
$s_forum_options = '<option value="0"' . ((!$forum_id) ? ' selected="selected"' : '') . '>' . $user->lang['VIEW_GLOBAL_PERMS'] . '</option>';
$s_forum_options .= make_forum_select($forum_id, false, true, false, false, false);
$template->assign_vars(array(
'S_PERMISSIONS' => true,
'S_GLOBAL' => (!$forum_id) ? true : false,
'S_FORUM_OPTIONS' => $s_forum_options,
'U_ACTION' => $this->u_action . '&u=' . $user_id,
'U_USER_PERMISSIONS' => append_sid("{$phpbb_admin_path}index.$phpEx" ,'i=permissions&mode=setting_user_global&user_id[]=' . $user_id),
'U_USER_FORUM_PERMISSIONS' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions&mode=setting_user_local&user_id[]=' . $user_id))
);
break;
}
// Assign general variables
$template->assign_vars(array(
'S_ERROR' => (sizeof($error)) ? true : false,
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '')
);
}
/**
* Set option bit field for user options in a user row array.
*
* Optionset replacement for this module based on $user->optionset.
*
* @param array $user_row Row from the users table.
* @param int $key Option key, as defined in $user->keyoptions property.
* @param bool $value True to set the option, false to clear the option.
* @param int $data Current bit field value, or false to use $user_row['user_options']
* @return int|bool If $data is false, the bit field is modified and
* written back to $user_row['user_options'], and
* return value is true if the bit field changed and
* false otherwise. If $data is not false, the new
* bitfield value is returned.
*/
function optionset(&$user_row, $key, $value, $data = false)
{
global $user;
$var = ($data !== false) ? $data : $user_row['user_options'];
$new_var = phpbb_optionset($user->keyoptions[$key], $value, $var);
if ($data === false)
{
if ($new_var != $var)
{
$user_row['user_options'] = $new_var;
return true;
}
else
{
return false;
}
}
else
{
return $new_var;
}
}
/**
* Get option bit field from user options in a user row array.
*
* Optionget replacement for this module based on $user->optionget.
*
* @param array $user_row Row from the users table.
* @param int $key option key, as defined in $user->keyoptions property.
* @param int $data bit field value to use, or false to use $user_row['user_options']
* @return bool true if the option is set in the bit field, false otherwise
*/
function optionget(&$user_row, $key, $data = false)
{
global $user;
$var = ($data !== false) ? $data : $user_row['user_options'];
return phpbb_optionget($user->keyoptions[$key], $var);
}
}
?>