Place display name input box/submit button on it's own page?

Started by samborabora, August 14, 2014, 07:10:38 AM

Previous topic - Next topic

samborabora

I'd like a custom action that contains just the display name change input box and the submit button that saves the changes to the users profile. I'd say this seems easy, but I'm not if trying to modify current users profile information extraneously to the profile edit page is difficult, or if it's just a case of copy paste. Either way, I'd be keen to know the steps required to accomplish this.

Hj Ahmad Rasyid Hj Ismail

IMO it is easier to ask for display name during registration rather than asking user to update (there is a mod for this). Plus, profile template is not a suitable place for it even if you can ajaxify it.

samborabora

It's already possible to update the display name from the profile template, I just wanted to move it to it's own dedicated page/action. I mean, could you move any input and submit you liked to it's own action from a template?

Hj Ahmad Rasyid Hj Ismail

Definitely you can. But whether that is practical or otherwise. (I am doing a lot of impractical things myself so bear with me too. ;) ).

Hj Ahmad Rasyid Hj Ismail

I was having a quick look just now. If you wanna try, you have to look into the function inside profile template under this code in particular:
// Template for editing profile options.
function template_edit_options()


Under it, you'll be needing to copy and modify the form until its end but change the input to only real_name (in Profile-Modify.php) - as the function is meant for all data when call in particular link but you need only to change displayname.

The form action url may need to be edited something like:
<form action="' . $scripturl . '?action=profile;area=account;u=' . $context['id_member'] . ';save'), '"
method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator"
enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">

real_name data call and input to be submitted/updated here

</form>


You'll need to improvise as this is just a rough idea which I am not sure nor tested.

samborabora

Quote from: ahrasis on August 14, 2014, 12:24:33 PM
I was having a quick look just now. If you wanna try, you have to look into the function inside profile template under this code in particular:
// Template for editing profile options.
function template_edit_options()


Under it, you'll be needing to copy and modify the form until its end but change the input to only real_name (in Profile-Modify.php) - as the function is meant for all data when call in particular link but you need only to change displayname.

The form action url may need to be edited something like:
<form action="' . $scripturl . '?action=profile;area=account;u=' . $context['id_member'] . ';save'), '"
method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator"
enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">

real_name data call and input to be submitted/updated here

</form>


You'll need to improvise as this is just a rough idea which I am not sure nor tested.

I think I'll have to try this without Custom Action mod, as for reason whenever I put anything in custom action mod, it never shows up and then when I try to delete the custom action, the code that I place in the template gets executed as part of the custom action admin page. I know. Don't ask me why! So the best change I have is actually just removing custom action mod and trying again after a reinstall.

