annotate forum/Sources/Profile.php @ 76:e3e11437ecea website

Add forum code
author Chris Cannam
date Sun, 07 Jul 2013 11:25:48 +0200
parents
children
rev   line source
Chris@76 1 <?php
Chris@76 2
Chris@76 3 /**
Chris@76 4 * Simple Machines Forum (SMF)
Chris@76 5 *
Chris@76 6 * @package SMF
Chris@76 7 * @author Simple Machines http://www.simplemachines.org
Chris@76 8 * @copyright 2011 Simple Machines
Chris@76 9 * @license http://www.simplemachines.org/about/smf/license.php BSD
Chris@76 10 *
Chris@76 11 * @version 2.0
Chris@76 12 */
Chris@76 13
Chris@76 14 if (!defined('SMF'))
Chris@76 15 die('Hacking attempt...');
Chris@76 16
Chris@76 17 /* This file has the primary job of showing and editing people's profiles.
Chris@76 18 It also allows the user to change some of their or another's preferences,
Chris@76 19 and such things. It uses the following functions:
Chris@76 20
Chris@76 21 void ModifyProfile(array errors = none)
Chris@76 22 // !!!
Chris@76 23
Chris@76 24 void loadCustomFields(int id_member, string area)
Chris@76 25 // !!!
Chris@76 26
Chris@76 27 */
Chris@76 28
Chris@76 29 // Allow the change or view of profiles...
Chris@76 30 function ModifyProfile($post_errors = array())
Chris@76 31 {
Chris@76 32 global $txt, $scripturl, $user_info, $context, $sourcedir, $user_profile, $cur_profile;
Chris@76 33 global $modSettings, $memberContext, $profile_vars, $smcFunc, $post_errors, $options, $user_settings;
Chris@76 34
Chris@76 35 // Don't reload this as we may have processed error strings.
Chris@76 36 if (empty($post_errors))
Chris@76 37 loadLanguage('Profile');
Chris@76 38 loadTemplate('Profile');
Chris@76 39
Chris@76 40 require_once($sourcedir . '/Subs-Menu.php');
Chris@76 41
Chris@76 42 // Did we get the user by name...
Chris@76 43 if (isset($_REQUEST['user']))
Chris@76 44 $memberResult = loadMemberData($_REQUEST['user'], true, 'profile');
Chris@76 45 // ... or by id_member?
Chris@76 46 elseif (!empty($_REQUEST['u']))
Chris@76 47 $memberResult = loadMemberData((int) $_REQUEST['u'], false, 'profile');
Chris@76 48 // If it was just ?action=profile, edit your own profile.
Chris@76 49 else
Chris@76 50 $memberResult = loadMemberData($user_info['id'], false, 'profile');
Chris@76 51
Chris@76 52 // Check if loadMemberData() has returned a valid result.
Chris@76 53 if (!is_array($memberResult))
Chris@76 54 fatal_lang_error('not_a_user', false);
Chris@76 55
Chris@76 56 // If all went well, we have a valid member ID!
Chris@76 57 list ($memID) = $memberResult;
Chris@76 58 $context['id_member'] = $memID;
Chris@76 59 $cur_profile = $user_profile[$memID];
Chris@76 60
Chris@76 61 // Let's have some information about this member ready, too.
Chris@76 62 loadMemberContext($memID);
Chris@76 63 $context['member'] = $memberContext[$memID];
Chris@76 64
Chris@76 65 // Is this the profile of the user himself or herself?
Chris@76 66 $context['user']['is_owner'] = $memID == $user_info['id'];
Chris@76 67
Chris@76 68 /* Define all the sections within the profile area!
Chris@76 69 We start by defining the permission required - then SMF takes this and turns it into the relevant context ;)
Chris@76 70 Possible fields:
Chris@76 71 For Section:
Chris@76 72 string $title: Section title.
Chris@76 73 array $areas: Array of areas within this section.
Chris@76 74
Chris@76 75 For Areas:
Chris@76 76 string $label: Text string that will be used to show the area in the menu.
Chris@76 77 string $file: Optional text string that may contain a file name that's needed for inclusion in order to display the area properly.
Chris@76 78 string $custom_url: Optional href for area.
Chris@76 79 string $function: Function to execute for this section.
Chris@76 80 bool $enabled: Should area be shown?
Chris@76 81 string $sc: Session check validation to do on save - note without this save will get unset - if set.
Chris@76 82 bool $hidden: Does this not actually appear on the menu?
Chris@76 83 bool $password: Whether to require the user's password in order to save the data in the area.
Chris@76 84 array $subsections: Array of subsections, in order of appearance.
Chris@76 85 array $permission: Array of permissions to determine who can access this area. Should contain arrays $own and $any.
Chris@76 86 */
Chris@76 87 $profile_areas = array(
Chris@76 88 'info' => array(
Chris@76 89 'title' => $txt['profileInfo'],
Chris@76 90 'areas' => array(
Chris@76 91 'summary' => array(
Chris@76 92 'label' => $txt['summary'],
Chris@76 93 'file' => 'Profile-View.php',
Chris@76 94 'function' => 'summary',
Chris@76 95 'permission' => array(
Chris@76 96 'own' => 'profile_view_own',
Chris@76 97 'any' => 'profile_view_any',
Chris@76 98 ),
Chris@76 99 ),
Chris@76 100 'statistics' => array(
Chris@76 101 'label' => $txt['statPanel'],
Chris@76 102 'file' => 'Profile-View.php',
Chris@76 103 'function' => 'statPanel',
Chris@76 104 'permission' => array(
Chris@76 105 'own' => 'profile_view_own',
Chris@76 106 'any' => 'profile_view_any',
Chris@76 107 ),
Chris@76 108 ),
Chris@76 109 'showposts' => array(
Chris@76 110 'label' => $txt['showPosts'],
Chris@76 111 'file' => 'Profile-View.php',
Chris@76 112 'function' => 'showPosts',
Chris@76 113 'subsections' => array(
Chris@76 114 'messages' => array($txt['showMessages'], array('profile_view_own', 'profile_view_any')),
Chris@76 115 'topics' => array($txt['showTopics'], array('profile_view_own', 'profile_view_any')),
Chris@76 116 'attach' => array($txt['showAttachments'], array('profile_view_own', 'profile_view_any')),
Chris@76 117 ),
Chris@76 118 'permission' => array(
Chris@76 119 'own' => 'profile_view_own',
Chris@76 120 'any' => 'profile_view_any',
Chris@76 121 ),
Chris@76 122 ),
Chris@76 123 'permissions' => array(
Chris@76 124 'label' => $txt['showPermissions'],
Chris@76 125 'file' => 'Profile-View.php',
Chris@76 126 'function' => 'showPermissions',
Chris@76 127 'permission' => array(
Chris@76 128 'own' => 'manage_permissions',
Chris@76 129 'any' => 'manage_permissions',
Chris@76 130 ),
Chris@76 131 ),
Chris@76 132 'tracking' => array(
Chris@76 133 'label' => $txt['trackUser'],
Chris@76 134 'file' => 'Profile-View.php',
Chris@76 135 'function' => 'tracking',
Chris@76 136 'subsections' => array(
Chris@76 137 'activity' => array($txt['trackActivity'], 'moderate_forum'),
Chris@76 138 'ip' => array($txt['trackIP'], 'moderate_forum'),
Chris@76 139 'edits' => array($txt['trackEdits'], 'moderate_forum'),
Chris@76 140 ),
Chris@76 141 'permission' => array(
Chris@76 142 'own' => 'moderate_forum',
Chris@76 143 'any' => 'moderate_forum',
Chris@76 144 ),
Chris@76 145 ),
Chris@76 146 'viewwarning' => array(
Chris@76 147 'label' => $txt['profile_view_warnings'],
Chris@76 148 'enabled' => in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1 && $cur_profile['warning'] && $context['user']['is_owner'] && !empty($modSettings['warning_show']),
Chris@76 149 'file' => 'Profile-View.php',
Chris@76 150 'function' => 'viewWarning',
Chris@76 151 'permission' => array(
Chris@76 152 'own' => 'profile_view_own',
Chris@76 153 'any' => 'issue_warning',
Chris@76 154 ),
Chris@76 155 ),
Chris@76 156 ),
Chris@76 157 ),
Chris@76 158 'edit_profile' => array(
Chris@76 159 'title' => $txt['profileEdit'],
Chris@76 160 'areas' => array(
Chris@76 161 'account' => array(
Chris@76 162 'label' => $txt['account'],
Chris@76 163 'file' => 'Profile-Modify.php',
Chris@76 164 'function' => 'account',
Chris@76 165 'enabled' => $context['user']['is_admin'] || ($cur_profile['id_group'] != 1 && !in_array(1, explode(',', $cur_profile['additional_groups']))),
Chris@76 166 'sc' => 'post',
Chris@76 167 'password' => true,
Chris@76 168 'permission' => array(
Chris@76 169 'own' => array('profile_identity_any', 'profile_identity_own', 'manage_membergroups'),
Chris@76 170 'any' => array('profile_identity_any', 'manage_membergroups'),
Chris@76 171 ),
Chris@76 172 ),
Chris@76 173 'forumprofile' => array(
Chris@76 174 'label' => $txt['forumprofile'],
Chris@76 175 'file' => 'Profile-Modify.php',
Chris@76 176 'function' => 'forumProfile',
Chris@76 177 'sc' => 'post',
Chris@76 178 'permission' => array(
Chris@76 179 'own' => array('profile_extra_any', 'profile_extra_own', 'profile_title_own', 'profile_title_any'),
Chris@76 180 'any' => array('profile_extra_any', 'profile_title_any'),
Chris@76 181 ),
Chris@76 182 ),
Chris@76 183 'theme' => array(
Chris@76 184 'label' => $txt['theme'],
Chris@76 185 'file' => 'Profile-Modify.php',
Chris@76 186 'function' => 'theme',
Chris@76 187 'sc' => 'post',
Chris@76 188 'permission' => array(
Chris@76 189 'own' => array('profile_extra_any', 'profile_extra_own'),
Chris@76 190 'any' => array('profile_extra_any'),
Chris@76 191 ),
Chris@76 192 ),
Chris@76 193 'authentication' => array(
Chris@76 194 'label' => $txt['authentication'],
Chris@76 195 'file' => 'Profile-Modify.php',
Chris@76 196 'function' => 'authentication',
Chris@76 197 'enabled' => !empty($modSettings['enableOpenID']) || !empty($cur_profile['openid_uri']),
Chris@76 198 'sc' => 'post',
Chris@76 199 'hidden' => empty($modSettings['enableOpenID']) && empty($cur_profile['openid_uri']),
Chris@76 200 'password' => true,
Chris@76 201 'permission' => array(
Chris@76 202 'own' => array('profile_identity_any', 'profile_identity_own'),
Chris@76 203 'any' => array('profile_identity_any'),
Chris@76 204 ),
Chris@76 205 ),
Chris@76 206 'notification' => array(
Chris@76 207 'label' => $txt['notification'],
Chris@76 208 'file' => 'Profile-Modify.php',
Chris@76 209 'function' => 'notification',
Chris@76 210 'sc' => 'post',
Chris@76 211 'permission' => array(
Chris@76 212 'own' => array('profile_extra_any', 'profile_extra_own'),
Chris@76 213 'any' => array('profile_extra_any'),
Chris@76 214 ),
Chris@76 215 ),
Chris@76 216 // Without profile_extra_own, settings are accessible from the PM section.
Chris@76 217 'pmprefs' => array(
Chris@76 218 'label' => $txt['pmprefs'],
Chris@76 219 'file' => 'Profile-Modify.php',
Chris@76 220 'function' => 'pmprefs',
Chris@76 221 'enabled' => allowedTo(array('profile_extra_own', 'profile_extra_any')),
Chris@76 222 'sc' => 'post',
Chris@76 223 'permission' => array(
Chris@76 224 'own' => array('pm_read'),
Chris@76 225 'any' => array('profile_extra_any'),
Chris@76 226 ),
Chris@76 227 ),
Chris@76 228 'ignoreboards' => array(
Chris@76 229 'label' => $txt['ignoreboards'],
Chris@76 230 'file' => 'Profile-Modify.php',
Chris@76 231 'function' => 'ignoreboards',
Chris@76 232 'enabled' => !empty($modSettings['allow_ignore_boards']),
Chris@76 233 'sc' => 'post',
Chris@76 234 'permission' => array(
Chris@76 235 'own' => array('profile_extra_any', 'profile_extra_own'),
Chris@76 236 'any' => array('profile_extra_any'),
Chris@76 237 ),
Chris@76 238 ),
Chris@76 239 'lists' => array(
Chris@76 240 'label' => $txt['editBuddyIgnoreLists'],
Chris@76 241 'file' => 'Profile-Modify.php',
Chris@76 242 'function' => 'editBuddyIgnoreLists',
Chris@76 243 'enabled' => !empty($modSettings['enable_buddylist']) && $context['user']['is_owner'],
Chris@76 244 'sc' => 'post',
Chris@76 245 'subsections' => array(
Chris@76 246 'buddies' => array($txt['editBuddies']),
Chris@76 247 'ignore' => array($txt['editIgnoreList']),
Chris@76 248 ),
Chris@76 249 'permission' => array(
Chris@76 250 'own' => array('profile_extra_any', 'profile_extra_own'),
Chris@76 251 'any' => array(),
Chris@76 252 ),
Chris@76 253 ),
Chris@76 254 'groupmembership' => array(
Chris@76 255 'label' => $txt['groupmembership'],
Chris@76 256 'file' => 'Profile-Modify.php',
Chris@76 257 'function' => 'groupMembership',
Chris@76 258 'enabled' => !empty($modSettings['show_group_membership']) && $context['user']['is_owner'],
Chris@76 259 'sc' => 'request',
Chris@76 260 'permission' => array(
Chris@76 261 'own' => array('profile_view_own'),
Chris@76 262 'any' => array('manage_membergroups'),
Chris@76 263 ),
Chris@76 264 ),
Chris@76 265 ),
Chris@76 266 ),
Chris@76 267 'profile_action' => array(
Chris@76 268 'title' => $txt['profileAction'],
Chris@76 269 'areas' => array(
Chris@76 270 'sendpm' => array(
Chris@76 271 'label' => $txt['profileSendIm'],
Chris@76 272 'custom_url' => $scripturl . '?action=pm;sa=send',
Chris@76 273 'permission' => array(
Chris@76 274 'own' => array(),
Chris@76 275 'any' => array('pm_send'),
Chris@76 276 ),
Chris@76 277 ),
Chris@76 278 'issuewarning' => array(
Chris@76 279 'label' => $txt['profile_issue_warning'],
Chris@76 280 'enabled' => in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1 && (!$context['user']['is_owner'] || $context['user']['is_admin']),
Chris@76 281 'file' => 'Profile-Actions.php',
Chris@76 282 'function' => 'issueWarning',
Chris@76 283 'permission' => array(
Chris@76 284 'own' => array('issue_warning'),
Chris@76 285 'any' => array('issue_warning'),
Chris@76 286 ),
Chris@76 287 ),
Chris@76 288 'banuser' => array(
Chris@76 289 'label' => $txt['profileBanUser'],
Chris@76 290 'custom_url' => $scripturl . '?action=admin;area=ban;sa=add',
Chris@76 291 'enabled' => $cur_profile['id_group'] != 1 && !in_array(1, explode(',', $cur_profile['additional_groups'])),
Chris@76 292 'permission' => array(
Chris@76 293 'own' => array(),
Chris@76 294 'any' => array('manage_bans'),
Chris@76 295 ),
Chris@76 296 ),
Chris@76 297 'subscriptions' => array(
Chris@76 298 'label' => $txt['subscriptions'],
Chris@76 299 'file' => 'Profile-Actions.php',
Chris@76 300 'function' => 'subscriptions',
Chris@76 301 'enabled' => !empty($modSettings['paid_enabled']),
Chris@76 302 'permission' => array(
Chris@76 303 'own' => array('profile_view_own'),
Chris@76 304 'any' => array('moderate_forum'),
Chris@76 305 ),
Chris@76 306 ),
Chris@76 307 'deleteaccount' => array(
Chris@76 308 'label' => $txt['deleteAccount'],
Chris@76 309 'file' => 'Profile-Actions.php',
Chris@76 310 'function' => 'deleteAccount',
Chris@76 311 'sc' => 'post',
Chris@76 312 'password' => true,
Chris@76 313 'permission' => array(
Chris@76 314 'own' => array('profile_remove_any', 'profile_remove_own'),
Chris@76 315 'any' => array('profile_remove_any'),
Chris@76 316 ),
Chris@76 317 ),
Chris@76 318 'activateaccount' => array(
Chris@76 319 'file' => 'Profile-Actions.php',
Chris@76 320 'function' => 'activateAccount',
Chris@76 321 'sc' => 'get',
Chris@76 322 'select' => 'summary',
Chris@76 323 'permission' => array(
Chris@76 324 'own' => array(),
Chris@76 325 'any' => array('moderate_forum'),
Chris@76 326 ),
Chris@76 327 ),
Chris@76 328 ),
Chris@76 329 ),
Chris@76 330 );
Chris@76 331
Chris@76 332 // Let them modify profile areas easily.
Chris@76 333 call_integration_hook('integrate_profile_areas', array(&$profile_areas));
Chris@76 334
Chris@76 335 // Do some cleaning ready for the menu function.
Chris@76 336 $context['password_areas'] = array();
Chris@76 337 $current_area = isset($_REQUEST['area']) ? $_REQUEST['area'] : '';
Chris@76 338
Chris@76 339 foreach ($profile_areas as $section_id => $section)
Chris@76 340 {
Chris@76 341 // Do a bit of spring cleaning so to speak.
Chris@76 342 foreach ($section['areas'] as $area_id => $area)
Chris@76 343 {
Chris@76 344 // If it said no permissions that meant it wasn't valid!
Chris@76 345 if (empty($area['permission'][$context['user']['is_owner'] ? 'own' : 'any']))
Chris@76 346 $profile_areas[$section_id]['areas'][$area_id]['enabled'] = false;
Chris@76 347 // Otherwise pick the right set.
Chris@76 348 else
Chris@76 349 $profile_areas[$section_id]['areas'][$area_id]['permission'] = $area['permission'][$context['user']['is_owner'] ? 'own' : 'any'];
Chris@76 350
Chris@76 351 // Password required - only if not on OpenID.
Chris@76 352 if (!empty($area['password']))
Chris@76 353 $context['password_areas'][] = $area_id;
Chris@76 354 }
Chris@76 355 }
Chris@76 356
Chris@76 357 // Is there an updated message to show?
Chris@76 358 if (isset($_GET['updated']))
Chris@76 359 $context['profile_updated'] = $txt['profile_updated_own'];
Chris@76 360
Chris@76 361 // Set a few options for the menu.
Chris@76 362 $menuOptions = array(
Chris@76 363 'disable_url_session_check' => true,
Chris@76 364 'current_area' => $current_area,
Chris@76 365 'extra_url_parameters' => array(
Chris@76 366 'u' => $context['id_member'],
Chris@76 367 ),
Chris@76 368 );
Chris@76 369
Chris@76 370 // Actually create the menu!
Chris@76 371 $profile_include_data = createMenu($profile_areas, $menuOptions);
Chris@76 372
Chris@76 373 // No menu means no access.
Chris@76 374 if (!$profile_include_data && (!$user_info['is_guest'] || validateSession()))
Chris@76 375 fatal_lang_error('no_access', false);
Chris@76 376
Chris@76 377 // Make a note of the Unique ID for this menu.
Chris@76 378 $context['profile_menu_id'] = $context['max_menu_id'];
Chris@76 379 $context['profile_menu_name'] = 'menu_data_' . $context['profile_menu_id'];
Chris@76 380
Chris@76 381 // Set the selected item - now it's been validated.
Chris@76 382 $current_area = $profile_include_data['current_area'];
Chris@76 383 $context['menu_item_selected'] = $current_area;
Chris@76 384
Chris@76 385 // 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!
Chris@76 386 $context['completed_save'] = false;
Chris@76 387 $security_checks = array();
Chris@76 388 $found_area = false;
Chris@76 389 foreach ($profile_areas as $section_id => $section)
Chris@76 390 {
Chris@76 391 // Do a bit of spring cleaning so to speak.
Chris@76 392 foreach ($section['areas'] as $area_id => $area)
Chris@76 393 {
Chris@76 394 // Is this our area?
Chris@76 395 if ($current_area == $area_id)
Chris@76 396 {
Chris@76 397 // This can't happen - but is a security check.
Chris@76 398 if ((isset($section['enabled']) && $section['enabled'] == false) || (isset($area['enabled']) && $area['enabled'] == false))
Chris@76 399 fatal_lang_error('no_access', false);
Chris@76 400
Chris@76 401 // Are we saving data in a valid area?
Chris@76 402 if (isset($area['sc']) && isset($_REQUEST['save']))
Chris@76 403 {
Chris@76 404 $security_checks['session'] = $area['sc'];
Chris@76 405 $context['completed_save'] = true;
Chris@76 406 }
Chris@76 407
Chris@76 408 // Does this require session validating?
Chris@76 409 if (!empty($area['validate']))
Chris@76 410 $security_checks['validate'] = true;
Chris@76 411
Chris@76 412 // Permissions for good measure.
Chris@76 413 if (!empty($profile_include_data['permission']))
Chris@76 414 $security_checks['permission'] = $profile_include_data['permission'];
Chris@76 415
Chris@76 416 // Either way got something.
Chris@76 417 $found_area = true;
Chris@76 418 }
Chris@76 419 }
Chris@76 420 }
Chris@76 421
Chris@76 422 // Oh dear, some serious security lapse is going on here... we'll put a stop to that!
Chris@76 423 if (!$found_area)
Chris@76 424 fatal_lang_error('no_access', false);
Chris@76 425
Chris@76 426 // Release this now.
Chris@76 427 unset($profile_areas);
Chris@76 428
Chris@76 429 // Now the context is setup have we got any security checks to carry out additional to that above?
Chris@76 430 if (isset($security_checks['session']))
Chris@76 431 checkSession($security_checks['session']);
Chris@76 432 if (isset($security_checks['validate']))
Chris@76 433 validateSession();
Chris@76 434 if (isset($security_checks['permission']))
Chris@76 435 isAllowedTo($security_checks['permission']);
Chris@76 436
Chris@76 437 // File to include?
Chris@76 438 if (isset($profile_include_data['file']))
Chris@76 439 require_once($sourcedir . '/' . $profile_include_data['file']);
Chris@76 440
Chris@76 441 // Make sure that the area function does exist!
Chris@76 442 if (!isset($profile_include_data['function']) || !function_exists($profile_include_data['function']))
Chris@76 443 {
Chris@76 444 destroyMenu();
Chris@76 445 fatal_lang_error('no_access', false);
Chris@76 446 }
Chris@76 447
Chris@76 448 // Build the link tree.
Chris@76 449 $context['linktree'][] = array(
Chris@76 450 'url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : ''),
Chris@76 451 'name' => sprintf($txt['profile_of_username'], $context['member']['name']),
Chris@76 452 );
Chris@76 453
Chris@76 454 if (!empty($profile_include_data['label']))
Chris@76 455 $context['linktree'][] = array(
Chris@76 456 'url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : '') . ';area=' . $profile_include_data['current_area'],
Chris@76 457 'name' => $profile_include_data['label'],
Chris@76 458 );
Chris@76 459
Chris@76 460 if (!empty($profile_include_data['current_subsection']) && $profile_include_data['subsections'][$profile_include_data['current_subsection']][0] != $profile_include_data['label'])
Chris@76 461 $context['linktree'][] = array(
Chris@76 462 'url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : '') . ';area=' . $profile_include_data['current_area'] . ';sa=' . $profile_include_data['current_subsection'],
Chris@76 463 'name' => $profile_include_data['subsections'][$profile_include_data['current_subsection']][0],
Chris@76 464 );
Chris@76 465
Chris@76 466 // Set the template for this area and add the profile layer.
Chris@76 467 $context['sub_template'] = $profile_include_data['function'];
Chris@76 468 $context['template_layers'][] = 'profile';
Chris@76 469
Chris@76 470 // All the subactions that require a user password in order to validate.
Chris@76 471 $check_password = $context['user']['is_owner'] && in_array($profile_include_data['current_area'], $context['password_areas']);
Chris@76 472 $context['require_password'] = $check_password && empty($user_settings['openid_uri']);
Chris@76 473
Chris@76 474 // If we're in wireless then we have a cut down template...
Chris@76 475 if (WIRELESS && $context['sub_template'] == 'summary' && WIRELESS_PROTOCOL != 'wap')
Chris@76 476 $context['sub_template'] = WIRELESS_PROTOCOL . '_profile';
Chris@76 477
Chris@76 478 // These will get populated soon!
Chris@76 479 $post_errors = array();
Chris@76 480 $profile_vars = array();
Chris@76 481
Chris@76 482 // Right - are we saving - if so let's save the old data first.
Chris@76 483 if ($context['completed_save'])
Chris@76 484 {
Chris@76 485 // If it's someone elses profile then validate the session.
Chris@76 486 if (!$context['user']['is_owner'])
Chris@76 487 validateSession();
Chris@76 488
Chris@76 489 // Clean up the POST variables.
Chris@76 490 $_POST = htmltrim__recursive($_POST);
Chris@76 491 $_POST = htmlspecialchars__recursive($_POST);
Chris@76 492
Chris@76 493 if ($check_password)
Chris@76 494 {
Chris@76 495 // If we're using OpenID try to revalidate.
Chris@76 496 if (!empty($user_settings['openid_uri']))
Chris@76 497 {
Chris@76 498 require_once($sourcedir . '/Subs-OpenID.php');
Chris@76 499 smf_openID_revalidate();
Chris@76 500 }
Chris@76 501 else
Chris@76 502 {
Chris@76 503 // You didn't even enter a password!
Chris@76 504 if (trim($_POST['oldpasswrd']) == '')
Chris@76 505 $post_errors[] = 'no_password';
Chris@76 506
Chris@76 507 // Since the password got modified due to all the $_POST cleaning, lets undo it so we can get the correct password
Chris@76 508 $_POST['oldpasswrd'] = un_htmlspecialchars($_POST['oldpasswrd']);
Chris@76 509
Chris@76 510 // Does the integration want to check passwords?
Chris@76 511 $good_password = in_array(true, call_integration_hook('integrate_verify_password', array($cur_profile['member_name'], $_POST['oldpasswrd'], false)), true);
Chris@76 512
Chris@76 513 // Bad password!!!
Chris@76 514 if (!$good_password && $user_info['passwd'] != sha1(strtolower($cur_profile['member_name']) . $_POST['oldpasswrd']))
Chris@76 515 $post_errors[] = 'bad_password';
Chris@76 516
Chris@76 517 // Warn other elements not to jump the gun and do custom changes!
Chris@76 518 if (in_array('bad_password', $post_errors))
Chris@76 519 $context['password_auth_failed'] = true;
Chris@76 520 }
Chris@76 521 }
Chris@76 522
Chris@76 523 // Change the IP address in the database.
Chris@76 524 if ($context['user']['is_owner'])
Chris@76 525 $profile_vars['member_ip'] = $user_info['ip'];
Chris@76 526
Chris@76 527 // Now call the sub-action function...
Chris@76 528 if ($current_area == 'activateaccount')
Chris@76 529 {
Chris@76 530 if (empty($post_errors))
Chris@76 531 activateAccount($memID);
Chris@76 532 }
Chris@76 533 elseif ($current_area == 'deleteaccount')
Chris@76 534 {
Chris@76 535 if (empty($post_errors))
Chris@76 536 {
Chris@76 537 deleteAccount2($profile_vars, $post_errors, $memID);
Chris@76 538 redirectexit();
Chris@76 539 }
Chris@76 540 }
Chris@76 541 elseif ($current_area == 'groupmembership' && empty($post_errors))
Chris@76 542 {
Chris@76 543 $msg = groupMembership2($profile_vars, $post_errors, $memID);
Chris@76 544
Chris@76 545 // Whatever we've done, we have nothing else to do here...
Chris@76 546 redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $memID) . ';area=groupmembership' . (!empty($msg) ? ';msg=' . $msg : ''));
Chris@76 547 }
Chris@76 548 // Authentication changes?
Chris@76 549 elseif ($current_area == 'authentication')
Chris@76 550 {
Chris@76 551 authentication($memID, true);
Chris@76 552 }
Chris@76 553 elseif (in_array($current_area, array('account', 'forumprofile', 'theme', 'pmprefs')))
Chris@76 554 saveProfileFields();
Chris@76 555 else
Chris@76 556 {
Chris@76 557 $force_redirect = true;
Chris@76 558 // Ensure we include this.
Chris@76 559 require_once($sourcedir . '/Profile-Modify.php');
Chris@76 560 saveProfileChanges($profile_vars, $post_errors, $memID);
Chris@76 561 }
Chris@76 562
Chris@76 563 // There was a problem, let them try to re-enter.
Chris@76 564 if (!empty($post_errors))
Chris@76 565 {
Chris@76 566 // Load the language file so we can give a nice explanation of the errors.
Chris@76 567 loadLanguage('Errors');
Chris@76 568 $context['post_errors'] = $post_errors;
Chris@76 569 }
Chris@76 570 elseif (!empty($profile_vars))
Chris@76 571 {
Chris@76 572 // If we've changed the password, notify any integration that may be listening in.
Chris@76 573 if (isset($profile_vars['passwd']))
Chris@76 574 call_integration_hook('integrate_reset_pass', array($cur_profile['member_name'], $cur_profile['member_name'], $_POST['passwrd2']));
Chris@76 575
Chris@76 576 updateMemberData($memID, $profile_vars);
Chris@76 577
Chris@76 578 // What if this is the newest member?
Chris@76 579 if ($modSettings['latestMember'] == $memID)
Chris@76 580 updateStats('member');
Chris@76 581 elseif (isset($profile_vars['real_name']))
Chris@76 582 updateSettings(array('memberlist_updated' => time()));
Chris@76 583
Chris@76 584 // If the member changed his/her birthdate, update calendar statistics.
Chris@76 585 if (isset($profile_vars['birthdate']) || isset($profile_vars['real_name']))
Chris@76 586 updateSettings(array(
Chris@76 587 'calendar_updated' => time(),
Chris@76 588 ));
Chris@76 589
Chris@76 590 // Anything worth logging?
Chris@76 591 if (!empty($context['log_changes']) && !empty($modSettings['modlog_enabled']))
Chris@76 592 {
Chris@76 593 $log_changes = array();
Chris@76 594 foreach ($context['log_changes'] as $k => $v)
Chris@76 595 $log_changes[] = array(
Chris@76 596 'action' => $k,
Chris@76 597 'id_log' => 2,
Chris@76 598 'log_time' => time(),
Chris@76 599 'id_member' => $memID,
Chris@76 600 'ip' => $user_info['ip'],
Chris@76 601 'extra' => serialize(array_merge($v, array('applicator' => $user_info['id']))),
Chris@76 602 );
Chris@76 603 $smcFunc['db_insert']('',
Chris@76 604 '{db_prefix}log_actions',
Chris@76 605 array(
Chris@76 606 'action' => 'string', 'id_log' => 'int', 'log_time' => 'int', 'id_member' => 'int', 'ip' => 'string-16',
Chris@76 607 'extra' => 'string-65534',
Chris@76 608 ),
Chris@76 609 $log_changes,
Chris@76 610 array('id_action')
Chris@76 611 );
Chris@76 612 }
Chris@76 613
Chris@76 614 // Have we got any post save functions to execute?
Chris@76 615 if (!empty($context['profile_execute_on_save']))
Chris@76 616 foreach ($context['profile_execute_on_save'] as $saveFunc)
Chris@76 617 $saveFunc();
Chris@76 618
Chris@76 619 // Let them know it worked!
Chris@76 620 $context['profile_updated'] = $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $cur_profile['member_name']);
Chris@76 621
Chris@76 622 // Invalidate any cached data.
Chris@76 623 cache_put_data('member_data-profile-' . $memID, null, 0);
Chris@76 624 }
Chris@76 625 }
Chris@76 626
Chris@76 627 // Have some errors for some reason?
Chris@76 628 if (!empty($post_errors))
Chris@76 629 {
Chris@76 630 // Set all the errors so the template knows what went wrong.
Chris@76 631 foreach ($post_errors as $error_type)
Chris@76 632 $context['modify_error'][$error_type] = true;
Chris@76 633 }
Chris@76 634 // If it's you then we should redirect upon save.
Chris@76 635 elseif (!empty($profile_vars) && $context['user']['is_owner'])
Chris@76 636 redirectexit('action=profile;area=' . $current_area . ';updated');
Chris@76 637 elseif (!empty($force_redirect))
Chris@76 638 redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $memID) . ';area=' . $current_area);
Chris@76 639
Chris@76 640 // Call the appropriate subaction function.
Chris@76 641 $profile_include_data['function']($memID);
Chris@76 642
Chris@76 643 // Set the page title if it's not already set...
Chris@76 644 if (!isset($context['page_title']))
Chris@76 645 $context['page_title'] = $txt['profile'] . (isset($txt[$current_area]) ? ' - ' . $txt[$current_area] : '');
Chris@76 646 }
Chris@76 647
Chris@76 648 // Load any custom fields for this area... no area means load all, 'summary' loads all public ones.
Chris@76 649 function loadCustomFields($memID, $area = 'summary')
Chris@76 650 {
Chris@76 651 global $context, $txt, $user_profile, $smcFunc, $user_info, $settings, $scripturl;
Chris@76 652
Chris@76 653 // Get the right restrictions in place...
Chris@76 654 $where = 'active = 1';
Chris@76 655 if (!allowedTo('admin_forum') && $area != 'register')
Chris@76 656 {
Chris@76 657 // If it's the owner they can see two types of private fields, regardless.
Chris@76 658 if ($memID == $user_info['id'])
Chris@76 659 $where .= $area == 'summary' ? ' AND private < 3' : ' AND (private = 0 OR private = 2)';
Chris@76 660 else
Chris@76 661 $where .= $area == 'summary' ? ' AND private < 2' : ' AND private = 0';
Chris@76 662 }
Chris@76 663
Chris@76 664 if ($area == 'register')
Chris@76 665 $where .= ' AND show_reg != 0';
Chris@76 666 elseif ($area != 'summary')
Chris@76 667 $where .= ' AND show_profile = {string:area}';
Chris@76 668
Chris@76 669 // Load all the relevant fields - and data.
Chris@76 670 $request = $smcFunc['db_query']('', '
Chris@76 671 SELECT
Chris@76 672 col_name, field_name, field_desc, field_type, field_length, field_options,
Chris@76 673 default_value, bbc, enclose, placement
Chris@76 674 FROM {db_prefix}custom_fields
Chris@76 675 WHERE ' . $where,
Chris@76 676 array(
Chris@76 677 'area' => $area,
Chris@76 678 )
Chris@76 679 );
Chris@76 680 $context['custom_fields'] = array();
Chris@76 681 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 682 {
Chris@76 683 // Shortcut.
Chris@76 684 $exists = $memID && isset($user_profile[$memID], $user_profile[$memID]['options'][$row['col_name']]);
Chris@76 685 $value = $exists ? $user_profile[$memID]['options'][$row['col_name']] : '';
Chris@76 686
Chris@76 687 // If this was submitted already then make the value the posted version.
Chris@76 688 if (isset($_POST['customfield']) && isset($_POST['customfield'][$row['col_name']]))
Chris@76 689 {
Chris@76 690 $value = $smcFunc['htmlspecialchars']($_POST['customfield'][$row['col_name']]);
Chris@76 691 if (in_array($row['field_type'], array('select', 'radio')))
Chris@76 692 $value = ($options = explode(',', $row['field_options'])) && isset($options[$value]) ? $options[$value] : '';
Chris@76 693 }
Chris@76 694
Chris@76 695 // HTML for the input form.
Chris@76 696 $output_html = $value;
Chris@76 697 if ($row['field_type'] == 'check')
Chris@76 698 {
Chris@76 699 $true = (!$exists && $row['default_value']) || $value;
Chris@76 700 $input_html = '<input type="checkbox" name="customfield[' . $row['col_name'] . ']" ' . ($true ? 'checked="checked"' : '') . ' class="input_check" />';
Chris@76 701 $output_html = $true ? $txt['yes'] : $txt['no'];
Chris@76 702 }
Chris@76 703 elseif ($row['field_type'] == 'select')
Chris@76 704 {
Chris@76 705 $input_html = '<select name="customfield[' . $row['col_name'] . ']"><option value="-1"></option>';
Chris@76 706 $options = explode(',', $row['field_options']);
Chris@76 707 foreach ($options as $k => $v)
Chris@76 708 {
Chris@76 709 $true = (!$exists && $row['default_value'] == $v) || $value == $v;
Chris@76 710 $input_html .= '<option value="' . $k . '"' . ($true ? ' selected="selected"' : '') . '>' . $v . '</option>';
Chris@76 711 if ($true)
Chris@76 712 $output_html = $v;
Chris@76 713 }
Chris@76 714
Chris@76 715 $input_html .= '</select>';
Chris@76 716 }
Chris@76 717 elseif ($row['field_type'] == 'radio')
Chris@76 718 {
Chris@76 719 $input_html = '<fieldset>';
Chris@76 720 $options = explode(',', $row['field_options']);
Chris@76 721 foreach ($options as $k => $v)
Chris@76 722 {
Chris@76 723 $true = (!$exists && $row['default_value'] == $v) || $value == $v;
Chris@76 724 $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 />';
Chris@76 725 if ($true)
Chris@76 726 $output_html = $v;
Chris@76 727 }
Chris@76 728 $input_html .= '</fieldset>';
Chris@76 729 }
Chris@76 730 elseif ($row['field_type'] == 'text')
Chris@76 731 {
Chris@76 732 $input_html = '<input type="text" name="customfield[' . $row['col_name'] . ']" ' . ($row['field_length'] != 0 ? 'maxlength="' . $row['field_length'] . '"' : '') . ' size="' . ($row['field_length'] == 0 || $row['field_length'] >= 50 ? 50 : ($row['field_length'] > 30 ? 30 : ($row['field_length'] > 10 ? 20 : 10))) . '" value="' . $value . '" class="input_text" />';
Chris@76 733 }
Chris@76 734 else
Chris@76 735 {
Chris@76 736 @list ($rows, $cols) = @explode(',', $row['default_value']);
Chris@76 737 $input_html = '<textarea name="customfield[' . $row['col_name'] . ']" ' . (!empty($rows) ? 'rows="' . $rows . '"' : '') . ' ' . (!empty($cols) ? 'cols="' . $cols . '"' : '') . '>' . $value . '</textarea>';
Chris@76 738 }
Chris@76 739
Chris@76 740 // Parse BBCode
Chris@76 741 if ($row['bbc'])
Chris@76 742 $output_html = parse_bbc($output_html);
Chris@76 743 elseif($row['field_type'] == 'textarea')
Chris@76 744 // Allow for newlines at least
Chris@76 745 $output_html = strtr($output_html, array("\n" => '<br />'));
Chris@76 746
Chris@76 747 // Enclosing the user input within some other text?
Chris@76 748 if (!empty($row['enclose']) && !empty($output_html))
Chris@76 749 $output_html = strtr($row['enclose'], array(
Chris@76 750 '{SCRIPTURL}' => $scripturl,
Chris@76 751 '{IMAGES_URL}' => $settings['images_url'],
Chris@76 752 '{DEFAULT_IMAGES_URL}' => $settings['default_images_url'],
Chris@76 753 '{INPUT}' => $output_html,
Chris@76 754 ));
Chris@76 755
Chris@76 756 $context['custom_fields'][] = array(
Chris@76 757 'name' => $row['field_name'],
Chris@76 758 'desc' => $row['field_desc'],
Chris@76 759 'type' => $row['field_type'],
Chris@76 760 'input_html' => $input_html,
Chris@76 761 'output_html' => $output_html,
Chris@76 762 'placement' => $row['placement'],
Chris@76 763 'colname' => $row['col_name'],
Chris@76 764 'value' => $value,
Chris@76 765 );
Chris@76 766 }
Chris@76 767 $smcFunc['db_free_result']($request);
Chris@76 768 }
Chris@76 769
Chris@76 770 ?>