function ModReport() { global $user_info, $context, $sourcedir, $scripturl, $txt, $smcFunc; // Have to at least give us something if (empty($_REQUEST['report'])) { fatal_lang_error('mc_no_modreport_specified'); } EoS_Smarty::setActive(); // Integers only please $_REQUEST['report'] = (int) $_REQUEST['report']; // Get the report details, need this so we can limit access to a particular board $request = smf_db_query(' SELECT lr.id_report, lr.id_msg, lr.id_topic, lr.id_board, lr.id_member, lr.subject, lr.body, lr.time_started, lr.time_updated, lr.num_reports, lr.closed, lr.ignore_all, IFNULL(mem.real_name, lr.membername) AS author_name, IFNULL(mem.id_member, 0) AS id_author FROM {db_prefix}log_reported AS lr LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lr.id_member) WHERE lr.id_report = {int:id_report} AND ' . ($user_info['mod_cache']['bq'] == '1=1' || $user_info['mod_cache']['bq'] == '0=1' ? $user_info['mod_cache']['bq'] : 'lr.' . $user_info['mod_cache']['bq']) . ' LIMIT 1', array('id_report' => $_REQUEST['report'])); // So did we find anything? if (!mysql_num_rows($request)) { fatal_lang_error('mc_no_modreport_found'); } // Woohoo we found a report and they can see it! Bad news is we have more work to do $row = mysql_fetch_assoc($request); mysql_free_result($request); // If they are adding a comment then... add a comment. if (isset($_POST['add_comment']) && !empty($_POST['mod_comment'])) { checkSession(); $newComment = trim(commonAPI::htmlspecialchars($_POST['mod_comment'])); // In it goes. if (!empty($newComment)) { smf_db_insert('', '{db_prefix}log_comments', array('id_member' => 'int', 'member_name' => 'string', 'comment_type' => 'string', 'recipient_name' => 'string', 'id_notice' => 'int', 'body' => 'string', 'log_time' => 'int'), array($user_info['id'], $user_info['name'], 'reportc', '', $_REQUEST['report'], $newComment, time()), array('id_comment')); // Redirect to prevent double submittion. redirectexit($scripturl . '?action=moderate;area=reports;report=' . $_REQUEST['report']); } } $context['report'] = array('id' => $row['id_report'], 'topic_id' => $row['id_topic'], 'board_id' => $row['id_board'], 'message_id' => $row['id_msg'], 'message_href' => $scripturl . '?msg=' . $row['id_msg'], 'message_link' => '<a href="' . $scripturl . '?msg=' . $row['id_msg'] . '">' . $row['subject'] . '</a>', 'report_href' => $scripturl . '?action=moderate;area=reports;report=' . $row['id_report'], 'author' => array('id' => $row['id_author'], 'name' => $row['author_name'], 'link' => $row['id_author'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_author'] . '">' . $row['author_name'] . '</a>' : $row['author_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_author']), 'comments' => array(), 'mod_comments' => array(), 'time_started' => timeformat($row['time_started']), 'last_updated' => timeformat($row['time_updated']), 'subject' => $row['subject'], 'body' => parse_bbc($row['body']), 'num_reports' => $row['num_reports'], 'closed' => $row['closed'], 'ignore' => $row['ignore_all']); // So what bad things do the reporters have to say about it? $request = smf_db_query(' SELECT lrc.id_comment, lrc.id_report, lrc.time_sent, lrc.comment, lrc.member_ip, IFNULL(mem.id_member, 0) AS id_member, IFNULL(mem.real_name, lrc.membername) AS reporter FROM {db_prefix}log_reported_comments AS lrc LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lrc.id_member) WHERE lrc.id_report = {int:id_report}', array('id_report' => $context['report']['id'])); while ($row = mysql_fetch_assoc($request)) { $context['report']['comments'][] = array('id' => $row['id_comment'], 'message' => $row['comment'], 'time' => timeformat($row['time_sent']), 'member' => array('id' => $row['id_member'], 'name' => empty($row['reporter']) ? $txt['guest'] : $row['reporter'], 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['reporter'] . '</a>' : (empty($row['reporter']) ? $txt['guest'] : $row['reporter']), 'href' => $row['id_member'] ? $scripturl . '?action=profile;u=' . $row['id_member'] : '', 'ip' => !empty($row['member_ip']) && allowedTo('moderate_forum') ? '<a href="' . $scripturl . '?action=trackip;searchip=' . $row['member_ip'] . '">' . $row['member_ip'] . '</a>' : '')); } mysql_free_result($request); // Hang about old chap, any comments from moderators on this one? $request = smf_db_query(' SELECT lc.id_comment, lc.id_notice, lc.log_time, lc.body, IFNULL(mem.id_member, 0) AS id_member, IFNULL(mem.real_name, lc.member_name) AS moderator FROM {db_prefix}log_comments AS lc LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lc.id_member) WHERE lc.id_notice = {int:id_report} AND lc.comment_type = {string:reportc}', array('id_report' => $context['report']['id'], 'reportc' => 'reportc')); while ($row = mysql_fetch_assoc($request)) { $context['report']['mod_comments'][] = array('id' => $row['id_comment'], 'message' => parse_bbc($row['body']), 'time' => timeformat($row['log_time']), 'member' => array('id' => $row['id_member'], 'name' => $row['moderator'], 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['moderator'] . '</a>' : $row['moderator'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member'])); } mysql_free_result($request); // What have the other moderators done to this message? require_once $sourcedir . '/Modlog.php'; require_once $sourcedir . '/lib/Subs-List.php'; loadLanguage('Modlog'); // This is all the information from the moderation log. $listOptions = array('id' => 'moderation_actions_list', 'title' => $txt['mc_modreport_modactions'], 'items_per_page' => 15, 'no_items_label' => $txt['modlog_no_entries_found'], 'base_href' => $scripturl . '?action=moderate;area=reports;report=' . $context['report']['id'], 'default_sort_col' => 'time', 'get_items' => array('function' => 'list_getModLogEntries', 'params' => array('lm.id_topic = {int:id_topic}', array('id_topic' => $context['report']['topic_id']), 1)), 'get_count' => array('function' => 'list_getModLogEntryCount', 'params' => array('lm.id_topic = {int:id_topic}', array('id_topic' => $context['report']['topic_id']), 1)), 'columns' => array('action' => array('header' => array('value' => $txt['modlog_action']), 'data' => array('db' => 'action_text', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.action', 'reverse' => 'lm.action DESC')), 'time' => array('header' => array('value' => $txt['modlog_date']), 'data' => array('db' => 'time', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.log_time', 'reverse' => 'lm.log_time DESC')), 'moderator' => array('header' => array('value' => $txt['modlog_member']), 'data' => array('db' => 'moderator_link', 'class' => 'smalltext'), 'sort' => array('default' => 'mem.real_name', 'reverse' => 'mem.real_name DESC')), 'position' => array('header' => array('value' => $txt['modlog_position']), 'data' => array('db' => 'position', 'class' => 'smalltext'), 'sort' => array('default' => 'mg.group_name', 'reverse' => 'mg.group_name DESC')), 'ip' => array('header' => array('value' => $txt['modlog_ip']), 'data' => array('db' => 'ip', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.ip', 'reverse' => 'lm.ip DESC')))); // Create the watched user list. createList($listOptions); // Make sure to get the correct tab selected. if ($context['report']['closed']) { $context[$context['moderation_menu_name']]['current_subsection'] = 'closed'; } // Finally we are done :P //loadTemplate('ModerationCenter'); EoS_Smarty::loadTemplate('modcenter/modcenter_base'); EoS_Smarty::getConfigInstance()->registerHookTemplate('modcenter_content_area', 'modcenter/viewmodreport'); $context['page_title'] = sprintf($txt['mc_viewmodreport'], $context['report']['subject'], $context['report']['author']['name']); $context['sub_template'] = 'viewmodreport'; $context['close_button'] = create_button($context['report']['closed'] ? 'mc_reportedp_open' : 'mc_reportedp_close', $context['report']['closed'] ? 'mc_reportedp_open' : 'mc_reportedp_close'); $context['ignore_button'] = create_button('mc_reportedp_ignore', 'mc_reportedp_ignore'); $context['unignore_button'] = create_button('mc_reportedp_unignore', 'mc_reportedp_unignore'); }
function MessageMain() { global $txt, $scripturl, $sourcedir, $context, $user_info, $user_settings, $smcFunc, $modSettings; // No guests! is_not_guest(); // You're not supposed to be here at all, if you can't even read PMs. isAllowedTo('pm_read'); // This file contains the basic functions for sending a PM. require_once $sourcedir . '/lib/Subs-Post.php'; loadLanguage('PersonalMessage'); EoS_Smarty::setActive(); $context['need_synhlt'] = true; // Load up the members maximum message capacity. if ($user_info['is_admin']) { $context['message_limit'] = 0; } elseif (($context['message_limit'] = CacheAPI::getCache('msgLimit:' . $user_info['id'], 360)) === null) { // !!! Why do we do this? It seems like if they have any limit we should use it. $request = smf_db_query(' SELECT MAX(max_messages) AS top_limit, MIN(max_messages) AS bottom_limit FROM {db_prefix}membergroups WHERE id_group IN ({array_int:users_groups})', array('users_groups' => $user_info['groups'])); list($maxMessage, $minMessage) = mysql_fetch_row($request); mysql_free_result($request); $context['message_limit'] = $minMessage == 0 ? 0 : $maxMessage; // Save us doing it again! CacheAPI::putCache('msgLimit:' . $user_info['id'], $context['message_limit'], 360); } // Prepare the context for the capacity bar. if (!empty($context['message_limit'])) { $bar = $user_info['messages'] * 100 / $context['message_limit']; $context['limit_bar'] = array('messages' => $user_info['messages'], 'allowed' => $context['message_limit'], 'percent' => $bar, 'bar' => min(100, (int) $bar), 'text' => sprintf($txt['pm_currently_using'], $user_info['messages'], round($bar, 1))); } // a previous message was sent successfully? show a small indication. if (isset($_GET['done']) && $_GET['done'] == 'sent') { $context['pm_sent'] = true; } // Now we have the labels, and assuming we have unsorted mail, apply our rules! if ($user_settings['new_pm']) { $context['labels'] = $user_settings['message_labels'] == '' ? array() : explode(',', $user_settings['message_labels']); foreach ($context['labels'] as $id_label => $label_name) { $context['labels'][(int) $id_label] = array('id' => $id_label, 'name' => trim($label_name), 'messages' => 0, 'unread_messages' => 0); } $context['labels'][-1] = array('id' => -1, 'name' => $txt['pm_msg_label_inbox'], 'messages' => 0, 'unread_messages' => 0); ApplyRules(); updateMemberData($user_info['id'], array('new_pm' => 0)); smf_db_query(' UPDATE {db_prefix}pm_recipients SET is_new = {int:not_new} WHERE id_member = {int:current_member}', array('current_member' => $user_info['id'], 'not_new' => 0)); } // Load the label data. if ($user_settings['new_pm'] || ($context['labels'] = CacheAPI::getCache('labelCounts:' . $user_info['id'], 720)) === null) { $context['labels'] = $user_settings['message_labels'] == '' ? array() : explode(',', $user_settings['message_labels']); foreach ($context['labels'] as $id_label => $label_name) { $context['labels'][(int) $id_label] = array('id' => $id_label, 'name' => trim($label_name), 'messages' => 0, 'unread_messages' => 0); } $context['labels'][-1] = array('id' => -1, 'name' => $txt['pm_msg_label_inbox'], 'messages' => 0, 'unread_messages' => 0); // Looks like we need to reseek! $result = smf_db_query(' SELECT labels, is_read, COUNT(*) AS num FROM {db_prefix}pm_recipients WHERE id_member = {int:current_member} AND deleted = {int:not_deleted} GROUP BY labels, is_read', array('current_member' => $user_info['id'], 'not_deleted' => 0)); while ($row = mysql_fetch_assoc($result)) { $this_labels = explode(',', $row['labels']); foreach ($this_labels as $this_label) { $context['labels'][(int) $this_label]['messages'] += $row['num']; if (!($row['is_read'] & 1)) { $context['labels'][(int) $this_label]['unread_messages'] += $row['num']; } } } mysql_free_result($result); // Store it please! CacheAPI::putCache('labelCounts:' . $user_info['id'], $context['labels'], 720); } // This determines if we have more labels than just the standard inbox. $context['currently_using_labels'] = count($context['labels']) > 1 ? 1 : 0; // Some stuff for the labels... $context['current_label_id'] = isset($_REQUEST['l']) && isset($context['labels'][(int) $_REQUEST['l']]) ? (int) $_REQUEST['l'] : -1; $context['current_label'] =& $context['labels'][(int) $context['current_label_id']]['name']; $context['folder'] = !isset($_REQUEST['f']) || $_REQUEST['f'] != 'sent' ? 'inbox' : 'sent'; // This is convenient. Do you know how annoying it is to do this every time?! $context['current_label_redirect'] = 'action=pm;f=' . $context['folder'] . (isset($_GET['start']) ? ';start=' . $_GET['start'] : '') . (isset($_REQUEST['l']) ? ';l=' . $_REQUEST['l'] : ''); $context['can_issue_warning'] = in_array('w', $context['admin_features']) && allowedTo('issue_warning') && $modSettings['warning_settings'][0] == 1; // Build the linktree for all the actions... $context['linktree'][] = array('url' => $scripturl . '?action=pm', 'name' => $txt['personal_messages']); // Preferences... $context['display_mode'] = $user_settings['pm_prefs'] & 3; $subActions = array('addbuddy' => 'WirelessAddBuddy', 'manlabels' => 'ManageLabels', 'manrules' => 'ManageRules', 'pmactions' => 'MessageActionsApply', 'prune' => 'MessagePrune', 'removeall' => 'MessageKillAllQuery', 'removeall2' => 'MessageKillAll', 'report' => 'ReportMessage', 'search' => 'MessageSearch', 'search2' => 'MessageSearch2', 'send' => 'MessagePost', 'send2' => 'MessagePost2', 'settings' => 'MessageSettings'); if (!isset($_REQUEST['sa']) || !isset($subActions[$_REQUEST['sa']])) { MessageFolder(); EoS_Smarty::loadTemplate('pm/base'); EoS_Smarty::getConfigInstance()->registerHookTemplate('pm_content_area', 'pm/folder'); } else { $sa = $_REQUEST['sa']; if ($sa == 'send' || $sa == 'send2') { EoS_Smarty::loadTemplate('pm/base'); EoS_Smarty::getConfigInstance()->registerHookTemplate('pm_content_area', 'pm/send'); } messageIndexBar($_REQUEST['sa']); $subActions[$_REQUEST['sa']](); } }
function ModifyProfile($post_errors = array()) { global $txt, $scripturl, $user_info, $context, $sourcedir, $user_profile, $cur_profile; global $modSettings, $memberContext, $profile_vars, $post_errors, $user_settings; $boards = boardsAllowedTo('moderate_board'); $is_mod = !empty($boards) || $user_info['is_admin'] || allowedTo('moderate_forum'); EoS_Smarty::setActive(); // Don't reload this as we may have processed error strings. if (empty($post_errors)) { loadLanguage('Profile'); } EoS_Smarty::getConfigInstance()->registerHookTemplate('sidemenu_top', 'profile/menu_top_content'); //$context['sef_full_rewrite'] = true; require_once $sourcedir . '/lib/Subs-Menu.php'; // Did we get the user by name... if (isset($_REQUEST['user'])) { $memberResult = loadMemberData($_REQUEST['user'], true, 'profile'); } elseif (!empty($_REQUEST['u'])) { $memberResult = loadMemberData((int) $_REQUEST['u'], false, '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')), 'likes' => array($txt['showLikes'], array('profile_view_own', 'profile_view_any')), 'likesout' => array($txt['showLikesGiven'], array('profile_view_own', 'profile_view_any'))), 'permission' => array('own' => 'profile_view_own', 'any' => 'profile_view_any')), 'activities' => array('label' => $txt['showActivitiesMenu'], 'file' => 'Activities.php', 'function' => 'showActivitiesProfile', 'subsections' => array('activities' => array($txt['showActivities'], array('profile_view_own', 'profile_view_any')), 'notifications' => array($txt['showNotifications'], array('profile_view_own', 'profile_view_any')), 'settings' => array($txt['astreamSettings'], 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] == 1 && $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')), 'view_topicbans' => array('label' => $txt['profile_view_topicbans'], 'enabled' => $is_mod, 'file' => 'Profile.php', 'function' => 'viewTopicBans', 'permission' => array('own' => 'profile_view_any', 'any' => 'profile_view_any')))), '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'] != 1 && !in_array(1, explode(',', $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'))), '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']), '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'))), 'boardnews' => array('label' => $txt['menu_boardnews'], 'file' => 'Profile-Modify.php', 'function' => 'profileManageBoardNews', 'enabled' => $context['user']['is_owner'], 'sc' => 'post', 'permission' => array('own' => array('profile_view_own'), 'any' => array())))), '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] == 1 && (!$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'] != 1 && !in_array(1, explode(',', $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')))))); //if(!$context['user']['is_owner'] || !in_array('dr', $context['admin_features'])) todo: drafts -> plugin unset($profile_areas['info']['areas']['drafts']); if (!in_array('as', $context['admin_features'])) { unset($profile_areas['info']['areas']['activities']); } if (!$user_info['is_admin'] && !$context['user']['is_owner'] && isset($profile_areas['info']['areas']['activities'])) { unset($profile_areas['info']['areas']['activities']['subsections']['notifications']); unset($profile_areas['info']['areas']['activities']['subsections']['settings']); } if (!$context['user']['is_owner'] && !allowedTo('can_view_ratings') || empty($modSettings['karmaMode'])) { unset($profile_areas['info']['areas']['showposts']['subsections']['likes']); unset($profile_areas['info']['areas']['showposts']['subsections']['likesout']); } // Let them modify profile areas easily. HookAPI::callHook('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; } 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']); // 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 . '/lib/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(true, HookAPI::callHook('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 : '')); } elseif ($current_area == 'authentication') { authentication($memID, true); } 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'])) { HookAPI::callHook('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'])))); } smf_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. CacheAPI::putCache('member_data-profile-' . $memID, null, 0); } } // 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; } } 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] : ''); } }