So, what's the manual way of, say, making a new action and duplicating the template_edit_options? I can obviously remove everything I don't need in the duplicate (in this case, everything except for 'change display name' and submit changes'), but what's the  manual method of putting this into it's own new action?

samborabora

Okay, some success. I made a new action in index.php, then I made a clone of profile.php into changeusername.php and changed the reference, then a clone of profile.template.php to changeusername.template.php and changed the reference. Now I'm trying to figure out if changeusername.tempalte.php is required if all I need (the box and the submit) could actually just be in  changeusername.php?

samborabora

After more digging through the templates, I still need to know how to call one specific field without all the other fields coming back, and since everything that's displayed to be viewed or edited on the profile page is all loaded from arrays, it's not unfortunately as simple as it seems. I might be able to just limit the array to displaying only the edit box for the input, but copy-pasta the profile-modify.php and profile.template results in a fine:

The database value you're trying to insert does not exist: selected_member

Mmm?

Hj Ahmad Rasyid Hj Ismail

Basically you can copy, rename and call template_edit2_options() (I named it 2) inside your profile view / info template. IMO you just need to reduce reduce it to needed data only. But originally the form is requesting ?action=profile;area= which depends on the menu you click. That's why IMO it should be changed to area=account. Other than that, I am not sure.

samborabora

Okay, managed to get my duplicated action to display template_edit_options, so thats:


  • Added the new action, changeusername, to index.php
  • Made changeusername.php in sources and duplicated the content from profile.php with the function profile change to function changeusername and changed loadTemplate('Profile'); to loadTemplate('Changeusername');
  • Duplicated profile.template.php as changeusername.template.php and changed the template_edit_options name to template_summary (so it loads the edit options by default) and changed template_summary to template_summary2 so it doesn't load.
And this actually works.

Only problem iiiiiissssss...........
......
........isn't the 'change displayname' field called by the area=settings rather than area=forumprofile, which is what I have here? If so, what's the best way to call the settings section into this new page?

samborabora

...which appear to be in profile-modify.php. So, the trick will be to somehow take function account($memID)
{ which calls for real_name and somehow juxtapose that with template_edit :D

samborabora

Quote from: samborabora on August 15, 2014, 06:45:17 AM
Quote from: ahrasis on August 14, 2014, 12:24:33 PM
I was having a quick look just now. If you wanna try, you have to look into the function inside profile template under this code in particular:
// Template for editing profile options.
function template_edit_options()


Under it, you'll be needing to copy and modify the form until its end but change the input to only real_name (in Profile-Modify.php) - as the function is meant for all data when call in particular link but you need only to change displayname.

The form action url may need to be edited something like:
<form action="' . $scripturl . '?action=profile;area=account;u=' . $context['id_member'] . ';save'), '"
method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator"
enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">

real_name data call and input to be submitted/updated here

</form>


You'll need to improvise as this is just a rough idea which I am not sure nor tested.

I think I'll have to try this without Custom Action mod, as for reason whenever I put anything in custom action mod, it never shows up and then when I try to delete the custom action, the code that I place in the template gets executed as part of the custom action admin page. I know. Don't ask me why! So the best change I have is actually just removing custom action mod and trying again after a reinstall.

So, what's the manual way of, say, making a new action and duplicating the template_edit_options? I can obviously remove everything I don't need in the duplicate (in this case, everything except for 'change display name' and submit changes'), but what's the  manual method of putting this into it's own new action?

Trying to have another go over exactly what you posted, I notice I'm getting a syntax error with:
<form action="' . $scripturl . '?action=profile;area=account;u=' . $context['id_member'] . ';save'), '"
method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator"
enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">


Which is a shame, as I was really hoping to give this a good shot!

Hj Ahmad Rasyid Hj Ismail

I don't know how did you do it. Nothing was shared here. Therefore how you got such an error is unknown to me and others.

I really do not know how to code this from a scratch but to make things work by duplicating and modding a bit of SMF codes, IMO is not so difficult though the result may not be so handsome. ;)

This is how I would do it. I'd copy some of the codes from function template_edit_options() as I mentioned, modify and rename it:

// Simple but unreliable codes that need rewritings and cleanings!
function template_edit_real_name()
{
global $context, $settings, $options, $scripturl, $modSettings, $txt;

echo '
<form action="', (!empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=forumprofile;u=' . $context['id_member'] . ';save'), '" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">';

echo '
<input type="text" name="real_name" id="real_name" size="30" value="', $context['member']['name'], '" />
<input type="submit" value="', $txt['change_profile'], '" class="button_submit" />
<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
<input type="hidden" name="u" value="', $context['id_member'], '" />
<input type="hidden" name="sa" value="', $context['menu_item_selected'], '" />
</form>';
}


I'd then add this just after the signature to call it for a test.

// Show the users signature.
if ($context['signature_enabled'] && !empty($context['member']['signature']))
echo '
<div class="signature">
<h5>', $txt['signature'], ':</h5>
', $context['member']['signature'], '
</div>';

template_edit_real_name();


Basically, the original page for this is area=account which requires password before you can change the real_name. Basically profile_identity will require that. But I don't know how to disable such permissions. So, I'd simply change permission for real_name to profile_extra in Profile-Modify.php and I'd use area=forumprofile as a test and not area=account.

Of course, it will go to Forum Profile page for updating since I submit the form to it but it works. That is how I think on solving this type of quest (part of it). You may have find for a better solution for this if you search and ask around. So good luck.

samborabora

Quote from: ahrasis on August 17, 2014, 09:42:05 PM
I don't know how did you do it. Nothing was shared here. Therefore how you got such an error is unknown to me and others.

I really do not know how to code this from a scratch but to make things work by duplicating and modding a bit of SMF codes, IMO is not so difficult though the result may not be so handsome. ;)

This is how I would do it. I'd copy some of the codes from function template_edit_options() as I mentioned, modify and rename it:

// Simple but unreliable codes that need rewritings and cleanings!
function template_edit_real_name()
{
global $context, $settings, $options, $scripturl, $modSettings, $txt;

echo '
<form action="', (!empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=forumprofile;u=' . $context['id_member'] . ';save'), '" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">';

echo '
<input type="text" name="real_name" id="real_name" size="30" value="', $context['member']['name'], '" />
<input type="submit" value="', $txt['change_profile'], '" class="button_submit" />
<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
<input type="hidden" name="u" value="', $context['id_member'], '" />
<input type="hidden" name="sa" value="', $context['menu_item_selected'], '" />
</form>';
}


I'd then add this just after the signature to call it for a test.

// Show the users signature.
if ($context['signature_enabled'] && !empty($context['member']['signature']))
echo '
<div class="signature">
<h5>', $txt['signature'], ':</h5>
', $context['member']['signature'], '
</div>';

template_edit_real_name();


Basically, the original page for this is area=account which requires password before you can change the real_name. Basically profile_identity will require that. But I don't know how to disable such permissions. So, I'd simply change permission for real_name to profile_extra in Profile-Modify.php and I'd use area=forumprofile as a test and not area=account.

Of course, it will go to Forum Profile page for updating since I submit the form to it but it works. That is how I think on solving this type of quest (part of it). You may have find for a better solution for this if you search and ask around. So good luck.

......i'm.... speechless. I've been trying to get to this for two days, so busy, I'm incredibly sorry but, er, I just tried it and... IT WORKED!!

;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D :laugh: :laugh: :laugh:

Right, so.... to summarise:

index.php
'activate' => array('Register.php', 'Activate'),
change to:
'changeusername' => array('Changeusername.php', 'ChangeUsername'),
'activate' => array('Register.php', 'Activate'),


make Sources/Changeusername.php (now this may need to be cut down to size, but this worked, whatever):
<?php

/**
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2011 Simple Machines
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.0
 */

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 loadCustomFields(int id_member, string area)
// !!!

*/

// Allow the change or view of profiles...
function changeusername($post_errors = array())
{
global $txt$scripturl$user_info$context$sourcedir$user_profile$cur_profile;
global $modSettings$memberContext$profile_vars$smcFunc$post_errors$options$user_settings;

// Don't reload this as we may have processed error strings.
if (empty($post_errors))
loadLanguage('Profile');
loadTemplate('Changeusername');

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

// 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($user_info['id'], false'profile');

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

// If all went well, we have a valid member ID!
list ($memID) = $memberResult;
$context['id_member'] = $memID;
$cur_profile $user_profile[$memID];

// Let's have some information about this member ready, too.
loadMemberContext($memID);
$context['member'] = $memberContext[$memID];

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

/* Define all the sections within the profile area!
We start by defining the permission required - then SMF takes this and turns it into the relevant context ;)
Possible fields:
For Section:
string $title: Section title.
array $areas: Array of areas within this section.

For Areas:
string $label: Text string that will be used to show the area in the menu.
string $file: Optional text string that may contain a file name that's needed for inclusion in order to display the area properly.
string $custom_url: Optional href for area.
string $function: Function to execute for this section.
bool $enabled: Should area be shown?
string $sc: Session check validation to do on save - note without this save will get unset - if set.
bool $hidden: Does this not actually appear on the menu?
bool $password: Whether to require the user's password in order to save the data in the area.
array $subsections: Array of subsections, in order of appearance.
array $permission: Array of permissions to determine who can access this area. Should contain arrays $own and $any.
*/
$profile_areas = array(
'info' => array(
'title' => $txt['profileInfo'],
'areas' => array(
'summary' => array(
'label' => $txt['summary'],
'file' => 'Profile-View.php',
'function' => 'summary',
'permission' => array(
'own' => 'profile_view_own',
'any' => 'profile_view_any',
),
),
'statistics' => array(
'label' => $txt['statPanel'],
'file' => 'Profile-View.php',
'function' => 'statPanel',
'permission' => array(
'own' => 'profile_view_own',
'any' => 'profile_view_any',
),
),
'showposts' => array(
'label' => $txt['showPosts'],
'file' => 'Profile-View.php',
'function' => 'showPosts',
'subsections' => array(
'messages' => array($txt['showMessages'], array('profile_view_own''profile_view_any')),
'topics' => array($txt['showTopics'], array('profile_view_own''profile_view_any')),
'attach' => array($txt['showAttachments'], array('profile_view_own''profile_view_any')),
),
'permission' => array(
'own' => 'profile_view_own',
'any' => 'profile_view_any',
),
),
'permissions' => array(
'label' => $txt['showPermissions'],
'file' => 'Profile-View.php',
'function' => 'showPermissions',
'permission' => array(
'own' => 'manage_permissions',
'any' => 'manage_permissions',
),
),
'tracking' => array(
'label' => $txt['trackUser'],
'file' => 'Profile-View.php',
'function' => 'tracking',
'subsections' => array(
'activity' => array($txt['trackActivity'], 'moderate_forum'),
'ip' => array($txt['trackIP'], 'moderate_forum'),
'edits' => array($txt['trackEdits'], 'moderate_forum'),
),
'permission' => array(
'own' => 'moderate_forum',
'any' => 'moderate_forum',
),
),
'viewwarning' => array(
'label' => $txt['profile_view_warnings'],
'enabled' => in_array('w'$context['admin_features']) && $modSettings['warning_settings'][0] == && $cur_profile['warning'] && $context['user']['is_owner'] && !empty($modSettings['warning_show']),
'file' => 'Profile-View.php',
'function' => 'viewWarning',
'permission' => array(
'own' => 'profile_view_own',
'any' => 'issue_warning',
),
),
),
),
'edit_profile' => array(
'title' => $txt['profileEdit'],
'areas' => array(
'account' => array(
'label' => $txt['account'],
'file' => 'Profile-Modify.php',
'function' => 'account',
'enabled' => $context['user']['is_admin'] || ($cur_profile['id_group'] != && !in_array(1explode(','$cur_profile['additional_groups']))),
'sc' => 'post',
'password' => true,
'permission' => array(
'own' => array('profile_identity_any''profile_identity_own''manage_membergroups'),
'any' => array('profile_identity_any''manage_membergroups'),
),
),
'forumprofile' => array(
'label' => $txt['forumprofile'],
'file' => 'Profile-Modify.php',
'function' => 'forumProfile',
'sc' => 'post',
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own''profile_title_own''profile_title_any'),
'any' => array('profile_extra_any''profile_title_any'),
),
),
'theme' => array(
'label' => $txt['theme'],
'file' => 'Profile-Modify.php',
'function' => 'theme',
'sc' => 'post',
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own'),
'any' => array('profile_extra_any'),
),
),
'authentication' => array(
'label' => $txt['authentication'],
'file' => 'Profile-Modify.php',
'function' => 'authentication',
'enabled' => !empty($modSettings['enableOpenID']) || !empty($cur_profile['openid_uri']),
'sc' => 'post',
'hidden' => empty($modSettings['enableOpenID']) && empty($cur_profile['openid_uri']),
'password' => true,
'permission' => array(
'own' => array('profile_identity_any''profile_identity_own'),
'any' => array('profile_identity_any'),
),
),
'notification' => array(
'label' => $txt['notification'],
'file' => 'Profile-Modify.php',
'function' => 'notification',
'sc' => 'post',
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own'),
'any' => array('profile_extra_any'),
),
),
// Without profile_extra_own, settings are accessible from the PM section.
'pmprefs' => array(
'label' => $txt['pmprefs'],
'file' => 'Profile-Modify.php',
'function' => 'pmprefs',
'enabled' => allowedTo(array('profile_extra_own''profile_extra_any')),
'sc' => 'post',
'permission' => array(
'own' => array('pm_read'),
'any' => array('profile_extra_any'),
),
),
'ignoreboards' => array(
'label' => $txt['ignoreboards'],
'file' => 'Profile-Modify.php',
'function' => 'ignoreboards',
'enabled' => !empty($modSettings['allow_ignore_boards']),
'sc' => 'post',
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own'),
'any' => array('profile_extra_any'),
),
),
'lists' => array(
'label' => $txt['editBuddyIgnoreLists'],
'file' => 'Profile-Modify.php',
'function' => 'editBuddyIgnoreLists',
'enabled' => !empty($modSettings['enable_buddylist']) && $context['user']['is_owner'],
'sc' => 'post',
'subsections' => array(
'buddies' => array($txt['editBuddies']),
'followers' => array($txt['Followers']),
'ignore' => array($txt['editIgnoreList']),
),
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own'),
'any' => array(),
),
),
'groupmembership' => array(
'label' => $txt['groupmembership'],
'file' => 'Profile-Modify.php',
'function' => 'groupMembership',
'enabled' => !empty($modSettings['show_group_membership']) && $context['user']['is_owner'],
'sc' => 'request',
'permission' => array(
'own' => array('profile_view_own'),
'any' => array('manage_membergroups'),
),
),
),
),
'profile_action' => array(
'title' => $txt['profileAction'],
'areas' => array(
'sendpm' => array(
'label' => $txt['profileSendIm'],
'custom_url' => $scripturl '?action=pm;sa=send',
'permission' => array(
'own' => array(),
'any' => array('pm_send'),
),
),
'issuewarning' => array(
'label' => $txt['profile_issue_warning'],
'enabled' => in_array('w'$context['admin_features']) && $modSettings['warning_settings'][0] == && (!$context['user']['is_owner'] || $context['user']['is_admin']),
'file' => 'Profile-Actions.php',
'function' => 'issueWarning',
'permission' => array(
'own' => array('issue_warning'),
'any' => array('issue_warning'),
),
),
'banuser' => array(
'label' => $txt['profileBanUser'],
'custom_url' => $scripturl '?action=admin;area=ban;sa=add',
'enabled' => $cur_profile['id_group'] != && !in_array(1explode(','$cur_profile['additional_groups'])),
'permission' => array(
'own' => array(),
'any' => array('manage_bans'),
),
),
'subscriptions' => array(
'label' => $txt['subscriptions'],
'file' => 'Profile-Actions.php',
'function' => 'subscriptions',
'enabled' => !empty($modSettings['paid_enabled']),
'permission' => array(
'own' => array('profile_view_own'),
'any' => array('moderate_forum'),
),
),
'deleteaccount' => array(
'label' => $txt['deleteAccount'],
'file' => 'Profile-Actions.php',
'function' => 'deleteAccount',
'sc' => 'post',
'password' => true,
'permission' => array(
'own' => array('profile_remove_any''profile_remove_own'),
'any' => array('profile_remove_any'),
),
),
'activateaccount' => array(
'file' => 'Profile-Actions.php',
'function' => 'activateAccount',
'sc' => 'get',
'select' => 'summary',
'permission' => array(
'own' => array(),
'any' => array('moderate_forum'),
),
),
),
),
);

