ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:27.17 GB of 70.42 GB (38.59%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ http/ smf/ Sources/ - drwxrwxrwx

Directory:
Viewing file:     Profile.php (115.24 KB)      -r--r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**********************************************************************************
* Profile.php                                                                     *
***********************************************************************************
* SMF: Simple Machines Forum                                                      *
* Open-Source Project Inspired by Zef Hemel (zef@zefhemel.com)                    *
* =============================================================================== *
* Software Version:           SMF 1.1.11                                          *
* Software by:                Simple Machines (http://www.simplemachines.org)     *
* Copyright 2006-2009 by:     Simple Machines LLC (http://www.simplemachines.org) *
*           2001-2006 by:     Lewis Media (http://www.lewismedia.com)             *
* Support, News, Updates at:  http://www.simplemachines.org                       *
***********************************************************************************
* This program is free software; you may redistribute it and/or modify it under   *
* the terms of the provided license as published by Simple Machines LLC.          *
*                                                                                 *
* This program is distributed in the hope that it is and will be useful, but      *
* WITHOUT ANY WARRANTIES; without even any implied warranty of MERCHANTABILITY    *
* or FITNESS FOR A PARTICULAR PURPOSE.                                            *
*                                                                                 *
* See the "license.txt" file for details of the Simple Machines license.          *
* The latest version can always be found at http://www.simplemachines.org.        *
**********************************************************************************/
if (!defined('SMF'))
    die(
'Hacking attempt...');

/*    This file has the primary job of showing and editing people's profiles.
    It also allows the user to change some of their or another's preferences,
    and such things.  It uses the following functions:

    void ModifyProfile(array errors = none)
        // !!!

    void ModifyProfile2()
        // !!!

    void saveProfileChanges(array &profile_variables, array &errors, int ID_MEMBER)
        // !!!

    void makeThemeChanges(int ID_MEMBER, int ID_THEME)
        // !!!

    void makeNotificationChanges(int ID_MEMBER)
        // !!!

    void makeAvatarChanges(int ID_MEMBER, array &errors)
        // !!!

    void summary(int ID_MEMBER)
        // !!!

    void showPosts(int ID_MEMBER)
        // !!!

    void statPanel(int ID_MEMBER)
        // !!!

    void trackUser(int ID_MEMBER)
        // !!!

    void TrackIP(int ID_MEMBER = none)
        // !!!

    void showPermissions(int ID_MEMBER)
        // !!!

    void account(int ID_MEMBER)
        // !!!

    void forumProfile(int ID_MEMBER)
        // !!!

    array getAvatars(string directory, int level)
        // !!!

    void theme(int ID_MEMBER)
        // !!!

    void notification(int ID_MEMBER)
        // !!!

    void pmprefs(int ID_MEMBER)
        // !!!

    void deleteAccount(int ID_MEMBER)
        // !!!

    void deleteAccount2(array profile_variables, array &errors, int ID_MEMBER)
        // !!!

    void rememberPostData()
        // !!!

    void loadThemeOptions(int ID_MEMBER)
        // !!!

    Adding new fields to the profile:
    ---------------------------------------------------------------------------
        // !!!
*/

// Allow the change or view of profiles...
function ModifyProfile($post_errors = array())
{
    global 
$txt$scripturl$user_info$context$ID_MEMBER$sourcedir$user_profile$modSettings;

    
loadLanguage('Profile');
    
loadTemplate('Profile');

    
/* Set allowed sub-actions.

     The format of $sa_allowed is as follows:

    $sa_allowed = array(
        'sub-action' => array(permission_array_for_editing_OWN_profile, permission_array_for_editing_ANY_profile[, require_validation]),
        ...
    );

    */

    
$sa_allowed = array(
        
'summary' => array(array('profile_view_any''profile_view_own'), array('profile_view_any')),
        
'statPanel' => array(array('profile_view_any''profile_view_own'), array('profile_view_any')),
        
'showPosts' => array(array('profile_view_any''profile_view_own'), array('profile_view_any')),
        
'editBuddies' => array(array('profile_extra_any''profile_extra_own'), array()),
        
'trackUser' => array(array('moderate_forum'), array('moderate_forum')),
        
'trackIP' => array(array('moderate_forum'), array('moderate_forum')),
        
'showPermissions' => array(array('manage_permissions'), array('manage_permissions')),
        
'account' => array(array('manage_membergroups''profile_identity_any''profile_identity_own'), array('manage_membergroups''profile_identity_any')),
        
'forumProfile' => array(array('profile_extra_any''profile_extra_own'), array('profile_extra_any')),
        
'theme' => array(array('profile_extra_any''profile_extra_own'), array('profile_extra_any')),
        
'notification' => array(array('profile_extra_any''profile_extra_own'), array('profile_extra_any')),
        
'pmprefs' => array(array('profile_extra_any''profile_extra_own'), array('profile_extra_any')),
        
'deleteAccount' => array(array('profile_remove_any''profile_remove_own'), array('profile_remove_any')),
    );

    
// Set the profile layer to be displayed.
    
$context['template_layers'][] = 'profile';

    
// Did we get the user by name...
    
if (isset($_REQUEST['user']))
        
$memberResult loadMemberData($_REQUEST['user'], true'profile');
    
// ... or by ID_MEMBER?
    
elseif (!empty($_REQUEST['u']))
        
$memberResult loadMemberData((int) $_REQUEST['u'], false'profile');
    
// If it was just ?action=profile, edit your own profile.
    
else
        
$memberResult loadMemberData($ID_MEMBERfalse'profile');

    
// Check if loadMemberData() has returned a valid result.
    
if (!is_array($memberResult))
        
fatal_lang_error(453false);

    
// If all went well, we have a valid member ID!
    
list ($memID) = $memberResult;

    
// Is this the profile of the user himself or herself?
    
$context['user']['is_owner'] = $memID == $ID_MEMBER;

    
// No Subaction?
    
if (!isset($_REQUEST['sa']) || !isset($sa_allowed[$_REQUEST['sa']]))
    {
        
// Pick the first subaction you're allowed to see.
        
if ((allowedTo('profile_view_own') && $context['user']['is_owner']) || allowedTo('profile_view_any'))
            
$_REQUEST['sa'] = 'summary';
        elseif (
allowedTo('moderate_forum'))
            
$_REQUEST['sa'] = 'trackUser';
        elseif (
allowedTo('manage_permissions'))
            
$_REQUEST['sa'] = 'showPermissions';
        elseif ((
allowedTo('profile_identity_own') && $context['user']['is_owner']) || allowedTo('profile_identity_any') || allowedTo('manage_membergroups'))
            
$_REQUEST['sa'] = 'account';
        elseif ((
allowedTo('profile_extra_own') && $context['user']['is_owner']) || allowedTo('profile_extra_any'))
            
$_REQUEST['sa'] = 'forumProfile';
        elseif ((
allowedTo('profile_remove_own') && $context['user']['is_owner']) || allowedTo('profile_remove_any'))
            
$_REQUEST['sa'] = 'deleteAccount';
        else
            
isAllowedTo('profile_view_' . ($context['user']['is_owner'] ? 'own' 'any'));
    }

    
// Check the permissions for the given sub action.
    
isAllowedTo($sa_allowed[$_REQUEST['sa']][$context['user']['is_owner'] ? 1]);

    
// Make sure the user is who he claims to be, before any important account stuff is changed.
    
if (!empty($sa_allowed[$_REQUEST['sa']][2]))
        
validateSession();

    
// No need for this anymore.
    
unset($sa_allowed);

    
$context['profile_areas'] = array();

    
// Set the menu items in the left bar...
    
if (!$user_info['is_guest'] && (($context['user']['is_owner'] && allowedTo('profile_view_own')) || allowedTo(array('profile_view_any''moderate_forum''manage_permissions'))))
    {
        
$context['profile_areas']['info'] = array(
            
'title' => $txt['profileInfo'],
            
'areas' => array()
        );

        if ((
$context['user']['is_owner'] && allowedTo('profile_view_own')) || allowedTo('profile_view_any'))
        {
            
$context['profile_areas']['info']['areas']['summary'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=summary">' $txt['summary'] . '</a>';
            
$context['profile_areas']['info']['areas']['statPanel']    = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=statPanel">' $txt['statPanel'] . '</a>';
            
$context['profile_areas']['info']['areas']['showPosts']    = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=showPosts">' $txt['showPosts'] . '</a>';
        }

        
// Groups with moderator permissions can also....
        
if (allowedTo('moderate_forum'))
        {
            
$context['profile_areas']['info']['areas']['trackUser'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=trackUser">' $txt['trackUser'] . '</a>';
            
$context['profile_areas']['info']['areas']['trackIP'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=trackIP">' $txt['trackIP'] . '</a>';
        }
        if (
allowedTo('manage_permissions'))
            
$context['profile_areas']['info']['areas']['showPermissions'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=showPermissions">' $txt['showPermissions'] . '</a>';
    }

    
// Edit your/this person's profile?
    
if (($context['user']['is_owner'] && (allowedTo(array('profile_identity_own''profile_extra_own')))) || allowedTo(array('profile_identity_any''profile_extra_any''manage_membergroups')))
    {
        
$context['profile_areas']['edit_profile'] = array(
            
'title' => $txt['profileEdit'],
            
'areas' => array()
        );

        if ((
$context['user']['is_owner'] && allowedTo('profile_identity_own')) || allowedTo(array('profile_identity_any''manage_membergroups')))
            
$context['profile_areas']['edit_profile']['areas']['account'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=account">' $txt['account'] . '</a>';

        if ((
$context['user']['is_owner'] && allowedTo('profile_extra_own')) || allowedTo('profile_extra_any'))
        {
            
$context['profile_areas']['edit_profile']['areas']['forumProfile'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=forumProfile">' $txt['forumProfile'] . '</a>';
            
$context['profile_areas']['edit_profile']['areas']['theme'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=theme">' $txt['theme'] . '</a>';
            
$context['profile_areas']['edit_profile']['areas']['notification'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=notification">' $txt['notification'] . '</a>';
            
$context['profile_areas']['edit_profile']['areas']['pmprefs'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=pmprefs">' $txt['pmprefs'] . '</a>';
        }

        
// !!! I still don't think this warrants a new section by any means, but it's definitely not part of viewing a person's profile, if only the owner can do it.
        
if (!empty($modSettings['enable_buddylist']) && $context['user']['is_owner'] && allowedTo(array('profile_extra_own''profile_extra_any')))
            
$context['profile_areas']['edit_profile']['areas']['editBuddies'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=editBuddies">' $txt['editBuddies'] . '</a>';
    }

    
// If you have permission to do something with this profile, you'll see one or more actions.
    
if (($context['user']['is_owner'] && allowedTo('profile_remove_own')) || allowedTo('profile_remove_any') || (!$context['user']['is_owner'] && allowedTo('pm_send')))
    {
        
// Initialize the action menu group...
        
$context['profile_areas']['profile_action'] = array(
            
'title' => $txt['profileAction'],
            
'areas' => array()
        );

        
// You shouldn't PM (or ban really..) yourself!! (only administrators see this because it's not in the menu.)
        
if (!$context['user']['is_owner'] && allowedTo('pm_send'))
            
$context['profile_areas']['profile_action']['areas']['send_pm'] = '<a href="' $scripturl '?action=pm;sa=send;u=' $memID '">' $txt['profileSendIm'] . '</a>';
        
// We don't wanna ban admins, do we?
        
if (allowedTo('manage_bans') && $user_profile[$memID]['ID_GROUP'] != && !in_array(1explode(','$user_profile[$memID]['additionalGroups'])))
            
$context['profile_areas']['profile_action']['areas']['banUser'] = '<a href="' $scripturl '?action=ban;sa=add;u=' $memID '">' $txt['profileBanUser'] . '</a>';

        
// You may remove your own account 'cuz it's yours or you're an admin.
        
if (($context['user']['is_owner'] && allowedTo('profile_remove_own')) || allowedTo('profile_remove_any'))
            
$context['profile_areas']['profile_action']['areas']['deleteAccount'] = '<a href="' $scripturl '?action=profile;u=' $memID ';sa=deleteAccount">' $txt['deleteAccount'] . '</a>';
    }

    
// This is here so the menu won't be shown unless it's actually needed.
    
if (!isset($context['profile_areas']['info']['areas']['trackUser']) && !isset($context['profile_areas']['info']['areas']['showPermissions']) && !isset($context['profile_areas']['edit_profile']) && !isset($context['profile_areas']['profile_action']['areas']['banUser']) && !isset($context['profile_areas']['profile_action']['areas']['deleteAccount']))
        
$context['profile_areas'] = array();

    
// Set the selected items.
    
$context['menu_item_selected'] = $_REQUEST['sa'];
    
$context['sub_template'] = $_REQUEST['sa'];

    
// All the subactions that require a user password in order to validate.
    
$context['require_password'] = in_array($context['menu_item_selected'], array('account'));

    
$context['member'] = array(
        
'id' => $memID,
        
'username' => $user_profile[$memID]['memberName'],
        
'name' => !isset($user_profile[$memID]['realName']) || $user_profile[$memID]['realName'] == '' '' $user_profile[$memID]['realName'],
        
'email' => $user_profile[$memID]['emailAddress'],
        
'posts' => empty($user_profile[$memID]['posts']) ? 0: (int) $user_profile[$memID]['posts'],
        
'hide_email' => empty($user_profile[$memID]['hideEmail']) ? $user_profile[$memID]['hideEmail'],
        
'show_online' => empty($user_profile[$memID]['showOnline']) ? $user_profile[$memID]['showOnline'],
        
'registered' => empty($user_profile[$memID]['dateRegistered']) ? $txt[470] : strftime('%Y-%m-%d'$user_profile[$memID]['dateRegistered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600),
        
'group' => $user_profile[$memID]['ID_GROUP'],
        
'gender' => array('name' => empty($user_profile[$memID]['gender']) ? '' : ($user_profile[$memID]['gender'] == 'f' 'm')),
        
'karma' => array(
            
'good' => empty($user_profile[$memID]['karmaGood']) ? '0' $user_profile[$memID]['karmaGood'],
            
'bad' => empty($user_profile[$memID]['karmaBad']) ? '0' $user_profile[$memID]['karmaBad'],
        ),
        
'avatar' => array(
            
'name' => &$user_profile[$memID]['avatar'],
            
'href' => empty($user_profile[$memID]['ID_ATTACH']) ? '' : (empty($user_profile[$memID]['attachmentType']) ? $scripturl '?action=dlattach;attach=' $user_profile[$memID]['ID_ATTACH'] . ';type=avatar' $modSettings['custom_avatar_url'] . '/' $user_profile[$memID]['filename']),
            
'custom' => stristr($user_profile[$memID]['avatar'], 'http://') ? $user_profile[$memID]['avatar'] : 'http://',
            
'selection' => $user_profile[$memID]['avatar'] == '' || stristr($user_profile[$memID]['avatar'], 'http://') ? '' $user_profile[$memID]['avatar'],
            
'ID_ATTACH' => &$user_profile[$memID]['ID_ATTACH'],
            
'filename' => &$user_profile[$memID]['filename'],
            
'allow_server_stored' => allowedTo('profile_server_avatar') || !$context['user']['is_owner'],
            
'allow_upload' => allowedTo('profile_upload_avatar') || !$context['user']['is_owner'],
            
'allow_external' => allowedTo('profile_remote_avatar') || !$context['user']['is_owner'],
        ),
        
'icq' => array('name' => !isset($user_profile[$memID]['ICQ']) ? '' $user_profile[$memID]['ICQ']),
        
'aim' => array('name' => empty($user_profile[$memID]['AIM']) ? '' str_replace('+'' '$user_profile[$memID]['AIM'])),
        
'yim' => array('name' => empty($user_profile[$memID]['YIM']) ? '' $user_profile[$memID]['YIM']),
        
'msn' => array('name' => empty($user_profile[$memID]['MSN']) ? '' $user_profile[$memID]['MSN']),
        
'website' => array(
            
'title' => !isset($user_profile[$memID]['websiteTitle']) ? '' $user_profile[$memID]['websiteTitle'],
            
'url' => !isset($user_profile[$memID]['websiteUrl']) ? '' $user_profile[$memID]['websiteUrl'],
        ),
    );

    
// Call the appropriate subaction function.
    
$_REQUEST['sa']($memID);

    if (!empty(
$post_errors))
    {
        
// Set all the errors so the template knows what went wrong.
        
foreach ($post_errors as $error_type)
            
$context['modify_error'][$error_type] = true;
        
rememberPostData();
    }

    
// Set the page title if it's not already set...
    
if (!isset($context['page_title']))
        
$context['page_title'] = $txt[79] . ' - ' $txt[$_REQUEST['sa']];
}

// Execute the modifications!
function ModifyProfile2()
{
    global 
$txt$modSettings;
    global 
$cookiename$context;
    global 
$sourcedir$scripturl$db_prefix;
    global 
$ID_MEMBER$user_info;
    global 
$context$newpassemail$user_profile$validationCode;

    
loadLanguage('Profile');

    
/* Set allowed sub-actions.

     The format of $sa_allowed is as follows:

    $sa_allowed = array(
        'sub-action' => array(permission_array_for_editing_OWN_profile, permission_array_for_editing_ANY_profile, session_validation_method[, require_password]),
        ...
    );

    */

    
$sa_allowed = array(
        
'account' => array(array('manage_membergroups''profile_identity_any''profile_identity_own'), array('manage_membergroups''profile_identity_any'), 'post'true),
        
'forumProfile' => array(array('profile_extra_any''profile_extra_own'), array('profile_extra_any'), 'post'),
        
'theme' => array(array('profile_extra_any''profile_extra_own'), array('profile_extra_any'), 'post'),
        
'notification' => array(array('profile_extra_any''profile_extra_own'), array('profile_extra_any'), 'post'),
        
'pmprefs' => array(array('profile_extra_any''profile_extra_own'), array('profile_extra_any'), 'post'),
        
'deleteAccount' => array(array('profile_remove_any''profile_remove_own'), array('profile_remove_any'), 'post'true),
        
'activateAccount' => array(array(), array('moderate_forum'), 'get'),
    );

    
// Is the current sub-action allowed?
    
if (empty($_REQUEST['sa']) || !isset($sa_allowed[$_REQUEST['sa']]))
        
fatal_lang_error(453false);

    
checkSession($sa_allowed[$_REQUEST['sa']][2]);

    
// Start with no updates and no errors.
    
$profile_vars = array();
    
$post_errors = array();

    
// Normally, don't send an email.
    
$newpassemail false;

    
// Clean up the POST variables.
    
$_POST htmltrim__recursive($_POST);
    
$_POST stripslashes__recursive($_POST);
    
$_POST htmlspecialchars__recursive($_POST);
    
$_POST addslashes__recursive($_POST);

    
// Search for the member being edited and put the information in $user_profile.
    
$memberResult loadMemberData((int) $_REQUEST['userID'], false'profile');

    if (!
is_array($memberResult))
        
fatal_lang_error(453false);

    list (
$memID) = $memberResult;

    
// Are you modifying your own, or someone else's?
    
if ($ID_MEMBER == $memID)
        
$context['user']['is_owner'] = true;
    else
    {
        
$context['user']['is_owner'] = false;
        
validateSession();
    }

    
// Check profile editing permissions.
    
isAllowedTo($sa_allowed[$_REQUEST['sa']][$context['user']['is_owner'] ? 1]);

    
// If this is yours, check the password.
    
if ($context['user']['is_owner'] && !empty($sa_allowed[$_REQUEST['sa']][3]))
    {
        
// You didn't even enter a password!
        
if (trim($_POST['oldpasswrd']) == '')
            
$post_errors[] = 'no_password';

        
// Since the password got modified due to all the $_POST cleaning, lets undo it so we can get the correct password
        
$_POST['oldpasswrd'] = addslashes(un_htmlspecialchars(stripslashes($_POST['oldpasswrd'])));

        
// Does the integration want to check passwords?
        
$good_password false;
        if (isset(
$modSettings['integrate_verify_password']) && function_exists($modSettings['integrate_verify_password']))
            if (
call_user_func($modSettings['integrate_verify_password'], $user_profile[$memID]['memberName'], $_POST['oldpasswrd'], false) === true)
                
$good_password true;

        
// Bad password!!!
        
if (!$good_password && $user_info['passwd'] != sha1(strtolower($user_profile[$memID]['memberName']) . $_POST['oldpasswrd']))
            
$post_errors[] = 'bad_password';
    }

    
// No need for the sub action array.
    
unset($sa_allowed);

    
// If the user is an admin - see if they are resetting someones username.
    
if ($user_info['is_admin'] && isset($_POST['memberName']))
    {
        
// We'll need this...
        
require_once($sourcedir '/Subs-Auth.php');

        
// Do the reset... this will send them an email too.
        
resetPassword($memID$_POST['memberName']);
    }

    
// Change the IP address in the database.
    
if ($context['user']['is_owner'])
        
$profile_vars['memberIP'] = "'$user_info[ip]'";

    
// Now call the sub-action function...
    
if (isset($_POST['sa']) && $_POST['sa'] == 'deleteAccount')
    {
        
deleteAccount2($profile_vars$post_errors$memID);

        if (empty(
$post_errors))
            
redirectexit();
    }
    else
        
saveProfileChanges($profile_vars$post_errors$memID);

    
// There was a problem, let them try to re-enter.
    
if (!empty($post_errors))
    {
        
// Load the language file so we can give a nice explanation of the errors.
        
loadLanguage('Errors');
        
$context['post_errors'] = $post_errors;

        
$_REQUEST['sa'] = $_POST['sa'];
        
$_REQUEST['u'] = $memID;
        return 
ModifyProfile($post_errors);
    }

    if (!empty(
$profile_vars))
    {
        
// If we've changed the password, notify any integration that may be listening in.
        
if (isset($profile_vars['passwd']) && isset($modSettings['integrate_reset_pass']) && function_exists($modSettings['integrate_reset_pass']))
            
call_user_func($modSettings['integrate_reset_pass'], $user_profile[$memID]['memberName'], $user_profile[$memID]['memberName'], $_POST['passwrd1']);

        
updateMemberData($memID$profile_vars);
    }

    
// What if this is the newest member?
    
if ($modSettings['latestMember'] == $memID)
        
updateStats('member');
    elseif (isset(
$profile_vars['realName']))
        
updateSettings(array('memberlist_updated' => time()));

    
// If the member changed his/her birthdate, update calendar statistics.
    
if (isset($profile_vars['birthdate']) || isset($profile_vars['realName']))
        
updateStats('calendar');

    
// Send an email?
    
if ($newpassemail)
    {
        require_once(
$sourcedir '/Subs-Post.php');

        
// Send off the email.
        
sendmail($_POST['emailAddress'], $txt['activate_reactivate_title'] . ' ' $context['forum_name'],
            
"$txt[activate_reactivate_mail]\n\n" .
            
"$scripturl?action=activate;u=$memID;code=$validationCode\n\n" .
            
"$txt[activate_code]$validationCode\n\n" .
            
$txt[130]);

        
// Log the user out.
        
db_query("
            DELETE FROM 
{$db_prefix}log_online
            WHERE ID_MEMBER = 
$memID"__FILE____LINE__);
        
$_SESSION['log_time'] = 0;
        
$_SESSION['login_' $cookiename] = serialize(array(0''0));

        if (isset(
$_COOKIE[$cookiename]))
            
$_COOKIE[$cookiename] = '';

        
loadUserSettings();

        
$context['user']['is_logged'] = false;
        
$context['user']['is_guest'] = true;

        
// Send them to the done-with-registration-login screen.
        
loadTemplate('Register');
        
$context += array(
            
'page_title' => &$txt[79],
            
'sub_template' => 'after',
            
'description' => &$txt['activate_changed_email']
        );
        return;
    }
    elseif (
$context['user']['is_owner'])
    {
        
// Log them back in.
        
if (isset($_POST['passwrd1']) && $_POST['passwrd1'] != '')
        {
            require_once(
$sourcedir '/Subs-Auth.php');
            
setLoginCookie(60 $modSettings['cookieTime'], $memIDsha1(sha1(strtolower($user_profile[$memID]['memberName']) . un_htmlspecialchars(stripslashes($_POST['passwrd1']))) . $user_profile[$memID]['passwordSalt']));
        }

        
loadUserSettings();
        
writeLog();
    }

    
// Back to same subaction page..
    
redirectexit('action=profile;u=' $memID ';sa=' $_REQUEST['sa'], (isset($_POST['passwrd1']) && $context['server']['needs_login_fix']) || ($context['browser']['is_ie'] && isset($_FILES['attachment'])));
}

// Save the profile changes....
function saveProfileChanges(&$profile_vars, &$post_errors$memID)
{
    global 
$db_prefix$user_info$txt$modSettings$user_profile;
    global 
$newpassemail$validationCode$context$settings$sourcedir;
    global 
$func;

    
// These make life easier....
    
$old_profile = &$user_profile[$memID];

    
// Permissions...
    
if ($context['user']['is_owner'])
    {
        
$changeIdentity allowedTo(array('profile_identity_any''profile_identity_own'));
        
$changeOther allowedTo(array('profile_extra_any''profile_extra_own'));
    }
    else
    {
        
$changeIdentity allowedTo('profile_identity_any');
        
$changeOther allowedTo('profile_extra_any');
    }

    
// Arrays of all the changes - makes things easier.
    
$profile_bools = array(
        
'notifyAnnouncements''notifyOnce''notifySendBody',
    );
    
$profile_ints = array(
        
'pm_email_notify',
        
'notifyTypes',
        
'ICQ',
        
'gender',
        
'ID_THEME',
    );
    
$profile_floats = array(
        
'timeOffset',
    );
    
$profile_strings = array(
        
'websiteUrl''websiteTitle',
        
'AIM''YIM',
        
'location''birthdate',
        
'timeFormat',
        
'buddy_list',
        
'pm_ignore_list',
        
'smileySet',
        
'signature''personalText''avatar',
    );

    
// Fix the spaces in messenger screennames...
    
$fix_spaces = array('MSN''AIM''YIM');
    foreach (
$fix_spaces as $var)
    {
        
// !!! Why?
        
if (isset($_POST[$var]))
            
$_POST[$var] = strtr($_POST[$var], ' ''+');
    }

    
// Make sure the MSN one is an email address, not something like 'none' :P.
    
if (isset($_POST['MSN']) && ($_POST['MSN'] == '' || preg_match('~^[0-9A-Za-z=_+\-/][0-9A-Za-z=_\'+\-/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$~'$_POST['MSN']) != 0))
        
$profile_strings[] = 'MSN';

    
// Validate the title...
    
if (!empty($modSettings['titlesEnable']) && (allowedTo('profile_title_any') || (allowedTo('profile_title_own') && $context['user']['is_owner'])))
        
$profile_strings[] = 'usertitle';

    
// Validate the timeOffset...
    
if (isset($_POST['timeOffset']))
    {
        
$_POST['timeOffset'] = strtr($_POST['timeOffset'], ',''.');

        if (
$_POST['timeOffset'] < -23.5 || $_POST['timeOffset'] > 23.5)
            
$post_errors[] = 'bad_offset';
    }

    
// Fix the URL...
    
if (isset($_POST['websiteUrl']))
    {
        if (
strlen(trim($_POST['websiteUrl'])) > && strpos($_POST['websiteUrl'], '://') === false)
            
$_POST['websiteUrl'] = 'http://' $_POST['websiteUrl'];
        if (
strlen($_POST['websiteUrl']) < || (substr($_POST['websiteUrl'], 07) !== 'http://' && substr($_POST['websiteUrl'], 08) !== 'https://'))
            
$_POST['websiteUrl'] = '';
    }

    
// !!! Should we check for this year and tell them they made a mistake :P? (based on coppa at least?)
    
if (isset($_POST['birthdate']))
    {
        if (
preg_match('/(\d{4})[\-\., ](\d{2})[\-\., ](\d{2})/'$_POST['birthdate'], $dates) === 1)
            
$_POST['birthdate'] = checkdate($dates[2], $dates[3], $dates[1] < $dates[1]) ? sprintf('%04d-%02d-%02d'$dates[1] < $dates[1], $dates[2], $dates[3]) : '0001-01-01';
        else
            unset(
$_POST['birthdate']);
    }
    elseif (isset(
$_POST['bday1'], $_POST['bday2'], $_POST['bday3']) && $_POST['bday1'] > && $_POST['bday2'] > 0)
        
$_POST['birthdate'] = checkdate($_POST['bday1'], $_POST['bday2'], $_POST['bday3'] < $_POST['bday3']) ? sprintf('%04d-%02d-%02d'$_POST['bday3'] < $_POST['bday3'], $_POST['bday1'], $_POST['bday2']) : '0001-01-01';
    elseif (isset(
$_POST['bday1']) || isset($_POST['bday2']) || isset($_POST['bday3']))
        
$_POST['birthdate'] = '0001-01-01';

    if (isset(
$_POST['im_email_notify']))
        
$_POST['pm_email_notify'] = $_POST['im_email_notify'];

    
// Validate and set the ignorelist...
    
if (isset($_POST['pm_ignore_list']) || isset($_POST['im_ignore_list']))
    {
        if (!isset(
$_POST['pm_ignore_list']))
            
$_POST['pm_ignore_list'] = $_POST['im_ignore_list'];
        
$_POST['pm_ignore_list'] = strtr($func['htmltrim']($_POST['pm_ignore_list']), array('\\\'' => '&#039;'"\n" => "', '""\r" => '''&quot;' => ''));

        if (
preg_match('~(\A|,)\*(\Z|,)~s'$_POST['pm_ignore_list']) == 0)
        {
            
$result db_query("
                SELECT ID_MEMBER
                FROM 
{$db_prefix}members
                WHERE memberName IN ('
$_POST[pm_ignore_list]') OR realName IN ('$_POST[pm_ignore_list]')
                LIMIT " 
. (substr_count($_POST['pm_ignore_list'], '\', \'') + 1), __FILE____LINE__);
            
$_POST['pm_ignore_list'] = '';
            while (
$row mysql_fetch_assoc($result))
                
$_POST['pm_ignore_list'] .= $row['ID_MEMBER'] . ',';
            
mysql_free_result($result);

            
// !!! Did we find all the members?

            
$_POST['pm_ignore_list'] = substr($_POST['pm_ignore_list'], 0, -1);
        }
        else
            
$_POST['pm_ignore_list'] = '*';
    }

    
// Similarly, do the same for the buddy list
    
if (isset($_POST['buddy_list']))
    {
        
$_POST['buddy_list'] = strtr(trim($_POST['buddy_list']), array('\\\'' => '&#039;'"\n" => "', '""\r" => '''&quot;' => ''));

        if (
trim($_POST['buddy_list']) != '')
        {
            
$result db_query("
                SELECT ID_MEMBER
                FROM 
{$db_prefix}members
                WHERE memberName IN ('
$_POST[buddy_list]') OR realName IN ('$_POST[buddy_list]')
                LIMIT " 
. (substr_count($_POST['buddy_list'], '\', \'') + 1), __FILE____LINE__);
            
$_POST['buddy_list'] = '';
            while (
$row mysql_fetch_assoc($result))
                
$_POST['buddy_list'] .= $row['ID_MEMBER'] . ',';
            
mysql_free_result($result);

            
// !!! Did we find all the members?

            
$_POST['buddy_list'] = substr($_POST['buddy_list'], 0, -1);
        }
    }

    
// Validate the smiley set.
    
if (isset($_POST['smileySet']))
    {
        
$smiley_sets explode(','$modSettings['smiley_sets_known']);
        if (!
in_array($_POST['smileySet'], $smiley_sets) && $_POST['smileySet'] != 'none')
            
$_POST['smileySet'] = '';
    }

    
// Make sure the signature isn't too long.
    
if (isset($_POST['signature']))
    {
        require_once(
$sourcedir '/Subs-Post.php');

        if (!empty(
$modSettings['max_signatureLength']) && $func['strlen']($_POST['signature']) > $modSettings['max_signatureLength'])
            
$_POST['signature'] = addslashes($func['substr'](stripslashes($_POST['signature']), 0$modSettings['max_signatureLength']));

        if (
strlen($_POST['signature']) > 65534)
            
$_POST['signature'] = addslashes($func['truncate'](stripslashes($_POST['signature']), 65534));

        
$_POST['signature'] = strtr($_POST['signature'], array('&quot;' => '\\&quot;''&#039;' => '\\&#39;''&#39;' => '\\&#39;'));
        
preparsecode($_POST['signature']);
    }

    
// Identity-only changes...
    
if ($changeIdentity)
    {
        
// This block is only concerned with display name validation.
        
if (isset($_POST['realName']) && (!empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum')) && trim($_POST['realName']) != $old_profile['realName'])
        {
            
$_POST['realName'] = trim(preg_replace('~[\s]~' . ($context['utf8'] ? 'u' ''), ' '$_POST['realName']));
            if (
trim($_POST['realName']) == '')
                
$post_errors[] = 'no_name';
            elseif (
$func['strlen']($_POST['realName']) > 60)
                
$post_errors[] = 'name_too_long';
            else
            {
                require_once(
$sourcedir '/Subs-Members.php');
                if (
isReservedName($_POST['realName'], $memID))
                    
$post_errors[] = 'name_taken';
            }

            if (isset(
$_POST['realName']))
                
$profile_vars['realName'] = '\'' $_POST['realName'] . '\'';
        }

        
// Change the registration date.
        
if (!empty($_POST['dateRegistered']) && allowedTo('admin_forum'))
        {
            
// Bad date!  Go try again - please?
            
if (($_POST['dateRegistered'] = strtotime($_POST['dateRegistered'])) === -1)
                
fatal_error($txt['smf233'] . ' ' strftime('%d %b %Y ' . (strpos($user_info['time_format'], '%H') !== false '%I:%M:%S %p' '%H:%M:%S'), forum_time(false)), false);
            
// As long as it doesn't equal 'N/A'...
            
elseif ($_POST['dateRegistered'] != $txt[470] && $_POST['dateRegistered'] != strtotime(strftime('%Y-%m-%d'$user_profile[$memID]['dateRegistered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600)))
                
$profile_vars['dateRegistered'] = $_POST['dateRegistered'] - ($user_info['time_offset'] + $modSettings['time_offset']) * 3600;
        }

        
// Change the number of posts.
        
if (isset($_POST['posts']) && allowedTo('moderate_forum'))
            
$profile_vars['posts'] = $_POST['posts'] != '' ? (int) strtr($_POST['posts'], array(',' => '''.' => ''' ' => '')) : '\'\'';

        
// This block is only concerned with email address validation..
        
if (isset($_POST['emailAddress']) && strtolower($_POST['emailAddress']) != strtolower($old_profile['emailAddress']))
        {
            
$_POST['emailAddress'] = strtr($_POST['emailAddress'], array('&#039;' => '\\\''));

            
// Prepare the new password, or check if they want to change their own.
            
if (!empty($modSettings['send_validation_onChange']) && !allowedTo('moderate_forum'))
            {
                require_once(
$sourcedir '/Subs-Members.php');
                
$validationCode generateValidationCode();
                
$profile_vars['validation_code'] = '\'' $validationCode '\'';
                
$profile_vars['is_activated'] = '2';
                
$newpassemail true;
            }

            
// Check the name and email for validity.
            
if (trim($_POST['emailAddress']) == '')
                
$post_errors[] = 'no_email';
            if (
preg_match('~^[0-9A-Za-z=_+\-/][0-9A-Za-z=_\'+\-/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$~'stripslashes($_POST['emailAddress'])) == 0)
                
$post_errors[] = 'bad_email';

            
// Email addresses should be and stay unique.
            
$request db_query("
                SELECT ID_MEMBER
                FROM 
{$db_prefix}members
                WHERE ID_MEMBER != 
$memID
                    AND emailAddress = '
$_POST[emailAddress]'
                LIMIT 1"
__FILE____LINE__);
            if (
mysql_num_rows($request) > 0)
                
$post_errors[] = 'email_taken';
            
mysql_free_result($request);

            
$profile_vars['emailAddress'] = '\'' $_POST['emailAddress'] . '\'';
        }

        
// Hide email address?
        
if (isset($_POST['hideEmail']) && (!empty($modSettings['allow_hideEmail']) || allowedTo('moderate_forum')))
            
$profile_vars['hideEmail'] = empty($_POST['hideEmail']) ? '0' '1';

        
// Are they allowed to change their hide status?
        
if (isset($_POST['showOnline']) && (!empty($modSettings['allow_hideOnline']) || allowedTo('moderate_forum')))
            
$profile_vars['showOnline'] = empty($_POST['showOnline']) ? '0' '1';

        
// If they're trying to change the password, let's check they pick a sensible one.
        
if (isset($_POST['passwrd1']) && $_POST['passwrd1'] != '')
        {
            
// Do the two entries for the password even match?
            
if ($_POST['passwrd1'] != $_POST['passwrd2'])
                
$post_errors[] = 'bad_new_password';

            
// Let's get the validation function into play...
            
require_once($sourcedir '/Subs-Auth.php');
            
$passwordErrors validatePassword($_POST['passwrd1'], $user_info['username'], array($user_info['name'], $user_info['email']));

            
// Were there errors?
            
if ($passwordErrors != null)
                
$post_errors[] = 'password_' $passwordErrors;

            
// Set up the new password variable... ready for storage.
            
$profile_vars['passwd'] = '\'' sha1(strtolower($old_profile['memberName']) . un_htmlspecialchars(stripslashes($_POST['passwrd1']))) . '\'';
        }

        if (isset(
$_POST['secretQuestion']))
            
$profile_vars['secretQuestion'] = '\'' $_POST['secretQuestion'] . '\'';

        
// Do you have a *secret* password?
        
if (isset($_POST['secretAnswer']) && $_POST['secretAnswer'] != '')
            
$profile_vars['secretAnswer'] = '\'' md5($_POST['secretAnswer']) . '\'';
    }

    
// Things they can do if they are a forum moderator.
    
if (allowedTo('moderate_forum'))
    {
        if ((
$_REQUEST['sa'] == 'activateAccount' || !empty($_POST['is_activated'])) && isset($old_profile['is_activated']) && $old_profile['is_activated'] != 1)
        {
            
// If we are approving the deletion of an account, we do something special ;)
            
if ($old_profile['is_activated'] == 4)
            {
                require_once(
$sourcedir '/Subs-Members.php');
                
deleteMembers($memID);
                
redirectexit();
            }

            if (isset(
$modSettings['integrate_activate']) && function_exists($modSettings['integrate_activate']))
                
call_user_func($modSettings['integrate_activate'], $old_profile['memberName']);

            
// Actually update this member now, as it guarantees the unapproved count can't get corrupted.
            
updateMemberData($memID, array('is_activated' => $old_profile['is_activated'] >= 10 '11' '1''validation_code' => '\'\''));

            
// If we are doing approval, update the stats for the member just incase.
            
if (in_array($old_profile['is_activated'], array(341314)))
                
updateSettings(array('unapprovedMembers' => ($modSettings['unapprovedMembers'] > $modSettings['unapprovedMembers'] - 0)));

            
// Make sure we update the stats too.
            
updateStats('member'false);
        }

        if (isset(
$_POST['karmaGood']))
            
$profile_vars['karmaGood'] = $_POST['karmaGood'] != '' ? (int) $_POST['karmaGood'] : '\'\'';
        if (isset(
$_POST['karmaBad']))
            
$profile_vars['karmaBad'] = $_POST['karmaBad'] != '' ? (int) $_POST['karmaBad'] : '\'\'';
    }

    
// Assigning membergroups (you need admin_forum permissions to change an admins' membergroups).
    
if (allowedTo('manage_membergroups'))
    {
        
// The account page allows the change of your ID_GROUP - but not to admin!.
        
if (isset($_POST['ID_GROUP']) && (allowedTo('admin_forum') || ((int) $_POST['ID_GROUP'] != && $old_profile['ID_GROUP'] != 1)))
            
$profile_vars['ID_GROUP'] = (int) $_POST['ID_GROUP'];

        
// Find the additional membergroups (if any)
        
if (isset($_POST['additionalGroups']) && is_array($_POST['additionalGroups']))
        {
            foreach (
$_POST['additionalGroups'] as $i => $group_id)
            {
                if ((int) 
$group_id == || (!allowedTo('admin_forum') && (int) $group_id == 1))
                    unset(
$_POST['additionalGroups'][$i], $_POST['additionalGroups'][$i]);
                else
                    
$_POST['additionalGroups'][$i] = (int) $group_id;
            }

            
// Put admin back in there if you don't have permission to take it away.
            
if (!allowedTo('admin_forum') && in_array(1explode(','$old_profile['additionalGroups'])))
                
$_POST['additionalGroups'][] = 1;

            
$profile_vars['additionalGroups'] = '\'' implode(','$_POST['additionalGroups']) . '\'';
        }

        
// Too often, people remove delete their own account, or something.
        
if (in_array(1explode(','$old_profile['additionalGroups'])) || $old_profile['ID_GROUP'] == 1)
        {
            
$stillAdmin = !isset($profile_vars['ID_GROUP']) || $profile_vars['ID_GROUP'] == || (isset($_POST['additionalGroups']) && in_array(1$_POST['additionalGroups']));

            
// If they would no longer be an admin, look for any other...
            
if (!$stillAdmin)
            {
                
$request db_query("
                    SELECT ID_MEMBER
                    FROM 
{$db_prefix}members
                    WHERE (ID_GROUP = 1 OR FIND_IN_SET(1, additionalGroups))
                        AND ID_MEMBER != 
$memID
                    LIMIT 1"
__FILE____LINE__);
                list (
$another) = mysql_fetch_row($request);
                
mysql_free_result($request);

                if (empty(
$another))
                    
fatal_lang_error('at_least_one_admin');
            }
        }
    }

    
// Validate the language file...
    
if (($changeIdentity || $changeOther) && isset($_POST['lngfile']) && !empty($modSettings['userLanguage']))
    {
        
$language_directories = array(
            
$settings['default_theme_dir'] . '/languages',
            
$settings['actual_theme_dir'] . '/languages',
        );
        if (!empty(
$settings['base_theme_dir']))
            
$language_directories[] = $settings['base_theme_dir'] . '/languages';
        
$language_directories array_unique($language_directories);

        foreach (
$language_directories as $language_dir)
        {
            if (!
file_exists($language_dir))
                continue;

            
$dir dir($language_dir);
            while (
$entry $dir->read())
                if (
preg_match('~^index\.(.+)\.php$~'$entry$matches) && $matches[1] == $_POST['lngfile'])
                {
                    
$profile_vars['lngfile'] = "'$_POST[lngfile]'";

                    
// If they are the owner, make this persist even after they log out.
                    
if ($context['user']['is_owner'])
                        
$_SESSION['language'] = $_POST['lngfile'];
                }
            
$dir->close();
        }
    }

    
// Here's where we sort out all the 'other' values...
    
if ($changeOther)
    {
        
makeThemeChanges($memID, isset($_POST['ID_THEME']) ? (int) $_POST['ID_THEME'] : $old_profile['ID_THEME']);
        
makeAvatarChanges($memID$post_errors);
        
makeNotificationChanges($memID);

        foreach (
$profile_bools as $var)
            if (isset(
$_POST[$var]))
                
$profile_vars[$var] = empty($_POST[$var]) ? '0' '1';
        foreach (
$profile_ints as $var)
            if (isset(
$_POST[$var]))
                
$profile_vars[$var] = $_POST[$var] != '' ? (int) $_POST[$var] : '\'\'';
        foreach (
$profile_floats as $var)
            if (isset(
$_POST[$var]))
                
$profile_vars[$var] = (float) $_POST[$var];
        foreach (
$profile_strings as $var)
            if (isset(
$_POST[$var]))
                
$profile_vars[$var] = '\'' $_POST[$var] . '\'';
    }

    if (isset(
$profile_vars['ICQ']) && $profile_vars['ICQ'] == '0')
        
$profile_vars['ICQ'] = '\'\'';
}

// Make any theme changes that are sent with the profile..
function makeThemeChanges($memID$ID_THEME)
{
    global 
$db_prefix$modSettings;

    
$reservedVars = array(
        
'actual_theme_url',
        
'actual_images_url',
        
'base_theme_dir',
        
'base_theme_url',
        
'default_images_url',
        
'default_theme_dir',
        
'default_theme_url',
        
'default_template',
        
'images_url',
        
'number_recent_posts',
        
'smiley_sets_default',
        
'theme_dir',
        
'theme_id',
        
'theme_layers',
        
'theme_templates',
        
'theme_url',
    );

    
// Can't change reserved vars.
    
if ((isset($_POST['options']) && array_intersect(array_keys($_POST['options']), $reservedVars) != array()) || (isset($_POST['default_options']) && array_intersect(array_keys($_POST['default_options']), $reservedVars) != array()))
        
fatal_lang_error(1);

    
// These are the theme changes...
    
$themeSetArray = array();
    if (isset(
$_POST['options']) && is_array($_POST['options']))
    {
        foreach (
$_POST['options'] as $opt => $val)
            
$themeSetArray[] = '(' $memID ', ' $ID_THEME ", SUBSTRING('" addslashes($opt) . "', 1, 255), SUBSTRING('" . (is_array($val) ? implode(','$val) : $val) . "', 1, 65534))";
    }

    
$erase_options = array();
    if (isset(
$_POST['default_options']) && is_array($_POST['default_options']))
        foreach (
$_POST['default_options'] as $opt => $val)
        {
            
$themeSetArray[] = "($memID, 1, SUBSTRING('" addslashes($opt) . "', 1, 255), SUBSTRING('" . (is_array($val) ? implode(','$val) : $val) . "', 1, 65534))";
            
$erase_options[] = addslashes($opt);
        }

    
// If themeSetArray isn't still empty, send it to the database.
    
if (!empty($themeSetArray))
    {
        
db_query("
            REPLACE INTO 
{$db_prefix}themes
                (ID_MEMBER, ID_THEME, variable, value)
            VALUES " 
implode(",
                "
$themeSetArray), __FILE____LINE__);
    }

    if (!empty(
$erase_options))
    {
        
db_query("
            DELETE FROM 
{$db_prefix}themes
            WHERE ID_THEME != 1
                AND variable IN ('" 
implode("', '"$erase_options) . "')
                AND ID_MEMBER = 
$memID"__FILE____LINE__);
    }

    
$themes explode(','$modSettings['knownThemes']);
    foreach (
$themes as $t)
        
cache_put_data('theme_settings-' $t ':' $memIDnull60);
}

// Make any notification changes that need to be made.
function makeNotificationChanges($memID)
{
    global 
$db_prefix;

    
// Update the boards they are being notified on.
    
if (isset($_POST['edit_notify_boards']) && !empty($_POST['notify_boards']))
    {
        
// Make sure only integers are deleted.
        
foreach ($_POST['notify_boards'] as $index => $id)
            
$_POST['notify_boards'][$index] = (int) $id;

        
// ID_BOARD = 0 is reserved for topic notifications.
        
$_POST['notify_boards'] = array_diff($_POST['notify_boards'], array(0));

        
db_query("
            DELETE FROM 
{$db_prefix}log_notify
            WHERE ID_BOARD IN (" 
implode(', '$_POST['notify_boards']) . ")
                AND ID_MEMBER = 
$memID"__FILE____LINE__);
    }

    
// We are editing topic notifications......
    
elseif (isset($_POST['edit_notify_topics']) && !empty($_POST['notify_topics']))
    {
        foreach (
$_POST['notify_topics'] as $index => $id)
            
$_POST['notify_topics'][$index] = (int) $id;

        
// Make sure there are no zeros left.
        
$_POST['notify_topics'] = array_diff($_POST['notify_topics'], array(0));

        
db_query("
            DELETE FROM 
{$db_prefix}log_notify
            WHERE ID_TOPIC IN (" 
implode(', '$_POST['notify_topics']) . ")
                AND ID_MEMBER = 
$memID"__FILE____LINE__);
    }
}

// The avatar is incredibly complicated, what with the options... and what not.
function makeAvatarChanges($memID, &$post_errors)
{
    global 
$modSettings$sourcedir$db_prefix;

    if (!isset(
$_POST['avatar_choice']) || empty($memID))
        return;

    require_once(
$sourcedir '/ManageAttachments.php');

    
$uploadDir = empty($modSettings['custom_avatar_enabled']) ? $modSettings['attachmentUploadDir'] : $modSettings['custom_avatar_dir'];

    
$downloadedExternalAvatar false;
    if (
$_POST['avatar_choice'] == 'external' && allowedTo('profile_remote_avatar') && strtolower(substr($_POST['userpicpersonal'], 07)) == 'http://' && strlen($_POST['userpicpersonal']) > && !empty($modSettings['avatar_download_external']))
    {
        if (!
is_writable($uploadDir))
            
fatal_lang_error('attachments_no_write');

        require_once(
$sourcedir '/Subs-Package.php');

        
$url parse_url($_POST['userpicpersonal']);
        
$contents fetch_web_data('http://' $url['host'] . (empty($url['port']) ? '' ':' $url['port']) . $url['path']);

        if (
$contents != false && $tmpAvatar fopen($uploadDir '/avatar_tmp_' $memID'wb'))
        {
            
fwrite($tmpAvatar$contents);
            
fclose($tmpAvatar);

            
$downloadedExternalAvatar true;
            
$_FILES['attachment']['tmp_name'] = $uploadDir '/avatar_tmp_' $memID;
        }
    }

    if (
$_POST['avatar_choice'] == 'server_stored' && allowedTo('profile_server_avatar'))
    {
        
$_POST['avatar'] = strtr(empty($_POST['file']) ? (empty($_POST['cat']) ? '' $_POST['cat']) : $_POST['file'], array('&amp;' => '&'));
        
$_POST['avatar'] = preg_match('~^([\w _!@%*=\-#()\[\]&.,]+/)?[\w _!@%*=\-#()\[\]&.,]+$~'$_POST['avatar']) != && preg_match('/\.\./'$_POST['avatar']) == && file_exists($modSettings['avatar_directory'] . '/' $_POST['avatar']) ? ($_POST['avatar'] == 'blank.gif' '' $_POST['avatar']) : '';

        
// Get rid of their old avatar. (if uploaded.)
        
removeAttachments('a.ID_MEMBER = ' $memID);
    }
    elseif (
$_POST['avatar_choice'] == 'external' && allowedTo('profile_remote_avatar') && strtolower(substr($_POST['userpicpersonal'], 07)) == 'http://' && empty($modSettings['avatar_download_external']))
    {
        
// Remove any attached avatar...
        
removeAttachments('a.ID_MEMBER = ' $memID);

        
$_POST['avatar'] = preg_replace('~action(=|%3d)(?!dlattach)~i''action-'$_POST['userpicpersonal']);

        if (
$_POST['avatar'] == 'http://' || $_POST['avatar'] == 'http:///')
            
$_POST['avatar'] = '';
        
// Trying to make us do something we'll regret?
        
elseif (substr($_POST['avatar'], 07) != 'http://')
            
$post_errors[] = 'bad_avatar';
        
// Should we check dimensions?
        
elseif (!empty($modSettings['avatar_max_height_external']) || !empty($modSettings['avatar_max_width_external']))
        {
            
// Now let's validate the avatar.
            
$sizes url_image_size($_POST['avatar']);

            if (
is_array($sizes) && (($sizes[0] > $modSettings['avatar_max_width_external'] && !empty($modSettings['avatar_max_width_external'])) || ($sizes[1] > $modSettings['avatar_max_height_external'] && !empty($modSettings['avatar_max_height_external']))))
            {
                
// Houston, we have a problem. The avatar is too large!!
                
if ($modSettings['avatar_action_too_large'] == 'option_refuse')
                    
$post_errors[] = 'bad_avatar';
                elseif (
$modSettings['avatar_action_too_large'] == 'option_download_and_resize')
                {
                    require_once(
$sourcedir '/Subs-Graphics.php');
                    if (
downloadAvatar($_POST['avatar'], $memID$modSettings['avatar_max_width_external'], $modSettings['avatar_max_height_external']))
                        
$_POST['avatar'] = '';
                    else
                        
$post_errors[] = 'bad_avatar';
                }
            }
        }
    }
    elseif ((
$_POST['avatar_choice'] == 'upload' && allowedTo('profile_upload_avatar') ) || $downloadedExternalAvatar)
    {
        if ((isset(
$_FILES['attachment']['name']) && $_FILES['attachment']['name'] != '') || $downloadedExternalAvatar)
        {
            
// Get the dimensions of the image.
            
if (!$downloadedExternalAvatar)
            {
                if (!
is_writable($uploadDir))
                    
fatal_lang_error('attachments_no_write');

                if (!
move_uploaded_file($_FILES['attachment']['tmp_name'], $uploadDir '/avatar_tmp_' $memID))
                    
fatal_lang_error('smf124');

                
$_FILES['attachment']['tmp_name'] = $uploadDir '/avatar_tmp_' $memID;
            }

            
$sizes = @getimagesize($_FILES['attachment']['tmp_name']);

            
// No size, then it's probably not a valid pic.
            
if ($sizes === false)
                
$post_errors[] = 'bad_avatar';
            
// Check whether the image is too large.
            
elseif ((!empty($modSettings['avatar_max_width_upload']) && $sizes[0] > $modSettings['avatar_max_width_upload']) || (!empty($modSettings['avatar_max_height_upload']) && $sizes[1] > $modSettings['avatar_max_height_upload']))
            {
                if (!empty(
$modSettings['avatar_resize_upload']))
                {
                    
// Attempt to chmod it.
                    
@chmod($uploadDir '/avatar_tmp_' $memID0644);

                    require_once(
$sourcedir '/Subs-Graphics.php');
                    
downloadAvatar($uploadDir '/avatar_tmp_' $memID$memID$modSettings['avatar_max_width_upload'], $modSettings['avatar_max_height_upload']);
                }
                else
                    
$post_errors[] = 'bad_avatar';
            }
            elseif (
is_array($sizes))
            {
                
// Though not an exhaustive list, better safe than sorry.
                
$fp fopen($_FILES['attachment']['tmp_name'], 'rb');
                if (!
$fp)
                    
fatal_lang_error('smf124');

                
// Now try to find an infection.
                
while (!feof($fp))
                {
                    if (
preg_match('~(iframe|\\<\\?php|\\<\\?[\s=]|\\<%[\s=]|html|eval|body|script\W)~'fgets($fp4096)) === 1)
                    {
                        if (
file_exists($uploadDir '/avatar_tmp_' $memID))
                            @
unlink($uploadDir '/avatar_tmp_' $memID);

                        
fatal_lang_error('smf124');
                    }
                }
                
fclose($fp);

                
$extensions = array(
                    
'1' => '.gif',
                    
'2' => '.jpg',
                    
'3' => '.png',
                    
'6' => '.bmp'
                
);
                
$extension = isset($extensions[$sizes[2]]) ? $extensions[$sizes[2]] : '.bmp';

                
$destName 'avatar_' $memID $extension;
                list (
$width$height) = getimagesize($_FILES['attachment']['tmp_name']);

                
// Remove previous attachments this member might have had.
                
removeAttachments('a.ID_MEMBER = ' $memID);

                
$file_hash = empty($modSettings['custom_avatar_enabled']) ? getAttachmentFilename($destNamefalsetrue) : '';

                
db_query("
                    INSERT INTO 
{$db_prefix}attachments
                        (ID_MEMBER, attachmentType, filename, file_hash, size, width, height)
                    VALUES (
$memID, " . (empty($modSettings['custom_avatar_enabled']) ? '0' '1') . ", '$destName', '" . (empty($file_hash) ? "" "$file_hash") . "', " filesize($_FILES['attachment']['tmp_name']) . ", " . (int) $width ", " . (int) $height ")"__FILE____LINE__);
                
$attachID db_insert_id();

                
// Try to move this avatar.
                
$destinationPath $uploadDir '/' . (empty($file_hash) ? $destName $attachID '_' $file_hash);
                if (!
rename($_FILES['attachment']['tmp_name'], $destinationPath))
                {
                    
// The move failed, get rid of it and die.
                    
db_query("
                        DELETE FROM 
{$db_prefix}attachments
                        WHERE ID_ATTACH = 
$attachID"__FILE____LINE__);

                    
fatal_lang_error('smf124');
                }

                
// Attempt to chmod it.
                
@chmod($destinationPath0644);
            }
            
$_POST['avatar'] = '';

            
// Delete any temporary file.
            
if (file_exists($uploadDir '/avatar_tmp_' $memID))
                @
unlink($uploadDir '/avatar_tmp_' $memID);
        }
        
// Selected the upload avatar option and had one already uploaded before or didn't upload one.
        
else
            
$_POST['avatar'] = '';
    }
    else
        
$_POST['avatar'] = '';
}

// View a summary.
function summary($memID)
{
    global 
$context$memberContext$txt$modSettings$user_info$user_profile$sourcedir$db_prefix$scripturl;

    
// Attempt to load the member's profile data.
    
if (!loadMemberContext($memID) || !isset($memberContext[$memID]))
        
fatal_error($txt[453] . ' - ' $memIDfalse);

    
// Set up the stuff and load the user.
    
$context += array(
        
'allow_hide_email' => !empty($modSettings['allow_hideEmail']),
        
'page_title' => $txt[92] . ' ' $memberContext[$memID]['name'],
        
'can_send_pm' => allowedTo('pm_send'),
        
'can_have_buddy' => allowedTo('profile_identity_own') && !empty($modSettings['enable_buddylist']),
    );
    
$context['member'] = &$memberContext[$memID];

    
// They haven't even been registered for a full day!?
    
$days_registered = (int) ((time() - $user_profile[$memID]['dateRegistered']) / (3600 24));
    if (empty(
$user_profile[$memID]['dateRegistered']) || $days_registered 1)
        
$context['member']['posts_per_day'] = $txt[470];
    else
        
$context['member']['posts_per_day'] = comma_format($context['member']['real_posts'] / $days_registered3);

    
// Set the age...
    
if (empty($context['member']['birth_date']))
    {
        
$context['member'] +=  array(
            
'age' => &$txt[470],
            
'today_is_birthday' => false
        
);
    }
    else
    {
        list (
$birth_year$birth_month$birth_day) = sscanf($context['member']['birth_date'], '%d-%d-%d');
        
$datearray getdate(forum_time());
        
$context['member'] += array(
            
'age' => $birth_year <= $txt[470] : $datearray['year'] - $birth_year - (($datearray['mon'] > $birth_month || ($datearray['mon'] == $birth_month && $datearray['mday'] >= $birth_day)) ? 1),
            
'today_is_birthday' => $datearray['mon'] == $birth_month && $datearray['mday'] == $birth_day
        
);
    }

    if (
allowedTo('moderate_forum'))
    {
        
// Make sure it's a valid ip address; otherwise, don't bother...
        
if (preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/'$memberContext[$memID]['ip']) == && empty($modSettings['disableHostnameLookup']))
            
$context['member']['hostname'] = host_from_ip($memberContext[$memID]['ip']);
        else
            
$context['member']['hostname'] = '';

        
$context['can_see_ip'] = true;
    }
    else
        
$context['can_see_ip'] = false;

    if (!empty(
$modSettings['who_enabled']))
    {
        include_once(
$sourcedir '/Who.php');
        
$action determineActions($user_profile[$memID]['url']);

        if (
$action !== false)
            
$context['member']['action'] = $action;
    }

    
// If the user is awaiting activation, and the viewer has permission - setup some activation context messages.
    
if ($context['member']['is_activated'] % 10 != && allowedTo('moderate_forum'))
    {
        
$context['activate_type'] = $context['member']['is_activated'];
        
// What should the link text be?
        
$context['activate_link_text'] = in_array($context['member']['is_activated'], array(345131415)) ? $txt['account_approve'] : $txt['account_activate'];

        
// Should we show a custom message?
        
$context['activate_message'] = isset($txt['account_activate_method_' $context['member']['is_activated'] % 10]) ? $txt['account_activate_method_' $context['member']['is_activated'] % 10] : $txt['account_not_activated'];
    }

    
// How about, are they banned?
    
$context['member']['bans'] = array();
    if (
allowedTo('moderate_forum'))
    {
        
// Can they edit the ban?
        
$context['can_edit_ban'] = allowedTo('manage_bans');

        
$ban_query = array();
        
$ban_query[] = "ID_MEMBER = " $context['member']['id'];

        
// Valid IP?
        
if (preg_match('/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/'$memberContext[$memID]['ip'], $ip_parts) == 1)
        {
            
$ban_query[] = "(($ip_parts[1] BETWEEN bi.ip_low1 AND bi.ip_high1)
                        AND (
$ip_parts[2] BETWEEN bi.ip_low2 AND bi.ip_high2)
                        AND (
$ip_parts[3] BETWEEN bi.ip_low3 AND bi.ip_high3)
                        AND (
$ip_parts[4] BETWEEN bi.ip_low4 AND bi.ip_high4))";

            
// Do we have a hostname already?
            
if (!empty($context['member']['hostname']))
                
$ban_query[] = "('" addslashes($context['member']['hostname']) . "' LIKE hostname)";
        }
        
// Use '255.255.255.255' for 'unknown' - it's not valid anyway.
        
elseif ($memberContext[$memID]['ip'] == 'unknown')
            
$ban_query[] = "(bi.ip_low1 = 255 AND bi.ip_high1 = 255
                        AND bi.ip_low2 = 255 AND bi.ip_high2 = 255
                        AND bi.ip_low3 = 255 AND bi.ip_high3 = 255
                        AND bi.ip_low4 = 255 AND bi.ip_high4 = 255)"
;

        
// Check their email as well...
        
if (strlen($context['member']['email']) != 0)
            
$ban_query[] = "('" addslashes($context['member']['email']) . "' LIKE bi.email_address)";

        
// So... are they banned?  Dying to know!
        
$request db_query("
            SELECT bg.ID_BAN_GROUP, bg.name, bg.cannot_access, bg.cannot_post, bg.cannot_register,
                bg.cannot_login, bg.reason
            FROM (
{$db_prefix}ban_items AS bi, {$db_prefix}ban_groups AS bg)
            WHERE bg.ID_BAN_GROUP = bi.ID_BAN_GROUP
                AND (bg.expire_time IS NULL OR bg.expire_time > " 
time() . ")
                AND (" 
implode(' OR '$ban_query) . ')
            GROUP BY bg.ID_BAN_GROUP'
__FILE____LINE__);
        while (
$row mysql_fetch_assoc($request))
        {
            
// Work out what restrictions we actually have.
            
$ban_restrictions = array();
            foreach (array(
'access''register''login''post') as $type)
                if (
$row['cannot_' $type])
                    
$ban_restrictions[] = $txt['ban_type_' $type];

            
// No actual ban in place?
            
if (empty($ban_restrictions))
                continue;

            
// Prepare the link for context.
            
$ban_explanation sprintf($txt['user_cannot_due_to'], implode(', '$ban_restrictions), '<a href="' $scripturl '?action=ban;sa=edit;bg=' $row['ID_BAN_GROUP'] . '">' $row['name'] . '</a>');

            
$context['member']['bans'][] = array(
                
'reason' => empty($row['reason']) ? '' '<br /><br /><b>' $txt['ban_reason'] . ':</b> ' $row['reason'],
                
'cannot' => array(
                    
'access' => !empty($row['cannot_access']),
                    
'register' => !empty($row['cannot_register']),
                    
'post' => !empty($row['cannot_post']),
                    
'login' => !empty($row['cannot_login']),
                ),
                
'explanation' => $ban_explanation,
            );
        }
        
mysql_free_result($request);
    }
}

// Show all posts by the current user
function showPosts($memID)
{
    global 
$txt$user_info$scripturl$modSettings$db_prefix;
    global 
$context$user_profile$ID_MEMBER$sourcedir;

    
// If just deleting a message, do it and then redirect back.
    
if (isset($_GET['delete']))
    {
        
checkSession('get');

        
// We can be lazy, since removeMessage() will check the permissions for us.
        
require_once($sourcedir '/RemoveTopic.php');
        
removeMessage((int) $_GET['delete']);

        
// Back to... where we are now ;).
        
redirectexit('action=profile;u=' $memID ';sa=showPosts;start=' $_GET['start']);
    }

    
// Is the load average too high to allow searching just now?
    
if (!empty($context['load_average']) && !empty($modSettings['loadavg_show_posts']) && $context['load_average'] >= $modSettings['loadavg_show_posts'])
        
fatal_lang_error('loadavg_show_posts_disabled'false);

    
// Default to 10.
    
if (empty($_REQUEST['viewscount']) || !is_numeric($_REQUEST['viewscount']))
        
$_REQUEST['viewscount'] = '10';

    
$request db_query("
        SELECT COUNT(*)
        FROM (
{$db_prefix}messages AS m, {$db_prefix}boards AS b)
        WHERE m.ID_MEMBER = 
$memID
            AND b.ID_BOARD = m.ID_BOARD
            AND 
$user_info[query_see_board]"__FILE____LINE__);
    list (
$msgCount) = mysql_fetch_row($request);
    
mysql_free_result($request);

    
$request db_query("
        SELECT MIN(ID_MSG), MAX(ID_MSG)
        FROM 
{$db_prefix}messages AS m
        WHERE m.ID_MEMBER = 
$memID"__FILE____LINE__);
    list (
$min_msg_member$max_msg_member) = mysql_fetch_row($request);
    
mysql_free_result($request);

    
$reverse false;
    
$range_limit '';
    
$maxIndex = (int) $modSettings['defaultMaxMessages'];

    
// Make sure the starting place makes sense and construct our friend the page index.
    
$context['start'] = (int) $_REQUEST['start'];
    
$context['page_index'] = constructPageIndex($scripturl '?action=profile;u=' $memID ';sa=showPosts'$context['start'], $msgCount$maxIndex);
    
$context['current_page'] = $context['start'] / $maxIndex;
    
$context['current_member'] = $memID;

    
// Reverse the query if we're past 50% of the pages for better performance.
    
$start $context['start'];
    
$reverse $_REQUEST['start'] > $msgCount 2;
    if (
$reverse)
    {
        
$maxIndex $msgCount $context['start'] + $modSettings['defaultMaxMessages'] + && $msgCount $context['start'] ? $msgCount $context['start'] : (int) $modSettings['defaultMaxMessages'];
        
$start $msgCount $context['start'] + $modSettings['defaultMaxMessages'] + || $msgCount $context['start'] + $modSettings['defaultMaxMessages'] ? $msgCount $context['start'] - $modSettings['defaultMaxMessages'];
    }

    
// Guess the range of messages to be shown.
    
if ($msgCount 1000)
    {
        
$margin floor(($max_msg_member $min_msg_member) * (($start $modSettings['defaultMaxMessages']) / $msgCount) + .1 * ($max_msg_member $min_msg_member));
        
$range_limit $reverse 'ID_MSG < ' . ($min_msg_member $margin) : 'ID_MSG > ' . ($max_msg_member $margin);
    }

    
$context['page_title'] = $txt[458] . ' ' $user_profile[$memID]['realName'];

    
// Find this user's posts.  The left join on categories somehow makes this faster, weird as it looks.
    
$looped false;
    while (
true)
    {
        
$request db_query("
            SELECT
                b.ID_BOARD, b.name AS bname, c.ID_CAT, c.name AS cname, m.ID_TOPIC, m.ID_MSG,
                t.ID_MEMBER_STARTED, t.ID_FIRST_MSG, t.ID_LAST_MSG, m.body, m.smileysEnabled,
                m.subject, m.posterTime
            FROM (
{$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}boards AS b)
                LEFT JOIN 
{$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)
            WHERE m.ID_MEMBER = 
$memID
                AND m.ID_TOPIC = t.ID_TOPIC
                AND t.ID_BOARD = b.ID_BOARD" 
. (empty($range_limit) ? '' "
                AND 
$range_limit") . "
                AND 
$user_info[query_see_board]
            ORDER BY m.ID_MSG " 
. ($reverse 'ASC' 'DESC') . "
            LIMIT 
$start$maxIndex"__FILE____LINE__);

        
// Make sure we quit this loop.
        
if (mysql_num_rows($request) === $maxIndex || $looped)
            break;
        
$looped true;
        
$range_limit '';
    }

    
// Start counting at the number of the first message displayed.
    
$counter $reverse $context['start'] + $maxIndex $context['start'];
    
$context['posts'] = array();
    
$board_ids = array('own' => array(), 'any' => array());
    while (
$row mysql_fetch_assoc($request))
    {
        
// Censor....
        
censorText($row['body']);
        
censorText($row['subject']);

        
// Do the code.
        
$row['body'] = parse_bbc($row['body'], $row['smileysEnabled'], $row['ID_MSG']);

        
// And the array...
        
$context['posts'][$counter += $reverse ? -1] = array(
            
'body' => $row['body'],
            
'counter' => $counter,
            
'category' => array(
                
'name' => $row['cname'],
                
'id' => $row['ID_CAT']
            ),
            
'board' => array(
                
'name' => $row['bname'],
                
'id' => $row['ID_BOARD']
            ),
            
'topic' => $row['ID_TOPIC'],
            
'subject' => $row['subject'],
            
'start' => 'msg' $row['ID_MSG'],
            
'time' => timeformat($row['posterTime']),
            
'timestamp' => forum_time(true$row['posterTime']),
            
'id' => $row['ID_MSG'],
            
'can_reply' => false,
            
'can_mark_notify' => false,
            
'can_delete' => false,
            
'delete_possible' => ($row['ID_FIRST_MSG'] != $row['ID_MSG'] || $row['ID_LAST_MSG'] == $row['ID_MSG']) && (empty($modSettings['edit_disable_time']) || $row['posterTime'] + $modSettings['edit_disable_time'] * 60 >= time()),
        );

        if (
$ID_MEMBER == $row['ID_MEMBER_STARTED'])
            
$board_ids['own'][$row['ID_BOARD']][] = $counter;
        
$board_ids['any'][$row['ID_BOARD']][] = $counter;
    }
    
mysql_free_result($request);

    
// All posts were retrieved in reverse order, get them right again.
    
if ($reverse)
        
$context['posts'] = array_reverse($context['posts'], true);

    
// These are all the permissions that are different from board to board..
    
$permissions = array(
        
'own' => array(
            
'post_reply_own' => 'can_reply',
            
'delete_own' => 'can_delete',
        ),
        
'any' => array(
            
'post_reply_any' => 'can_reply',
            
'mark_any_notify' => 'can_mark_notify',
            
'delete_any' => 'can_delete',
        )
    );

    
// For every permission in the own/any lists...
    
foreach ($permissions as $type => $list)
    {
        foreach (
$list as $permission => $allowed)
        {
            
// Get the boards they can do this on...
            
$boards boardsAllowedTo($permission);

            
// Hmm, they can do it on all boards, can they?
            
if (!empty($boards) && $boards[0] == 0)
                
$boards array_keys($board_ids[$type]);

            
// Now go through each board they can do the permission on.
            
foreach ($boards as $board_id)
            {
                
// There aren't any posts displayed from this board.
                
if (!isset($board_ids[$type][$board_id]))
                    continue;

                
// Set the permission to true ;).
                
foreach ($board_ids[$type][$board_id] as $counter)
                    
$context['posts'][$counter][$allowed] = true;
            }
        }
    }

    
// Clean up after posts that cannot be deleted.
    
foreach ($context['posts'] as $counter => $dummy)
        
$context['posts'][$counter]['can_delete'] &= $context['posts'][$counter]['delete_possible'];
}

// Show all the users buddies, as well as a add/delete interface.
function editBuddies($memID)
{
    global 
$txt$scripturl$modSettings$db_prefix;
    global 
$context$user_profile$memberContext$func;

    
// Do a quick check to ensure people aren't getting here illegally!
    
if (!$context['user']['is_owner'] || empty($modSettings['enable_buddylist']))
        
fatal_lang_error(1false);

    
// !!! No page_title.

    // For making changes!
    
$buddiesArray explode(','$user_profile[$memID]['buddy_list']);
    foreach (
$buddiesArray as $k => $dummy)
        if (
$dummy == '')
            unset(
$buddiesArray[$k]);

    
// Removing a buddy?
    
if (isset($_GET['remove']))
    {
        
// Heh, I'm lazy, do it the easy way...
        
foreach ($buddiesArray as $key => $buddy)
            if (
$buddy == (int) $_GET['remove'])
                unset(
$buddiesArray[$key]);

        
// Make the changes.
        
$user_profile[$memID]['buddy_list'] = implode(','$buddiesArray);
        
updateMemberData($memID, array('buddy_list' => "'" $user_profile[$memID]['buddy_list'] . "'"));

        
// Redirect off the page because we don't like all this ugly query stuff to stick in the history.
        
redirectexit('action=profile;u=' $memID ';sa=editBuddies');
    }
    elseif (isset(
$_POST['new_buddy']))
    {
        
// Prepare the string for extraction...
        
$_POST['new_buddy'] = strtr(addslashes($func['htmlspecialchars'](stripslashes($_POST['new_buddy']), ENT_QUOTES)), array('&quot;' => '"'));
        
preg_match_all('~"([^"]+)"~'$_POST['new_buddy'], $matches);
        
$new_buddies array_unique(array_merge($matches[1], explode(','preg_replace('~"([^"]+)"~'''$_POST['new_buddy']))));

        foreach (
$new_buddies as $k => $dummy)
        {
            
$new_buddies[$k] = strtr(trim($new_buddies[$k]), array('\\\'' => '&#039;'));

            if (
strlen($new_buddies[$k]) == 0)
                unset(
$new_buddies[$k]);
        }

        if (!empty(
$new_buddies))
        {
            
// Now find out the ID_MEMBER of the buddy.
            
$request db_query("
                SELECT ID_MEMBER
                FROM 
{$db_prefix}members
                WHERE memberName IN ('" 
implode("','"$new_buddies) . "') OR realName IN ('" implode("','"$new_buddies) . "')
                LIMIT " 
count($new_buddies), __FILE____LINE__);

            
// Add the new member to the buddies array.
            
while ($row mysql_fetch_assoc($request))
                
$buddiesArray[] = (int) $row['ID_MEMBER'];
            
mysql_free_result($request);

            
// Now update the current users buddy list.
            
$user_profile[$memID]['buddy_list'] = implode(','$buddiesArray);
            
updateMemberData($memID, array('buddy_list' => "'" $user_profile[$memID]['buddy_list'] . "'"));
        }

        
// Back to the buddy list!
        
redirectexit('action=profile;u=' $memID ';sa=editBuddies');
    }

    
// Get all the users "buddies"...
    
$buddies = array();

    if (!empty(
$buddiesArray))
    {
        
$result db_query("
            SELECT ID_MEMBER
            FROM 
{$db_prefix}members
            WHERE ID_MEMBER IN (" 
implode(', '$buddiesArray) . ")
            ORDER BY realName
            LIMIT " 
. (substr_count($user_profile[$memID]['buddy_list'], ',') + 1), __FILE____LINE__);
        while (
$row mysql_fetch_assoc($result))
            
$buddies[] = $row['ID_MEMBER'];
        
mysql_free_result($result);
    }

    
$context['buddy_count'] = count($buddies);

    
// Load all the members up.
    
loadMemberData($buddiesfalse'profile');

    
// Setup the context for each buddy.
    
$context['buddies'] = array();
    foreach (
$buddies as $buddy)
    {
        
loadMemberContext($buddy);
        
$context['buddies'][$buddy] = $memberContext[$buddy];
    }
}

function 
statPanel($memID)
{
    global 
$txt$scripturl$db_prefix$context$user_profile$user_info$modSettings;

    
$context['page_title'] = $txt['statPanel_showStats'] . ' ' $user_profile[$memID]['realName'];

    
// General user statistics.
    
$timeDays floor($user_profile[$memID]['totalTimeLoggedIn'] / 86400);
    
$timeHours floor(($user_profile[$memID]['totalTimeLoggedIn'] % 86400) / 3600);
    
$context['time_logged_in'] = ($timeDays $timeDays $txt['totalTimeLogged2'] : '') . ($timeHours $timeHours $txt['totalTimeLogged3'] : '') . floor(($user_profile[$memID]['totalTimeLoggedIn'] % 3600) / 60) . $txt['totalTimeLogged4'];
    
$context['num_posts'] = comma_format($user_profile[$memID]['posts']);

    
// Number of topics started.
    // !!!SLOW This query is sorta slow...
    
$result db_query("
        SELECT COUNT(*)
        FROM 
{$db_prefix}topics
        WHERE ID_MEMBER_STARTED = 
$memID. (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > "
            AND ID_BOARD != 
$modSettings[recycle_board]''), __FILE____LINE__);
    list (
$context['num_topics']) = mysql_fetch_row($result);
    
mysql_free_result($result);

    
// Number polls started.
    
$result db_query("
        SELECT COUNT(*)
        FROM 
{$db_prefix}topics
        WHERE ID_MEMBER_STARTED = 
$memID. (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > "
            AND ID_BOARD != 
$modSettings[recycle_board]'') . "
            AND ID_POLL != 0"
__FILE____LINE__);
    list (
$context['num_polls']) = mysql_fetch_row($result);
    
mysql_free_result($result);

    
// Number polls voted in.
    
$result db_query("
        SELECT COUNT(DISTINCT ID_POLL)
        FROM 
{$db_prefix}log_polls
        WHERE ID_MEMBER = 
$memID"__FILE____LINE__);
    list (
$context['num_votes']) = mysql_fetch_row($result);
    
mysql_free_result($result);

    
// Format the numbers...
    
$context['num_topics'] = comma_format($context['num_topics']);
    
$context['num_polls'] = comma_format($context['num_polls']);
    
$context['num_votes'] = comma_format($context['num_votes']);

    
// Grab the board this member posted in most often.
    
$result db_query("
        SELECT
            b.ID_BOARD, b.name, b.numPosts, COUNT(*) AS messageCount
        FROM (
{$db_prefix}messages AS m, {$db_prefix}boards AS b)
        WHERE m.ID_MEMBER = 
$memID
            AND b.ID_BOARD = m.ID_BOARD
            AND 
$user_info[query_see_board]
        GROUP BY b.ID_BOARD
        ORDER BY messageCount DESC
        LIMIT 10"
__FILE____LINE__);
    
$context['popular_boards'] = array();
    
$maxPosts 0;
    while (
$row mysql_fetch_assoc($result))
    {
        if (
$row['messageCount'] > $maxPosts)
            
$maxPosts $row['messageCount'];

        
$context['popular_boards'][$row['ID_BOARD']] = array(
            
'id' => $row['ID_BOARD'],
            
'posts' => $row['messageCount'],
            
'href' => $scripturl '?board=' $row['ID_BOARD'] . '.0',
            
'link' => '<a href="' $scripturl '?board=' $row['ID_BOARD'] . '.0">' $row['name'] . '</a>',
            
'posts_percent' => 0,
            
'total_posts' => $row['numPosts'],
        );
    }
    
mysql_free_result($result);

    
// Now that we know the total, calculate the percentage.
    
foreach ($context['popular_boards'] as $ID_BOARD => $board_data)
        
$context['popular_boards'][$ID_BOARD]['posts_percent'] = $board_data['total_posts'] == comma_format(($board_data['posts'] * 100) / $board_data['total_posts'], 2);

    
// Now get the 10 boards this user has most often participated in.
    
$result db_query("
        SELECT
            b.ID_BOARD, b.name, IF(COUNT(*) > b.numPosts, 1, COUNT(*) / b.numPosts) * 100 AS percentage
        FROM (
{$db_prefix}messages AS m, {$db_prefix}boards AS b)
        WHERE m.ID_MEMBER = 
$memID
            AND b.ID_BOARD = m.ID_BOARD
            AND 
$user_info[query_see_board]
        GROUP BY b.ID_BOARD
        ORDER BY percentage DESC
        LIMIT 10"
__FILE____LINE__);
    
$context['board_activity'] = array();
    while (
$row mysql_fetch_assoc($result))
    {
        
$context['board_activity'][$row['ID_BOARD']] = array(
            
'id' => $ID_BOARD,
            
'href' => $scripturl '?board=' $row['ID_BOARD'] . '.0',
            
'link' => '<a href="' $scripturl '?board=' $row['ID_BOARD'] . '.0">' $row['name'] . '</a>',
            
'percent' => $row['percentage'],
        );
    }
    
mysql_free_result($result);

    
// Posting activity by time.
    
$result db_query("
        SELECT
            HOUR(FROM_UNIXTIME(posterTime + " 
. (($user_info['time_offset'] + $modSettings['time_offset']) * 3600) . ")) AS hour,
            COUNT(*) AS postCount
        FROM 
{$db_prefix}messages
        WHERE ID_MEMBER = 
$memID. ($modSettings['totalMessages'] > 100000 "
            AND ID_TOPIC > " 
. ($modSettings['totalTopics'] - 10000) : '') . "
        GROUP BY hour"
__FILE____LINE__);
    
$maxPosts 0;
    
$context['posts_by_time'] = array();
    while (
$row mysql_fetch_assoc($result))
    {
        if (
$row['postCount'] > $maxPosts)
            
$maxPosts $row['postCount'];

        
$context['posts_by_time'][$row['hour']] = array(
            
'hour' => $row['hour'],
            
'posts_percent' => $row['postCount']
        );
    }
    
mysql_free_result($result);

    if (
$maxPosts 0)
        for (
$hour 0$hour 24$hour++)
        {
            if (!isset(
$context['posts_by_time'][$hour]))
                
$context['posts_by_time'][$hour] = array(
                    
'hour' => $hour,
                    
'posts_percent' => 0,
                );
            else
                
$context['posts_by_time'][$hour]['posts_percent'] = round(($context['posts_by_time'][$hour]['posts_percent'] * 100) / $maxPosts);
        }

    
// Put it in the right order.
    
ksort($context['posts_by_time']);
}

function 
trackUser($memID)
{
    global 
$scripturl$txt$db_prefix$modSettings;
    global 
$user_profile$context;

    
// Verify if the user has sufficient permissions.
    
isAllowedTo('moderate_forum');

    
$context['page_title'] = $txt['trackUser'] . ' - ' $user_profile[$memID]['realName'];

    
$context['last_ip'] = $user_profile[$memID]['memberIP'];
    
$context['member']['name'] = $user_profile[$memID]['realName'];

    
// If this is a big forum, or a large posting user, let's limit the search.
    
if ($modSettings['totalMessages'] > 50000 && $user_profile[$memID]['posts'] > 500)
    {
        
$request db_query("
            SELECT MAX(ID_MSG)
            FROM 
{$db_prefix}messages AS m
            WHERE m.ID_MEMBER = 
$memID"__FILE____LINE__);
        list (
$max_msg_member) = mysql_fetch_row($request);
        
mysql_free_result($request);

        
// There's no point worrying ourselves with messages made yonks ago, just get recent ones!
        
$min_msg_member max(0$max_msg_member $user_profile[$memID]['posts'] * 3);
    }

    
// Default to at least the ones we know about.
    
$ips = array(
        
$user_profile[$memID]['memberIP'],
        
$user_profile[$memID]['memberIP2'],
    );

    
// Get all IP addresses this user has used for his messages.
    
$request db_query("
        SELECT posterIP
        FROM 
{$db_prefix}messages
        WHERE ID_MEMBER = 
$memID
        " 
. (isset($min_msg_member) ? "
            AND ID_MSG >= 
$min_msg_member AND ID_MSG <= $max_msg_member'') . "
        GROUP BY posterIP"
__FILE____LINE__);
    
$context['ips'] = array();
    while (
$row mysql_fetch_assoc($request))
    {
        
$context['ips'][] = '<a href="' $scripturl '?action=trackip;searchip=' $row['posterIP'] . '">' $row['posterIP'] . '</a>';
        
$ips[] = $row['posterIP'];
    }
    
mysql_free_result($request);

    
// Now also get the IP addresses from the error messages.
    
$request db_query("
        SELECT COUNT(*) AS errorCount, ip
        FROM 
{$db_prefix}log_errors
        WHERE ID_MEMBER = 
$memID
        GROUP BY ip"
__FILE____LINE__);
    
$context['error_ips'] = array();
    
$totalErrors 0;
    while (
$row mysql_fetch_assoc($request))
    {
        
$context['error_ips'][] = '<a href="' $scripturl '?action=trackip;searchip=' $row['ip'] . '">' $row['ip'] . '</a>';
        
$ips[] = $row['ip'];
        
$totalErrors += $row['errorCount'];
    }
    
mysql_free_result($request);

    
// Create the page indexes.
    
$context['page_index'] = constructPageIndex($scripturl '?action=profile;u=' $memID ';sa=trackUser'$_REQUEST['start'], $totalErrors20);
    
$context['start'] = $_REQUEST['start'];

    
// Get a list of error messages from this ip (range).
    
$request db_query("
        SELECT
            le.logTime, le.ip, le.url, le.message, IFNULL(mem.ID_MEMBER, 0) AS ID_MEMBER,
            IFNULL(mem.realName, '
$txt[28]') AS display_name, mem.memberName
        FROM 
{$db_prefix}log_errors AS le
            LEFT JOIN 
{$db_prefix}members AS mem ON (mem.ID_MEMBER = le.ID_MEMBER)
        WHERE le.ID_MEMBER = 
$memID
        ORDER BY le.ID_ERROR DESC
        LIMIT 
$context[start], 20"__FILE____LINE__);
    
$context['error_messages'] = array();
    while (
$row mysql_fetch_assoc($request))
        
$context['error_messages'][] = array(
            
'ip' => $row['ip'],
            
'message' => strtr($row['message'], array('&lt;span class=&quot;remove&quot;&gt;' => '''&lt;/span&gt;' => '')),
            
'url' => $row['url'],
            
'time' => timeformat($row['logTime']),
            
'timestamp' => forum_time(true$row['logTime'])
        );
    
mysql_free_result($request);

    
// Find other users that might use the same IP.
    
$ips array_unique($ips);
    
$context['members_in_range'] = array();
    if (!empty(
$ips))
    {
        
$request db_query("
            SELECT ID_MEMBER, realName
            FROM 
{$db_prefix}members
            WHERE ID_MEMBER != 
$memID
                AND memberIP IN ('" 
implode("', '"$ips) . "')"__FILE____LINE__);
        if (
mysql_num_rows($request) > 0)
            while (
$row mysql_fetch_assoc($request))
                
$context['members_in_range'][$row['ID_MEMBER']] = '<a href="' $scripturl '?action=profile;u=' $row['ID_MEMBER'] . '">' $row['realName'] . '</a>';
        
mysql_free_result($request);

        
$request db_query("
            SELECT mem.ID_MEMBER, mem.realName
            FROM (
{$db_prefix}messages AS m, {$db_prefix}members AS mem)
            WHERE mem.ID_MEMBER = m.ID_MEMBER
                AND mem.ID_MEMBER != 
$memID
                AND m.posterIP IN ('" 
implode("', '"$ips) . "')"__FILE____LINE__);
        if (
mysql_num_rows($request) > 0)
            while (
$row mysql_fetch_assoc($request))
                
$context['members_in_range'][$row['ID_MEMBER']] = '<a href="' $scripturl '?action=profile;u=' $row['ID_MEMBER'] . '">' $row['realName'] . '</a>';
        
mysql_free_result($request);
    }
}

function 
TrackIP($memID 0)
{
    global 
$user_profile$scripturl$txt$user_info;
    global 
$db_prefix$context;

    
// Can the user do this?
    
isAllowedTo('moderate_forum');

    if (
$memID == 0)
    {
        
$context['ip'] = isset($_REQUEST['searchip']) ? trim($_REQUEST['searchip']) : $user_info['ip'];
        
loadTemplate('Profile');
        
loadLanguage('Profile');
        
$context['sub_template'] = 'trackIP';
        
$context['page_title'] = $txt[79];
    }
    else
        
$context['ip'] = $user_profile[$memID]['memberIP'];

    if (
preg_match('/^\d{1,3}\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)$/'$context['ip']) == 0)
        
fatal_error($txt['invalid_ip'], false);

    
$dbip str_replace('*''%'$context['ip']);
    
$dbip strpos($dbip'%') === false "= '$dbip'" "LIKE '$dbip'";

    
$context['page_title'] = $txt['trackIP'] . ' - ' $context['ip'];

    
// Get some totals for pagination.
    
$request db_query("
        SELECT COUNT(*)
        FROM 
{$db_prefix}messages AS m
            INNER JOIN 
{$db_prefix}boards AS b ON (b.ID_BOARD = m.ID_BOARD)
        WHERE 
$user_info[query_see_board]
            AND m.posterIP 
$dbip"__FILE____LINE__);
    list (
$totalMessages) = mysql_fetch_row($request);
    
mysql_free_result($request);
    
$request db_query("
        SELECT COUNT(*)
        FROM 
{$db_prefix}log_errors
        WHERE ip 
$dbip"__FILE____LINE__);
    list (
$totalErrors) = mysql_fetch_row($request);
    
mysql_free_result($request);

    
$context['message_start'] = isset($_GET['mesStart']) ? (int) $_GET['mesStart'] : 0;
    
$context['error_start'] = isset($_GET['errStart']) ? $_GET['errStart'] : 0;
    
$context['message_page_index'] = constructPageIndex($scripturl '?action=' . ($memID == 'trackip;searchip=' $context['ip'] : 'profile;u=' $memID ';sa=trackIP') . ';mesStart=%d;errStart=' $context['error_start'], $context['message_start'], $totalMessages20true);
    
$context['error_page_index'] = constructPageIndex($scripturl '?action=' . ($memID == 'trackip;searchip=' $context['ip'] : 'profile;u=' $memID ';sa=trackIP') . ';mesStart=' $context['message_start'] . ';errStart=%d'$context['error_start'], $totalErrors20true);

    
$request db_query("
        SELECT ID_MEMBER, realName AS display_name, memberIP
        FROM 
{$db_prefix}members
        WHERE memberIP 
$dbip"__FILE____LINE__);
    
$context['ips'] = array();
    while (
$row mysql_fetch_assoc($request))
        
$context['ips'][$row['memberIP']][] = '<a href="' $scripturl '?action=profile;u=' $row['ID_MEMBER'] . '">' $row['display_name'] . '</a>';
    
mysql_free_result($request);

    
ksort($context['ips']);

    
// !!!SLOW This query is using a filesort.
    
$request db_query("
        SELECT
            m.ID_MSG, m.posterIP, IFNULL(mem.realName, m.posterName) AS display_name, mem.ID_MEMBER,
            m.subject, m.posterTime, m.ID_TOPIC, m.ID_BOARD
        FROM 
{$db_prefix}messages AS m
            INNER JOIN 
{$db_prefix}boards AS b ON (b.ID_BOARD = m.ID_BOARD)
            LEFT JOIN 
{$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)
        WHERE 
$user_info[query_see_board]
            AND m.posterIP 
$dbip
        ORDER BY m.ID_MSG DESC
        LIMIT 
$context[message_start], 20"__FILE____LINE__);
    
$context['messages'] = array();
    while (
$row mysql_fetch_assoc($request))
        
$context['messages'][] = array(
            
'ip' => $row['posterIP'],
            
'member' => array(
                
'id' => $row['ID_MEMBER'],
                
'name' => $row['display_name'],
                
'href' => $scripturl '?action=profile;u=' $row['ID_MEMBER'],
                
'link' => empty($row['ID_MEMBER']) ? $row['display_name'] : '<a href="' $scripturl '?action=profile;u=' $row['ID_MEMBER'] . '">' $row['display_name'] . '</a>'
            
),
            
'board' => array(
                
'id' => $row['ID_BOARD'],
                
'href' => $scripturl '?board=' $row['ID_BOARD']
            ),
            
'topic' => $row['ID_TOPIC'],
            
'id' => $row['ID_MSG'],
            
'subject' => $row['subject'],
            
'time' => timeformat($row['posterTime']),
            
'timestamp' => forum_time(true$row['posterTime'])
        );
    
mysql_free_result($request);

    
// !!!SLOW This query is using a filesort.
    
$request db_query("
        SELECT
            le.logTime, le.ip, le.url, le.message, IFNULL(mem.ID_MEMBER, 0) AS ID_MEMBER,
            IFNULL(mem.realName, '
$txt[28]') AS display_name, mem.memberName
        FROM 
{$db_prefix}log_errors AS le
            LEFT JOIN 
{$db_prefix}members AS mem ON (mem.ID_MEMBER = le.ID_MEMBER)
        WHERE le.ip 
$dbip
        ORDER BY le.ID_ERROR DESC
        LIMIT 
$context[error_start], 20"__FILE____LINE__);
    
$context['error_messages'] = array();
    while (
$row mysql_fetch_assoc($request))
        
$context['error_messages'][] = array(
            
'ip' => $row['ip'],
            
'member' => array(
                
'id' => $row['ID_MEMBER'],
                
'name' => $row['display_name'],
                
'href' => $row['ID_MEMBER'] > $scripturl '?action=profile;u=' $row['ID_MEMBER'] : '',
                
'link' => $row['ID_MEMBER'] > '<a href="' $scripturl '?action=profile;u=' $row['ID_MEMBER'] . '">' $row['display_name'] . '</a>' $row['display_name']
            ),
            
'message' => strtr($row['message'], array('&lt;span class=&quot;remove&quot;&gt;' => '''&lt;/span&gt;' => '')),
            
'url' => $row['url'],
            
'error_time' => timeformat($row['logTime'])
        );
    
mysql_free_result($request);

    
$context['single_ip'] = strpos($context['ip'], '*') === false;
    if (
$context['single_ip'])
    {
        
$context['whois_servers'] = array(
            
'afrinic' => array(
                
'name' => &$txt['whois_afrinic'],
                
'url' => 'http://www.afrinic.net/cgi-bin/whois?searchtext=' $context['ip'],
                
'range' => array(),
            ),
            
'apnic' => array(
                
'name' => &$txt['whois_apnic'],
                
'url' => 'http://wq.apnic.net/apnic-bin/whois.pl?searchtext=' $context['ip'],
                
'range' => array(58596061124125126202203210211218219220221222),
            ),
            
'arin' => array(
                
'name' => &$txt['whois_arin'],
                
'url' => 'http://ws.arin.net/whois/?queryinput=' $context['ip'],
                
'range' => array(63646566676869707172199204205206207208209216),
            ),
            
'lacnic' => array(
                
'name' => &$txt['whois_lacnic'],
                
'url' => 'http://lacnic.net/cgi-bin/lacnic/whois?query=' $context['ip'],
                
'range' => array(200201),
            ),
            
'ripe' => array(
                
'name' => &$txt['whois_ripe'],
                
'url' => 'http://www.db.ripe.net/whois?searchtext=' $context['ip'],
                
'range' => array(62808182838485868788193194195212213217),
            ),
        );

        foreach (
$context['whois_servers'] as $whois)
        {
            
// Strip off the "decimal point" and anything following...
            
if (in_array((int) $context['ip'], $whois['range']))
                
$context['auto_whois_server'] = $whois;
        }
    }
}

function 
showPermissions($memID)
{
    global 
$scripturl$txt$db_prefix$board$modSettings;
    global 
$user_profile$context$user_info;

    
// Verify if the user has sufficient permissions.
    
isAllowedTo('manage_permissions');

    
loadLanguage('ManagePermissions');
    
loadLanguage('Admin');
    
loadTemplate('ManageMembers');

    
$context['member']['id'] = $memID;
    
$context['member']['name'] = $user_profile[$memID]['realName'];

    
$context['page_title'] = $txt['showPermissions'];
    
$board = empty($board) ? : (int) $board;
    
$context['board'] = $board;

    
// Determine which groups this user is in.
    
if (empty($user_profile[$memID]['additionalGroups']))
        
$curGroups = array();
    else
        
$curGroups explode(','$user_profile[$memID]['additionalGroups']);
    
$curGroups[] = $user_profile[$memID]['ID_GROUP'];
    
$curGroups[] = $user_profile[$memID]['ID_POST_GROUP'];

    
// Load a list of boards for the jump box (but only those that have separate local permissions).
    
$request db_query("
        SELECT b.ID_BOARD, b.name, b.permission_mode, b.memberGroups, b.permission_mode != 0 OR mods.ID_MEMBER IS NOT NULL AS show_board
        FROM 
{$db_prefix}boards AS b
            LEFT JOIN 
{$db_prefix}moderators AS mods ON (mods.ID_BOARD = b.ID_BOARD AND mods.ID_MEMBER = $memID)
        WHERE 
$user_info[query_see_board]"__FILE____LINE__);
    
$context['boards'] = array();
    
$context['no_access_boards'] = array();
    while (
$row mysql_fetch_assoc($request))
    {
        if (
count(array_intersect($curGroupsexplode(','$row['memberGroups']))) === 0)
            
$context['no_access_boards'][] = array(
                
'id' => $row['ID_BOARD'],
                
'name' => $row['name'],
                
'is_last' => false,
            );
        elseif (!empty(
$row['show_board']))
            
$context['boards'][$row['ID_BOARD']] = array(
                
'id' => $row['ID_BOARD'],
                
'name' => $row['name'],
                
'selected' => $board == $row['ID_BOARD'],
                
'permission_mode' => $row['permission_mode'],
            );
    }
    
mysql_free_result($request);

    if (!empty(
$context['no_access_boards']))
        
$context['no_access_boards'][count($context['no_access_boards']) - 1]['is_last'] = true;

    
$context['member']['permissions'] = array(
        
'general' => array(),
        
'board' => array()
    );

    
// If you're an admin we know you can do everything, we might as well leave.
    
$context['member']['has_all_permissions'] = in_array(1$curGroups);
    if (
$context['member']['has_all_permissions'])
        return;

    
$denied = array();

    
// Get all general permissions.
    
$result db_query("
        SELECT p.permission, p.addDeny, mg.groupName, p.ID_GROUP
        FROM 
{$db_prefix}permissions AS p
            LEFT JOIN 
{$db_prefix}membergroups AS mg ON (mg.ID_GROUP = p.ID_GROUP)
        WHERE p.ID_GROUP IN (" 
implode(', '$curGroups) . ")
        ORDER BY p.addDeny DESC, p.permission, mg.minPosts, IF(mg.ID_GROUP < 4, mg.ID_GROUP, 4), mg.groupName"
__FILE____LINE__);
    while (
$row mysql_fetch_assoc($result))
    {
        
// We don't know about this permission, it doesn't exist :P.
        
if (!isset($txt['permissionname_' $row['permission']]))
            continue;

        if (empty(
$row['addDeny']))
            
$denied[] = $row['permission'];

        
// Permissions that end with _own or _any consist of two parts.
        
if (in_array(substr($row['permission'], -4), array('_own''_any')) && isset($txt['permissionname_' substr($row['permission'], 0, -4)]))
            
$name $txt['permissionname_' substr($row['permission'], 0, -4)] . ' - ' $txt['permissionname_' $row['permission']];
        else
            
$name $txt['permissionname_' $row['permission']];

        
// Add this permission if it doesn't exist yet.
        
if (!isset($context['member']['permissions']['general'][$row['permission']]))
            
$context['member']['permissions']['general'][$row['permission']] = array(
                
'id' => $row['permission'],
                
'groups' => array(
                    
'allowed' => array(),
                    
'denied' => array()
                ),
                
'name' => $name,
                
'is_denied' => false,
                
'is_global' => true,
            );

        
// Add the membergroup to either the denied or the allowed groups.
        
$context['member']['permissions']['general'][$row['permission']]['groups'][empty($row['addDeny']) ? 'denied' 'allowed'][] = $row['ID_GROUP'] == $txt['membergroups_members'] : $row['groupName'];

        
// Once denied is always denied.
        
$context['member']['permissions']['general'][$row['permission']]['is_denied'] |= empty($row['addDeny']);
    }
    
mysql_free_result($result);

    
$request db_query("
        SELECT
            bp.addDeny, bp.permission, bp.ID_GROUP, mg.groupName" 
. (empty($board) ? '' ',
            b.permission_mode, IF(mods.ID_MEMBER IS NULL, 0, 1) AS is_moderator'
) . "
        FROM (
{$db_prefix}board_permissions AS bp" . (empty($board) ? ')' ", {$db_prefix}boards AS b)
            LEFT JOIN 
{$db_prefix}moderators AS mods ON (mods.ID_BOARD = b.ID_BOARD AND mods.ID_MEMBER = $memID)") . "
            LEFT JOIN 
{$db_prefix}membergroups AS mg ON (mg.ID_GROUP = bp.ID_GROUP)
        WHERE bp.ID_BOARD = " 
. (empty($modSettings['permission_enable_by_board']) || empty($board) ? '0' 'IF(b.permission_mode = 1, b.ID_BOARD, 0)') . "
            AND bp.ID_GROUP IN (" 
implode(', '$curGroups) . "" . (empty($board) ? ')' ", 3)
            AND b.ID_BOARD = 
$board
            AND (mods.ID_MEMBER IS NOT NULL OR bp.ID_GROUP != 3)"
), __FILE____LINE__);

    while (
$row mysql_fetch_assoc($request))
    {
        
// We don't know about this permission, it doesn't exist :P.
        
if (!isset($txt['permissionname_' $row['permission']]))
            continue;

        
// Filter these special cases of board permissions out.
        
if (empty($modSettings['permission_enable_by_board']) && !empty($board) && $row['ID_GROUP'] != 3)
        {
            if (
in_array($row['permission'], array('post_reply_own''post_reply_any')) && $row['permission_mode'] == 4)
                continue;
            elseif (
$row['permission'] == 'post_new' && $row['permission_mode'] >= 3)
                continue;
            elseif (
$row['permission'] == 'poll_post' && $row['permission_mode'] >= 2)
                continue;
        }

        
// The name of the permission using the format 'permission name' - 'own/any topic/event/etc.'.
        
if (in_array(substr($row['permission'], -4), array('_own''_any')) && isset($txt['permissionname_' substr($row['permission'], 0, -4)]))
            
$name $txt['permissionname_' substr($row['permission'], 0, -4)] . ' - ' $txt['permissionname_' $row['permission']];
        else
            
$name $txt['permissionname_' $row['permission']];

        
// Create the structure for this permission.
        
if (!isset($context['member']['permissions']['board'][$row['permission']]))
            
$context['member']['permissions']['board'][$row['permission']] = array(
                
'id' => $row['permission'],
                
'groups' => array(
                    
'allowed' => array(),
                    
'denied' => array()
                ),
                
'name' => $name,
                
'is_denied' => false,
                
'is_global' => empty($board),
            );

        
$context['member']['permissions']['board'][$row['permission']]['groups'][empty($row['addDeny']) ? 'denied' 'allowed'][$row['ID_GROUP']] = $row['ID_GROUP'] == $txt['membergroups_members'] : $row['groupName'];

        
$context['member']['permissions']['board'][$row['permission']]['is_denied'] |= empty($row['addDeny']);
    }
    
mysql_free_result($request);
}

function 
account($memID)
{
    global 
$context$settings$user_profile$txt$db_prefix;
    global 
$scripturl$membergroups$modSettings$language$user_info;
    global 
$func;

    
// Allow an administrator to edit the username?
    
$context['allow_edit_username'] = isset($_GET['changeusername']) && allowedTo('admin_forum');

    
// You might be allowed to only assign the membergroups, so let's check.
    
$context['allow_edit_membergroups'] = allowedTo('manage_membergroups');
    
$context['allow_edit_account'] = ($context['user']['is_owner'] && allowedTo('profile_identity_own')) || allowedTo('profile_identity_any');

    
// How about their email address... online status, and name?
    
$context['allow_hide_email'] = !empty($modSettings['allow_hideEmail']) || allowedTo('moderate_forum');
    
$context['allow_hide_online'] = !empty($modSettings['allow_hideOnline']) || allowedTo('moderate_forum');
    
$context['allow_edit_name'] = !empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum');

    
// Load up the existing contextual data.
    
$context['member'] += array(
        
'is_admin' => !empty($user_profile[$memID]['ID_GROUP']) && $user_profile[$memID]['ID_GROUP'] == 1,
        
'secret_question' => !isset($user_profile[$memID]['secretQuestion']) ? '' $user_profile[$memID]['secretQuestion'],
    );

    
// You need 'manage membergroups' permission for this.
    
if ($context['allow_edit_membergroups'])
    {
        
$context['member_groups'] = array(
            
=> array(
                
'id' => 0,
                
'name' => &$txt['no_primary_membergroup'],
                
'is_primary' => $user_profile[$memID]['ID_GROUP'] == 0,
                
'can_be_additional' => false,
            )
        );
        
$curGroups explode(','$user_profile[$memID]['additionalGroups']);

        
// Load membergroups, but only those groups the user can assign.
        
$request db_query("
            SELECT groupName, ID_GROUP
            FROM 
{$db_prefix}membergroups
            WHERE ID_GROUP != 3
                AND minPosts = -1
            ORDER BY minPosts, IF(ID_GROUP < 4, ID_GROUP, 4), groupName"
__FILE____LINE__);
        while (
$row mysql_fetch_assoc($request))
        {
            
// We should skip the administrator group if they don't have the admin_forum permission!
            
if ($row['ID_GROUP'] == && !allowedTo('admin_forum'))
                continue;

            
$context['member_groups'][$row['ID_GROUP']] = array(
                
'id' => $row['ID_GROUP'],
                
'name' => $row['groupName'],
                
'is_primary' => $user_profile[$memID]['ID_GROUP'] == $row['ID_GROUP'],
                
'is_additional' => in_array($row['ID_GROUP'], $curGroups),
                
'can_be_additional' => true,
            );
        }
        
mysql_free_result($request);
    }

    
// Are languages user selectable?  If so, get a list.
    
$context['languages'] = array();
    if (
$context['allow_edit_account'] && !empty($modSettings['userLanguage']))
    {
        
// Select the default language if the user has no language selected yet.
        
$selectedLanguage = empty($user_profile[$memID]['lngfile']) ? $language $user_profile[$memID]['lngfile'];

        
$language_directories = array(
            
$settings['default_theme_dir'] . '/languages',
            
$settings['actual_theme_dir'] . '/languages',
        );
        if (!empty(
$settings['base_theme_dir']))
            
$language_directories[] = $settings['base_theme_dir'] . '/languages';
        
$language_directories array_unique($language_directories);

        foreach (
$language_directories as $language_dir)
        {
            if (!
file_exists($language_dir))
                continue;

            
$dir dir($language_dir);
            while (
$entry $dir->read())
            {
                
// Each language file must *at least* have a 'index.LANGUAGENAME.php' file.
                
if (preg_match('~^index\.(.+)\.php$~'$entry$matches) == 0)
                    continue;

                
$context['languages'][$matches[1]] = array(
                    
'name' => $func['ucwords'](strtr($matches[1], array('_' => ' ''-utf8' => ''))),
                    
'selected' => $selectedLanguage == $matches[1],
                    
'filename' => $matches[1],
                );
            }
            
$dir->close();
        }
    }

    
loadThemeOptions($memID);
}

function 
forumProfile($memID)
{
    global 
$context$user_profile;
    global 
$user_info$txt$ID_MEMBER$modSettings;

    
$context['avatar_url'] = $modSettings['avatar_url'];
    
$context['max_signature_length'] = $modSettings['max_signatureLength'];
    
$context['allow_edit_title'] = allowedTo('profile_title_any') || (allowedTo('profile_title_own') && $context['user']['is_owner']);

    
$context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');

    
$context['member'] += array(
        
'birth_date' => empty($user_profile[$memID]['birthdate']) || $user_profile[$memID]['birthdate'] === '0001-01-01' '0000-00-00' : (substr($user_profile[$memID]['birthdate'], 04) === '0004' '0000' substr($user_profile[$memID]['birthdate'], 4) : $user_profile[$memID]['birthdate']),
        
'location' => !isset($user_profile[$memID]['location']) ? '' $user_profile[$memID]['location'],
        
'title' => !isset($user_profile[$memID]['usertitle']) || $user_profile[$memID]['usertitle'] == '' '' $user_profile[$memID]['usertitle'],
        
'blurb' => !isset($user_profile[$memID]['personalText']) ? '' str_replace(array('<''>''&amp;#039;'), array('&lt;''&gt;''&#039;'), $user_profile[$memID]['personalText']),
        
'signature' => !isset($user_profile[$memID]['signature']) ? '' str_replace(array('<br />''<''>''"''\''), array("\n"'&lt;''&gt;''&quot;''&#039;'), $user_profile[$memID]['signature']),
    );

    
// Split up the birthdate....
    
list ($uyear$umonth$uday) = explode('-'$context['member']['birth_date']);
    
$context['member']['birth_date'] = array(
        
'year' => $uyear,
        
'month' => $umonth,
        
'day' => $uday
    
);

    if (
$user_profile[$memID]['avatar'] == '' && $user_profile[$memID]['ID_ATTACH'] > && $context['member']['avatar']['allow_upload'])
        
$context['member']['avatar'] += array(
            
'choice' => 'upload',
            
'server_pic' => 'blank.gif',
            
'external' => 'http://'
        
);
    elseif (
stristr($user_profile[$memID]['avatar'], 'http://') && $context['member']['avatar']['allow_external'])
        
$context['member']['avatar'] += array(
            
'choice' => 'external',
            
'server_pic' => 'blank.gif',
            
'external' => $user_profile[$memID]['avatar']
        );
    elseif (
file_exists($modSettings['avatar_directory'] . '/' $user_profile[$memID]['avatar']) && $context['member']['avatar']['allow_server_stored'])
        
$context['member']['avatar'] += array(
            
'choice' => 'server_stored',
            
'server_pic' => $user_profile[$memID]['avatar'] == '' 'blank.gif' $user_profile[$memID]['avatar'],
            
'external' => 'http://'
        
);
    else
        
$context['member']['avatar'] += array(
            
'choice' => 'server_stored',
            
'server_pic' => 'blank.gif',
            
'external' => 'http://'
        
);

    
// Get a list of all the avatars.
    
if ($context['member']['avatar']['allow_server_stored'])
    {
        
$context['avatar_list'] = array();
        
$context['avatars'] = is_dir($modSettings['avatar_directory']) ? getAvatars(''0) : array();
    }
    else
        
$context['avatars'] = array();

    
// Second level selected avatar...
    
$context['avatar_selected'] = substr(strrchr($context['member']['avatar']['server_pic'], '/'), 1);

    
loadThemeOptions($memID);
}

// Recursive function to retrieve avatar files
function getAvatars($directory$level)
{
    global 
$context$txt$modSettings;

    
$result = array();

    
// Open the directory..
    
$dir dir($modSettings['avatar_directory'] . (!empty($directory) ? '/' '') . $directory);
    
$dirs = array();
    
$files = array();

    if (!
$dir)
        return array();

    while (
$line $dir->read())
    {
        if (
in_array($line, array('.''..''blank.gif''index.php')))
            continue;

        if (
is_dir($modSettings['avatar_directory'] . '/' $directory . (!empty($directory) ? '/' '') . $line))
            
$dirs[] = $line;
        else
            
$files[] = $line;
    }
    
$dir->close();

    
// Sort the results...
    
natcasesort($dirs);
    
natcasesort($files);

    if (
$level == 0)
    {
        
$result[] = array(
            
'filename' => 'blank.gif',
            
'checked' => in_array($context['member']['avatar']['server_pic'], array('''blank.gif')),
            
'name' => &$txt[422],
            
'is_dir' => false
        
);
    }

    foreach (
$dirs as $line)
    {
        
$tmp getAvatars($directory . (!empty($directory) ? '/' '') . $line$level 1);
        if (!empty(
$tmp))
            
$result[] = array(
                
'filename' => htmlspecialchars($line),
                
'checked' => strpos($context['member']['avatar']['server_pic'], $line '/') !== false,
                
'name' => '[' htmlspecialchars(str_replace('_'' '$line)) . ']',
                
'is_dir' => true,
                
'files' => $tmp
        
);
        unset(
$tmp);
    }

    foreach (
$files as $line)
    {
        
$filename substr($line0, (strlen($line) - strlen(strrchr($line'.'))));
        
$extension substr(strrchr($line'.'), 1);

        
// Make sure it is an image.
        
if (strcasecmp($extension'gif') != && strcasecmp($extension'jpg') != && strcasecmp($extension'jpeg') != && strcasecmp($extension'png') != && strcasecmp($extension'bmp') != 0)
            continue;

        
$result[] = array(
            
'filename' => htmlspecialchars($line),
            
'checked' => $line == $context['member']['avatar']['server_pic'],
            
'name' => htmlspecialchars(str_replace('_'' '$filename)),
            
'is_dir' => false
        
);
        if (
$level == 1)
            
$context['avatar_list'][] = $directory '/' $line;
    }

    return 
$result;
}

function 
theme($memID)
{
    global 
$txt$context$user_profile$db_prefix$modSettings$settings$user_info;

    
$request db_query("
        SELECT value
        FROM 
{$db_prefix}themes
        WHERE ID_THEME = " 
. (int) $user_profile[$memID]['ID_THEME'] . "
            AND variable = 'name'
        LIMIT 1"
__FILE____LINE__);
    list (
$name) = mysql_fetch_row($request);
    
mysql_free_result($request);

    
$context['member'] += array(
        
'theme' => array(
            
'id' => $user_profile[$memID]['ID_THEME'],
            
'name' => empty($user_profile[$memID]['ID_THEME']) ? $txt['theme_forum_default'] : $name
        
),
        
'smiley_set' => array(
            
'id' => empty($user_profile[$memID]['smileySet']) ? '' $user_profile[$memID]['smileySet']
        ),
        
'time_format' => !isset($user_profile[$memID]['timeFormat']) ? '' $user_profile[$memID]['timeFormat'],
        
'time_offset' => empty($user_profile[$memID]['timeOffset']) ? '0' $user_profile[$memID]['timeOffset'],
    );

    
$context['easy_timeformats'] = array(
        array(
'format' => '''title' => $txt['timeformat_easy0']),
        array(
'format' => '%B %d, %Y, %I:%M:%S %p''title' => $txt['timeformat_easy1']),
        array(
'format' => '%B %d, %Y, %H:%M:%S''title' => $txt['timeformat_easy2']),
        array(
'format' => '%Y-%m-%d, %H:%M:%S''title' => $txt['timeformat_easy3']),
        array(
'format' => '%d %B %Y, %H:%M:%S''title' => $txt['timeformat_easy4']),
        array(
'format' => '%d-%m-%Y, %H:%M:%S''title' => $txt['timeformat_easy5'])
    );

    
$context['current_forum_time'] = timeformat(time() - $user_info['time_offset'] * 3600false);
    
$context['current_forum_time_hour'] = (int) strftime('%H'forum_time(false));

    
$context['smiley_sets'] = explode(',''none,,' $modSettings['smiley_sets_known']);
    
$set_names explode("\n"$txt['smileys_none'] . "\n" $txt['smileys_forum_board_default'] . "\n" $modSettings['smiley_sets_names']);
    foreach (
$context['smiley_sets'] as $i => $set)
    {
        
$context['smiley_sets'][$i] = array(
            
'id' => htmlspecialchars($set),
            
'name' => htmlspecialchars($set_names[$i]),
            
'selected' => $set == $context['member']['smiley_set']['id']
        );

        if (
$context['smiley_sets'][$i]['selected'])
            
$context['member']['smiley_set']['name'] = htmlspecialchars($set_names[$i]);
    }

    
loadThemeOptions($memID);

    
loadLanguage('Settings');
}

// Display the notifications and settings for changes.
function notification($memID)
{
    global 
$txt$db_prefix$scripturl$user_profile$user_info$context$ID_MEMBER$modSettings;

    
// All the boards with notification on..
    
$request db_query("
        SELECT b.ID_BOARD, b.name, IFNULL(lb.ID_MSG, 0) AS boardRead, b.ID_MSG_UPDATED
        FROM (
{$db_prefix}log_notify AS ln, {$db_prefix}boards AS b)
            LEFT JOIN 
{$db_prefix}log_boards AS lb ON (lb.ID_BOARD = b.ID_BOARD AND lb.ID_MEMBER = $ID_MEMBER)
        WHERE ln.ID_MEMBER = 
$memID
            AND b.ID_BOARD = ln.ID_BOARD
            AND 
$user_info[query_see_board]
        ORDER BY b.boardOrder"
__FILE____LINE__);
    
$context['board_notifications'] = array();
    while (
$row mysql_fetch_assoc($request))
        
$context['board_notifications'][] = array(
            
'id' => $row['ID_BOARD'],
            
'name' => $row['name'],
            
'href' => $scripturl '?board=' $row['ID_BOARD'] . '.0',
            
'link' => '<a href="' $scripturl '?board=' $row['ID_BOARD'] . '.0">' $row['name'] . '</a>',
            
'new' => $row['boardRead'] < $row['ID_MSG_UPDATED']
        );
    
mysql_free_result($request);

    
$request db_query("
        SELECT COUNT(*)
        FROM (
{$db_prefix}log_notify AS ln, {$db_prefix}boards AS b, {$db_prefix}topics AS t)
        WHERE ln.ID_MEMBER = 
$memID
            AND t.ID_TOPIC = ln.ID_TOPIC
            AND b.ID_BOARD = t.ID_BOARD
            AND 
$user_info[query_see_board]"__FILE____LINE__);
    list (
$num_topics) = mysql_fetch_row($request);
    
mysql_free_result($request);

    
$context['page_index'] = constructPageIndex($scripturl '?action=profile;u=' $memID ';sa=notification'$_REQUEST['start'], $num_topics$modSettings['defaultMaxMessages']);

    
// All the topics with notification on...
    
$request db_query("
        SELECT
            IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, -1)) + 1 AS new_from, b.ID_BOARD, b.name,
            t.ID_TOPIC, ms.subject, ms.ID_MEMBER, IFNULL(mem.realName, ms.posterName) AS realName,
            ml.ID_MSG_MODIFIED
        FROM (
{$db_prefix}log_notify AS ln, {$db_prefix}boards AS b, {$db_prefix}topics AS t, {$db_prefix}messages AS ms, {$db_prefix}messages AS ml)
            LEFT JOIN 
{$db_prefix}members AS mem ON (mem.ID_MEMBER = ms.ID_MEMBER)
            LEFT JOIN 
{$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = $ID_MEMBER)
            LEFT JOIN 
{$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = b.ID_BOARD AND lmr.ID_MEMBER = $ID_MEMBER)
        WHERE ln.ID_MEMBER = 
$memID
            AND t.ID_TOPIC = ln.ID_TOPIC
            AND ms.ID_MSG = t.ID_FIRST_MSG
            AND ml.ID_MSG = t.ID_LAST_MSG
            AND b.ID_BOARD = t.ID_BOARD
            AND 
$user_info[query_see_board]
        ORDER BY ms.ID_MSG DESC
        LIMIT 
$_REQUEST[start]$modSettings[defaultMaxMessages]"__FILE____LINE__);
    
$context['topic_notifications'] = array();
    while (
$row mysql_fetch_assoc($request))
    {
        
censorText($row['subject']);

        
$context['topic_notifications'][] = array(
            
'id' => $row['ID_TOPIC'],
            
'poster' => array(
                
'id' => $row['ID_MEMBER'],
                
'name' => $row['realName'],
                
'href' => empty($row['ID_MEMBER']) ? '' $scripturl '?action=profile;u=' $row['ID_MEMBER'],
                
'link' => empty($row['ID_MEMBER']) ? $row['realName'] : '<a href="' $scripturl '?action=profile;u=' $row['ID_MEMBER'] . '">' $row['realName'] . '</a>'
            
),
            
'subject' => $row['subject'],
            
'href' => $scripturl '?topic=' $row['ID_TOPIC'] . '.0',
            
'link' => '<a href="' $scripturl '?topic=' $row['ID_TOPIC'] . '.0">' $row['subject'] . '</a>',
            
'new' => $row['new_from'] <= $row['ID_MSG_MODIFIED'],
            
'new_from' => $row['new_from'],
            
'new_href' => $scripturl '?topic=' $row['ID_TOPIC'] . '.msg' $row['new_from'] . '#new',
            
'new_link' => '<a href="' $scripturl '?topic=' $row['ID_TOPIC'] . '.msg' $row['new_from'] . '#new">' $row['subject'] . '</a>',
            
'board' => array(
                
'id' => $row['ID_BOARD'],
                
'name' => $row['name'],
                
'href' => $scripturl '?board=' $row['ID_BOARD'] . '.0',
                
'link' => '<a href="' $scripturl '?board=' $row['ID_BOARD'] . '.0">' $row['name'] . '</a>'
            
)
        );
    }
    
mysql_free_result($request);

    
// What options are set?
    
$context['member'] += array(
        
'notify_announcements' => $user_profile[$memID]['notifyAnnouncements'],
        
'notify_once' => $user_profile[$memID]['notifyOnce'],
        
'notify_send_body' => $user_profile[$memID]['notifySendBody'],
        
'notify_types' => $user_profile[$memID]['notifyTypes'],
    );

    
// How many rows can we expect?
    
$context['num_rows'] = array(
        
'topic' => count($context['topic_notifications']) + 3,
        
'board' => count($context['board_notifications']) + 2
    
);

    
loadThemeOptions($memID);
}

function 
pmprefs($memID)
{
    global 
$txt$user_profile$db_prefix$context$db_prefix;

    
// Tell the template what they are....
    
$context['send_email'] = $user_profile[$memID]['pm_email_notify'];

    if (
$user_profile[$memID]['pm_ignore_list'] != '*')
    {
        
$result db_query("
            SELECT realName
            FROM 
{$db_prefix}members
            WHERE FIND_IN_SET(ID_MEMBER, '" 
$user_profile[$memID]['pm_ignore_list'] . "')
            LIMIT " 
. (substr_count($user_profile[$memID]['pm_ignore_list'], ',') + 1), __FILE____LINE__);
        
$pm_ignore_list '';
        while (
$row mysql_fetch_assoc($result))
            
$pm_ignore_list .= "\n" $row['realName'];
        
mysql_free_result($result);

        
$pm_ignore_list substr($pm_ignore_list1);
    }
    else
        
$pm_ignore_list '*';

    
// Get all their "buddies"...
    
$result db_query("
        SELECT realName
        FROM 
{$db_prefix}members
        WHERE FIND_IN_SET(ID_MEMBER, '" 
$user_profile[$memID]['buddy_list'] . "')
        LIMIT " 
. (substr_count($user_profile[$memID]['buddy_list'], ',') + 1), __FILE____LINE__);
    
$buddy_list '';
    while (
$row mysql_fetch_assoc($result))
        
$buddy_list .= "\n" $row['realName'];
    
mysql_free_result($result);

    
$context['buddy_list'] = substr($buddy_list1);
    
$context['ignore_list'] = $pm_ignore_list;
    
$context['page_title'] = $txt['pmprefs'] . ': ' $txt[144];

    
loadThemeOptions($memID);
}

// Present a screen to make sure the user wants to be deleted
function deleteAccount($memID)
{
    global 
$txt$context$ID_MEMBER$modSettings$user_profile;

    if (!
$context['user']['is_owner'])
        
isAllowedTo('profile_remove_any');
    elseif (!
allowedTo('profile_remove_any'))
        
isAllowedTo('profile_remove_own');

    
// Permissions for removing stuff...
    
$context['can_delete_posts'] = !$context['user']['is_owner'] && allowedTo('moderate_forum');

    
// Can they do this, or will they need approval?
    
$context['needs_approval'] = $context['user']['is_owner'] && !empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum');
    
$context['page_title'] = $txt['deleteAccount'] . ': ' $user_profile[$memID]['realName'];
}

function 
deleteAccount2($profile_vars$post_errors$memID)
{
    global 
$ID_MEMBER$user_info$sourcedir$context$db_prefix$user_profile$modSettings;

    
// !!! Add a way to delete pms as well?

    
if (!$context['user']['is_owner'])
        
isAllowedTo('profile_remove_any');
    elseif (!
allowedTo('profile_remove_any'))
        
isAllowedTo('profile_remove_own');

    
checkSession();

    
$old_profile = &$user_profile[$memID];

    
// Too often, people remove/delete their own only account.
    
if (in_array(1explode(','$old_profile['additionalGroups'])) || $old_profile['ID_GROUP'] == 1)
    {
        
// Are you allowed to administrate the forum, as they are?
        
isAllowedTo('admin_forum');

        
$request db_query("
            SELECT ID_MEMBER
            FROM 
{$db_prefix}members
            WHERE (ID_GROUP = 1 OR FIND_IN_SET(1, additionalGroups))
                AND ID_MEMBER != 
$memID
            LIMIT 1"
__FILE____LINE__);
        list (
$another) = mysql_fetch_row($request);
        
mysql_free_result($request);

        if (empty(
$another))
            
fatal_lang_error('at_least_one_admin');
    }

    
// This file is needed for the deleteMembers function.
    
require_once($sourcedir '/Subs-Members.php');

    
// Do you have permission to delete others profiles, or is that your profile you wanna delete?
    
if ($memID != $ID_MEMBER)
    {
        
isAllowedTo('profile_remove_any');

        
// Now, have you been naughty and need your posts deleting?
        // !!! Should this check board permissions?
        
if ($_POST['remove_type'] != 'none' && allowedTo('moderate_forum'))
        {
            
// Include RemoveTopics - essential for this type of work!
            
require_once($sourcedir '/RemoveTopic.php');

            
// First off we delete any topics the member has started - if they wanted topics being done.
            
if ($_POST['remove_type'] == 'topics')
            {
                
// Fetch all topics started by this user within the time period.
                
$request db_query("
                    SELECT t.ID_TOPIC
                    FROM 
{$db_prefix}topics AS t
                    WHERE t.ID_MEMBER_STARTED = 
$memID"__FILE____LINE__);
                
$topicIDs = array();
                while (
$row mysql_fetch_assoc($request))
                    
$topicIDs[] = $row['ID_TOPIC'];
                
mysql_free_result($request);

                
// Actually remove the topics.
                // !!! This needs to check permissions, but we'll let it slide for now because of moderate_forum already being had.
                
removeTopics($topicIDs);
            }

            
// Now delete the remaining messages.
            
$request db_query("
                SELECT m.ID_MSG
                FROM (
{$db_prefix}messages AS m, {$db_prefix}topics AS t)
                WHERE m.ID_MEMBER = 
$memID
                    AND m.ID_TOPIC = t.ID_TOPIC
                    AND t.ID_FIRST_MSG != m.ID_MSG"
__FILE____LINE__);
            
// This could take a while... but ya know it's gonna be worth it in the end.
            
while ($row mysql_fetch_assoc($request))
                
removeMessage($row['ID_MSG']);
            
mysql_free_result($request);
        }

        
// Only delete this poor members account if they are actually being booted out of camp.
        
if (isset($_POST['deleteAccount']))
            
deleteMembers($memID);
    }
    
// Do they need approval to delete?
    
elseif (empty($post_errors) && !empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum'))
    {
        
// Setup their account for deletion ;)
        
updateMemberData($memID, array('is_activated' => 4));
        
// Another account needs approval...
        
updateSettings(array('unapprovedMembers' => true), true);
    }
    
// Also check if you typed your password correctly.
    
elseif (empty($post_errors))
        
deleteMembers($memID);
}

// This function 'remembers' the profile changes a user made after erronious input.
function rememberPostData()
{
    global 
$context$scripturl$txt$modSettings$ID_MEMBER$user_profile$user_info;

    
// Overwrite member settings with the ones you selected.
    
$context['member'] = array(
        
'is_owner' => $_REQUEST['userID'] == $ID_MEMBER,
        
'username' => $user_profile[$_REQUEST['userID']]['memberName'],
        
'name' => !isset($_POST['realName']) || $_POST['realName'] == '' $user_profile[$_REQUEST['userID']]['memberName'] : stripslashes($_POST['realName']),
        
'id' => (int) $_REQUEST['userID'],
        
'title' => !isset($_POST['usertitle']) || $_POST['usertitle'] == '' '' stripslashes($_POST['usertitle']),
        
'email' => isset($_POST['emailAddress']) ? $_POST['emailAddress'] : '',
        
'hide_email' => empty($_POST['hideEmail']) ? 1,
        
'show_online' => empty($_POST['showOnline']) ? 1,
        
'registered' => empty($_POST['dateRegistered']) || $_POST['dateRegistered'] == '0001-01-01' $txt[470] : strftime('%Y-%m-%d'$_POST['dateRegistered']),
        
'blurb' => !isset($_POST['personalText']) ? '' str_replace(array('<''>''&amp;#039;'), array('&lt;''&gt;''&#039;'), stripslashes($_POST['personalText'])),
        
'gender' => array(
            
'name' => empty($_POST['gender']) ? '' : ($_POST['gender'] == 'f' 'm')
        ),
        
'website' => array(
            
'title' => !isset($_POST['websiteTitle']) ? '' stripslashes($_POST['websiteTitle']),
            
'url' => !isset($_POST['websiteUrl']) ? '' stripslashes($_POST['websiteUrl']),
        ),
        
'birth_date' => array(
            
'month' => empty($_POST['bday1']) ? '00' : (int) $_POST['bday1'],
            
'day' => empty($_POST['bday2']) ? '00' : (int) $_POST['bday2'],
            
'year' => empty($_POST['bday3']) ? '0000' : (int) $_POST['bday3']
        ),
        
'signature' => !isset($_POST['signature']) ? '' str_replace(array('<''>'), array('&lt;''&gt;'), $_POST['signature']),
        
'location' => !isset($_POST['location']) ? '' stripslashes($_POST['location']),
        
'icq' => array(
            
'name' => !isset($_POST['icq']) ? '' stripslashes($_POST['ICQ'])
        ),
        
'aim' => array(
            
'name' => empty($_POST['aim']) ? '' str_replace('+'' '$_POST['AIM'])
        ),
        
'yim' => array(
            
'name' => empty($_POST['yim']) ? '' stripslashes($_POST['YIM'])
        ),
        
'msn' => array(
            
'name' => empty($_POST['msn']) ? '' stripslashes($_POST['MSN'])
        ),
        
'posts' => empty($_POST['posts']) ? : (int) $_POST['posts'],
        
'avatar' => array(
            
'name' => &$_POST['avatar'],
            
'href' => empty($user_profile[$_REQUEST['userID']]['ID_ATTACH']) ? '' : (empty($user_profile[$_REQUEST['userID']]['attachmentType']) ? $scripturl '?action=dlattach;attach=' $user_profile[$_REQUEST['userID']]['ID_ATTACH'] . ';type=avatar' $modSettings['custom_avatar_url'] . '/' $user_profile[$_REQUEST['userID']]['filename']),
            
'custom' => stristr($_POST['avatar'], 'http://') ? $_POST['avatar'] : 'http://',
            
'selection' => $_POST['avatar'] == '' || stristr($_POST['avatar'], 'http://') ? '' $_POST['avatar'],
            
'choice' => empty($_POST['avatar_choice']) ? 'server_stored' $_POST['avatar_choice'],
            
'external' => empty($_POST['userpicpersonal']) ? 'http://' $_POST['userpicpersonal'],
            
'ID_ATTACH' => empty($_POST['ID_ATTACH']) ? '0' $_POST['ID_ATTACH'],
            
'allow_server_stored' => allowedTo('profile_server_avatar') || !$context['user']['is_owner'],
            
'allow_upload' => allowedTo('profile_upload_avatar') || !$context['user']['is_owner'],
            
'allow_external' => allowedTo('profile_remote_avatar') || !$context['user']['is_owner'],
        ),
        
'karma' => array(
            
'good' => empty($_POST['karmaGood']) ? '0' $_POST['karmaGood'],
            
'bad' => empty($_POST['karmaBad']) ? '0' $_POST['karmaBad'],
        ),
        
'time_format' => !isset($_POST['timeFormat']) ? '' stripslashes($_POST['timeFormat']),
        
'time_offset' => empty($_POST['timeOffset']) ? '0' $_POST['timeOffset'],
        
'secret_question' => !isset($_POST['secretQuestion']) ? '' stripslashes($_POST['secretQuestion']),
        
'theme' => array(
            
'id' => isset($context['member']['theme']['id']) ? $context['member']['theme']['id'] : 0,
            
'name' => isset($context['member']['theme']['name']) ? $context['member']['theme']['name'] : '',
        ),
        
'notify_announcements' => empty($_POST['notifyAnnouncements']) ? 1,
        
'notify_once' => empty($_POST['notifyOnce']) ? 1,
        
'notify_send_body' => empty($_POST['notifySendBody']) ? : (int) $_POST['notifySendBody'],
        
'notify_types' => empty($_POST['notifyTypes']) ? : (int) $_POST['notifyTypes'],
        
'group' => isset($_POST['ID_GROUP']) ? $_POST['ID_GROUP'] : 0,
        
'smiley_set' => array(
            
'id' => isset($_POST['smileySet']) ? $_POST['smileySet'] : (isset($context['member']['smiley_set']) ? $context['member']['smiley_set']['id'] : ''),
            
'name' => isset($context['member']['smiley_set']) ? $context['member']['smiley_set']['name'] : ''
        
),
    );

    
// Overwrite the currently set membergroups with those you just selected.
    
if (allowedTo('manage_membergroups') && isset($_POST['ID_GROUP']))
    {
        foreach (
$context['member_groups'] as $ID_GROUP => $dummy)
        {
            
$context['member_groups'][$ID_GROUP]['is_primary'] = $ID_GROUP == $_POST['ID_GROUP'];
            
$context['member_groups'][$ID_GROUP]['is_additional'] = !empty($_POST['additionalGroups']) && in_array($ID_GROUP$_POST['additionalGroups']);
        }
    }

    
loadThemeOptions((int) $_REQUEST['userID']);
}

function 
loadThemeOptions($memID)
{
    global 
$context$options$db_prefix$user_profile;

    if (isset(
$_POST['options'], $_POST['default_options']))
        
$_POST['options'] += $_POST['default_options'];

    if (
$context['user']['is_owner'])
        
$context['member']['options'] = $options;
    else
    {
        
$request db_query("
            SELECT ID_MEMBER, variable, value
            FROM 
{$db_prefix}themes
            WHERE ID_THEME IN (1, " 
. (int) $user_profile[$memID]['ID_THEME'] . ")
                AND ID_MEMBER IN (-1, 
$memID)"__FILE____LINE__);
        
$temp = array();
        while (
$row mysql_fetch_assoc($request))
        {
            if (
$row['ID_MEMBER'] == -1)
            {
                
$temp[$row['variable']] = $row['value'];
                continue;
            }

            if (isset(
$_POST['options'][$row['variable']]))
                
$row['value'] = $_POST['options'][$row['variable']];
            
$context['member']['options'][$row['variable']] = $row['value'];
        }
        
mysql_free_result($request);

        
// Load up the default theme options for any missing.
        
foreach ($temp as $k => $v)
        {
            if (!isset(
$context['member']['options'][$k]))
                
$context['member']['options'][$k] = $v;
        }
    }
}

?>
Command:
Quick Commands:
Upload:
[OK] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [OK]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.3196 seconds