1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This file has the primary job of showing and editing people's profiles. |
||
5 | * It also allows the user to change some of their or another's preferences, |
||
6 | * and such things. |
||
7 | * |
||
8 | * Simple Machines Forum (SMF) |
||
9 | * |
||
10 | * @package SMF |
||
11 | * @author Simple Machines https://www.simplemachines.org |
||
12 | * @copyright 2022 Simple Machines and individual contributors |
||
13 | * @license https://www.simplemachines.org/about/smf/license.php BSD |
||
14 | * |
||
15 | * @version 2.1.0 |
||
16 | */ |
||
17 | |||
18 | if (!defined('SMF')) |
||
19 | die('No direct access...'); |
||
20 | |||
21 | /** |
||
22 | * The main designating function for modifying profiles. Loads up info, determins what to do, etc. |
||
23 | * |
||
24 | * @param array $post_errors Any errors that occurred |
||
25 | */ |
||
26 | function ModifyProfile($post_errors = array()) |
||
27 | { |
||
28 | global $txt, $scripturl, $user_info, $context, $sourcedir, $user_profile, $cur_profile; |
||
29 | global $modSettings, $memberContext, $profile_vars, $post_errors, $smcFunc; |
||
30 | |||
31 | // Don't reload this as we may have processed error strings. |
||
32 | if (empty($post_errors)) |
||
33 | loadLanguage('Profile+Drafts'); |
||
34 | loadTemplate('Profile'); |
||
35 | |||
36 | require_once($sourcedir . '/Subs-Menu.php'); |
||
37 | |||
38 | // Did we get the user by name... |
||
39 | if (isset($_REQUEST['user'])) |
||
40 | $memberResult = loadMemberData($_REQUEST['user'], true, 'profile'); |
||
41 | // ... or by id_member? |
||
42 | elseif (!empty($_REQUEST['u'])) |
||
43 | $memberResult = loadMemberData((int) $_REQUEST['u'], false, 'profile'); |
||
44 | // If it was just ?action=profile, edit your own profile, but only if you're not a guest. |
||
45 | else |
||
46 | { |
||
47 | // Members only... |
||
48 | is_not_guest(); |
||
49 | $memberResult = loadMemberData($user_info['id'], false, 'profile'); |
||
50 | } |
||
51 | |||
52 | // Check if loadMemberData() has returned a valid result. |
||
53 | if (!$memberResult) |
||
54 | fatal_lang_error('not_a_user', false, 404); |
||
55 | |||
56 | // If all went well, we have a valid member ID! |
||
57 | list ($memID) = $memberResult; |
||
58 | $memID = (int) $memID; |
||
59 | $context['id_member'] = $memID; |
||
60 | $cur_profile = $user_profile[$memID]; |
||
61 | |||
62 | // Let's have some information about this member ready, too. |
||
63 | loadMemberContext($memID); |
||
64 | $context['member'] = $memberContext[$memID]; |
||
65 | |||
66 | // Is this the profile of the user himself or herself? |
||
67 | $context['user']['is_owner'] = $memID == $user_info['id']; |
||
68 | |||
69 | // Group management isn't actually a permission. But we need it to be for this, so we need a phantom permission. |
||
70 | // And we care about what the current user can do, not what the user whose profile it is. |
||
71 | if ($user_info['mod_cache']['gq'] != '0=1') |
||
72 | $user_info['permissions'][] = 'approve_group_requests'; |
||
73 | |||
74 | // If paid subscriptions are enabled, make sure we actually have at least one subscription available... |
||
75 | $context['subs_available'] = false; |
||
76 | |||
77 | if (!empty($modSettings['paid_enabled'])) |
||
78 | { |
||
79 | $get_active_subs = $smcFunc['db_query']('', ' |
||
80 | SELECT COUNT(*) |
||
81 | FROM {db_prefix}subscriptions |
||
82 | WHERE active = {int:active}', array( |
||
83 | 'active' => 1, |
||
84 | ) |
||
85 | ); |
||
86 | |||
87 | list ($num_subs) = $smcFunc['db_fetch_row']($get_active_subs); |
||
88 | |||
89 | $context['subs_available'] = ($num_subs > 0); |
||
90 | |||
91 | $smcFunc['db_free_result']($get_active_subs); |
||
92 | } |
||
93 | |||
94 | /* Define all the sections within the profile area! |
||
95 | We start by defining the permission required - then SMF takes this and turns it into the relevant context ;) |
||
96 | Possible fields: |
||
97 | For Section: |
||
98 | string $title: Section title. |
||
99 | array $areas: Array of areas within this section. |
||
100 | |||
101 | For Areas: |
||
102 | string $label: Text string that will be used to show the area in the menu. |
||
103 | string $file: Optional text string that may contain a file name that's needed for inclusion in order to display the area properly. |
||
104 | string $custom_url: Optional href for area. |
||
105 | string $function: Function to execute for this section. Can be a call to an static method: class::method |
||
106 | string $class If your function is a method, set the class field with your class's name and SMF will create a new instance for it. |
||
107 | bool $enabled: Should area be shown? |
||
108 | string $sc: Session check validation to do on save - note without this save will get unset - if set. |
||
109 | bool $hidden: Does this not actually appear on the menu? |
||
110 | bool $password: Whether to require the user's password in order to save the data in the area. |
||
111 | array $subsections: Array of subsections, in order of appearance. |
||
112 | array $permission: Array of permissions to determine who can access this area. Should contain arrays $own and $any. |
||
113 | */ |
||
114 | $profile_areas = array( |
||
115 | 'info' => array( |
||
116 | 'title' => $txt['profileInfo'], |
||
117 | 'areas' => array( |
||
118 | 'summary' => array( |
||
119 | 'label' => $txt['summary'], |
||
120 | 'file' => 'Profile-View.php', |
||
121 | 'function' => 'summary', |
||
122 | 'icon' => 'administration', |
||
123 | 'permission' => array( |
||
124 | 'own' => 'is_not_guest', |
||
125 | 'any' => 'profile_view', |
||
126 | ), |
||
127 | ), |
||
128 | 'popup' => array( |
||
129 | 'function' => 'profile_popup', |
||
130 | 'permission' => array( |
||
131 | 'own' => 'is_not_guest', |
||
132 | 'any' => array(), |
||
133 | ), |
||
134 | 'select' => 'summary', |
||
135 | ), |
||
136 | 'alerts_popup' => array( |
||
137 | 'function' => 'alerts_popup', |
||
138 | 'permission' => array( |
||
139 | 'own' => 'is_not_guest', |
||
140 | 'any' => array(), |
||
141 | ), |
||
142 | 'select' => 'summary', |
||
143 | ), |
||
144 | 'statistics' => array( |
||
145 | 'label' => $txt['statPanel'], |
||
146 | 'file' => 'Profile-View.php', |
||
147 | 'function' => 'statPanel', |
||
148 | 'icon' => 'stats', |
||
149 | 'permission' => array( |
||
150 | 'own' => 'is_not_guest', |
||
151 | 'any' => 'profile_view', |
||
152 | ), |
||
153 | ), |
||
154 | 'showposts' => array( |
||
155 | 'label' => $txt['showPosts'], |
||
156 | 'file' => 'Profile-View.php', |
||
157 | 'function' => 'showPosts', |
||
158 | 'icon' => 'posts', |
||
159 | 'subsections' => array( |
||
160 | 'messages' => array($txt['showMessages'], array('is_not_guest', 'profile_view')), |
||
161 | 'topics' => array($txt['showTopics'], array('is_not_guest', 'profile_view')), |
||
162 | 'unwatchedtopics' => array($txt['showUnwatched'], array('is_not_guest', 'profile_view'), 'enabled' => $context['user']['is_owner']), |
||
163 | 'attach' => array($txt['showAttachments'], array('is_not_guest', 'profile_view')), |
||
164 | ), |
||
165 | 'permission' => array( |
||
166 | 'own' => 'is_not_guest', |
||
167 | 'any' => 'profile_view', |
||
168 | ), |
||
169 | ), |
||
170 | 'showdrafts' => array( |
||
171 | 'label' => $txt['drafts_show'], |
||
172 | 'file' => 'Drafts.php', |
||
173 | 'function' => 'showProfileDrafts', |
||
174 | 'icon' => 'drafts', |
||
175 | 'enabled' => !empty($modSettings['drafts_post_enabled']) && $context['user']['is_owner'], |
||
176 | 'permission' => array( |
||
177 | 'own' => 'is_not_guest', |
||
178 | 'any' => array(), |
||
179 | ), |
||
180 | ), |
||
181 | 'showalerts' => array( |
||
182 | 'label' => $txt['alerts_show'], |
||
183 | 'file' => 'Profile-View.php', |
||
184 | 'function' => 'showAlerts', |
||
185 | 'icon' => 'alerts', |
||
186 | 'permission' => array( |
||
187 | 'own' => 'is_not_guest', |
||
188 | 'any' => array(), |
||
189 | ), |
||
190 | ), |
||
191 | 'permissions' => array( |
||
192 | 'label' => $txt['showPermissions'], |
||
193 | 'file' => 'Profile-View.php', |
||
194 | 'function' => 'showPermissions', |
||
195 | 'icon' => 'permissions', |
||
196 | 'permission' => array( |
||
197 | 'own' => 'manage_permissions', |
||
198 | 'any' => 'manage_permissions', |
||
199 | ), |
||
200 | ), |
||
201 | 'tracking' => array( |
||
202 | 'label' => $txt['trackUser'], |
||
203 | 'file' => 'Profile-View.php', |
||
204 | 'function' => 'tracking', |
||
205 | 'icon' => 'logs', |
||
206 | 'subsections' => array( |
||
207 | 'activity' => array($txt['trackActivity'], 'moderate_forum'), |
||
208 | 'ip' => array($txt['trackIP'], 'moderate_forum'), |
||
209 | 'edits' => array($txt['trackEdits'], 'moderate_forum', 'enabled' => !empty($modSettings['userlog_enabled'])), |
||
210 | 'groupreq' => array($txt['trackGroupRequests'], 'approve_group_requests', 'enabled' => !empty($modSettings['show_group_membership'])), |
||
211 | 'logins' => array($txt['trackLogins'], 'moderate_forum', 'enabled' => !empty($modSettings['loginHistoryDays'])), |
||
212 | ), |
||
213 | 'permission' => array( |
||
214 | 'own' => array('moderate_forum', 'approve_group_requests'), |
||
215 | 'any' => array('moderate_forum', 'approve_group_requests'), |
||
216 | ), |
||
217 | ), |
||
218 | 'viewwarning' => array( |
||
219 | 'label' => $txt['profile_view_warnings'], |
||
220 | 'enabled' => $modSettings['warning_settings'][0] == 1 && $cur_profile['warning'], |
||
221 | 'file' => 'Profile-View.php', |
||
222 | 'function' => 'viewWarning', |
||
223 | 'icon' => 'warning', |
||
224 | 'permission' => array( |
||
225 | 'own' => array('view_warning_own', 'view_warning_any', 'issue_warning', 'moderate_forum'), |
||
226 | 'any' => array('view_warning_any', 'issue_warning', 'moderate_forum'), |
||
227 | ), |
||
228 | ), |
||
229 | ), |
||
230 | ), |
||
231 | 'edit_profile' => array( |
||
232 | 'title' => $txt['forumprofile'], |
||
233 | 'areas' => array( |
||
234 | 'account' => array( |
||
235 | 'label' => $txt['account'], |
||
236 | 'file' => 'Profile-Modify.php', |
||
237 | 'function' => 'account', |
||
238 | 'icon' => 'maintain', |
||
239 | 'enabled' => $context['user']['is_admin'] || ($cur_profile['id_group'] != 1 && !in_array(1, explode(',', $cur_profile['additional_groups']))), |
||
240 | 'sc' => 'post', |
||
241 | 'token' => 'profile-ac%u', |
||
242 | 'password' => true, |
||
243 | 'permission' => array( |
||
244 | 'own' => array('profile_identity_any', 'profile_identity_own', 'profile_password_any', 'profile_password_own', 'manage_membergroups'), |
||
245 | 'any' => array('profile_identity_any', 'profile_password_any', 'manage_membergroups'), |
||
246 | ), |
||
247 | ), |
||
248 | 'tfasetup' => array( |
||
249 | 'label' => $txt['account'], |
||
250 | 'file' => 'Profile-Modify.php', |
||
251 | 'function' => 'tfasetup', |
||
252 | 'token' => 'profile-tfa%u', |
||
253 | 'enabled' => !empty($modSettings['tfa_mode']), |
||
254 | 'hidden' => true, |
||
255 | 'select' => 'account', |
||
256 | 'permission' => array( |
||
257 | 'own' => array('profile_password_own'), |
||
258 | 'any' => array('profile_password_any'), |
||
259 | ), |
||
260 | ), |
||
261 | 'tfadisable' => array( |
||
262 | 'label' => $txt['account'], |
||
263 | 'file' => 'Profile-Modify.php', |
||
264 | 'function' => 'tfadisable', |
||
265 | 'token' => 'profile-tfa%u', |
||
266 | 'sc' => 'post', |
||
267 | 'password' => true, |
||
268 | 'enabled' => !empty($modSettings['tfa_mode']), |
||
269 | 'hidden' => true, |
||
270 | 'select' => 'account', |
||
271 | 'permission' => array( |
||
272 | 'own' => array('profile_password_own'), |
||
273 | 'any' => array('profile_password_any'), |
||
274 | ), |
||
275 | ), |
||
276 | 'forumprofile' => array( |
||
277 | 'label' => $txt['forumprofile'], |
||
278 | 'file' => 'Profile-Modify.php', |
||
279 | 'function' => 'forumProfile', |
||
280 | 'icon' => 'members', |
||
281 | 'sc' => 'post', |
||
282 | 'token' => 'profile-fp%u', |
||
283 | 'permission' => array( |
||
284 | 'own' => array('profile_forum_any', 'profile_forum_own'), |
||
285 | 'any' => array('profile_forum_any'), |
||
286 | ), |
||
287 | ), |
||
288 | 'theme' => array( |
||
289 | 'label' => $txt['theme'], |
||
290 | 'file' => 'Profile-Modify.php', |
||
291 | 'function' => 'theme', |
||
292 | 'icon' => 'features', |
||
293 | 'sc' => 'post', |
||
294 | 'token' => 'profile-th%u', |
||
295 | 'permission' => array( |
||
296 | 'own' => array('profile_extra_any', 'profile_extra_own'), |
||
297 | 'any' => array('profile_extra_any'), |
||
298 | ), |
||
299 | ), |
||
300 | 'notification' => array( |
||
301 | 'label' => $txt['notification'], |
||
302 | 'file' => 'Profile-Modify.php', |
||
303 | 'function' => 'notification', |
||
304 | 'icon' => 'alerts', |
||
305 | 'sc' => 'post', |
||
306 | //'token' => 'profile-nt%u', This is not checked here. We do it in the function itself - but if it was checked, this is what it'd be. |
||
307 | 'subsections' => array( |
||
308 | 'alerts' => array($txt['alert_prefs'], array('is_not_guest', 'profile_extra_any')), |
||
309 | 'topics' => array($txt['watched_topics'], array('is_not_guest', 'profile_extra_any')), |
||
310 | 'boards' => array($txt['watched_boards'], array('is_not_guest', 'profile_extra_any')), |
||
311 | ), |
||
312 | 'permission' => array( |
||
313 | 'own' => array('is_not_guest'), |
||
314 | 'any' => array('profile_extra_any'), // If you change this, update it in the functions themselves; we delegate all saving checks there. |
||
315 | ), |
||
316 | ), |
||
317 | 'ignoreboards' => array( |
||
318 | 'label' => $txt['ignoreboards'], |
||
319 | 'file' => 'Profile-Modify.php', |
||
320 | 'function' => 'ignoreboards', |
||
321 | 'icon' => 'boards', |
||
322 | 'enabled' => !empty($modSettings['allow_ignore_boards']), |
||
323 | 'sc' => 'post', |
||
324 | 'token' => 'profile-ib%u', |
||
325 | 'permission' => array( |
||
326 | 'own' => array('profile_extra_any', 'profile_extra_own'), |
||
327 | 'any' => array('profile_extra_any'), |
||
328 | ), |
||
329 | ), |
||
330 | 'lists' => array( |
||
331 | 'label' => $txt['editBuddyIgnoreLists'], |
||
332 | 'file' => 'Profile-Modify.php', |
||
333 | 'function' => 'editBuddyIgnoreLists', |
||
334 | 'icon' => 'frenemy', |
||
335 | 'enabled' => !empty($modSettings['enable_buddylist']) && $context['user']['is_owner'], |
||
336 | 'sc' => 'post', |
||
337 | 'subsections' => array( |
||
338 | 'buddies' => array($txt['editBuddies']), |
||
339 | 'ignore' => array($txt['editIgnoreList']), |
||
340 | ), |
||
341 | 'permission' => array( |
||
342 | 'own' => array('profile_extra_any', 'profile_extra_own'), |
||
343 | 'any' => array(), |
||
344 | ), |
||
345 | ), |
||
346 | 'groupmembership' => array( |
||
347 | 'label' => $txt['groupmembership'], |
||
348 | 'file' => 'Profile-Modify.php', |
||
349 | 'function' => 'groupMembership', |
||
350 | 'icon' => 'people', |
||
351 | 'enabled' => !empty($modSettings['show_group_membership']) && $context['user']['is_owner'], |
||
352 | 'sc' => 'request', |
||
353 | 'token' => 'profile-gm%u', |
||
354 | 'token_type' => 'request', |
||
355 | 'permission' => array( |
||
356 | 'own' => array('is_not_guest'), |
||
357 | 'any' => array('manage_membergroups'), |
||
358 | ), |
||
359 | ), |
||
360 | ), |
||
361 | ), |
||
362 | 'profile_action' => array( |
||
363 | 'title' => $txt['profileAction'], |
||
364 | 'areas' => array( |
||
365 | 'sendpm' => array( |
||
366 | 'label' => $txt['profileSendIm'], |
||
367 | 'custom_url' => $scripturl . '?action=pm;sa=send', |
||
368 | 'icon' => 'personal_message', |
||
369 | 'enabled' => allowedTo('profile_view'), |
||
370 | 'permission' => array( |
||
371 | 'own' => array(), |
||
372 | 'any' => array('pm_send'), |
||
373 | ), |
||
374 | ), |
||
375 | 'report' => array( |
||
376 | 'label' => $txt['report_profile'], |
||
377 | 'custom_url' => $scripturl . '?action=reporttm;' . $context['session_var'] . '=' . $context['session_id'], |
||
378 | 'icon' => 'warning', |
||
379 | 'enabled' => allowedTo('profile_view'), |
||
380 | 'permission' => array( |
||
381 | 'own' => array(), |
||
382 | 'any' => array('report_user'), |
||
383 | ), |
||
384 | ), |
||
385 | 'issuewarning' => array( |
||
386 | 'label' => $txt['profile_issue_warning'], |
||
387 | 'enabled' => $modSettings['warning_settings'][0] == 1, |
||
388 | 'file' => 'Profile-Actions.php', |
||
389 | 'function' => 'issueWarning', |
||
390 | 'icon' => 'warning', |
||
391 | 'token' => 'profile-iw%u', |
||
392 | 'permission' => array( |
||
393 | 'own' => array(), |
||
394 | 'any' => array('issue_warning'), |
||
395 | ), |
||
396 | ), |
||
397 | 'banuser' => array( |
||
398 | 'label' => $txt['profileBanUser'], |
||
399 | 'custom_url' => $scripturl . '?action=admin;area=ban;sa=add', |
||
400 | 'icon' => 'ban', |
||
401 | 'enabled' => $cur_profile['id_group'] != 1 && !in_array(1, explode(',', $cur_profile['additional_groups'])), |
||
402 | 'permission' => array( |
||
403 | 'own' => array(), |
||
404 | 'any' => array('manage_bans'), |
||
405 | ), |
||
406 | ), |
||
407 | 'subscriptions' => array( |
||
408 | 'label' => $txt['subscriptions'], |
||
409 | 'file' => 'Profile-Actions.php', |
||
410 | 'function' => 'subscriptions', |
||
411 | 'icon' => 'paid', |
||
412 | 'enabled' => !empty($modSettings['paid_enabled']) && $context['subs_available'], |
||
413 | 'permission' => array( |
||
414 | 'own' => array('is_not_guest'), |
||
415 | 'any' => array('moderate_forum'), |
||
416 | ), |
||
417 | ), |
||
418 | 'getprofiledata' => array( |
||
419 | 'label' => $txt['export_profile_data'], |
||
420 | 'file' => 'Profile-Export.php', |
||
421 | 'function' => 'export_profile_data', |
||
422 | 'icon' => 'packages', |
||
423 | // 'token' => 'profile-ex%u', // This is not checked here. We do it in the function itself - but if it was checked, this is what it'd be. |
||
424 | 'permission' => array( |
||
425 | 'own' => array('profile_view_own'), |
||
426 | 'any' => array('moderate_forum'), |
||
427 | ), |
||
428 | ), |
||
429 | 'download' => array( |
||
430 | 'label' => $txt['export_profile_data'], |
||
431 | 'file' => 'Profile-Export.php', |
||
432 | 'function' => 'download_export_file', |
||
433 | 'icon' => 'packages', |
||
434 | 'hidden' => true, |
||
435 | 'select' => 'getprofiledata', |
||
436 | 'permission' => array( |
||
437 | 'own' => array('profile_view_own'), |
||
438 | 'any' => array('moderate_forum'), |
||
439 | ), |
||
440 | ), |
||
441 | 'dlattach' => array( |
||
442 | 'label' => $txt['export_profile_data'], |
||
443 | 'file' => 'Profile-Export.php', |
||
444 | 'function' => 'export_attachment', |
||
445 | 'icon' => 'packages', |
||
446 | 'hidden' => true, |
||
447 | 'select' => 'getprofiledata', |
||
448 | 'permission' => array( |
||
449 | 'own' => array('profile_view_own'), |
||
450 | 'any' => array(), |
||
451 | ), |
||
452 | ), |
||
453 | 'deleteaccount' => array( |
||
454 | 'label' => $txt['deleteAccount'], |
||
455 | 'file' => 'Profile-Actions.php', |
||
456 | 'function' => 'deleteAccount', |
||
457 | 'icon' => 'members_delete', |
||
458 | 'sc' => 'post', |
||
459 | 'token' => 'profile-da%u', |
||
460 | 'password' => true, |
||
461 | 'permission' => array( |
||
462 | 'own' => array('profile_remove_any', 'profile_remove_own'), |
||
463 | 'any' => array('profile_remove_any'), |
||
464 | ), |
||
465 | ), |
||
466 | 'activateaccount' => array( |
||
467 | 'file' => 'Profile-Actions.php', |
||
468 | 'function' => 'activateAccount', |
||
469 | 'icon' => 'regcenter', |
||
470 | 'sc' => 'get', |
||
471 | 'token' => 'profile-aa%u', |
||
472 | 'token_type' => 'get', |
||
473 | 'permission' => array( |
||
474 | 'own' => array(), |
||
475 | 'any' => array('moderate_forum'), |
||
476 | ), |
||
477 | ), |
||
478 | // A logout link just for the popup menu. |
||
479 | 'logout' => array( |
||
480 | 'label' => $txt['logout'], |
||
481 | 'custom_url' => $scripturl . '?action=logout;%1$s=%2$s', |
||
482 | 'icon' => 'logout', |
||
483 | 'enabled' => !empty($_REQUEST['area']) && $_REQUEST['area'] === 'popup', |
||
484 | 'permission' => array( |
||
485 | 'own' => array('is_not_guest'), |
||
486 | 'any' => array(), |
||
487 | ), |
||
488 | ), |
||
489 | ), |
||
490 | ), |
||
491 | ); |
||
492 | |||
493 | // Let them modify profile areas easily. |
||
494 | call_integration_hook('integrate_pre_profile_areas', array(&$profile_areas)); |
||
495 | |||
496 | // Do some cleaning ready for the menu function. |
||
497 | $context['password_areas'] = array(); |
||
498 | $current_area = isset($_REQUEST['area']) ? $_REQUEST['area'] : ''; |
||
499 | |||
500 | foreach ($profile_areas as $section_id => $section) |
||
501 | { |
||
502 | // Do a bit of spring cleaning so to speak. |
||
503 | foreach ($section['areas'] as $area_id => $area) |
||
504 | { |
||
505 | // If it said no permissions that meant it wasn't valid! |
||
506 | if (empty($area['permission'][$context['user']['is_owner'] ? 'own' : 'any'])) |
||
507 | $profile_areas[$section_id]['areas'][$area_id]['enabled'] = false; |
||
508 | // Otherwise pick the right set. |
||
509 | else |
||
510 | $profile_areas[$section_id]['areas'][$area_id]['permission'] = $area['permission'][$context['user']['is_owner'] ? 'own' : 'any']; |
||
511 | |||
512 | // Password required in most cases |
||
513 | if (!empty($area['password'])) |
||
514 | $context['password_areas'][] = $area_id; |
||
515 | } |
||
516 | } |
||
517 | |||
518 | // Is there an updated message to show? |
||
519 | if (isset($_GET['updated'])) |
||
520 | $context['profile_updated'] = $txt['profile_updated_own']; |
||
521 | |||
522 | // Set a few options for the menu. |
||
523 | $menuOptions = array( |
||
524 | 'disable_url_session_check' => true, |
||
525 | 'current_area' => $current_area, |
||
526 | 'extra_url_parameters' => array( |
||
527 | 'u' => $context['id_member'], |
||
528 | ), |
||
529 | ); |
||
530 | |||
531 | // Logging out requires the session id in the url. |
||
532 | $profile_areas['profile_action']['areas']['logout']['custom_url'] = sprintf($profile_areas['profile_action']['areas']['logout']['custom_url'], $context['session_var'], $context['session_id']); |
||
533 | |||
534 | // Actually create the menu! |
||
535 | $profile_include_data = createMenu($profile_areas, $menuOptions); |
||
536 | |||
537 | // No menu means no access. |
||
538 | if (!$profile_include_data && (!$user_info['is_guest'] || validateSession())) |
||
539 | fatal_lang_error('no_access', false); |
||
540 | |||
541 | // Make a note of the Unique ID for this menu. |
||
542 | $context['profile_menu_id'] = $context['max_menu_id']; |
||
543 | $context['profile_menu_name'] = 'menu_data_' . $context['profile_menu_id']; |
||
544 | |||
545 | // Set the selected item - now it's been validated. |
||
546 | $current_area = $profile_include_data['current_area']; |
||
547 | $current_sa = $profile_include_data['current_subsection']; |
||
548 | $context['menu_item_selected'] = $current_area; |
||
549 | |||
550 | // 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 ever compromise the menu function in error! |
||
551 | $context['completed_save'] = false; |
||
552 | $context['do_preview'] = isset($_REQUEST['preview_signature']); |
||
553 | |||
554 | $security_checks = array(); |
||
555 | $found_area = false; |
||
556 | foreach ($profile_areas as $section_id => $section) |
||
557 | { |
||
558 | // Do a bit of spring cleaning so to speak. |
||
559 | foreach ($section['areas'] as $area_id => $area) |
||
560 | { |
||
561 | // Is this our area? |
||
562 | if ($current_area == $area_id) |
||
563 | { |
||
564 | // This can't happen - but is a security check. |
||
565 | if ((isset($section['enabled']) && $section['enabled'] == false) || (isset($area['enabled']) && $area['enabled'] == false)) |
||
566 | fatal_lang_error('no_access', false); |
||
567 | |||
568 | // Are we saving data in a valid area? |
||
569 | if (isset($area['sc']) && (isset($_REQUEST['save']) || $context['do_preview'])) |
||
570 | { |
||
571 | $security_checks['session'] = $area['sc']; |
||
572 | $context['completed_save'] = true; |
||
573 | } |
||
574 | |||
575 | // Do we need to perform a token check? |
||
576 | if (!empty($area['token'])) |
||
577 | { |
||
578 | $security_checks[isset($_REQUEST['save']) ? 'validateToken' : 'needsToken'] = $area['token']; |
||
579 | $token_name = $area['token'] !== true ? str_replace('%u', $context['id_member'], $area['token']) : 'profile-u' . $context['id_member']; |
||
580 | |||
581 | $token_type = isset($area['token_type']) && in_array($area['token_type'], array('request', 'post', 'get')) ? $area['token_type'] : 'post'; |
||
582 | } |
||
583 | |||
584 | // Does this require session validating? |
||
585 | if (!empty($area['validate']) || (isset($_REQUEST['save']) && !$context['user']['is_owner'] && ($area_id != 'issuewarning' || empty($modSettings['securityDisable_moderate'])))) |
||
586 | $security_checks['validate'] = true; |
||
587 | |||
588 | // Permissions for good measure. |
||
589 | if (!empty($profile_include_data['permission'])) |
||
590 | $security_checks['permission'] = $profile_include_data['permission']; |
||
591 | |||
592 | // Either way got something. |
||
593 | $found_area = true; |
||
594 | } |
||
595 | } |
||
596 | } |
||
597 | |||
598 | // Oh dear, some serious security lapse is going on here... we'll put a stop to that! |
||
599 | if (!$found_area) |
||
600 | fatal_lang_error('no_access', false); |
||
601 | |||
602 | // Release this now. |
||
603 | unset($profile_areas); |
||
604 | |||
605 | // Now the context is setup have we got any security checks to carry out additional to that above? |
||
606 | if (isset($security_checks['session'])) |
||
607 | checkSession($security_checks['session']); |
||
608 | if (isset($security_checks['validate'])) |
||
609 | validateSession(); |
||
610 | if (isset($security_checks['validateToken'])) |
||
611 | validateToken($token_name, $token_type); |
||
612 | if (isset($security_checks['permission'])) |
||
613 | isAllowedTo($security_checks['permission']); |
||
614 | |||
615 | // Create a token if needed. |
||
616 | if (isset($security_checks['needsToken']) || isset($security_checks['validateToken'])) |
||
617 | { |
||
618 | createToken($token_name, $token_type); |
||
619 | $context['token_check'] = $token_name; |
||
620 | } |
||
621 | |||
622 | // File to include? |
||
623 | if (isset($profile_include_data['file'])) |
||
624 | require_once($sourcedir . '/' . $profile_include_data['file']); |
||
625 | |||
626 | // Build the link tree. |
||
627 | $context['linktree'][] = array( |
||
628 | 'url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : ''), |
||
629 | 'name' => sprintf($txt['profile_of_username'], $context['member']['name']), |
||
630 | ); |
||
631 | |||
632 | if (!empty($profile_include_data['label'])) |
||
633 | $context['linktree'][] = array( |
||
634 | 'url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : '') . ';area=' . $profile_include_data['current_area'], |
||
635 | 'name' => $profile_include_data['label'], |
||
636 | ); |
||
637 | |||
638 | if (!empty($profile_include_data['current_subsection']) && $profile_include_data['subsections'][$profile_include_data['current_subsection']][0] != $profile_include_data['label']) |
||
639 | $context['linktree'][] = array( |
||
640 | 'url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : '') . ';area=' . $profile_include_data['current_area'] . ';sa=' . $profile_include_data['current_subsection'], |
||
641 | 'name' => $profile_include_data['subsections'][$profile_include_data['current_subsection']][0], |
||
642 | ); |
||
643 | |||
644 | // Set the template for this area and add the profile layer. |
||
645 | $context['sub_template'] = $profile_include_data['function']; |
||
646 | $context['template_layers'][] = 'profile'; |
||
647 | |||
648 | // All the subactions that require a user password in order to validate. |
||
649 | $check_password = $context['user']['is_owner'] && in_array($profile_include_data['current_area'], $context['password_areas']); |
||
650 | $context['require_password'] = $check_password; |
||
651 | |||
652 | loadJavaScriptFile('profile.js', array('defer' => false, 'minimize' => true), 'smf_profile'); |
||
653 | |||
654 | // These will get populated soon! |
||
655 | $post_errors = array(); |
||
656 | $profile_vars = array(); |
||
657 | |||
658 | // Right - are we saving - if so let's save the old data first. |
||
659 | if ($context['completed_save']) |
||
660 | { |
||
661 | // Clean up the POST variables. |
||
662 | $_POST = htmltrim__recursive($_POST); |
||
663 | $_POST = htmlspecialchars__recursive($_POST); |
||
664 | |||
665 | if ($check_password) |
||
666 | { |
||
667 | // Check to ensure we're forcing SSL for authentication |
||
668 | if (!empty($modSettings['force_ssl']) && empty($maintenance) && !httpsOn()) |
||
669 | fatal_lang_error('login_ssl_required', false); |
||
670 | |||
671 | $password = isset($_POST['oldpasswrd']) ? $_POST['oldpasswrd'] : ''; |
||
672 | |||
673 | // You didn't even enter a password! |
||
674 | if (trim($password) == '') |
||
675 | $post_errors[] = 'no_password'; |
||
676 | |||
677 | // Since the password got modified due to all the $_POST cleaning, lets undo it so we can get the correct password |
||
678 | $password = un_htmlspecialchars($password); |
||
679 | |||
680 | // Does the integration want to check passwords? |
||
681 | $good_password = in_array(true, call_integration_hook('integrate_verify_password', array($cur_profile['member_name'], $password, false)), true); |
||
682 | |||
683 | // Bad password!!! |
||
684 | if (!$good_password && !hash_verify_password($user_profile[$memID]['member_name'], $password, $user_info['passwd'])) |
||
685 | $post_errors[] = 'bad_password'; |
||
686 | |||
687 | // Warn other elements not to jump the gun and do custom changes! |
||
688 | if (in_array('bad_password', $post_errors)) |
||
689 | $context['password_auth_failed'] = true; |
||
690 | } |
||
691 | |||
692 | // Change the IP address in the database. |
||
693 | if ($context['user']['is_owner'] && $menuOptions['current_area'] != 'tfasetup') |
||
694 | $profile_vars['member_ip'] = $user_info['ip']; |
||
695 | |||
696 | // Now call the sub-action function... |
||
697 | if ($current_area == 'activateaccount') |
||
698 | { |
||
699 | if (empty($post_errors)) |
||
700 | activateAccount($memID); |
||
701 | } |
||
702 | elseif ($current_area == 'deleteaccount') |
||
703 | { |
||
704 | if (empty($post_errors)) |
||
705 | { |
||
706 | deleteAccount2($memID); |
||
707 | redirectexit(); |
||
708 | } |
||
709 | } |
||
710 | elseif ($menuOptions['current_area'] == 'tfadisable') |
||
711 | { |
||
712 | // Already checked the password, token, permissions, and session. |
||
713 | $profile_vars += array( |
||
714 | 'tfa_secret' => '', |
||
715 | 'tfa_backup' => '', |
||
716 | ); |
||
717 | } |
||
718 | elseif ($current_area == 'groupmembership' && empty($post_errors)) |
||
719 | { |
||
720 | $msg = groupMembership2($profile_vars, $post_errors, $memID); |
||
721 | |||
722 | // Whatever we've done, we have nothing else to do here... |
||
723 | redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $memID) . ';area=groupmembership' . (!empty($msg) ? ';msg=' . $msg : '')); |
||
724 | } |
||
725 | elseif (in_array($current_area, array('account', 'forumprofile', 'theme'))) |
||
726 | saveProfileFields(); |
||
727 | else |
||
728 | { |
||
729 | $force_redirect = true; |
||
730 | // Ensure we include this. |
||
731 | require_once($sourcedir . '/Profile-Modify.php'); |
||
732 | saveProfileChanges($profile_vars, $post_errors, $memID); |
||
733 | } |
||
734 | |||
735 | call_integration_hook('integrate_profile_save', array(&$profile_vars, &$post_errors, $memID, $cur_profile, $current_area)); |
||
736 | |||
737 | // There was a problem, let them try to re-enter. |
||
738 | if (!empty($post_errors)) |
||
739 | { |
||
740 | // Load the language file so we can give a nice explanation of the errors. |
||
741 | loadLanguage('Errors'); |
||
742 | $context['post_errors'] = $post_errors; |
||
743 | } |
||
744 | elseif (!empty($profile_vars)) |
||
745 | { |
||
746 | // If we've changed the password, notify any integration that may be listening in. |
||
747 | if (isset($profile_vars['passwd'])) |
||
748 | call_integration_hook('integrate_reset_pass', array($cur_profile['member_name'], $cur_profile['member_name'], $_POST['passwrd2'])); |
||
749 | |||
750 | updateMemberData($memID, $profile_vars); |
||
751 | |||
752 | // What if this is the newest member? |
||
753 | if ($modSettings['latestMember'] == $memID) |
||
754 | updateStats('member'); |
||
755 | elseif (isset($profile_vars['real_name'])) |
||
756 | updateSettings(array('memberlist_updated' => time())); |
||
757 | |||
758 | // If the member changed his/her birthdate, update calendar statistics. |
||
759 | if (isset($profile_vars['birthdate']) || isset($profile_vars['real_name'])) |
||
760 | updateSettings(array( |
||
761 | 'calendar_updated' => time(), |
||
762 | )); |
||
763 | |||
764 | // Anything worth logging? |
||
765 | if (!empty($context['log_changes']) && !empty($modSettings['modlog_enabled'])) |
||
766 | { |
||
767 | $log_changes = array(); |
||
768 | require_once($sourcedir . '/Logging.php'); |
||
769 | foreach ($context['log_changes'] as $k => $v) |
||
770 | $log_changes[] = array( |
||
771 | 'action' => $k, |
||
772 | 'log_type' => 'user', |
||
773 | 'extra' => array_merge($v, array( |
||
774 | 'applicator' => $user_info['id'], |
||
775 | 'member_affected' => $memID, |
||
776 | )), |
||
777 | ); |
||
778 | |||
779 | logActions($log_changes); |
||
780 | } |
||
781 | |||
782 | // Have we got any post save functions to execute? |
||
783 | if (!empty($context['profile_execute_on_save'])) |
||
784 | foreach ($context['profile_execute_on_save'] as $saveFunc) |
||
785 | $saveFunc(); |
||
786 | |||
787 | // Let them know it worked! |
||
788 | $context['profile_updated'] = $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $cur_profile['member_name']); |
||
789 | |||
790 | // Invalidate any cached data. |
||
791 | cache_put_data('member_data-profile-' . $memID, null, 0); |
||
792 | } |
||
793 | } |
||
794 | |||
795 | // Have some errors for some reason? |
||
796 | if (!empty($post_errors)) |
||
797 | { |
||
798 | // Set all the errors so the template knows what went wrong. |
||
799 | foreach ($post_errors as $error_type) |
||
800 | $context['modify_error'][$error_type] = true; |
||
801 | } |
||
802 | // If it's you then we should redirect upon save. |
||
803 | elseif (!empty($profile_vars) && $context['user']['is_owner'] && !$context['do_preview']) |
||
804 | redirectexit('action=profile;area=' . $current_area . (!empty($current_sa) ? ';sa=' . $current_sa : '') . ';updated'); |
||
805 | elseif (!empty($force_redirect)) |
||
806 | redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $memID) . ';area=' . $current_area); |
||
807 | |||
808 | // Get the right callable. |
||
809 | $call = call_helper($profile_include_data['function'], true); |
||
810 | |||
811 | // Is it valid? |
||
812 | if (!empty($call)) |
||
813 | call_user_func($call, $memID); |
||
814 | |||
815 | // Set the page title if it's not already set... |
||
816 | if (!isset($context['page_title'])) |
||
817 | $context['page_title'] = $txt['profile'] . (isset($txt[$current_area]) ? ' - ' . $txt[$current_area] : ''); |
||
818 | } |
||
819 | |||
820 | /** |
||
821 | * Set up the requirements for the profile popup - the area that is shown as the popup menu for the current user. |
||
822 | * |
||
823 | * @param int $memID The ID of the member |
||
824 | */ |
||
825 | function profile_popup($memID) |
||
826 | { |
||
827 | global $context, $scripturl, $txt, $db_show_debug; |
||
828 | |||
829 | // We do not want to output debug information here. |
||
830 | $db_show_debug = false; |
||
831 | |||
832 | // We only want to output our little layer here. |
||
833 | $context['template_layers'] = array(); |
||
834 | |||
835 | // This list will pull from the master list wherever possible. Hopefully it should be clear what does what. |
||
836 | $profile_items = array( |
||
837 | array( |
||
838 | 'menu' => 'edit_profile', |
||
839 | 'area' => 'account', |
||
840 | ), |
||
841 | array( |
||
842 | 'menu' => 'edit_profile', |
||
843 | 'area' => 'forumprofile', |
||
844 | 'title' => $txt['popup_forumprofile'], |
||
845 | ), |
||
846 | array( |
||
847 | 'menu' => 'edit_profile', |
||
848 | 'area' => 'theme', |
||
849 | 'title' => $txt['theme'], |
||
850 | ), |
||
851 | array( |
||
852 | 'menu' => 'edit_profile', |
||
853 | 'area' => 'notification', |
||
854 | ), |
||
855 | array( |
||
856 | 'menu' => 'edit_profile', |
||
857 | 'area' => 'ignoreboards', |
||
858 | ), |
||
859 | array( |
||
860 | 'menu' => 'edit_profile', |
||
861 | 'area' => 'lists', |
||
862 | 'url' => $scripturl . '?action=profile;area=lists;sa=ignore', |
||
863 | 'title' => $txt['popup_ignore'], |
||
864 | ), |
||
865 | array( |
||
866 | 'menu' => 'info', |
||
867 | 'area' => 'showposts', |
||
868 | 'title' => $txt['popup_showposts'], |
||
869 | ), |
||
870 | array( |
||
871 | 'menu' => 'info', |
||
872 | 'area' => 'showdrafts', |
||
873 | 'title' => $txt['popup_showdrafts'], |
||
874 | ), |
||
875 | array( |
||
876 | 'menu' => 'edit_profile', |
||
877 | 'area' => 'groupmembership', |
||
878 | 'title' => $txt['popup_groupmembership'], |
||
879 | ), |
||
880 | array( |
||
881 | 'menu' => 'profile_action', |
||
882 | 'area' => 'subscriptions', |
||
883 | 'title' => $txt['popup_subscriptions'], |
||
884 | ), |
||
885 | array( |
||
886 | 'menu' => 'profile_action', |
||
887 | 'area' => 'logout', |
||
888 | ), |
||
889 | ); |
||
890 | |||
891 | call_integration_hook('integrate_profile_popup', array(&$profile_items)); |
||
892 | |||
893 | // Now check if these items are available |
||
894 | $context['profile_items'] = array(); |
||
895 | $menu_context = &$context[$context['profile_menu_name']]['sections']; |
||
896 | foreach ($profile_items as $item) |
||
897 | { |
||
898 | if (isset($menu_context[$item['menu']]['areas'][$item['area']])) |
||
899 | { |
||
900 | $context['profile_items'][] = $item; |
||
901 | } |
||
902 | } |
||
903 | } |
||
904 | |||
905 | /** |
||
906 | * Set up the requirements for the alerts popup - the area that shows all the alerts just quickly for the current user. |
||
907 | * |
||
908 | * @param int $memID The ID of the member |
||
909 | */ |
||
910 | function alerts_popup($memID) |
||
911 | { |
||
912 | global $context, $sourcedir, $db_show_debug, $cur_profile, $modSettings; |
||
913 | |||
914 | // Load the Alerts language file. |
||
915 | loadLanguage('Alerts'); |
||
916 | |||
917 | // We do not want to output debug information here. |
||
918 | $db_show_debug = false; |
||
919 | |||
920 | // We only want to output our little layer here. |
||
921 | $context['template_layers'] = array(); |
||
922 | |||
923 | // No funny business allowed |
||
924 | $counter = isset($_REQUEST['counter']) ? max(0, (int) $_REQUEST['counter']) : 0; |
||
925 | $limit = !empty($modSettings['alerts_per_page']) && (int) $modSettings['alerts_per_page'] < 1000 ? min((int) $modSettings['alerts_per_page'], 1000) : 25; |
||
926 | |||
927 | $context['unread_alerts'] = array(); |
||
928 | if ($counter < $cur_profile['alerts']) |
||
929 | { |
||
930 | // Now fetch me my unread alerts, pronto! |
||
931 | require_once($sourcedir . '/Profile-View.php'); |
||
932 | $context['unread_alerts'] = fetch_alerts($memID, false, !empty($counter) ? $cur_profile['alerts'] - $counter : $limit, 0, !isset($_REQUEST['counter'])); |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
933 | |||
934 | // This shouldn't happen, but just in case... |
||
935 | if (empty($counter) && $cur_profile['alerts'] != count($context['unread_alerts'])) |
||
936 | updateMemberData($memID, array('alerts' => count($context['unread_alerts']))); |
||
937 | } |
||
938 | } |
||
939 | |||
940 | /** |
||
941 | * Load any custom fields for this area... no area means load all, 'summary' loads all public ones. |
||
942 | * |
||
943 | * @param int $memID The ID of the member |
||
944 | * @param string $area Which area to load fields for |
||
945 | */ |
||
946 | function loadCustomFields($memID, $area = 'summary') |
||
947 | { |
||
948 | global $context, $txt, $user_profile, $smcFunc, $user_info, $settings, $scripturl; |
||
949 | |||
950 | // Get the right restrictions in place... |
||
951 | $where = 'active = 1'; |
||
952 | if (!allowedTo('admin_forum') && $area != 'register') |
||
953 | { |
||
954 | // If it's the owner they can see two types of private fields, regardless. |
||
955 | if ($memID == $user_info['id']) |
||
956 | $where .= $area == 'summary' ? ' AND private < 3' : ' AND (private = 0 OR private = 2)'; |
||
957 | else |
||
958 | $where .= $area == 'summary' ? ' AND private < 2' : ' AND private = 0'; |
||
959 | } |
||
960 | |||
961 | if ($area == 'register') |
||
962 | $where .= ' AND show_reg != 0'; |
||
963 | elseif ($area != 'summary') |
||
964 | $where .= ' AND show_profile = {string:area}'; |
||
965 | |||
966 | // Load all the relevant fields - and data. |
||
967 | $request = $smcFunc['db_query']('', ' |
||
968 | SELECT |
||
969 | col_name, field_name, field_desc, field_type, field_order, show_reg, field_length, field_options, |
||
970 | default_value, bbc, enclose, placement |
||
971 | FROM {db_prefix}custom_fields |
||
972 | WHERE ' . $where . ' |
||
973 | ORDER BY field_order', |
||
974 | array( |
||
975 | 'area' => $area, |
||
976 | ) |
||
977 | ); |
||
978 | $context['custom_fields'] = array(); |
||
979 | $context['custom_fields_required'] = false; |
||
980 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
981 | { |
||
982 | // Shortcut. |
||
983 | $exists = $memID && isset($user_profile[$memID], $user_profile[$memID]['options'][$row['col_name']]); |
||
984 | $value = $exists ? $user_profile[$memID]['options'][$row['col_name']] : ''; |
||
985 | |||
986 | $currentKey = 0; |
||
987 | if (!empty($row['field_options'])) |
||
988 | { |
||
989 | $fieldOptions = explode(',', $row['field_options']); |
||
990 | foreach ($fieldOptions as $k => $v) |
||
991 | { |
||
992 | if (empty($currentKey)) |
||
993 | $currentKey = $v === $value ? $k : 0; |
||
994 | } |
||
995 | } |
||
996 | |||
997 | // If this was submitted already then make the value the posted version. |
||
998 | if (isset($_POST['customfield']) && isset($_POST['customfield'][$row['col_name']])) |
||
999 | { |
||
1000 | $value = $smcFunc['htmlspecialchars']($_POST['customfield'][$row['col_name']]); |
||
1001 | if (in_array($row['field_type'], array('select', 'radio'))) |
||
1002 | $value = ($options = explode(',', $row['field_options'])) && isset($options[$value]) ? $options[$value] : ''; |
||
1003 | } |
||
1004 | |||
1005 | // Don't show the "disabled" option for the "gender" field if we are on the "summary" area. |
||
1006 | if ($area == 'summary' && $row['col_name'] == 'cust_gender' && $value == '{gender_0}') |
||
1007 | continue; |
||
1008 | |||
1009 | // HTML for the input form. |
||
1010 | $output_html = $value; |
||
1011 | if ($row['field_type'] == 'check') |
||
1012 | { |
||
1013 | $true = (!$exists && $row['default_value']) || $value; |
||
1014 | $input_html = '<input type="checkbox" name="customfield[' . $row['col_name'] . ']" id="customfield[' . $row['col_name'] . ']"' . ($true ? ' checked' : '') . '>'; |
||
1015 | $output_html = $true ? $txt['yes'] : $txt['no']; |
||
1016 | } |
||
1017 | elseif ($row['field_type'] == 'select') |
||
1018 | { |
||
1019 | $input_html = '<select name="customfield[' . $row['col_name'] . ']" id="customfield[' . $row['col_name'] . ']"><option value="-1"></option>'; |
||
1020 | $options = explode(',', $row['field_options']); |
||
1021 | foreach ($options as $k => $v) |
||
1022 | { |
||
1023 | $true = (!$exists && $row['default_value'] == $v) || $value == $v; |
||
1024 | $input_html .= '<option value="' . $k . '"' . ($true ? ' selected' : '') . '>' . tokenTxtReplace($v) . '</option>'; |
||
1025 | if ($true) |
||
1026 | $output_html = $v; |
||
1027 | } |
||
1028 | |||
1029 | $input_html .= '</select>'; |
||
1030 | } |
||
1031 | elseif ($row['field_type'] == 'radio') |
||
1032 | { |
||
1033 | $input_html = '<fieldset>'; |
||
1034 | $options = explode(',', $row['field_options']); |
||
1035 | foreach ($options as $k => $v) |
||
1036 | { |
||
1037 | $true = (!$exists && $row['default_value'] == $v) || $value == $v; |
||
1038 | $input_html .= '<label for="customfield_' . $row['col_name'] . '_' . $k . '"><input type="radio" name="customfield[' . $row['col_name'] . ']" id="customfield_' . $row['col_name'] . '_' . $k . '" value="' . $k . '"' . ($true ? ' checked' : '') . '>' . tokenTxtReplace($v) . '</label><br>'; |
||
1039 | if ($true) |
||
1040 | $output_html = $v; |
||
1041 | } |
||
1042 | $input_html .= '</fieldset>'; |
||
1043 | } |
||
1044 | elseif ($row['field_type'] == 'text') |
||
1045 | { |
||
1046 | $input_html = '<input type="text" name="customfield[' . $row['col_name'] . ']" id="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="' . un_htmlspecialchars($value) . '"' . ($row['show_reg'] == 2 ? ' required' : '') . '>'; |
||
1047 | } |
||
1048 | else |
||
1049 | { |
||
1050 | @list ($rows, $cols) = @explode(',', $row['default_value']); |
||
1051 | $input_html = '<textarea name="customfield[' . $row['col_name'] . ']" id="customfield[' . $row['col_name'] . ']"' . ($row['field_length'] != 0 ? ' maxlength="' . $row['field_length'] . '"' : '') . (!empty($rows) ? ' rows="' . $rows . '"' : '') . (!empty($cols) ? ' cols="' . $cols . '"' : '') . ($row['show_reg'] == 2 ? ' required' : '') . '>' . un_htmlspecialchars($value) . '</textarea>'; |
||
1052 | } |
||
1053 | |||
1054 | // Parse BBCode |
||
1055 | if ($row['bbc']) |
||
1056 | $output_html = parse_bbc($output_html); |
||
1057 | elseif ($row['field_type'] == 'textarea') |
||
1058 | // Allow for newlines at least |
||
1059 | $output_html = strtr($output_html, array("\n" => '<br>')); |
||
1060 | |||
1061 | // Enclosing the user input within some other text? |
||
1062 | if (!empty($row['enclose']) && !empty($output_html)) |
||
1063 | $output_html = strtr($row['enclose'], array( |
||
1064 | '{SCRIPTURL}' => $scripturl, |
||
1065 | '{IMAGES_URL}' => $settings['images_url'], |
||
1066 | '{DEFAULT_IMAGES_URL}' => $settings['default_images_url'], |
||
1067 | '{INPUT}' => un_htmlspecialchars($output_html), |
||
1068 | '{KEY}' => $currentKey |
||
1069 | )); |
||
1070 | |||
1071 | $context['custom_fields'][] = array( |
||
1072 | 'name' => tokenTxtReplace($row['field_name']), |
||
1073 | 'desc' => tokenTxtReplace($row['field_desc']), |
||
1074 | 'type' => $row['field_type'], |
||
1075 | 'order' => $row['field_order'], |
||
1076 | 'input_html' => $input_html, |
||
1077 | 'output_html' => tokenTxtReplace($output_html), |
||
1078 | 'placement' => $row['placement'], |
||
1079 | 'colname' => $row['col_name'], |
||
1080 | 'value' => $value, |
||
1081 | 'show_reg' => $row['show_reg'], |
||
1082 | ); |
||
1083 | $context['custom_fields_required'] = $context['custom_fields_required'] || $row['show_reg'] == 2; |
||
1084 | } |
||
1085 | $smcFunc['db_free_result']($request); |
||
1086 | |||
1087 | call_integration_hook('integrate_load_custom_profile_fields', array($memID, $area)); |
||
1088 | } |
||
1089 | |||
1090 | ?> |