// Let them modify profile areas easily.
call_integration_hook('integrate_profile_areas', array(&$profile_areas));

// Do some cleaning ready for the menu function.
$context['password_areas'] = array();
$current_area = isset($_REQUEST['area']) ? $_REQUEST['area'] : '';

foreach ($profile_areas as $section_id => $section)
{
// Do a bit of spring cleaning so to speak.
foreach ($section['areas'] as $area_id => $area)
{
// If it said no permissions that meant it wasn't valid!
if (empty($area['permission'][$context['user']['is_owner'] ? 'own' 'any']))
$profile_areas[$section_id]['areas'][$area_id]['enabled'] = false;
// Otherwise pick the right set.
else
$profile_areas[$section_id]['areas'][$area_id]['permission'] = $area['permission'][$context['user']['is_owner'] ? 'own' 'any'];

// Password required - only if not on OpenID.
if (!empty($area['password']))
$context['password_areas'][] = $area_id;
}
}

// Is there an updated message to show?
if (isset($_GET['updated']))
$context['profile_updated'] = $txt['profile_updated_own'];

// Set a few options for the menu.
$menuOptions = array(
'disable_url_session_check' => true,
'current_area' => $current_area,
'extra_url_parameters' => array(
'u' => $context['id_member'],
),
);

// Actually create the menu!
$profile_include_data createMenu($profile_areas$menuOptions);

// No menu means no access.
if (!$profile_include_data && (!$user_info['is_guest'] || validateSession()))
fatal_lang_error('no_access'false);

// Make a note of the Unique ID for this menu.
$context['profile_menu_id'] = $context['max_menu_id'];
$context['profile_menu_name'] = 'menu_data_' $context['profile_menu_id'];

// Set the selected item - now it's been validated.
$current_area $profile_include_data['current_area'];
$context['menu_item_selected'] = $current_area;

// Before we go any further, let's work on the area we've said is valid. Note this is done here just in case we every compromise the menu function in error!
$context['completed_save'] = false;
$security_checks = array();
$found_area false;
foreach ($profile_areas as $section_id => $section)
{
// Do a bit of spring cleaning so to speak.
foreach ($section['areas'] as $area_id => $area)
{
// Is this our area?
if ($current_area == $area_id)
{
// This can't happen - but is a security check.
if ((isset($section['enabled']) && $section['enabled'] == false) || (isset($area['enabled']) && $area['enabled'] == false))
fatal_lang_error('no_access'false);

// Are we saving data in a valid area?
if (isset($area['sc']) && isset($_REQUEST['save']))
{
$security_checks['session'] = $area['sc'];
$context['completed_save'] = true;
}

// Does this require session validating?
if (!empty($area['validate']))
$security_checks['validate'] = true;

// Permissions for good measure.
if (!empty($profile_include_data['permission']))
$security_checks['permission'] = $profile_include_data['permission'];

// Either way got something.
$found_area true;
}
}
}

// Oh dear, some serious security lapse is going on here... we'll put a stop to that!
if (!$found_area)
fatal_lang_error('no_access'false);

// Release this now.
unset($profile_areas);

// Now the context is setup have we got any security checks to carry out additional to that above?
if (isset($security_checks['session']))
checkSession($security_checks['session']);
if (isset($security_checks['validate']))
validateSession();
if (isset($security_checks['permission']))
isAllowedTo($security_checks['permission']);

// File to include?
if (isset($profile_include_data['file']))
require_once($sourcedir '/' $profile_include_data['file']);

// Make sure that the area function does exist!
if (!isset($profile_include_data['function']) || !function_exists($profile_include_data['function']))
{
destroyMenu();
fatal_lang_error('no_access'false);
}

// Build the link tree.
$context['linktree'][] = array(
'url' => $scripturl '?action=profile' . ($memID != $user_info['id'] ? ';u=' $memID ''),
'name' => sprintf($txt['profile_of_username'], $context['member']['name']),
);

if (!empty($profile_include_data['label']))
$context['linktree'][] = array(
'url' => $scripturl '?action=profile' . ($memID != $user_info['id'] ? ';u=' $memID '') . ';area=' $profile_include_data['current_area'],
'name' => $profile_include_data['label'],
);

if (!empty($profile_include_data['current_subsection']) && $profile_include_data['subsections'][$profile_include_data['current_subsection']][0] != $profile_include_data['label'])
$context['linktree'][] = array(
'url' => $scripturl '?action=profile' . ($memID != $user_info['id'] ? ';u=' $memID '') . ';area=' $profile_include_data['current_area'] . ';sa=' $profile_include_data['current_subsection'],
'name' => $profile_include_data['subsections'][$profile_include_data['current_subsection']][0],
);

// Set the template for this area and add the profile layer.
$context['sub_template'] = $profile_include_data['function'];
$context['template_layers'][] = 'profile';

// All the subactions that require a user password in order to validate.
$check_password $context['user']['is_owner'] && in_array($profile_include_data['current_area'], $context['password_areas']);
$context['require_password'] = $check_password && empty($user_settings['openid_uri']);

// If we're in wireless then we have a cut down template...
if (WIRELESS && $context['sub_template'] == 'summary' && WIRELESS_PROTOCOL != 'wap')
$context['sub_template'] = WIRELESS_PROTOCOL '_profile';

// These will get populated soon!
$post_errors = array();
$profile_vars = array();

// Right - are we saving - if so let's save the old data first.
if ($context['completed_save'])
{
// If it's someone elses profile then validate the session.
if (!$context['user']['is_owner'])
validateSession();

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

if ($check_password)
{
// If we're using OpenID try to revalidate.
if (!empty($user_settings['openid_uri']))
{
require_once($sourcedir '/Subs-OpenID.php');
smf_openID_revalidate();
}
else
{
// 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'] = un_htmlspecialchars($_POST['oldpasswrd']);

// Does the integration want to check passwords?
$good_password in_array(truecall_integration_hook('integrate_verify_password', array($cur_profile['member_name'], $_POST['oldpasswrd'], false)), true);

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

// Warn other elements not to jump the gun and do custom changes!
if (in_array('bad_password'$post_errors))
$context['password_auth_failed'] = true;
}
}

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

// Now call the sub-action function...
if ($current_area == 'activateaccount')
{
if (empty($post_errors))
activateAccount($memID);
}
elseif ($current_area == 'deleteaccount')
{
if (empty($post_errors))
{
deleteAccount2($profile_vars$post_errors$memID);
redirectexit();
}
}
elseif ($current_area == 'groupmembership' && empty($post_errors))
{
$msg groupMembership2($profile_vars$post_errors$memID);

// Whatever we've done, we have nothing else to do here...
redirectexit('action=profile' . ($context['user']['is_owner'] ? '' ';u=' $memID) . ';area=groupmembership' . (!empty($msg) ? ';msg=' $msg ''));
}
// Authentication changes?
elseif ($current_area == 'authentication')
{
authentication($memIDtrue);
}
elseif (in_array($current_area, array('account''forumprofile''theme''pmprefs')))
saveProfileFields();
else
{
$force_redirect true;
// Ensure we include this.
require_once($sourcedir '/Profile-Modify.php');
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;
}
elseif (!empty($profile_vars))
{
// If we've changed the password, notify any integration that may be listening in.
if (isset($profile_vars['passwd']))
call_integration_hook('integrate_reset_pass', array($cur_profile['member_name'], $cur_profile['member_name'], $_POST['passwrd2']));

updateMemberData($memID$profile_vars);

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

// If the member changed his/her birthdate, update calendar statistics.
if (isset($profile_vars['birthdate']) || isset($profile_vars['real_name']))
updateSettings(array(
'calendar_updated' => time(),
));

// Anything worth logging?
if (!empty($context['log_changes']) && !empty($modSettings['modlog_enabled']))
{
$log_changes = array();
foreach ($context['log_changes'] as $k => $v)
$log_changes[] = array(
'action' => $k,
'id_log' => 2,
'log_time' => time(),
'id_member' => $memID,
'ip' => $user_info['ip'],
'extra' => serialize(array_merge($v, array('applicator' => $user_info['id']))),
);
$smcFunc['db_insert']('',
'{db_prefix}log_actions',
array(
'action' => 'string''id_log' => 'int''log_time' => 'int''id_member' => 'int''ip' => 'string-16',
'extra' => 'string-65534',
),
$log_changes,
array('id_action')
);
}

// Have we got any post save functions to execute?
if (!empty($context['profile_execute_on_save']))
foreach ($context['profile_execute_on_save'] as $saveFunc)
$saveFunc();

// Let them know it worked!
$context['profile_updated'] = $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $cur_profile['member_name']);

// Invalidate any cached data.
cache_put_data('member_data-profile-' $memIDnull0);
}
}

// Have some errors for some reason?
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;
}
// If it's you then we should redirect upon save.
elseif (!empty($profile_vars) && $context['user']['is_owner'])
redirectexit('action=profile;area=' $current_area ';updated');
elseif (!empty($force_redirect))
redirectexit('action=profile' . ($context['user']['is_owner'] ? '' ';u=' $memID) . ';area=' $current_area);

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

// Set the page title if it's not already set...
if (!isset($context['page_title']))
$context['page_title'] = $txt['profile'] . (isset($txt[$current_area]) ? ' - ' $txt[$current_area] : '');
}

// Load any custom fields for this area... no area means load all, 'summary' loads all public ones.
function loadCustomFields($memID$area 'summary')
{
global $context$txt$user_profile$smcFunc$user_info$settings$scripturl;

// Get the right restrictions in place...
$where 'active = 1';
if (!allowedTo('admin_forum') && $area != 'register')
{
// If it's the owner they can see two types of private fields, regardless.
if ($memID == $user_info['id'])
$where .= $area == 'summary' ' AND private < 3' ' AND (private = 0 OR private = 2)';
else
$where .= $area == 'summary' ' AND private < 2' ' AND private = 0';
}

if ($area == 'register')
$where .= ' AND show_reg != 0';
elseif ($area != 'summary')
$where .= ' AND show_profile = {string:area}';

// Load all the relevant fields - and data.
$request $smcFunc['db_query']('''
SELECT
col_name, field_name, field_desc, field_type, field_length, field_options,
default_value, bbc, enclose, placement
FROM {db_prefix}custom_fields
WHERE ' 
$where,
array(
'area' => $area,
)
);
$context['custom_fields'] = array();
while ($row $smcFunc['db_fetch_assoc']($request))
{
// Shortcut.
$exists $memID && isset($user_profile[$memID], $user_profile[$memID]['options'][$row['col_name']]);
$value $exists $user_profile[$memID]['options'][$row['col_name']] : '';

// If this was submitted already then make the value the posted version.
if (isset($_POST['customfield']) && isset($_POST['customfield'][$row['col_name']]))
{
$value $smcFunc['htmlspecialchars']($_POST['customfield'][$row['col_name']]);
if (in_array($row['field_type'], array('select''radio')))
$value = ($options explode(','$row['field_options'])) && isset($options[$value]) ? $options[$value] : '';
}

// HTML for the input form.
$output_html $value;
if ($row['field_type'] == 'check')
{
$true = (!$exists && $row['default_value']) || $value;
$input_html '<input type="checkbox" name="customfield[' $row['col_name'] . ']" ' . ($true 'checked="checked"' '') . ' class="input_check" />';
$output_html $true $txt['yes'] : $txt['no'];
}
elseif ($row['field_type'] == 'select')
{
$input_html '<select name="customfield[' $row['col_name'] . ']"><option value="-1"></option>';
$options explode(','$row['field_options']);
foreach ($options as $k => $v)
{
$true = (!$exists && $row['default_value'] == $v) || $value == $v;
$input_html .= '<option value="' $k '"' . ($true ' selected="selected"' '') . '>' $v '</option>';
if ($true)
$output_html $v;
}

$input_html .= '</select>';
}
elseif ($row['field_type'] == 'radio')
{
$input_html '<fieldset>';
$options explode(','$row['field_options']);
foreach ($options as $k => $v)
{
$true = (!$exists && $row['default_value'] == $v) || $value == $v;
$input_html .= '<label for="customfield_' $row['col_name'] . '_' $k '"><input type="radio" name="customfield[' $row['col_name'] . ']" class="input_radio" id="customfield_' $row['col_name'] . '_' $k '" value="' $k '" ' . ($true 'checked="checked"' '') . '>' $v '</label><br />';
if ($true)
$output_html $v;
}
$input_html .= '</fieldset>';
}
elseif ($row['field_type'] == 'text')
{
$input_html '<input type="text" name="customfield[' $row['col_name'] . ']" ' . ($row['field_length'] != 'maxlength="' $row['field_length'] . '"' '') . ' size="' . ($row['field_length'] == || $row['field_length'] >= 50 50 : ($row['field_length'] > 30 30 : ($row['field_length'] > 10 20 10))) . '" value="' $value '" class="input_text" />';
}
else
{
@list ($rows$cols) = @explode(','$row['default_value']);
$input_html '<textarea name="customfield[' $row['col_name'] . ']" ' . (!empty($rows) ? 'rows="' $rows '"' '') . ' ' . (!empty($cols) ? 'cols="' $cols '"' '') . '>' $value '</textarea>';
}

// Parse BBCode
if ($row['bbc'])
$output_html parse_bbc($output_html);
elseif($row['field_type'] == 'textarea')
// Allow for newlines at least
$output_html strtr($output_html, array("\n" => '<br />'));

// Enclosing the user input within some other text?
if (!empty($row['enclose']) && !empty($output_html))
$output_html strtr($row['enclose'], array(
'{SCRIPTURL}' => $scripturl,
'{IMAGES_URL}' => $settings['images_url'],
'{DEFAULT_IMAGES_URL}' => $settings['default_images_url'],
'{INPUT}' => $output_html,
));

$context['custom_fields'][] = array(
'name' => $row['field_name'],
'desc' => $row['field_desc'],
'type' => $row['field_type'],
'input_html' => $input_html,
'output_html' => $output_html,
'placement' => $row['placement'],
'colname' => $row['col_name'],
'value' => $value,
);
}
$smcFunc['db_free_result']($request);
}

?>


And, the genius code in [theme folder]/Changeusername.template.php:
<?php
/**
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines
 * @copyright 2011 Simple Machines
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.0
 */

// Template for the profile side bar - goes before any other profile template.
function template_profile_above()
{
global $context$settings$options$scripturl$modSettings$txt;

echo '
<script type="text/javascript" src="'
$settings['default_theme_url'], '/scripts/profile.js"></script>

'
;

// Prevent Chrome from auto completing fields when viewing/editing other members profiles
if ($context['browser']['is_chrome'] && !$context['user']['is_owner'])
echo '
<script type="text/javascript"><!-- // --><![CDATA[
disableAutoComplete();
// ]]></script>'
;

/*
// If an error occurred while trying to save previously, give the user a clue!
if (!empty($context['post_errors']) && $context['section'] !== 'forumprofile')
echo '
', template_error_message();

// If the profile was update successfully, let the user know this.
if (!empty($context['profile_updated']) && $section['section'] !== 'forumprofile')
echo '
<div id="profile_success">
', $context['profile_updated'], '
</div>'
*/
;
}

// Template for closing off table started in profile_above.
function template_profile_below()
{
}

// This template displays users details without any option to edit them.
function template_summary()
{
global $context$settings$options$scripturl$modSettings$txt;

echo '
<form action="'
, (!empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl '?action=profile;area=forumprofile;u=' $context['id_member'] . ';save'), '" method="post" accept-charset="'$context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">';

echo '
<input type="text" name="real_name" id="real_name" size="30" value="'
$context['member']['name'], '" />
<input type="submit" value="'
$txt['change_profile'], '" class="button_submit" />
<input type="hidden" name="'
$context['session_var'], '" value="'$context['session_id'], '" />
<input type="hidden" name="u" value="'
$context['id_member'], '" />
<input type="hidden" name="sa" value="'
$context['menu_item_selected'], '" />
</form>'
;
}

?>


So, erm, that was really really easy when it was spelled out for an absolute idiot coder like myself, lol.

Thank you once more ahrasis, for solving life's mysteries!!!

Hj Ahmad Rasyid Hj Ismail

Nice coding sambabora. I think you could have duplicated the right thing in changeusername.php but have not refine it.

I haven't tested this but looking your code you may be able to edit directly from your summary page instead of going to forum profile page. Change this part of your code to inlude permission to edit as well.
'summary' => array(
'label' => $txt['summary'],
'file' => 'Profile-View.php',
'function' => 'summary',
'permission' => array(
'own' => 'profile_view_own',
'any' => 'profile_view_any',

Change it to:
'summary' => array(
'label' => $txt['summary'],
'file' => 'Profile-View.php',
'function' => 'summary',
'permission' => array(
'own' => array('profile_view_own',  'profile_identity_own', 'profile_extra_own'),
'any' => 'profile_view_any',


This time round I think (just a thought ok) any of the profile_extra and profile_identity in real_name permission should be fine since you didn't add 'password' => true, in summary array since we added both profile_extra and profile_identity in it. So, no need to change that in Profile_Modify.php.

Then, on your template, find this:
<form action="', (!empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=forumprofile;u=' . $context['id_member'] . ';save'), '" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">';

And change it to:
<form action="', (!empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=summary;u=' . $context['id_member'] . ';save'), '" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">';

It might work though I have never tested it. It will be more handsome than the earlier one, if it works that is. I will give it a shot later myself. ;)

Edited: I have this thought a shot but it doesn't work since the file that was called is Profile View and not Profile Modify. May you can duplicate and add up real name user info call in side Profile View to make it works. Will try this idea later.

samborabora

Interestingly, I tried these changes twice to be sure, and the changes stop it from working! Not sure why but with this code instead of what you posted before,if you try to change your username from the changeusername action page I made, and it just returns the user to their profile without the changes! Strange, but it works perfectly as per your original specifications! :D

So, does this mean you've figured out how to actually call profile fields individually from outside of that array that it uses? Cause I had to go through one hell of a load of hacking and css-ery to re-organise my profile fields!

Hj Ahmad Rasyid Hj Ismail

Quote from: ahrasis on August 20, 2014, 02:56:33 AM
Edited: I have this thought a shot but it doesn't work since the file that was called is Profile View and not Profile Modify. May be you can duplicate and add up real name user info call in side Profile View to make it works. Will try this idea later.
From what I tested earlier, it will still need to load real_name data and save it. So may be, only this two functions needed to be duplicated from Profile Modify file, modified and put into Profile View file.

Hj Ahmad Rasyid Hj Ismail

I finally managed to test this properly and make it works more nicely. I will repeat some of the code I gave earlier as I change some of its line/name. Let me list what I did.

Firstly, as stated in post #12, I added the new function. Find:
// Template for showing all the posts of the user, in chronological order.
function template_showPosts()

Add before:
// Template to add and edit displayname inside profile
function template_edit_displayname()
{
global $context, $settings, $options, $scripturl, $modSettings, $txt;

echo '
<div class="edit_displayname">
<form action="', $scripturl . '?action=profile;area=displayname;u=' . $context['id_member'] . ';save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator" />
<input type="text" name="real_name" id="real_name" size="30" value="', $context['member']['name'], '" />
<input type="submit" value="Update Displayname" class="button_submit" />
<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
</form>
</div>';
}


Secondly, I add this newly created template inside the summary template. To simplify things, I added it under signature as I did previously. Find:
// Show the users signature.
if ($context['signature_enabled'] && !empty($context['member']['signature']))
echo '
<div class="signature">
<h5>', $txt['signature'], ':</h5>
', $context['member']['signature'], '
</div>';

Add after:

template_edit_displayname();


Thirdly, as we have discussed, to make it work, we need to call a function from Profile-Modify.php. Using forumprofile function, as I mentioned earlier won't be nice. So the solution is, we need to create a new function (again). But this time, we also have to call some context that have been defined in Profile-View.php but not yet defined in Profile-Modify.php.

So, basically find:
function forumProfile($memID)
And add before it this code:

function displayname($memID)
{
global $context, $user_profile, $user_info, $txt, $modSettings, $memberContext;

// Choose default profile template
$context['sub_template'] = 'summary';

// Copy some $context from Profile-View.php or you'll get undefined error(s)
// Define #1 signature_enabled
$context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1;
// Define #2 can_view_warning
$context['can_view_warning'] = in_array('w', $context['admin_features']) && (allowedTo('issue_warning') && !$context['user']['is_owner']) || (!empty($modSettings['warning_show']) && ($modSettings['warning_show'] > 1 || $context['user']['is_owner']));
// Define #3 can_send_pm
$context['can_send_pm'] = allowedTo('pm_send');
// Define #4 posts_per_day
$days_registered = (int) ((time() - $user_profile[$memID]['date_registered']) / (3600 * 24));
if (empty($user_profile[$memID]['date_registered']) || $days_registered < 1)
$context['member']['posts_per_day'] = $txt['not_applicable'];
else
$context['member']['posts_per_day'] = comma_format($context['member']['real_posts'] / $days_registered, 3);

// Define #5 & #6 age and today_is_birthday
if (empty($context['member']['birth_date']))
{
$context['member'] += array(
'age' => $txt['not_applicable'],
'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 <= 4 ? $txt['not_applicable'] : $datearray['year'] - $birth_year - (($datearray['mon'] > $birth_month || ($datearray['mon'] == $birth_month && $datearray['mday'] >= $birth_day)) ? 0 : 1),
'today_is_birthday' => $datearray['mon'] == $birth_month && $datearray['mday'] == $birth_day
);
}
// Define #7 can_see_ip
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']) == 1 && 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;
}


Finally, we need to set this function up inside the Profile.php for it to post and save properly. But we don't need any menu in this case, and simply just want to hide it from being listed as on of the profile menu.

To save it properly, we need to add function displayname in saving array. Find:

elseif (in_array($current_area, array('account', 'forumprofile', 'theme', 'pmprefs')))
saveProfileFields();

And change to:

elseif (in_array($current_area, array('displayname', 'account', 'forumprofile', 'theme', 'pmprefs')))
saveProfileFields();


As for the posting of displayname update, find:

'summary' => array(
'label' => $txt['summary'],
'file' => 'Profile-View.php',
'function' => 'summary',
'permission' => array(
'own' => 'profile_view_own',
'any' => 'profile_view_any',
),
),

Add after:

'displayname' => array(
'label' => 'Displayname Edit',
'file' => 'Profile-Modify.php',
'function' => 'displayname',
'hidden' => true,
'sc' => 'post',
'permission' => array(
'own' => 'profile_extra_own',
'any' => 'profile_extra_own',
),
),


I have tested this and it works just fine. Pus, I have cleaned up all undefined error(s) so that your error log won't be spammed by error(s) from this mod.

With this approach, a user will feel that he is redirected to his summary page after an update though it is actually in Displayname Edit page.

IMO this should be a better one as it is much cleaner. Please update if you are facing any error(s) while implementing this mod.

Enhancement tip: You may actually remove the input box as well as its submit button via css. If you do so, you may replace the current displayname with this mod and allow user to change it directly from its place. The idea is to replace <div class="username"><h4>', $context['member']['name'], ' <span class="position"> with <div class="username"><h4>', template_edit_displayname(), ' <span class="position">. If you are not sure how to implement this, do ask.

Note: I may submit this as a new mod though I know it is not really needed by many.

samborabora

This is excellent! Okay, just so I don't screw things up, let me recap what I've got:

index.php
$actionArray = array(
'changeusername' => array('Changeusername.php', 'ChangeUsername'),


Then:
Changeusername.php in Sources
<?php

/**
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2011 Simple Machines
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.0
 */

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 loadCustomFields(int id_member, string area)
// !!!

*/

// Allow the change or view of profiles...
function changeusername($post_errors = array())
{
global $txt$scripturl$user_info$context$sourcedir$user_profile$cur_profile;
global $modSettings$memberContext$profile_vars$smcFunc$post_errors$options$user_settings;

// Don't reload this as we may have processed error strings.
if (empty($post_errors))
loadLanguage('Profile');
loadTemplate('Changeusername');

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

// 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($user_info['id'], false'profile');

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

// If all went well, we have a valid member ID!
list ($memID) = $memberResult;
$context['id_member'] = $memID;
$cur_profile $user_profile[$memID];

// Let's have some information about this member ready, too.
loadMemberContext($memID);
$context['member'] = $memberContext[$memID];

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

/* Define all the sections within the profile area!
We start by defining the permission required - then SMF takes this and turns it into the relevant context ;)
Possible fields:
For Section:
string $title: Section title.
array $areas: Array of areas within this section.

For Areas:
string $label: Text string that will be used to show the area in the menu.
string $file: Optional text string that may contain a file name that's needed for inclusion in order to display the area properly.
string $custom_url: Optional href for area.
string $function: Function to execute for this section.
bool $enabled: Should area be shown?
string $sc: Session check validation to do on save - note without this save will get unset - if set.
bool $hidden: Does this not actually appear on the menu?
bool $password: Whether to require the user's password in order to save the data in the area.
array $subsections: Array of subsections, in order of appearance.
array $permission: Array of permissions to determine who can access this area. Should contain arrays $own and $any.
*/
$profile_areas = array(
'info' => array(
'title' => $txt['profileInfo'],
'areas' => array(
'summary' => array(
'label' => $txt['summary'],
'file' => 'Profile-View.php',
'function' => 'summary',
'permission' => array(
'own' => 'profile_view_own',
'any' => 'profile_view_any',
),
),
'statistics' => array(
'label' => $txt['statPanel'],
'file' => 'Profile-View.php',
'function' => 'statPanel',
'permission' => array(
'own' => 'profile_view_own',
'any' => 'profile_view_any',
),
),
'showposts' => array(
'label' => $txt['showPosts'],
'file' => 'Profile-View.php',
'function' => 'showPosts',
'subsections' => array(
'messages' => array($txt['showMessages'], array('profile_view_own''profile_view_any')),
'topics' => array($txt['showTopics'], array('profile_view_own''profile_view_any')),
'attach' => array($txt['showAttachments'], array('profile_view_own''profile_view_any')),
),
'permission' => array(
'own' => 'profile_view_own',
'any' => 'profile_view_any',
),
),
'permissions' => array(
'label' => $txt['showPermissions'],
'file' => 'Profile-View.php',
'function' => 'showPermissions',
'permission' => array(
'own' => 'manage_permissions',
'any' => 'manage_permissions',
),
),
'tracking' => array(
'label' => $txt['trackUser'],
'file' => 'Profile-View.php',
'function' => 'tracking',
'subsections' => array(
'activity' => array($txt['trackActivity'], 'moderate_forum'),
'ip' => array($txt['trackIP'], 'moderate_forum'),
'edits' => array($txt['trackEdits'], 'moderate_forum'),
),
'permission' => array(
'own' => 'moderate_forum',
'any' => 'moderate_forum',
),
),
'viewwarning' => array(
'label' => $txt['profile_view_warnings'],
'enabled' => in_array('w'$context['admin_features']) && $modSettings['warning_settings'][0] == && $cur_profile['warning'] && $context['user']['is_owner'] && !empty($modSettings['warning_show']),
'file' => 'Profile-View.php',
'function' => 'viewWarning',
'permission' => array(
'own' => 'profile_view_own',
'any' => 'issue_warning',
),
),
),
),
'edit_profile' => array(
'title' => $txt['profileEdit'],
'areas' => array(
'account' => array(
'label' => $txt['account'],
'file' => 'Profile-Modify.php',
'function' => 'account',
'enabled' => $context['user']['is_admin'] || ($cur_profile['id_group'] != && !in_array(1explode(','$cur_profile['additional_groups']))),
'sc' => 'post',
'password' => true,
'permission' => array(
'own' => array('profile_identity_any''profile_identity_own''manage_membergroups'),
'any' => array('profile_identity_any''manage_membergroups'),
),
),
'forumprofile' => array(
'label' => $txt['forumprofile'],
'file' => 'Profile-Modify.php',
'function' => 'forumProfile',
'sc' => 'post',
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own''profile_title_own''profile_title_any'),
'any' => array('profile_extra_any''profile_title_any'),
),
),
'theme' => array(
'label' => $txt['theme'],
'file' => 'Profile-Modify.php',
'function' => 'theme',
'sc' => 'post',
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own'),
'any' => array('profile_extra_any'),
),
),
'authentication' => array(
'label' => $txt['authentication'],
'file' => 'Profile-Modify.php',
'function' => 'authentication',
'enabled' => !empty($modSettings['enableOpenID']) || !empty($cur_profile['openid_uri']),
'sc' => 'post',
'hidden' => empty($modSettings['enableOpenID']) && empty($cur_profile['openid_uri']),
'password' => true,
'permission' => array(
'own' => array('profile_identity_any''profile_identity_own'),
'any' => array('profile_identity_any'),
),
),
'notification' => array(
'label' => $txt['notification'],
'file' => 'Profile-Modify.php',
'function' => 'notification',
'sc' => 'post',
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own'),
'any' => array('profile_extra_any'),
),
),
// Without profile_extra_own, settings are accessible from the PM section.
'pmprefs' => array(
'label' => $txt['pmprefs'],
'file' => 'Profile-Modify.php',
'function' => 'pmprefs',
'enabled' => allowedTo(array('profile_extra_own''profile_extra_any')),
'sc' => 'post',
'permission' => array(
'own' => array('pm_read'),
'any' => array('profile_extra_any'),
),
),
'ignoreboards' => array(
'label' => $txt['ignoreboards'],
'file' => 'Profile-Modify.php',
'function' => 'ignoreboards',
'enabled' => !empty($modSettings['allow_ignore_boards']),
'sc' => 'post',
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own'),
'any' => array('profile_extra_any'),
),
),
'lists' => array(
'label' => $txt['editBuddyIgnoreLists'],
'file' => 'Profile-Modify.php',
'function' => 'editBuddyIgnoreLists',
'enabled' => !empty($modSettings['enable_buddylist']) && $context['user']['is_owner'],
'sc' => 'post',
'subsections' => array(
'buddies' => array($txt['editBuddies']),
'followers' => array($txt['Followers']),
'ignore' => array($txt['editIgnoreList']),
),
'permission' => array(
'own' => array('profile_extra_any''profile_extra_own'),
'any' => array(),
),
),
'groupmembership' => array(
'label' => $txt['groupmembership'],
'file' => 'Profile-Modify.php',
'function' => 'groupMembership',
'enabled' => !empty($modSettings['show_group_membership']) && $context['user']['is_owner'],
'sc' => 'request',
'permission' => array(
'own' => array('profile_view_own'),
'any' => array('manage_membergroups'),
),
),
),
),
'profile_action' => array(
'title' => $txt['profileAction'],
'areas' => array(
'sendpm' => array(
'label' => $txt['profileSendIm'],
'custom_url' => $scripturl '?action=pm;sa=send',
'permission' => array(
'own' => array(),
'any' => array('pm_send'),
),
),
'issuewarning' => array(
'label' => $txt['profile_issue_warning'],
'enabled' => in_array('w'$context['admin_features']) && $modSettings['warning_settings'][0] == && (!$context['user']['is_owner'] || $context['user']['is_admin']),
'file' => 'Profile-Actions.php',
'function' => 'issueWarning',
'permission' => array(
'own' => array('issue_warning'),
'any' => array('issue_warning'),
),
),
'banuser' => array(
'label' => $txt['profileBanUser'],
'custom_url' => $scripturl '?action=admin;area=ban;sa=add',
'enabled' => $cur_profile['id_group'] != && !in_array(1explode(','$cur_profile['additional_groups'])),
'permission' => array(
'own' => array(),
'any' => array('manage_bans'),
),
),
'subscriptions' => array(
'label' => $txt['subscriptions'],
'file' => 'Profile-Actions.php',
'function' => 'subscriptions',
'enabled' => !empty($modSettings['paid_enabled']),
'permission' => array(
'own' => array('profile_view_own'),
'any' => array('moderate_forum'),
),
),
'deleteaccount' => array(
'label' => $txt['deleteAccount'],
'file' => 'Profile-Actions.php',
'function' => 'deleteAccount',
'sc' => 'post',
'password' => true,
'permission' => array(
'own' => array('profile_remove_any''profile_remove_own'),
'any' => array('profile_remove_any'),
),
),
'activateaccount' => array(
'file' => 'Profile-Actions.php',
'function' => 'activateAccount',
'sc' => 'get',
'select' => 'summary',
'permission' => array(
'own' => array(),
'any' => array('moderate_forum'),
),
),
),
),
);

// Let them modify profile areas easily.
call_integration_hook('integrate_profile_areas', array(&$profile_areas));

// Do some cleaning ready for the menu function.
$context['password_areas'] = array();
$current_area = isset($_REQUEST['area']) ? $_REQUEST['area'] : '';

foreach ($profile_areas as $section_id => $section)
{
// Do a bit of spring cleaning so to speak.
foreach ($section['areas'] as $area_id => $area)
{
// If it said no permissions that meant it wasn't valid!
if (empty($area['permission'][$context['user']['is_owner'] ? 'own' 'any']))
$profile_areas[$section_id]['areas'][$area_id]['enabled'] = false;
// Otherwise pick the right set.
else
$profile_areas[$section_id]['areas'][$area_id]['permission'] = $area['permission'][$context['user']['is_owner'] ? 'own' 'any'];

// Password required - only if not on OpenID.
if (!empty($area['password']))
$context['password_areas'][] = $area_id;
}
}

// Is there an updated message to show?
if (isset($_GET['updated']))
$context['profile_updated'] = $txt['profile_updated_own'];

// Set a few options for the menu.
$menuOptions = array(
'disable_url_session_check' => true,
'current_area' => $current_area,
'extra_url_parameters' => array(
'u' => $context['id_member'],
),
);

// Actually create the menu!
$profile_include_data createMenu($profile_areas$menuOptions);

// No menu means no access.
if (!$profile_include_data && (!$user_info['is_guest'] || validateSession()))
fatal_lang_error('no_access'false);

// Make a note of the Unique ID for this menu.
$context['profile_menu_id'] = $context['max_menu_id'];
$context['profile_menu_name'] = 'menu_data_' $context['profile_menu_id'];

// Set the selected item - now it's been validated.
$current_area $profile_include_data['current_area'];
$context['menu_item_selected'] = $current_area;

// Before we go any further, let's work on the area we've said is valid. Note this is done here just in case we every compromise the menu function in error!
$context['completed_save'] = false;
$security_checks = array();
$found_area false;
foreach ($profile_areas as $section_id => $section)
{
// Do a bit of spring cleaning so to speak.
foreach ($section['areas'] as $area_id => $area)
{
// Is this our area?
if ($current_area == $area_id)
{
// This can't happen - but is a security check.
if ((isset($section['enabled']) && $section['enabled'] == false) || (isset($area['enabled']) && $area['enabled'] == false))
fatal_lang_error('no_access'false);

// Are we saving data in a valid area?
if (isset($area['sc']) && isset($_REQUEST['save']))
{
$security_checks['session'] = $area['sc'];
$context['completed_save'] = true;
}

// Does this require session validating?
if (!empty($area['validate']))
$security_checks['validate'] = true;

// Permissions for good measure.
if (!empty($profile_include_data['permission']))
$security_checks['permission'] = $profile_include_data['permission'];

// Either way got something.
$found_area true;
}
}
}

// Oh dear, some serious security lapse is going on here... we'll put a stop to that!
if (!$found_area)
fatal_lang_error('no_access'false);

// Release this now.
unset($profile_areas);

// Now the context is setup have we got any security checks to carry out additional to that above?
if (isset($security_checks['session']))
checkSession($security_checks['session']);
if (isset($security_checks['validate']))
validateSession();
if (isset($security_checks['permission']))
isAllowedTo($security_checks['permission']);

// File to include?
if (isset($profile_include_data['file']))
require_once($sourcedir '/' $profile_include_data['file']);

// Make sure that the area function does exist!
if (!isset($profile_include_data['function']) || !function_exists($profile_include_data['function']))
{
destroyMenu();
fatal_lang_error('no_access'false);
}

// Build the link tree.
$context['linktree'][] = array(
'url' => $scripturl '?action=profile' . ($memID != $user_info['id'] ? ';u=' $memID ''),
'name' => sprintf($txt['profile_of_username'], $context['member']['name']),
);

if (!empty($profile_include_data['label']))
$context['linktree'][] = array(
'url' => $scripturl '?action=profile' . ($memID != $user_info['id'] ? ';u=' $memID '') . ';area=' $profile_include_data['current_area'],
'name' => $profile_include_data['label'],
);

if (!empty($profile_include_data['current_subsection']) && $profile_include_data['subsections'][$profile_include_data['current_subsection']][0] != $profile_include_data['label'])
$context['linktree'][] = array(
'url' => $scripturl '?action=profile' . ($memID != $user_info['id'] ? ';u=' $memID '') . ';area=' $profile_include_data['current_area'] . ';sa=' $profile_include_data['current_subsection'],
'name' => $profile_include_data['subsections'][$profile_include_data['current_subsection']][0],
);

// Set the template for this area and add the profile layer.
$context['sub_template'] = $profile_include_data['function'];
$context['template_layers'][] = 'profile';

// All the subactions that require a user password in order to validate.
$check_password $context['user']['is_owner'] && in_array($profile_include_data['current_area'], $context['password_areas']);
$context['require_password'] = $check_password && empty($user_settings['openid_uri']);

// If we're in wireless then we have a cut down template...
if (WIRELESS && $context['sub_template'] == 'summary' && WIRELESS_PROTOCOL != 'wap')
$context['sub_template'] = WIRELESS_PROTOCOL '_profile';

// These will get populated soon!
$post_errors = array();
$profile_vars = array();

// Right - are we saving - if so let's save the old data first.
if ($context['completed_save'])
{
// If it's someone elses profile then validate the session.
if (!$context['user']['is_owner'])
validateSession();

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

if ($check_password)
{
// If we're using OpenID try to revalidate.
if (!empty($user_settings['openid_uri']))
{
require_once($sourcedir '/Subs-OpenID.php');
smf_openID_revalidate();
}
else
{
// 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'] = un_htmlspecialchars($_POST['oldpasswrd']);

// Does the integration want to check passwords?
$good_password in_array(truecall_integration_hook('integrate_verify_password', array($cur_profile['member_name'], $_POST['oldpasswrd'], false)), true);

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

// Warn other elements not to jump the gun and do custom changes!
if (in_array('bad_password'$post_errors))
$context['password_auth_failed'] = true;
}
}

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

// Now call the sub-action function...
if ($current_area == 'activateaccount')
{
if (empty($post_errors))
activateAccount($memID);
}
elseif ($current_area == 'deleteaccount')
{
if (empty($post_errors))
{
deleteAccount2($profile_vars$post_errors$memID);
redirectexit();
}
}
elseif ($current_area == 'groupmembership' && empty($post_errors))
{
$msg groupMembership2($profile_vars$post_errors$memID);

// Whatever we've done, we have nothing else to do here...
redirectexit('action=profile' . ($context['user']['is_owner'] ? '' ';u=' $memID) . ';area=groupmembership' . (!empty($msg) ? ';msg=' $msg ''));
}
// Authentication changes?
elseif ($current_area == 'authentication')
{
authentication($memIDtrue);
}
elseif (in_array($current_area, array('account''forumprofile''theme''pmprefs')))
saveProfileFields();
else
{
$force_redirect true;
// Ensure we include this.
require_once($sourcedir '/Profile-Modify.php');
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;
}
elseif (!empty($profile_vars))
{
// If we've changed the password, notify any integration that may be listening in.
if (isset($profile_vars['passwd']))
call_integration_hook('integrate_reset_pass', array($cur_profile['member_name'], $cur_profile['member_name'], $_POST['passwrd2']));

updateMemberData($memID$profile_vars);

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

// If the member changed his/her birthdate, update calendar statistics.
if (isset($profile_vars['birthdate']) || isset($profile_vars['real_name']))
updateSettings(array(
'calendar_updated' => time(),
));

// Anything worth logging?
if (!empty($context['log_changes']) && !empty($modSettings['modlog_enabled']))
{
$log_changes = array();
foreach ($context['log_changes'] as $k => $v)
$log_changes[] = array(
'action' => $k,
'id_log' => 2,
'log_time' => time(),
'id_member' => $memID,
'ip' => $user_info['ip'],
'extra' => serialize(array_merge($v, array('applicator' => $user_info['id']))),
);
$smcFunc['db_insert']('',
'{db_prefix}log_actions',
array(
'action' => 'string''id_log' => 'int''log_time' => 'int''id_member' => 'int''ip' => 'string-16',
'extra' => 'string-65534',
),
$log_changes,
array('id_action')
);
}

// Have we got any post save functions to execute?
if (!empty($context['profile_execute_on_save']))
foreach ($context['profile_execute_on_save'] as $saveFunc)
$saveFunc();

// Let them know it worked!
$context['profile_updated'] = $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $cur_profile['member_name']);

// Invalidate any cached data.
cache_put_data('member_data-profile-' $memIDnull0);
}
}

// Have some errors for some reason?
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;
}
// If it's you then we should redirect upon save.
elseif (!empty($profile_vars) && $context['user']['is_owner'])
redirectexit('action=profile;area=' $current_area ';updated');
elseif (!empty($force_redirect))
redirectexit('action=profile' . ($context['user']['is_owner'] ? '' ';u=' $memID) . ';area=' $current_area);

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

// Set the page title if it's not already set...
if (!isset($context['page_title']))
$context['page_title'] = $txt['profile'] . (isset($txt[$current_area]) ? ' - ' $txt[$current_area] : '');
}

// Load any custom fields for this area... no area means load all, 'summary' loads all public ones.
function loadCustomFields($memID$area 'summary')
{
global $context$txt$user_profile$smcFunc$user_info$settings$scripturl;

// Get the right restrictions in place...
$where 'active = 1';
if (!allowedTo('admin_forum') && $area != 'register')
{
// If it's the owner they can see two types of private fields, regardless.
if ($memID == $user_info['id'])
$where .= $area == 'summary' ' AND private < 3' ' AND (private = 0 OR private = 2)';
else
$where .= $area == 'summary' ' AND private < 2' ' AND private = 0';
}

if ($area == 'register')
$where .= ' AND show_reg != 0';
elseif ($area != 'summary')
$where .= ' AND show_profile = {string:area}';

// Load all the relevant fields - and data.
$request $smcFunc['db_query']('''
SELECT
col_name, field_name, field_desc, field_type, field_length, field_options,
default_value, bbc, enclose, placement
FROM {db_prefix}custom_fields
WHERE ' 
$where,
array(
'area' => $area,
)
);
$context['custom_fields'] = array();
while ($row $smcFunc['db_fetch_assoc']($request))
{
// Shortcut.
$exists $memID && isset($user_profile[$memID], $user_profile[$memID]['options'][$row['col_name']]);
$value $exists $user_profile[$memID]['options'][$row['col_name']] : '';

// If this was submitted already then make the value the posted version.
if (isset($_POST['customfield']) && isset($_POST['customfield'][$row['col_name']]))
{
$value $smcFunc['htmlspecialchars']($_POST['customfield'][$row['col_name']]);
if (in_array($row['field_type'], array('select''radio')))
$value = ($options explode(','$row['field_options'])) && isset($options[$value]) ? $options[$value] : '';
}

// HTML for the input form.
$output_html $value;
if ($row['field_type'] == 'check')
{
$true = (!$exists && $row['default_value']) || $value;
$input_html '<input type="checkbox" name="customfield[' $row['col_name'] . ']" ' . ($true 'checked="checked"' '') . ' class="input_check" />';
$output_html $true $txt['yes'] : $txt['no'];
}
elseif ($row['field_type'] == 'select')
{
$input_html '<select name="customfield[' $row['col_name'] . ']"><option value="-1"></option>';
$options explode(','$row['field_options']);
foreach ($options as $k => $v)
{
$true = (!$exists && $row['default_value'] == $v) || $value == $v;
$input_html .= '<option value="' $k '"' . ($true ' selected="selected"' '') . '>' $v '</option>';
if ($true)
$output_html $v;
}

$input_html .= '</select>';
}
elseif ($row['field_type'] == 'radio')
{
$input_html '<fieldset>';
$options explode(','$row['field_options']);
foreach ($options as $k => $v)
{
$true = (!$exists && $row['default_value'] == $v) || $value == $v;
$input_html .= '<label for="customfield_' $row['col_name'] . '_' $k '"><input type="radio" name="customfield[' $row['col_name'] . ']" class="input_radio" id="customfield_' $row['col_name'] . '_' $k '" value="' $k '" ' . ($true 'checked="checked"' '') . '>' $v '</label><br />';
if ($true)
$output_html $v;
}
$input_html .= '</fieldset>';
}
elseif ($row['field_type'] == 'text')
{
$input_html '<input type="text" name="customfield[' $row['col_name'] . ']" ' . ($row['field_length'] != 'maxlength="' $row['field_length'] . '"' '') . ' size="' . ($row['field_length'] == || $row['field_length'] >= 50 50 : ($row['field_length'] > 30 30 : ($row['field_length'] > 10 20 10))) . '" value="' $value '" class="input_text" />';
}
else
{
@list ($rows$cols) = @explode(','$row['default_value']);
$input_html '<textarea name="customfield[' $row['col_name'] . ']" ' . (!empty($rows) ? 'rows="' $rows '"' '') . ' ' . (!empty($cols) ? 'cols="' $cols '"' '') . '>' $value '</textarea>';
}

// Parse BBCode
if ($row['bbc'])
$output_html parse_bbc($output_html);
elseif($row['field_type'] == 'textarea')
// Allow for newlines at least
$output_html strtr($output_html, array("\n" => '<br />'));

// Enclosing the user input within some other text?
if (!empty($row['enclose']) && !empty($output_html))
$output_html strtr($row['enclose'], array(
'{SCRIPTURL}' => $scripturl,
'{IMAGES_URL}' => $settings['images_url'],
'{DEFAULT_IMAGES_URL}' => $settings['default_images_url'],
'{INPUT}' => $output_html,
));

$context['custom_fields'][] = array(
'name' => $row['field_name'],
'desc' => $row['field_desc'],
'type' => $row['field_type'],
'input_html' => $input_html,
'output_html' => $output_html,
'placement' => $row['placement'],
'colname' => $row['col_name'],
'value' => $value,
);
}
$smcFunc['db_free_result']($request);
}

?>


Then finally:
Changeuser.template.php in themes
<?php
/**
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines
 * @copyright 2011 Simple Machines
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.0
 */

// Template for the profile side bar - goes before any other profile template.
function template_profile_above()
{
global $context$settings$options$scripturl$modSettings$txt;

echo '
<script type="text/javascript" src="'
$settings['default_theme_url'], '/scripts/profile.js"></script>
<div id="bodbod">
'
;

// Prevent Chrome from auto completing fields when viewing/editing other members profiles
if ($context['browser']['is_chrome'] && !$context['user']['is_owner'])
echo '
<script type="text/javascript"><!-- // --><![CDATA[
disableAutoComplete();
// ]]></script>'
;

/*
// If an error occurred while trying to save previously, give the user a clue!
if (!empty($context['post_errors']) && $context['section'] !== 'forumprofile')
echo '
', template_error_message();

// If the profile was update successfully, let the user know this.
if (!empty($context['profile_updated']) && $section['section'] !== 'forumprofile')
echo '
<div id="profile_success">
', $context['profile_updated'], '
</div>'
*/
;
}

// Template for closing off table started in profile_above.
function template_profile_below()
{
echo '
</div>
'
;
}

// This template displays users details without any option to edit them.
function template_summary()
{
global $context$settings$options$scripturl$modSettings$txt;

echo '
<header>

<a href="' 
$context['member']['href'] . '">&laquo; Back to Profile</a>


<h1>Change username</h1>

</header>
 
  <div id="main">

 
  <section>
 
  <h1>New Username</h1>

  <div><h2>Choose new username. <br />Only letters, numbers, dots and spaces are allowed.</h2>  
<form action="'
, (!empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl '?action=profile;area=forumprofile;u=' $context['id_member'] . ';save'), '" method="post" accept-charset="'$context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data" onsubmit="return checkProfileSubmit();">';

echo '
<input type="text" name="real_name" id="url" size="30" style="width:200px;" placeholder="'
$context['member']['name'], '" />

 
    </div>
 
  </section>
     
  <input id="subchang" type="image" src="/Themes/Captain%20Kidd/images/button_continue.png" height="36" width="102" alt="Continue" value="'
$txt['change_profile'], '" />
<input type="hidden" name="'
$context['session_var'], '" value="'$context['session_id'], '" />
<input type="hidden" name="u" value="'
$context['id_member'], '" />
<input type="hidden" name="sa" value="'
$context['menu_item_selected'], '" />
</form>
 
 
  </div>
 
  <footer></footer>
'
;
}

?>


So, can I modify what I have so far without having to start all over again? As you can see, I've styled the action page for changeusername, but I am getting errors. Can I just take your changes and apply them to these?

Advertisement: