function MembergroupMembers() { global $txt, $scripturl, $context, $modSettings, $sourcedir, $user_info, $settings, $smcFunc; $_REQUEST['group'] = isset($_REQUEST['group']) ? (int) $_REQUEST['group'] : 0; // No browsing of guests, membergroup 0 or moderators. if (in_array($_REQUEST['group'], array(-1, 0, 3))) { fatal_lang_error('membergroup_does_not_exist', false); } // Load up the group details. $request = $smcFunc['db_query']('', ' SELECT id_group AS id, group_name AS name, CASE WHEN min_posts = {int:min_posts} THEN 1 ELSE 0 END AS assignable, hidden, online_color, stars, description, CASE WHEN min_posts != {int:min_posts} THEN 1 ELSE 0 END AS is_post_group FROM {db_prefix}membergroups WHERE id_group = {int:id_group} LIMIT 1', array('min_posts' => -1, 'id_group' => $_REQUEST['group'])); // Doesn't exist? if ($smcFunc['db_num_rows']($request) == 0) { fatal_lang_error('membergroup_does_not_exist', false); } $context['group'] = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); // Fix the stars. $context['group']['stars'] = explode('#', $context['group']['stars']); $context['group']['stars'] = !empty($context['group']['stars'][0]) && !empty($context['group']['stars'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/' . $context['group']['stars'][1] . '" alt="*" border="0" />', $context['group']['stars'][0]) : ''; $context['group']['can_moderate'] = allowedTo('manage_membergroups'); $context['linktree'][] = array('url' => $scripturl . '?action=groups;sa=members;group=' . $context['group']['id'], 'name' => $context['group']['name']); // Load all the group moderators, for fun. $request = $smcFunc['db_query']('', ' SELECT mem.id_member, mem.real_name FROM {db_prefix}group_moderators AS mods INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member) WHERE mods.id_group = {int:id_group}', array('id_group' => $_REQUEST['group'])); $context['group']['moderators'] = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $context['MemberColor_ID_MEMBER'][$row['id_member']] = $row['id_member']; $context['group']['moderators'][] = array('id' => $row['id_member'], 'name' => $row['real_name']); if ($user_info['id'] == $row['id_member']) { $context['group']['can_moderate'] = true; } } $smcFunc['db_free_result']($request); // If this group is hidden then it can only "exists" if the user can moderate it! if ($context['group']['hidden'] && !$context['group']['can_moderate']) { fatal_lang_error('membergroup_does_not_exist', false); } // You can only assign membership if you are the moderator and/or can manage groups! if (!$context['group']['can_moderate']) { $context['group']['assignable'] = 0; } elseif ($context['group']['id'] == 1 && !allowedTo('admin_forum')) { $context['group']['assignable'] = 0; } // Removing member from group? if (isset($_POST['remove']) && !empty($_REQUEST['rem']) && is_array($_REQUEST['rem']) && $context['group']['assignable']) { checkSession(); // Make sure we're dealing with integers only. foreach ($_REQUEST['rem'] as $key => $group) { $_REQUEST['rem'][$key] = (int) $group; } require_once $sourcedir . '/Subs-Membergroups.php'; removeMembersFromGroups($_REQUEST['rem'], $_REQUEST['group'], true); } elseif (isset($_REQUEST['add']) && (!empty($_REQUEST['toAdd']) || !empty($_REQUEST['member_add'])) && $context['group']['assignable']) { checkSession(); $member_query = array(); $member_parameters = array(); // Get all the members to be added... taking into account names can be quoted ;) $_REQUEST['toAdd'] = strtr($smcFunc['htmlspecialchars']($_REQUEST['toAdd'], ENT_QUOTES), array('"' => '"')); preg_match_all('~"([^"]+)"~', $_REQUEST['toAdd'], $matches); $member_names = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_REQUEST['toAdd'])))); foreach ($member_names as $index => $member_name) { $member_names[$index] = trim($smcFunc['strtolower']($member_names[$index])); if (strlen($member_names[$index]) == 0) { unset($member_names[$index]); } } // Any passed by ID? $member_ids = array(); if (!empty($_REQUEST['member_add'])) { foreach ($_REQUEST['member_add'] as $id) { if ($id > 0) { $member_ids[] = (int) $id; } } } // Construct the query pelements. if (!empty($member_ids)) { $member_query[] = 'id_member IN ({array_int:member_ids})'; $member_parameters['member_ids'] = $member_ids; } if (!empty($member_names)) { $member_query[] = 'LOWER(member_name) IN ({array_string:member_names})'; $member_query[] = 'LOWER(real_name) IN ({array_string:member_names})'; $member_parameters['member_names'] = $member_names; } $members = array(); if (!empty($member_query)) { $request = $smcFunc['db_query']('', ' SELECT id_member FROM {db_prefix}members WHERE (' . implode(' OR ', $member_query) . ') AND id_group != {int:id_group} AND FIND_IN_SET({int:id_group}, additional_groups) = 0', array_merge($member_parameters, array('id_group' => $_REQUEST['group']))); while ($row = $smcFunc['db_fetch_assoc']($request)) { $members[] = $row['id_member']; } $smcFunc['db_free_result']($request); } // !!! Add $_POST['additional'] to templates! // Do the updates... if (!empty($members)) { require_once $sourcedir . '/Subs-Membergroups.php'; addMembersToGroup($members, $_REQUEST['group'], isset($_POST['additional']) || $context['group']['hidden'] ? 'only_additional' : 'auto', true); } } // Sort out the sorting! $sort_methods = array('name' => 'real_name', 'email' => allowedTo('moderate_forum') ? 'email_address' : 'hide_email ' . (isset($_REQUEST['desc']) ? 'DESC' : 'ASC') . ', email_address', 'active' => 'last_login', 'registered' => 'date_registered', 'posts' => 'posts'); // They didn't pick one, default to by name.. if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) { $context['sort_by'] = 'name'; $querySort = 'real_name'; } else { $context['sort_by'] = $_REQUEST['sort']; $querySort = $sort_methods[$_REQUEST['sort']]; } $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up'; // The where on the query is interesting. Non-moderators should only see people who are in this group as primary. if ($context['group']['can_moderate']) { $where = $context['group']['is_post_group'] ? 'id_post_group = {int:group}' : 'id_group = {int:group} OR FIND_IN_SET({int:group}, additional_groups) != 0'; } else { $where = $context['group']['is_post_group'] ? 'id_post_group = {int:group}' : 'id_group = {int:group}'; } // Count members of the group. $request = $smcFunc['db_query']('', ' SELECT COUNT(*) FROM {db_prefix}members WHERE ' . $where, array('group' => $_REQUEST['group'])); list($context['total_members']) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); $context['total_members'] = comma_format($context['total_members']); // Create the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=' . ($context['group']['can_moderate'] ? 'moderate;area=viewgroups' : 'groups') . ';sa=members;group=' . $_REQUEST['group'] . ';sort=' . $context['sort_by'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $context['total_members'], $modSettings['defaultMaxMembers']); $context['start'] = $_REQUEST['start']; $context['can_moderate_forum'] = allowedTo('moderate_forum'); // Load up all members of this group. $request = $smcFunc['db_query']('', ' SELECT id_member, member_name, real_name, email_address, member_ip, date_registered, last_login, hide_email, posts, is_activated, real_name FROM {db_prefix}members WHERE ' . $where . ' ORDER BY ' . $querySort . ' ' . ($context['sort_direction'] == 'down' ? 'DESC' : 'ASC') . ' LIMIT ' . $context['start'] . ', ' . $modSettings['defaultMaxMembers'], array('group' => $_REQUEST['group'])); $context['members'] = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $last_online = empty($row['last_login']) ? $txt['never'] : timeformat($row['last_login']); // Italicize the online note if they aren't activated. if ($row['is_activated'] % 10 != 1) { $last_online = '<em title="' . $txt['not_activated'] . '">' . $last_online . '</em>'; } if (!empty($row['id_member'])) { $context['MemberColor_ID_MEMBER'][$row['id_member']] = $row['id_member']; } $context['members'][] = array('id' => $row['id_member'], 'name' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>', 'email' => $row['email_address'], 'show_email' => showEmailAddress(!empty($row['hide_email']), $row['id_member']), 'ip' => '<a href="' . $scripturl . '?action=trackip;searchip=' . $row['member_ip'] . '">' . $row['member_ip'] . '</a>', 'registered' => timeformat($row['date_registered']), 'last_online' => $last_online, 'posts' => comma_format($row['posts']), 'is_activated' => $row['is_activated'] % 10 == 1); } $smcFunc['db_free_result']($request); //Color the Groups List ;D if (!empty($modSettings['MemberColorModCenter']) && !empty($context['MemberColor_ID_MEMBER'])) { $colorDatas = load_onlineColors($context['MemberColor_ID_MEMBER']); if (!empty($context['group']['moderators'])) { foreach ($context['group']['moderators'] as $key => $item) { if (!empty($colorDatas[$item['id']]['colored_link'])) { $context['group']['moderators'][$key]['name'] = $colorDatas[$item['id']]['colored_name']; } } } if (!empty($context['members'])) { foreach ($context['members'] as $key => $item) { if (!empty($colorDatas[$item['id']]['colored_link'])) { $context['members'][$key]['name'] = $colorDatas[$item['id']]['colored_link']; } } } } // Select the template. $context['sub_template'] = 'group_members'; $context['page_title'] = $txt['membergroups_members_title'] . ': ' . $context['group']['name']; }
function loadMemberContext($user, $display_custom_fields = false) { global $memberContext, $user_profile, $txt, $scripturl, $user_info; global $context, $modSettings, $settings; static $dataLoaded = array(); // If this person's data is already loaded, skip it. if (isset($dataLoaded[$user])) { return true; } // We can't load guests or members not loaded by loadMemberData()! if ($user == 0) { return false; } if (!isset($user_profile[$user])) { trigger_error('loadMemberContext(): member id ' . $user . ' not previously loaded by loadMemberData()', E_USER_WARNING); return false; } // Well, it's loaded now anyhow. $dataLoaded[$user] = true; $profile = $user_profile[$user]; // Censor everything. censorText($profile['signature']); censorText($profile['personal_text']); censorText($profile['location']); // Set things up to be used before hand. $gendertxt = $profile['gender'] == 2 ? $txt['female'] : ($profile['gender'] == 1 ? $txt['male'] : ''); $profile['signature'] = str_replace(array("\n", "\r"), array('<br />', ''), $profile['signature']); $profile['signature'] = parse_bbc($profile['signature'], true, 'sig' . $profile['id_member']); $profile['is_online'] = (!empty($profile['show_online']) || allowedTo('moderate_forum')) && $profile['is_online'] > 0; $profile['stars'] = empty($profile['stars']) ? array('', '') : explode('#', $profile['stars']); // Setup the buddy status here (One whole in_array call saved :P) $profile['buddy'] = in_array($profile['id_member'], $user_info['buddies']); $buddy_list = !empty($profile['buddy_list']) ? explode(',', $profile['buddy_list']) : array(); // If we're always html resizing, assume it's too large. if ($modSettings['avatar_action_too_large'] == 'option_html_resize' || $modSettings['avatar_action_too_large'] == 'option_js_resize') { $avatar_width = !empty($modSettings['avatar_max_width_external']) ? ' width="' . $modSettings['avatar_max_width_external'] . '"' : ''; $avatar_height = !empty($modSettings['avatar_max_height_external']) ? ' height="' . $modSettings['avatar_max_height_external'] . '"' : ''; } else { $avatar_width = ''; $avatar_height = ''; } $m_href = URL::user($profile['id_member'], $profile['real_name']); // What a monstrous array... $memberContext[$user] = array('username' => $profile['member_name'], 'name' => $profile['real_name'], 'id' => $profile['id_member'], 'is_buddy' => $profile['buddy'], 'is_reverse_buddy' => in_array($user_info['id'], $buddy_list), 'buddies' => $buddy_list, 'title' => !empty($modSettings['titlesEnable']) ? $profile['usertitle'] : '', 'href' => $m_href, 'link' => '<a class="member group_' . (empty($profile['id_group']) ? $profile['id_post_group'] : $profile['id_group']) . '" onclick="getMcard(' . $profile['id_member'] . ');return(false);" href="' . $m_href . '" title="' . $txt['profile_of'] . ' ' . $profile['real_name'] . '">' . $profile['real_name'] . '</a>', 'email' => $profile['email_address'], 'show_email' => showEmailAddress(!empty($profile['hide_email']), $profile['id_member']), 'registered' => empty($profile['date_registered']) ? $txt['not_applicable'] : timeformat($profile['date_registered']), 'blurb' => $profile['personal_text'], 'gender' => array('name' => $gendertxt, 'image' => !empty($profile['gender']) ? '<img class="gender" src="' . $settings['images_url'] . '/' . ($profile['gender'] == 1 ? 'Male' : 'Female') . '.gif" alt="' . $gendertxt . '" />' : ''), 'birth_date' => empty($profile['birthdate']) || $profile['birthdate'] === '0001-01-01' ? '0000-00-00' : (substr($profile['birthdate'], 0, 4) === '0004' ? '0000' . substr($profile['birthdate'], 4) : $profile['birthdate']), 'signature' => $profile['signature'], 'location' => $profile['location'], 'real_posts' => $profile['posts'], 'posts' => comma_format($profile['posts']), 'avatar' => array('name' => $profile['avatar'], 'image' => $profile['avatar'] == '' ? $profile['id_attach'] > 0 ? '<img class="avatar" src="' . (empty($profile['attachment_type']) ? $scripturl . '?action=dlattach;attach=' . $profile['id_attach'] . ';type=avatar' : $modSettings['custom_avatar_url'] . '/' . $profile['filename']) . '" alt="" />' : '' : (stristr($profile['avatar'], 'http://') ? '<img class="avatar" src="' . $profile['avatar'] . '"' . $avatar_width . $avatar_height . ' alt="" />' : '<img class="avatar" src="' . $modSettings['avatar_url'] . '/' . htmlspecialchars($profile['avatar']) . '" alt="" />'), 'href' => $profile['avatar'] == '' ? $profile['id_attach'] > 0 ? empty($profile['attachment_type']) ? $scripturl . '?action=dlattach;attach=' . $profile['id_attach'] . ';type=avatar' : $modSettings['custom_avatar_url'] . '/' . $profile['filename'] : '' : (stristr($profile['avatar'], 'http://') ? $profile['avatar'] : $modSettings['avatar_url'] . '/' . $profile['avatar']), 'url' => $profile['avatar'] == '' ? '' : (stristr($profile['avatar'], 'http://') ? $profile['avatar'] : $modSettings['avatar_url'] . '/' . $profile['avatar'])), 'last_login' => empty($profile['last_login']) ? $txt['never'] : !empty($profile['show_online']) || allowedTo('moderate_forum') ? timeformat($profile['last_login']) : $txt['hidden'], 'ip' => htmlspecialchars($profile['member_ip']), 'ip2' => htmlspecialchars($profile['member_ip2']), 'online' => array('is_online' => $profile['is_online'], 'text' => $txt[$profile['is_online'] ? 'online' : 'offline'], 'href' => $scripturl . '?action=pm;sa=send;u=' . $profile['id_member'], 'link' => '<a href="' . $scripturl . '?action=pm;sa=send;u=' . $profile['id_member'] . '">' . $txt[$profile['is_online'] ? 'online' : 'offline'] . '</a>', 'image_href' => $settings['images_url'] . '/' . ($profile['buddy'] ? 'buddy_' : '') . ($profile['is_online'] ? 'useron' : 'useroff') . '.gif', 'label' => $txt[$profile['is_online'] ? 'online' : 'offline']), 'language' => commonAPI::ucwords(strtr($profile['lngfile'], array('_' => ' ', '-utf8' => ''))), 'is_activated' => isset($profile['is_activated']) ? $profile['is_activated'] : 1, 'is_banned' => isset($profile['is_activated']) ? $profile['is_activated'] >= 10 : 0, 'options' => $profile['options'], 'is_guest' => false, 'group' => $profile['member_group'], 'group_id' => $profile['id_group'], 'post_group_id' => $profile['id_post_group'], 'post_group' => $profile['post_group'], 'group_stars' => str_repeat('<img src="' . str_replace('$language', $context['user']['language'], isset($profile['stars'][1]) ? $settings['images_url'] . '/' . $profile['stars'][1] : '') . '" alt="*" />', empty($profile['stars'][0]) || empty($profile['stars'][1]) ? 0 : $profile['stars'][0]), 'warning' => $profile['warning'], 'warning_status' => !empty($modSettings['warning_mute']) && $modSettings['warning_mute'] <= $profile['warning'] ? 'mute' : (!empty($modSettings['warning_moderate']) && $modSettings['warning_moderate'] <= $profile['warning'] ? 'moderate' : (!empty($modSettings['warning_watch']) && $modSettings['warning_watch'] <= $profile['warning'] ? 'watch' : '')), 'local_time' => timeformat_static(time() + ($profile['time_offset'] - $user_info['time_offset']) * 3600, false), 'liked' => isset($profile['liked']) ? $profile['liked'] : 0, 'likesgiven' => isset($profile['likesgiven']) ? $profile['likesgiven'] : 0, 'notify_optout' => isset($profile['notify_optout']) ? $profile['notify_optout'] : ''); if ($memberContext[$user]['avatar']['name'] == 'gravatar') { $hash = md5(strtolower(trim($memberContext[$user]['email']))); $memberContext[$user]['avatar']['image'] = '<img class="avatar" alt="avatar" src="http://www.gravatar.com/avatar/' . $hash . '" />'; $memberContext[$user]['avatar']['href'] = 'http://www.gravatar.com/avatar/' . $hash; $memberContext[$user]['avatar']['url'] = $memberContext[$user]['avatar']['href']; } // First do a quick run through to make sure there is something to be shown. $memberContext[$user]['has_messenger'] = false; // Are we also loading the members custom fields into context? if ($display_custom_fields && !empty($modSettings['displayFields'])) { $memberContext[$user]['custom_fields'] = array(); if (!isset($context['display_fields'])) { $context['display_fields'] = unserialize($modSettings['displayFields']); } foreach ($context['display_fields'] as $custom) { if (empty($custom['title']) || empty($profile['options'][$custom['colname']])) { continue; } $value = $profile['options'][$custom['colname']]; // BBC? if ($custom['bbc']) { $value = parse_bbc($value); } elseif (isset($custom['type']) && $custom['type'] == 'check') { $value = $value ? $txt['yes'] : $txt['no']; } // Enclosing the user input within some other text? if (!empty($custom['enclose'])) { $value = strtr($custom['enclose'], array('{SCRIPTURL}' => $scripturl, '{IMAGES_URL}' => $settings['images_url'], '{DEFAULT_IMAGES_URL}' => $settings['default_images_url'], '{INPUT}' => $value)); } $memberContext[$user]['custom_fields'][] = array('title' => $custom['title'], 'colname' => $custom['colname'], 'value' => $value, 'placement' => !empty($custom['placement']) ? $custom['placement'] : 0); } } HookAPI::callHook('integrate_loadmembercontext', array(&$memberContext[$user], &$profile)); return true; }
/** * Finds members by email address, username, or real name. * - searches for members whose username, display name, or e-mail address match the given pattern of array names. * - searches only buddies if buddies_only is set. * * @param array $names, * @param bool $use_wildcards = false, accepts wildcards ? and * in the patern if true * @param bool $buddies_only = false, * @param int $max = 500 retrieves a maximum of max members, if passed * @return array containing information about the matching members */ function findMembers($names, $use_wildcards = false, $buddies_only = false, $max = 500) { global $scripturl, $user_info, $modSettings, $smcFunc; // If it's not already an array, make it one. if (!is_array($names)) { $names = explode(',', $names); } $maybe_email = false; foreach ($names as $i => $name) { // Trim, and fix wildcards for each name. $names[$i] = trim($smcFunc['strtolower']($name)); $maybe_email |= strpos($name, '@') !== false; // Make it so standard wildcards will work. (* and ?) if ($use_wildcards) { $names[$i] = strtr($names[$i], array('%' => '\\%', '_' => '\\_', '*' => '%', '?' => '_', '\'' => ''')); } else { $names[$i] = strtr($names[$i], array('\'' => ''')); } } // What are we using to compare? $comparison = $use_wildcards ? 'LIKE' : '='; // Nothing found yet. $results = array(); // This ensures you can't search someones email address if you can't see it. $email_condition = allowedTo('moderate_forum') ? '' : 'hide_email = 0 AND '; if ($use_wildcards || $maybe_email) { $email_condition = ' OR (' . $email_condition . 'email_address ' . $comparison . ' \'' . implode('\') OR (' . $email_condition . ' email_address ' . $comparison . ' \'', $names) . '\')'; } else { $email_condition = ''; } // Get the case of the columns right - but only if we need to as things like MySQL will go slow needlessly otherwise. $member_name = $smcFunc['db_case_sensitive'] ? 'LOWER(member_name)' : 'member_name'; $real_name = $smcFunc['db_case_sensitive'] ? 'LOWER(real_name)' : 'real_name'; // Search by username, display name, and email address. $request = $smcFunc['db_query']('', ' SELECT id_member, member_name, real_name, email_address, hide_email FROM {db_prefix}members WHERE ({raw:member_name_search} OR {raw:real_name_search} {raw:email_condition}) ' . ($buddies_only ? 'AND id_member IN ({array_int:buddy_list})' : '') . ' AND is_activated IN (1, 11) LIMIT {int:limit}', array('buddy_list' => $user_info['buddies'], 'member_name_search' => $member_name . ' ' . $comparison . ' \'' . implode('\' OR ' . $member_name . ' ' . $comparison . ' \'', $names) . '\'', 'real_name_search' => $real_name . ' ' . $comparison . ' \'' . implode('\' OR ' . $real_name . ' ' . $comparison . ' \'', $names) . '\'', 'email_condition' => $email_condition, 'limit' => $max)); while ($row = $smcFunc['db_fetch_assoc']($request)) { $results[$row['id_member']] = array('id' => $row['id_member'], 'name' => $row['real_name'], 'username' => $row['member_name'], 'email' => in_array(showEmailAddress(!empty($row['hide_email']), $row['id_member']), array('yes', 'yes_permission_override')) ? $row['email_address'] : '', 'href' => $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>'); } $smcFunc['db_free_result']($request); // Return all the results. return $results; }
function CustomEmail() { global $context, $modSettings, $user_info, $smcFunc, $txt, $scripturl, $sourcedir; // Can the user even see this information? if ($user_info['is_guest'] && !empty($modSettings['guest_hideContacts'])) { fatal_lang_error('no_access', false); } // Are we sending to a user? $context['form_hidden_vars'] = array(); if (isset($_REQUEST['uid'])) { $request = $smcFunc['db_query']('', ' SELECT email_address AS email, real_name AS name, id_member, hide_email FROM {db_prefix}members WHERE id_member = {int:id_member}', array('id_member' => (int) $_REQUEST['uid'])); $context['form_hidden_vars']['uid'] = (int) $_REQUEST['uid']; } elseif (isset($_REQUEST['msg'])) { $request = $smcFunc['db_query']('', ' SELECT IFNULL(mem.email_address, m.poster_email) AS email, IFNULL(mem.real_name, m.poster_name) AS name, IFNULL(mem.id_member, 0) AS id_member, hide_email FROM {db_prefix}messages AS m LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) WHERE m.id_msg = {int:id_msg}', array('id_msg' => (int) $_REQUEST['msg'])); $context['form_hidden_vars']['msg'] = (int) $_REQUEST['msg']; } if (empty($request) || $smcFunc['db_num_rows']($request) == 0) { fatal_lang_error('cant_find_user_email'); } $row = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); // Are you sure you got the address? if (empty($row['email'])) { fatal_lang_error('cant_find_user_email'); } // Can they actually do this? $context['show_email_address'] = showEmailAddress(!empty($row['hide_email']), $row['id_member']); if ($context['show_email_address'] === 'no') { fatal_lang_error('no_access', false); } // Setup the context! $context['recipient'] = array('id' => $row['id_member'], 'name' => $row['name'], 'email' => $row['email'], 'email_link' => ($context['show_email_address'] == 'yes_permission_override' ? '<em>' : '') . '<a href="mailto:' . $row['email'] . '">' . $row['email'] . '</a>' . ($context['show_email_address'] == 'yes_permission_override' ? '</em>' : ''), 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['name'] . '</a>' : $row['name']); // Can we see this person's email address? $context['can_view_receipient_email'] = $context['show_email_address'] == 'yes' || $context['show_email_address'] == 'yes_permission_override'; // Are we actually sending it? if (isset($_POST['send']) && isset($_POST['email_body'])) { require_once $sourcedir . '/Subs-Post.php'; checkSession(); // If it's a guest sort out their names. if ($user_info['is_guest']) { if (empty($_POST['y_name']) || $_POST['y_name'] == '_' || trim($_POST['y_name']) == '') { fatal_lang_error('no_name', false); } if (empty($_POST['y_email'])) { fatal_lang_error('no_email', false); } if (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['y_email']) == 0) { fatal_lang_error('email_invalid_character', false); } $from_name = trim($_POST['y_name']); $from_email = trim($_POST['y_email']); } else { $from_name = $user_info['name']; $from_email = $user_info['email']; } // Check we have a body (etc). if (trim($_POST['email_body']) == '' || trim($_POST['email_subject']) == '') { fatal_lang_error('email_missing_data'); } // We use a template in case they want to customise! $replacements = array('EMAILSUBJECT' => $_POST['email_subject'], 'EMAILBODY' => $_POST['email_body'], 'SENDERNAME' => $from_name, 'RECPNAME' => $context['recipient']['name']); // Don't let them send too many! spamProtection('sendmail'); // Get the template and get out! $emaildata = loadEmailTemplate('send_email', $replacements); sendmail($context['recipient']['email'], $emaildata['subject'], $emaildata['body'], $from_email, null, false, 1, null, true); // Now work out where to go! if (isset($_REQUEST['uid'])) { redirectexit('action=profile;u=' . (int) $_REQUEST['uid']); } elseif (isset($_REQUEST['msg'])) { redirectexit('msg=' . (int) $_REQUEST['msg']); } else { redirectexit(); } } $context['sub_template'] = 'custom_email'; $context['page_title'] = $txt['send_email']; }
/** * Callback for the message display. * It actually gets and prepares the message context. * This method will start over from the beginning if reset is set to true, which is * useful for showing an index before or after the posts. * * @param bool $reset default false. */ public function prepareDisplayContext_callback($reset = false) { global $settings, $txt, $modSettings, $scripturl, $options, $user_info; global $memberContext, $context, $messages_request, $topic; static $counter = null; // If the query returned false, bail. if ($messages_request == false) { return false; } // Remember which message this is. (ie. reply #83) if ($counter === null || $reset) { $counter = $context['start']; } // Start from the beginning... if ($reset) { return currentContext($messages_request, $reset); } // Attempt to get the next message. $message = currentContext($messages_request); if (!$message) { return false; } // $context['icon_sources'] says where each icon should come from - here we set up the ones which will always exist! if (empty($context['icon_sources'])) { require_once SUBSDIR . '/MessageIndex.subs.php'; $context['icon_sources'] = MessageTopicIcons(); } // Message Icon Management... check the images exist. if (empty($modSettings['messageIconChecks_disable'])) { // If the current icon isn't known, then we need to do something... if (!isset($context['icon_sources'][$message['icon']])) { $context['icon_sources'][$message['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $message['icon'] . '.png') ? 'images_url' : 'default_images_url'; } } elseif (!isset($context['icon_sources'][$message['icon']])) { $context['icon_sources'][$message['icon']] = 'images_url'; } // If you're a lazy bum, you probably didn't give a subject... $message['subject'] = $message['subject'] != '' ? $message['subject'] : $txt['no_subject']; // Are you allowed to remove at least a single reply? $context['can_remove_post'] |= allowedTo('delete_own') && (empty($modSettings['edit_disable_time']) || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()) && $message['id_member'] == $user_info['id']; // Have you liked this post, can you? $message['you_liked'] = !empty($context['likes'][$message['id_msg']]['member']) && isset($context['likes'][$message['id_msg']]['member'][$user_info['id']]); $message['use_likes'] = allowedTo('like_posts') && ($message['id_member'] != $user_info['id'] || !empty($modSettings['likeAllowSelf'])) && (empty($modSettings['likeMinPosts']) ? true : $modSettings['likeMinPosts'] <= $user_info['posts']); $message['like_count'] = !empty($context['likes'][$message['id_msg']]['count']) ? $context['likes'][$message['id_msg']]['count'] : 0; // If it couldn't load, or the user was a guest.... someday may be done with a guest table. if (!loadMemberContext($message['id_member'], true)) { // Notice this information isn't used anywhere else.... $memberContext[$message['id_member']]['name'] = $message['poster_name']; $memberContext[$message['id_member']]['id'] = 0; $memberContext[$message['id_member']]['group'] = $txt['guest_title']; $memberContext[$message['id_member']]['link'] = $message['poster_name']; $memberContext[$message['id_member']]['email'] = $message['poster_email']; $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0); $memberContext[$message['id_member']]['is_guest'] = true; } else { $memberContext[$message['id_member']]['can_view_profile'] = allowedTo('profile_view_any') || $message['id_member'] == $user_info['id'] && allowedTo('profile_view_own'); $memberContext[$message['id_member']]['is_topic_starter'] = $message['id_member'] == $context['topic_starter_id']; $memberContext[$message['id_member']]['can_see_warning'] = !isset($context['disabled_fields']['warning_status']) && $memberContext[$message['id_member']]['warning_status'] && ($context['user']['can_mod'] || !$user_info['is_guest'] && !empty($modSettings['warning_show']) && ($modSettings['warning_show'] > 1 || $message['id_member'] == $user_info['id'])); } $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; $memberContext[$message['id_member']]['show_profile_buttons'] = $settings['show_profile_buttons'] && (!empty($memberContext[$message['id_member']]['can_view_profile']) || !empty($memberContext[$message['id_member']]['website']['url']) && !isset($context['disabled_fields']['website']) || in_array($memberContext[$message['id_member']]['show_email'], array('yes', 'yes_permission_override', 'no_through_forum')) || $context['can_send_pm']); // Do the censor thang. censorText($message['body']); censorText($message['subject']); // Run BBC interpreter on the message. $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg']); // Compose the memory eat- I mean message array. require_once SUBSDIR . '/Attachments.subs.php'; $output = array('attachment' => loadAttachmentContext($message['id_msg']), 'alternate' => $counter % 2, 'id' => $message['id_msg'], 'href' => $scripturl . '?topic=' . $topic . '.msg' . $message['id_msg'] . '#msg' . $message['id_msg'], 'link' => '<a href="' . $scripturl . '?topic=' . $topic . '.msg' . $message['id_msg'] . '#msg' . $message['id_msg'] . '" rel="nofollow">' . $message['subject'] . '</a>', 'member' => &$memberContext[$message['id_member']], 'icon' => $message['icon'], 'icon_url' => $settings[$context['icon_sources'][$message['icon']]] . '/post/' . $message['icon'] . '.png', 'subject' => $message['subject'], 'time' => standardTime($message['poster_time']), 'html_time' => htmlTime($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'counter' => $counter, 'modified' => array('time' => standardTime($message['modified_time']), 'html_time' => htmlTime($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'name' => $message['modified_name']), 'body' => $message['body'], 'new' => empty($message['is_read']), 'approved' => $message['approved'], 'first_new' => isset($context['start_from']) && $context['start_from'] == $counter, 'is_ignored' => !empty($modSettings['enable_buddylist']) && in_array($message['id_member'], $context['user']['ignoreusers']), 'is_message_author' => $message['id_member'] == $user_info['id'], 'can_approve' => !$message['approved'] && $context['can_approve'], 'can_unapprove' => !empty($modSettings['postmod_active']) && $context['can_approve'] && $message['approved'], 'can_modify' => (!$context['is_locked'] || allowedTo('moderate_board')) && (allowedTo('modify_any') || allowedTo('modify_replies') && $context['user']['started'] || allowedTo('modify_own') && $message['id_member'] == $user_info['id'] && (empty($modSettings['edit_disable_time']) || !$message['approved'] || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 > time())), 'can_remove' => allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'] || allowedTo('delete_own') && $message['id_member'] == $user_info['id'] && (empty($modSettings['edit_disable_time']) || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 > time()), 'can_see_ip' => allowedTo('moderate_forum') || $message['id_member'] == $user_info['id'] && !empty($user_info['id']), 'can_like' => $message['use_likes'] && !$message['you_liked'], 'can_unlike' => $message['use_likes'] && $message['you_liked'], 'like_counter' => $message['like_count'], 'likes_enabled' => !empty($modSettings['likes_enabled']) && ($message['use_likes'] || $message['like_count'] != 0)); if (!empty($output['modified']['name'])) { $output['modified']['last_edit_text'] = sprintf($txt['last_edit_by'], $output['modified']['time'], $output['modified']['name'], standardTime($output['modified']['timestamp'])); } if (!empty($output['member']['karma']['allow'])) { $output['member']['karma'] += array('applaud_url' => $scripturl . '?action=karma;sa=applaud;uid=' . $output['member']['id'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';m=' . $output['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'smite_url' => $scripturl . '?action=karma;sa=smite;uid=' . $output['member']['id'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';m=' . $output['id'] . ';' . $context['session_var'] . '=' . $context['session_id']); } call_integration_hook('integrate_prepare_display_context', array(&$output, &$message)); $counter++; return $output; }
function loadMemberContext($user, $display_custom_fields = false) { global $memberContext, $user_profile, $txt, $scripturl, $user_info; global $context, $modSettings, $board_info, $settings; global $smcFunc; static $dataLoaded = array(); // If this person's data is already loaded, skip it. if (isset($dataLoaded[$user])) { return true; } // We can't load guests or members not loaded by loadMemberData()! if ($user == 0) { return false; } if (!isset($user_profile[$user])) { trigger_error('loadMemberContext(): member id ' . $user . ' not previously loaded by loadMemberData()', E_USER_WARNING); return false; } // Well, it's loaded now anyhow. $dataLoaded[$user] = true; $profile = $user_profile[$user]; // Censor everything. censorText($profile['signature']); censorText($profile['personal_text']); censorText($profile['location']); // Set things up to be used before hand. $gendertxt = $profile['gender'] == 2 ? $txt['female'] : ($profile['gender'] == 1 ? $txt['male'] : ''); $profile['signature'] = str_replace(array("\n", "\r"), array('<br />', ''), $profile['signature']); $profile['signature'] = parse_bbc($profile['signature'], true, 'sig' . $profile['id_member']); $profile['is_online'] = (!empty($profile['show_online']) || allowedTo('moderate_forum')) && $profile['is_online'] > 0; $profile['stars'] = empty($profile['stars']) ? array('', '') : explode('#', $profile['stars']); // Setup the buddy status here (One whole in_array call saved :P) $profile['buddy'] = in_array($profile['id_member'], $user_info['buddies']); $buddy_list = !empty($profile['buddy_list']) ? explode(',', $profile['buddy_list']) : array(); // If we're always html resizing, assume it's too large. if ($modSettings['avatar_action_too_large'] == 'option_html_resize' || $modSettings['avatar_action_too_large'] == 'option_js_resize') { $avatar_width = !empty($modSettings['avatar_max_width_external']) ? ' width="' . $modSettings['avatar_max_width_external'] . '"' : ''; $avatar_height = !empty($modSettings['avatar_max_height_external']) ? ' height="' . $modSettings['avatar_max_height_external'] . '"' : ''; } else { $avatar_width = ''; $avatar_height = ''; } // What a monstrous array... $memberContext[$user] = array('username' => $profile['member_name'], 'name' => $profile['real_name'], 'id' => $profile['id_member'], 'is_buddy' => $profile['buddy'], 'is_reverse_buddy' => in_array($user_info['id'], $buddy_list), 'buddies' => $buddy_list, 'title' => !empty($modSettings['titlesEnable']) ? $profile['usertitle'] : '', 'href' => $scripturl . '?action=profile;u=' . $profile['id_member'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $profile['id_member'] . '" title="' . $txt['profile_of'] . ' ' . $profile['real_name'] . '">' . $profile['real_name'] . '</a>', 'email' => $profile['email_address'], 'show_email' => showEmailAddress(!empty($profile['hide_email']), $profile['id_member']), 'registered' => empty($profile['date_registered']) ? $txt['not_applicable'] : timeformat($profile['date_registered']), 'registered_timestamp' => empty($profile['date_registered']) ? 0 : forum_time(true, $profile['date_registered']), 'blurb' => $profile['personal_text'], 'gender' => array('name' => $gendertxt, 'image' => !empty($profile['gender']) ? '<img class="gender" src="' . $settings['images_url'] . '/' . ($profile['gender'] == 1 ? 'Male' : 'Female') . '.gif" alt="' . $gendertxt . '" />' : ''), 'website' => array('title' => $profile['website_title'], 'url' => $profile['website_url']), 'birth_date' => empty($profile['birthdate']) || $profile['birthdate'] === '0001-01-01' ? '0000-00-00' : (substr($profile['birthdate'], 0, 4) === '0004' ? '0000' . substr($profile['birthdate'], 4) : $profile['birthdate']), 'signature' => $profile['signature'], 'location' => $profile['location'], 'icq' => $profile['icq'] != '' && (empty($modSettings['guest_hideContacts']) || !$user_info['is_guest']) ? array('name' => $profile['icq'], 'href' => 'http://www.icq.com/whitepages/about_me.php?uin=' . $profile['icq'], 'link' => '<a class="icq new_win" href="http://www.icq.com/whitepages/about_me.php?uin=' . $profile['icq'] . '" target="_blank" title="' . $txt['icq_title'] . ' - ' . $profile['icq'] . '"><img src="http://status.icq.com/online.gif?img=5&icq=' . $profile['icq'] . '" alt="' . $txt['icq_title'] . ' - ' . $profile['icq'] . '" width="18" height="18" /></a>', 'link_text' => '<a class="icq extern" href="http://www.icq.com/whitepages/about_me.php?uin=' . $profile['icq'] . '" title="' . $txt['icq_title'] . ' - ' . $profile['icq'] . '">' . $profile['icq'] . '</a>') : array('name' => '', 'add' => '', 'href' => '', 'link' => '', 'link_text' => ''), 'aim' => $profile['aim'] != '' && (empty($modSettings['guest_hideContacts']) || !$user_info['is_guest']) ? array('name' => $profile['aim'], 'href' => 'aim:goim?screenname=' . urlencode(strtr($profile['aim'], array(' ' => '%20'))) . '&message=' . $txt['aim_default_message'], 'link' => '<a class="aim" href="aim:goim?screenname=' . urlencode(strtr($profile['aim'], array(' ' => '%20'))) . '&message=' . $txt['aim_default_message'] . '" title="' . $txt['aim_title'] . ' - ' . $profile['aim'] . '"><img src="' . $settings['images_url'] . '/aim.gif" alt="' . $txt['aim_title'] . ' - ' . $profile['aim'] . '" /></a>', 'link_text' => '<a class="aim" href="aim:goim?screenname=' . urlencode(strtr($profile['aim'], array(' ' => '%20'))) . '&message=' . $txt['aim_default_message'] . '" title="' . $txt['aim_title'] . ' - ' . $profile['aim'] . '">' . $profile['aim'] . '</a>') : array('name' => '', 'href' => '', 'link' => '', 'link_text' => ''), 'yim' => $profile['yim'] != '' && (empty($modSettings['guest_hideContacts']) || !$user_info['is_guest']) ? array('name' => $profile['yim'], 'href' => 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($profile['yim']), 'link' => '<a class="yim" href="http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($profile['yim']) . '" title="' . $txt['yim_title'] . ' - ' . $profile['yim'] . '"><img src="http://opi.yahoo.com/online?u=' . urlencode($profile['yim']) . '&m=g&t=0" alt="' . $txt['yim_title'] . ' - ' . $profile['yim'] . '" /></a>', 'link_text' => '<a class="yim" href="http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($profile['yim']) . '" title="' . $txt['yim_title'] . ' - ' . $profile['yim'] . '">' . $profile['yim'] . '</a>') : array('name' => '', 'href' => '', 'link' => '', 'link_text' => ''), 'msn' => $profile['msn'] != '' && (empty($modSettings['guest_hideContacts']) || !$user_info['is_guest']) ? array('name' => $profile['msn'], 'href' => 'http://members.msn.com/' . $profile['msn'], 'link' => '<a class="msn new_win" href="http://members.msn.com/' . $profile['msn'] . '" title="' . $txt['msn_title'] . ' - ' . $profile['msn'] . '"><img src="' . $settings['images_url'] . '/msntalk.gif" alt="' . $txt['msn_title'] . ' - ' . $profile['msn'] . '" /></a>', 'link_text' => '<a class="msn new_win" href="http://members.msn.com/' . $profile['msn'] . '" title="' . $txt['msn_title'] . ' - ' . $profile['msn'] . '">' . $profile['msn'] . '</a>') : array('name' => '', 'href' => '', 'link' => '', 'link_text' => ''), 'real_posts' => $profile['posts'], 'posts' => $profile['posts'] > 500000 ? $txt['geek'] : comma_format($profile['posts']), 'avatar' => array('name' => $profile['avatar'], 'image' => $profile['avatar'] == '' ? $profile['id_attach'] > 0 ? '<img class="avatar" src="' . (empty($profile['attachment_type']) ? $scripturl . '?action=dlattach;attach=' . $profile['id_attach'] . ';type=avatar' : $modSettings['custom_avatar_url'] . '/' . $profile['filename']) . '" alt="" />' : '' : (stristr($profile['avatar'], 'http://') ? '<img class="avatar" src="' . $profile['avatar'] . '"' . $avatar_width . $avatar_height . ' alt="" />' : '<img class="avatar" src="' . $modSettings['avatar_url'] . '/' . htmlspecialchars($profile['avatar']) . '" alt="" />'), 'href' => $profile['avatar'] == '' ? $profile['id_attach'] > 0 ? empty($profile['attachment_type']) ? $scripturl . '?action=dlattach;attach=' . $profile['id_attach'] . ';type=avatar' : $modSettings['custom_avatar_url'] . '/' . $profile['filename'] : '' : (stristr($profile['avatar'], 'http://') ? $profile['avatar'] : $modSettings['avatar_url'] . '/' . $profile['avatar']), 'url' => $profile['avatar'] == '' ? '' : (stristr($profile['avatar'], 'http://') ? $profile['avatar'] : $modSettings['avatar_url'] . '/' . $profile['avatar'])), 'last_login' => empty($profile['last_login']) ? $txt['never'] : timeformat($profile['last_login']), 'last_login_timestamp' => empty($profile['last_login']) ? 0 : forum_time(0, $profile['last_login']), 'karma' => array('good' => $profile['karma_good'], 'bad' => $profile['karma_bad'], 'allow' => !$user_info['is_guest'] && !empty($modSettings['karmaMode']) && $user_info['id'] != $user && allowedTo('karma_edit') && ($user_info['posts'] >= $modSettings['karmaMinPosts'] || $user_info['is_admin'])), 'ip' => htmlspecialchars($profile['member_ip']), 'ip2' => htmlspecialchars($profile['member_ip2']), 'online' => array('is_online' => $profile['is_online'], 'text' => $txt[$profile['is_online'] ? 'online' : 'offline'], 'href' => $scripturl . '?action=pm;sa=send;u=' . $profile['id_member'], 'link' => '<a href="' . $scripturl . '?action=pm;sa=send;u=' . $profile['id_member'] . '">' . $txt[$profile['is_online'] ? 'online' : 'offline'] . '</a>', 'image_href' => $settings['images_url'] . '/' . ($profile['buddy'] ? 'buddy_' : '') . ($profile['is_online'] ? 'useron' : 'useroff') . '.gif', 'label' => $txt[$profile['is_online'] ? 'online' : 'offline']), 'language' => $smcFunc['ucwords'](strtr($profile['lngfile'], array('_' => ' ', '-utf8' => ''))), 'is_activated' => isset($profile['is_activated']) ? $profile['is_activated'] : 1, 'is_banned' => isset($profile['is_activated']) ? $profile['is_activated'] >= 10 : 0, 'options' => $profile['options'], 'is_guest' => false, 'group' => $profile['member_group'], 'group_color' => $profile['member_group_color'], 'group_id' => $profile['id_group'], 'post_group' => $profile['post_group'], 'post_group_color' => $profile['post_group_color'], 'group_stars' => str_repeat('<img src="' . str_replace('$language', $context['user']['language'], isset($profile['stars'][1]) ? $settings['images_url'] . '/' . $profile['stars'][1] : '') . '" alt="*" />', empty($profile['stars'][0]) || empty($profile['stars'][1]) ? 0 : $profile['stars'][0]), 'warning' => $profile['warning'], 'warning_status' => !empty($modSettings['warning_mute']) && $modSettings['warning_mute'] <= $profile['warning'] ? 'mute' : (!empty($modSettings['warning_moderate']) && $modSettings['warning_moderate'] <= $profile['warning'] ? 'moderate' : (!empty($modSettings['warning_watch']) && $modSettings['warning_watch'] <= $profile['warning'] ? 'watch' : '')), 'local_time' => timeformat(time() + ($profile['time_offset'] - $user_info['time_offset']) * 3600, false)); // First do a quick run through to make sure there is something to be shown. $memberContext[$user]['has_messenger'] = false; foreach (array('icq', 'msn', 'aim', 'yim') as $messenger) { if (!isset($context['disabled_fields'][$messenger]) && !empty($memberContext[$user][$messenger]['link'])) { $memberContext[$user]['has_messenger'] = true; break; } } // Are we also loading the members custom fields into context? if ($display_custom_fields && !empty($modSettings['displayFields'])) { $memberContext[$user]['custom_fields'] = array(); if (!isset($context['display_fields'])) { $context['display_fields'] = unserialize($modSettings['displayFields']); } foreach ($context['display_fields'] as $custom) { if (empty($custom['title']) || empty($profile['options'][$custom['colname']])) { continue; } $value = $profile['options'][$custom['colname']]; // BBC? if ($custom['bbc']) { $value = parse_bbc($value); } elseif (isset($custom['type']) && $custom['type'] == 'check') { $value = $value ? $txt['yes'] : $txt['no']; } // Enclosing the user input within some other text? if (!empty($custom['enclose'])) { $value = strtr($custom['enclose'], array('{SCRIPTURL}' => $scripturl, '{IMAGES_URL}' => $settings['images_url'], '{DEFAULT_IMAGES_URL}' => $settings['default_images_url'], '{INPUT}' => $value)); } $memberContext[$user]['custom_fields'][] = array('title' => $custom['title'], 'colname' => $custom['colname'], 'value' => $value, 'placement' => !empty($custom['placement']) ? $custom['placement'] : 0); } } return true; }
function shd_prepare_reply_context() { global $settings, $txt, $modSettings, $scripturl, $options, $user_info, $smcFunc; global $memberContext, $context, $reply_request; if (empty($reply_request)) { return false; } $message = $smcFunc['db_fetch_assoc']($reply_request); if (!$message) { $smcFunc['db_free_result']($reply_request); return false; } if (!loadMemberContext($message['id_member'], true)) { // Notice this information isn't used anywhere else.... $memberContext[$message['id_member']]['name'] = $message['poster_name']; $memberContext[$message['id_member']]['id'] = 0; $memberContext[$message['id_member']]['group'] = $txt['guest_title']; $memberContext[$message['id_member']]['link'] = $message['poster_name']; $memberContext[$message['id_member']]['email'] = $message['poster_email']; $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0); $memberContext[$message['id_member']]['is_guest'] = true; $memberContext[$message['id_member']]['group_stars'] = ''; } $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; censorText($message['body']); $message['body'] = shd_format_text($message['body'], $message['smileys_enabled'], 'shd_reply_' . $message['id_msg']); $output = array('id' => $message['id_msg'], 'member' => &$memberContext[$message['id_member']], 'time' => timeformat($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'body' => $message['body'], 'is_staff' => !empty($context['shd_is_staff'][$message['id_member']]), 'can_edit' => shd_allowed_to('shd_edit_reply_any', $context['ticket_form']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_edit_reply_own', $context['ticket_form']['dept']), 'ip_address' => $message['poster_ip']); if (!empty($message['modified_time'])) { $output['modified'] = array('time' => timeformat($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'id' => !empty($user_profile[$message['modified_member']]) ? $message['modified_member'] : 0, 'name' => !empty($user_profile[$message['modified_member']]) ? $user_profile[$message['modified_member']]['real_name'] : $message['modified_name']); $output['modified']['link'] = shd_profile_link($output['modified']['name'], $output['modified']['id']); } return $output; }
/** * Callback function for the template to load messages. * * The process set up by shd_view_ticket() and invoked within template_view_replies() is reasonably complex. * {@link shd_view_ticket()} identifies what messages should be displayed on the current page of the ticket, and performs a query * to load the ticket data. Instead, however, of retrieving every row directly into memory before passing to the template, * it passes the query result, and the name of a handler function into $context, so the template can call to get an * individual row at a time, which saves memory amongst other things. * * With respect to {@link shd_view_ticket()}, the relevant items are $reply_request being defined and $context['get_replies'] * being defined as the name of this function, and in {@link template_view_replies()}, the reference is $reply = $context['get_replies']() * * @return mixed The function returns the "next" message reply's details, or simply false if no replies were available, or no further replies are available. Assuming a reply can be returned, it will be a hash array in the following format: * <ul> * <li>id: numeric message id</li> * <li>member: hash array containing details of the poster; normally the return value from SMF's loadMemberContext() function. A minimal set of details is prepared if the poster holds no current SMF account. Common values: * <ul> * <li>name: User's name (falls back to the poster name specified in the replies table)</li> * <li>id: User's id</li> * <li>group: Name of the assigned group/post count group of the user</li> * <li>link: HTML for a hyperlink to their profile</li> * <li>email: Email address of the poster</li> * <li>ip: IP address of the poster</li> * </ul> * </li> * <li>body: censored, parsed for smileys and bbcode (in {@link shd_format_text()})</li> * <li>time: string of the time the reply was posted</li> * <li>timestamp: internal stored timestamp attached to the reply</li> * <li>is_staff: boolean value of whether the posting member is currently helpdesk staff</li> * <li>can_edit: boolean value reflecting if this reply can be edited</li> * <li>can_delete: boolean value reflecting if this reply can be deleted</li> * <li>can_restore: boolean value reflecting if this reply can be restored</li> * <li>ip_address: IP address used to post the message (not necessarily the user's normal IP address); if the user has moderate_forum_members permission, this returns a link to the track IP area, with the IP address as the link text, alternatively simply the IP address if not (is only displayed to helpdesk staff)</li> * <li>modified: may not be declared, if it is, the message was modified some time after posting, and the following data items are in the hash array within: * <ul> * <li>id: user id who edited the reply (not always available)</li> * <li>time: formatted string of the time the post was edited</li> * <li>timestamp: raw timestamp of the time the post was edited</li> * <li>name: user name of the editing user; if we have a definite user id, this should contain the current name, falling back to the previously stored name</li> * <li>link: if we have a known, valid user id for the post's editor, this will contain a link to their profile, with the link text using their current display name; alternatively it will contain a regular string which is the username stored with the edit.</li> * </ul> * </li> * </ul> * * @see shd_view_ticket() * @since 1.0 */ function shd_prepare_ticket_context() { global $settings, $txt, $modSettings, $scripturl, $options, $user_info, $smcFunc; global $memberContext, $context, $reply_request, $user_profile; if (empty($reply_request)) { return false; } $message = $smcFunc['db_fetch_assoc']($reply_request); if (!$message) { $smcFunc['db_free_result']($reply_request); return false; } if (!loadMemberContext($message['id_member'], true)) { // Notice this information isn't used anywhere else.... $memberContext[$message['id_member']]['name'] = $message['poster_name']; $memberContext[$message['id_member']]['id'] = 0; $memberContext[$message['id_member']]['group'] = $txt['guest_title']; $memberContext[$message['id_member']]['link'] = $message['poster_name']; $memberContext[$message['id_member']]['email'] = $message['poster_email']; $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0); $memberContext[$message['id_member']]['is_guest'] = true; $memberContext[$message['id_member']]['group_stars'] = ''; } $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; censorText($message['body']); $message['body'] = shd_format_text($message['body'], $message['smileys_enabled'], 'shd_reply_' . $message['id_msg']); $output = array('id' => $message['id_msg'], 'member' => &$memberContext[$message['id_member']], 'time' => timeformat($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'body' => $message['body'], 'is_staff' => !empty($context['shd_is_staff'][$message['id_member']]), 'can_edit' => $message['message_status'] != MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_edit_reply_any', $context['ticket']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_edit_reply_own', $context['ticket']['dept'])), 'can_delete' => $message['message_status'] != MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_delete_reply_any', $context['ticket']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_delete_reply_own', $context['ticket']['dept'])), 'can_restore' => $message['message_status'] == MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_restore_reply_any', $context['ticket']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_restore_reply_own', $context['ticket']['dept'])), 'can_permadelete' => $message['message_status'] == MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && shd_allowed_to('shd_delete_recycling', $context['ticket']['dept']), 'message_status' => $message['message_status'], 'link' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . '.msg' . $message['id_msg'] . '#msg' . $message['id_msg']); if (shd_allowed_to('shd_view_ip_any', $context['ticket']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_view_ip_own', $context['ticket']['dept'])) { $output['ip_address'] = $context['link_ip_address'] ? '<a href="' . $scripturl . '?action=trackip;searchip=' . $message['poster_ip'] . '">' . $message['poster_ip'] . '</a>' : $message['poster_ip']; } if (!empty($message['modified_time'])) { $output['modified'] = array('time' => timeformat($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'id' => !empty($user_profile[$message['modified_member']]) ? $message['modified_member'] : 0, 'name' => !empty($user_profile[$message['modified_member']]) ? $user_profile[$message['modified_member']]['real_name'] : $message['modified_name']); $output['modified']['link'] = shd_profile_link($output['modified']['name'], $output['modified']['id']); } if (!empty($context['ticket_start_newfrom']) && $context['ticket_start_newfrom'] == $message['id_msg']) { $output['is_new'] = true; } return $output; }
/** * Allow a user to send an email. * * - Send an email to the user - allow the sender to write the message. * - Can either be passed a user ID as uid or a message id as msg. * - Does not check permissions for a message ID as there is no information disclosed. * - accessed by ?action=emailuser;sa=email */ public function action_email() { global $context, $user_info, $txt, $scripturl; // Can the user even see this information? if ($user_info['is_guest']) { fatal_lang_error('no_access', false); } isAllowedTo('send_email_to_members'); // Are we sending to a user? $context['form_hidden_vars'] = array(); if (isset($_REQUEST['uid'])) { require_once SUBSDIR . '/Members.subs.php'; // Get the latest activated member's display name. $row = getBasicMemberData((int) $_REQUEST['uid']); $context['form_hidden_vars']['uid'] = (int) $_REQUEST['uid']; } elseif (isset($_REQUEST['msg'])) { require_once SUBSDIR . '/Messages.subs.php'; $row = mailFromMessage((int) $_REQUEST['msg']); $context['form_hidden_vars']['msg'] = (int) $_REQUEST['msg']; } // Are you sure you got the address or any data? if (empty($row['email_address']) || empty($row)) { fatal_lang_error('cant_find_user_email'); } // Can they actually do this? $context['show_email_address'] = showEmailAddress(!empty($row['hide_email']), $row['id_member']); if ($context['show_email_address'] === 'no') { fatal_lang_error('no_access', false); } // Does the user want to be contacted at all by you? require_once SUBSDIR . '/Members.subs.php'; if (!canContact($row['id_member'])) { fatal_lang_error('no_access', false); } // Setup the context! $context['recipient'] = array('id' => $row['id_member'], 'name' => $row['real_name'], 'email' => $row['email_address'], 'email_link' => ($context['show_email_address'] == 'yes_permission_override' ? '<em>' : '') . '<a href="mailto:' . $row['email_address'] . '">' . $row['email_address'] . '</a>' . ($context['show_email_address'] == 'yes_permission_override' ? '</em>' : ''), 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>' : $row['real_name']); // Can we see this person's email address? $context['can_view_recipient_email'] = $context['show_email_address'] == 'yes' || $context['show_email_address'] == 'yes_permission_override'; // Template $context['sub_template'] = 'custom_email'; $context['page_title'] = $txt['send_email']; // Are we actually sending it? if (isset($_POST['send']) && isset($_POST['email_body'])) { checkSession(); // Don't let them send too many! spamProtection('sendmail'); require_once SUBSDIR . '/Mail.subs.php'; require_once SUBSDIR . '/DataValidator.class.php'; // We will need to do some data checking $validator = new Data_Validator(); $validator->sanitation_rules(array('y_name' => 'trim', 'email_body' => 'trim', 'email_subject' => 'trim')); $validator->validation_rules(array('y_name' => 'required|notequal[_]', 'y_email' => 'required|valid_email', 'email_body' => 'required', 'email_subject' => 'required')); $validator->text_replacements(array('y_name' => $txt['sendtopic_sender_name'], 'y_email' => $txt['sendtopic_sender_email'], 'email_body' => $txt['message'], 'email_subject' => $txt['send_email_subject'])); $validator->validate($_POST); // If it's a guest sort out their names. if ($user_info['is_guest']) { $errors = $validator->validation_errors(array('y_name', 'y_email')); if ($errors) { $context['sendemail_error'] = array('errors' => $errors, 'type' => 'minor', 'title' => $txt['validation_failure']); return; } $from_name = $validator->y_name; $from_email = $validator->y_email; } else { $from_name = $user_info['name']; $from_email = $user_info['email']; } // Check we have a body (etc). $errors = $validator->validation_errors(array('email_body', 'email_subject')); if (!empty($errors)) { $context['sendemail_error'] = array('errors' => $errors, 'type' => 'minor', 'title' => $txt['validation_failure']); return; } // We use a template in case they want to customise! $replacements = array('EMAILSUBJECT' => $validator->email_subject, 'EMAILBODY' => $validator->email_body, 'SENDERNAME' => $from_name, 'RECPNAME' => $context['recipient']['name']); // Get the template and get out! $emaildata = loadEmailTemplate('send_email', $replacements); sendmail($context['recipient']['email'], $emaildata['subject'], $emaildata['body'], $from_email, null, false, 1, null, true); // Now work out where to go! if (isset($_REQUEST['uid'])) { redirectexit('action=profile;u=' . (int) $_REQUEST['uid']); } elseif (isset($_REQUEST['msg'])) { redirectexit('msg=' . (int) $_REQUEST['msg']); } else { redirectexit(); } } }
/** * Loads the user's basic values... meant for template/theme usage. * * What it does: * - Always loads the minimal values of username, name, id, href, link, email, show_email, registered, registered_timestamp * - if $context['loadMemberContext_set'] is not minimal it will load in full a full set of user information * - prepares signature, personal_text, location fields for display (censoring if enabled) * - loads in the members custom fields if any * - prepares the users buddy list, including reverse buddy flags * * @param int $user * @param bool $display_custom_fields = false * @return boolean */ function loadMemberContext($user, $display_custom_fields = false) { global $memberContext, $user_profile, $txt, $scripturl, $user_info; global $context, $modSettings, $settings; static $dataLoaded = array(); // If this person's data is already loaded, skip it. if (isset($dataLoaded[$user])) { return true; } // We can't load guests or members not loaded by loadMemberData()! if ($user == 0) { return false; } if (!isset($user_profile[$user])) { trigger_error('loadMemberContext(): member id ' . $user . ' not previously loaded by loadMemberData()', E_USER_WARNING); return false; } // Well, it's loaded now anyhow. $dataLoaded[$user] = true; $profile = $user_profile[$user]; // Censor everything. censorText($profile['signature']); censorText($profile['personal_text']); censorText($profile['location']); // Set things up to be used before hand. $gendertxt = $profile['gender'] == 2 ? $txt['female'] : ($profile['gender'] == 1 ? $txt['male'] : ''); $profile['signature'] = str_replace(array("\n", "\r"), array('<br />', ''), $profile['signature']); $profile['signature'] = parse_bbc($profile['signature'], true, 'sig' . $profile['id_member']); $profile['is_online'] = (!empty($profile['show_online']) || allowedTo('moderate_forum')) && $profile['is_online'] > 0; $profile['icons'] = empty($profile['icons']) ? array('', '') : explode('#', $profile['icons']); // Setup the buddy status here (One whole in_array call saved :P) $profile['buddy'] = in_array($profile['id_member'], $user_info['buddies']); $buddy_list = !empty($profile['buddy_list']) ? explode(',', $profile['buddy_list']) : array(); // These minimal values are always loaded $memberContext[$user] = array('username' => $profile['member_name'], 'name' => $profile['real_name'], 'id' => $profile['id_member'], 'href' => $scripturl . '?action=profile;u=' . $profile['id_member'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $profile['id_member'] . '" title="' . $txt['profile_of'] . ' ' . trim($profile['real_name']) . '">' . $profile['real_name'] . '</a>', 'email' => $profile['email_address'], 'show_email' => showEmailAddress(!empty($profile['hide_email']), $profile['id_member']), 'registered' => empty($profile['date_registered']) ? $txt['not_applicable'] : standardTime($profile['date_registered']), 'registered_timestamp' => empty($profile['date_registered']) ? 0 : forum_time(true, $profile['date_registered'])); // If the set isn't minimal then load the monstrous array. if ($context['loadMemberContext_set'] !== 'minimal') { $memberContext[$user] += array('username_color' => '<span ' . (!empty($profile['member_group_color']) ? 'style="color:' . $profile['member_group_color'] . ';"' : '') . '>' . $profile['member_name'] . '</span>', 'name_color' => '<span ' . (!empty($profile['member_group_color']) ? 'style="color:' . $profile['member_group_color'] . ';"' : '') . '>' . $profile['real_name'] . '</span>', 'link_color' => '<a href="' . $scripturl . '?action=profile;u=' . $profile['id_member'] . '" title="' . $txt['profile_of'] . ' ' . $profile['real_name'] . '" ' . (!empty($profile['member_group_color']) ? 'style="color:' . $profile['member_group_color'] . ';"' : '') . '>' . $profile['real_name'] . '</a>', 'is_buddy' => $profile['buddy'], 'is_reverse_buddy' => in_array($user_info['id'], $buddy_list), 'buddies' => $buddy_list, 'title' => !empty($modSettings['titlesEnable']) ? $profile['usertitle'] : '', 'blurb' => $profile['personal_text'], 'gender' => array('name' => $gendertxt, 'image' => !empty($profile['gender']) ? '<img class="gender" src="' . $settings['images_url'] . '/profile/' . ($profile['gender'] == 1 ? 'Male' : 'Female') . '.png" alt="' . $gendertxt . '" />' : ''), 'website' => array('title' => $profile['website_title'], 'url' => $profile['website_url']), 'birth_date' => empty($profile['birthdate']) || $profile['birthdate'] === '0001-01-01' ? '0000-00-00' : (substr($profile['birthdate'], 0, 4) === '0004' ? '0000' . substr($profile['birthdate'], 4) : $profile['birthdate']), 'signature' => $profile['signature'], 'location' => $profile['location'], 'real_posts' => $profile['posts'], 'posts' => comma_format($profile['posts']), 'avatar' => determineAvatar($profile), 'last_login' => empty($profile['last_login']) ? $txt['never'] : standardTime($profile['last_login']), 'last_login_timestamp' => empty($profile['last_login']) ? 0 : forum_time(false, $profile['last_login']), 'karma' => array('good' => $profile['karma_good'], 'bad' => $profile['karma_bad'], 'allow' => !$user_info['is_guest'] && !empty($modSettings['karmaMode']) && $user_info['id'] != $user && allowedTo('karma_edit') && ($user_info['posts'] >= $modSettings['karmaMinPosts'] || $user_info['is_admin'])), 'likes' => array('given' => $profile['likes_given'], 'received' => $profile['likes_received']), 'ip' => htmlspecialchars($profile['member_ip'], ENT_COMPAT, 'UTF-8'), 'ip2' => htmlspecialchars($profile['member_ip2'], ENT_COMPAT, 'UTF-8'), 'online' => array('is_online' => $profile['is_online'], 'text' => Util::htmlspecialchars($txt[$profile['is_online'] ? 'online' : 'offline']), 'member_online_text' => sprintf($txt[$profile['is_online'] ? 'member_is_online' : 'member_is_offline'], Util::htmlspecialchars($profile['real_name'])), 'href' => $scripturl . '?action=pm;sa=send;u=' . $profile['id_member'], 'link' => '<a href="' . $scripturl . '?action=pm;sa=send;u=' . $profile['id_member'] . '">' . $txt[$profile['is_online'] ? 'online' : 'offline'] . '</a>', 'image_href' => $settings['images_url'] . '/profile/' . ($profile['buddy'] ? 'buddy_' : '') . ($profile['is_online'] ? 'useron' : 'useroff') . '.png', 'label' => $txt[$profile['is_online'] ? 'online' : 'offline']), 'language' => Util::ucwords(strtr($profile['lngfile'], array('_' => ' '))), 'is_activated' => isset($profile['is_activated']) ? $profile['is_activated'] : 1, 'is_banned' => isset($profile['is_activated']) ? $profile['is_activated'] >= 10 : 0, 'options' => $profile['options'], 'is_guest' => false, 'group' => $profile['member_group'], 'group_color' => $profile['member_group_color'], 'group_id' => $profile['id_group'], 'post_group' => $profile['post_group'], 'post_group_color' => $profile['post_group_color'], 'group_icons' => str_repeat('<img src="' . str_replace('$language', $context['user']['language'], isset($profile['icons'][1]) ? $settings['images_url'] . '/group_icons/' . $profile['icons'][1] : '') . '" alt="[*]" />', empty($profile['icons'][0]) || empty($profile['icons'][1]) ? 0 : $profile['icons'][0]), 'warning' => $profile['warning'], 'warning_status' => !empty($modSettings['warning_mute']) && $modSettings['warning_mute'] <= $profile['warning'] ? 'mute' : (!empty($modSettings['warning_moderate']) && $modSettings['warning_moderate'] <= $profile['warning'] ? 'moderate' : (!empty($modSettings['warning_watch']) && $modSettings['warning_watch'] <= $profile['warning'] ? 'watch' : '')), 'local_time' => standardTime(time() + ($profile['time_offset'] - $user_info['time_offset']) * 3600, false), 'custom_fields' => array()); } // Are we also loading the members custom fields into context? if ($display_custom_fields && !empty($modSettings['displayFields'])) { if (!isset($context['display_fields'])) { $context['display_fields'] = unserialize($modSettings['displayFields']); } foreach ($context['display_fields'] as $custom) { if (!isset($custom['title']) || trim($custom['title']) == '' || empty($profile['options'][$custom['colname']])) { continue; } $value = $profile['options'][$custom['colname']]; // BBC? if ($custom['bbc']) { $value = parse_bbc($value); } elseif (isset($custom['type']) && $custom['type'] == 'check') { $value = $value ? $txt['yes'] : $txt['no']; } // Enclosing the user input within some other text? if (!empty($custom['enclose'])) { $value = strtr($custom['enclose'], array('{SCRIPTURL}' => $scripturl, '{IMAGES_URL}' => $settings['images_url'], '{DEFAULT_IMAGES_URL}' => $settings['default_images_url'], '{INPUT}' => $value)); } $memberContext[$user]['custom_fields'][] = array('title' => $custom['title'], 'colname' => $custom['colname'], 'value' => $value, 'placement' => !empty($custom['placement']) ? $custom['placement'] : 0); } } call_integration_hook('integrate_member_context', array($user, $display_custom_fields)); return true; }
function get_pm_list($type = 'subject', $reset = false) { global $txt, $user_profile, $scripturl, $modSettings, $context, $messages_request, $memberContext, $recipients, $smcFunc; global $user_info, $subjects_request; // Count the current message number.... static $counter = null; if ($counter === null || $reset) { $counter = $context['start']; } static $temp_pm_selected = null; if ($temp_pm_selected === null) { $temp_pm_selected = isset($_SESSION['pm_selected']) ? $_SESSION['pm_selected'] : array(); $_SESSION['pm_selected'] = array(); } // Bail if it's false, ie. no messages. if ($messages_request == false) { return false; } // Reset the data? if ($reset == true) { return @$smcFunc['db_data_seek']($messages_request, 0); } // Get the next one... bail if anything goes wrong. $message = $smcFunc['db_fetch_assoc']($messages_request); if (!$message) { if ($type != 'subject') { $smcFunc['db_free_result']($messages_request); } return false; } // Use '(no subject)' if none was specified. $message['subject'] = $message['subject'] == '' ? $txt['no_subject'] : $message['subject']; // add for tapatalk if ($context['folder'] == 'sent') { $id_member = preg_replace('/^.*?u=(\\d+).*?$/s', '$1', $recipients[$message['id_pm']]['to'][0]); if (!isset($user_profile[$id_member])) { loadMemberData($id_member); } } else { $id_member = $message['id_member_from']; } // Load the message's information - if it's not there, load the guest information. if (!loadMemberContext($id_member, true)) { $memberContext[$id_member]['name'] = $message['from_name']; $memberContext[$id_member]['id'] = 0; // Sometimes the forum sends messages itself (Warnings are an example) - in this case don't label it from a guest. $memberContext[$id_member]['group'] = $message['from_name'] == $context['forum_name'] ? '' : $txt['guest_title']; $memberContext[$id_member]['link'] = $message['from_name']; $memberContext[$id_member]['email'] = ''; $memberContext[$id_member]['show_email'] = showEmailAddress(true, 0); $memberContext[$id_member]['is_guest'] = true; } else { $memberContext[$id_member]['can_view_profile'] = allowedTo('profile_view_any') || $id_member == $user_info['id'] && allowedTo('profile_view_own'); $memberContext[$id_member]['can_see_warning'] = !isset($context['disabled_fields']['warning_status']) && $memberContext[$id_member]['warning_status'] && ($context['user']['can_mod'] || !empty($modSettings['warning_show']) || $memberContext[$id_member]['id'] == $context['user']['id'] && !empty($modSettings['warning_show']) && $modSettings['warning_show'] == 1); } // Censor all the important text... censorText($message['body']); censorText($message['subject']); // Run UBBC interpreter on the message. $message['body'] = mobiquo_parse_bbc($message['body'], false, 'pm' . $message['id_pm']); // Send the array. $output = array('alternate' => $counter % 2, 'id' => $message['id_pm'], 'member' => &$memberContext[$id_member], 'subject' => $message['subject'], 'time' => timeformat($message['msgtime']), 'timestamp' => $message['msgtime'], 'counter' => $counter, 'body' => $message['body'], 'recipients' => &$recipients[$message['id_pm']], 'number_recipients' => count($recipients[$message['id_pm']]['to']), 'labels' => &$context['message_labels'][$message['id_pm']], 'fully_labeled' => count($context['message_labels'][$message['id_pm']]) == count($context['labels']), 'is_replied_to' => &$context['message_replied'][$message['id_pm']], 'is_unread' => &$context['message_unread'][$message['id_pm']], 'is_selected' => !empty($temp_pm_selected) && in_array($message['id_pm'], $temp_pm_selected), 'msg_from' => $context['folder'] == 'sent' ? $context['user']['name'] : $memberContext[$id_member]['name'], 'msg_from_id' => $id_member); $counter++; return $output; }
function prepareDisplayContext($reset = false) { global $txt, $modSettings, $options, $user_info, $output; global $memberContext, $context, $messages_request; static $counter = null; static $seqnr = 0; // If the query returned false, bail. if ($messages_request == false) { return false; } // Remember which message this is. (ie. reply #83) if ($counter === null || $reset) { $counter = empty($options['view_newest_first']) ? $context['start'] : $context['total_visible_posts'] - $context['start']; } // Start from the beginning... if ($reset) { return @mysql_data_seek($messages_request, 0); } // Attempt to get the next message. $message = mysql_fetch_assoc($messages_request); if (!$message) { mysql_free_result($messages_request); return false; } // If you're a lazy bum, you probably didn't give a subject... $message['subject'] = $message['subject'] != '' ? $message['subject'] : $txt['no_subject']; // Are you allowed to remove at least a single reply? $context['can_remove_post'] |= $context['can_delete_own'] && (empty($modSettings['edit_disable_time']) || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()) && $message['id_member'] == $user_info['id']; // If it couldn't load, or the user was a guest.... someday may be done with a guest table. if (!loadMemberContext($message['id_member'], true)) { // Notice this information isn't used anywhere else.... $memberContext[$message['id_member']]['name'] = $message['poster_name']; $memberContext[$message['id_member']]['id'] = 0; $memberContext[$message['id_member']]['group'] = $txt['guest_title']; $memberContext[$message['id_member']]['link'] = $message['poster_name']; $memberContext[$message['id_member']]['email'] = $message['poster_email']; $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0); $memberContext[$message['id_member']]['is_guest'] = true; $memberContext[$message['id_member']]['is_banned_from_topic'] = $memberContext[$message['id_member']]['can_see_warning'] = false; } else { $memberContext[$message['id_member']]['can_view_profile'] = $context['can_profile_view_any'] || $message['id_member'] == $user_info['id'] && $context['can_profile_view_own']; $memberContext[$message['id_member']]['is_topic_starter'] = $message['id_member'] == $context['topic_starter_id']; $memberContext[$message['id_member']]['can_see_warning'] = !isset($context['disabled_fields']['warning_status']) && $memberContext[$message['id_member']]['warning_status'] && ($context['user']['can_mod'] || !$user_info['is_guest'] && !empty($modSettings['warning_show']) && ($modSettings['warning_show'] > 1 || $message['id_member'] == $user_info['id'])); $memberContext[$message['id_member']]['is_banned_from_topic'] = !empty($context['topic_banned_members']) ? in_array($message['id_member'], $context['topic_banned_members']) : false; } $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; // Do the censor thang. censorText($message['subject']); // create a cached (= parsed) version of the post on the fly // but only if it's not older than the cutoff time. // and do not cache more than PCACHE_UPDATE_PER_VIEW posts per thread view to reduce load spikes $dateline = max($message['modified_time'], $message['poster_time']); if ($context['pcache_update_counter'] < PCACHE_UPDATE_PER_VIEW && $context['time_cutoff_ref'] - $dateline < $modSettings['post_cache_cutoff'] * 86400) { if (empty($message['cached_body'])) { $context['pcache_update_counter']++; $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], ''); // don't cache bbc when we pre-parse the post anyway... smf_db_insert('replace', '{db_prefix}messages_cache', array('id_msg' => 'int', 'body' => 'string', 'style' => 'string', 'lang' => 'string', 'updated' => 'int'), array($message['id_msg'], $message['body'], $user_info['smiley_set_id'], $user_info['language_id'], $dateline), array('id_msg', 'body', 'style', 'lang', 'updated')); parse_bbc_stage2($message['body'], $message['id_msg']); } else { $message['body'] =& $message['cached_body']; parse_bbc_stage2($message['body'], $message['id_msg']); } } else { $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg'] . '|' . $message['modified_time']); parse_bbc_stage2($message['body'], $message['id_msg']); } censorText($message['body']); // Compose the memory eat- I mean message array. //$t_href = URL::topic($topic, $message['subject'], 0, false, '.msg' . $message['id_msg'] . '#msg'.$message['id_msg']); $output = array('attachment' => loadAttachmentContext($message['id_msg']), 'id' => $message['id_msg'], 'permahref' => URL::parse('?msg=' . $message['id_msg'] . (isset($_REQUEST['perma']) ? '' : ';perma')), 'member' => &$memberContext[$message['id_member']], 'icon' => $message['icon'], 'icon_url' => getPostIcon($message['icon']), 'subject' => $message['subject'], 'time' => timeformat($message['poster_time']), 'timestamp' => $message['poster_time'], 'counter' => $counter, 'permalink' => isset($_REQUEST['perma']) ? $txt['view_in_thread'] : ' #' . ($counter + 1), 'modified' => array('time' => timeformat($message['modified_time']), 'name' => $message['modified_name']), 'body' => &$message['body'], 'new' => empty($message['is_read']), 'approved' => $message['approved'], 'first_new' => isset($context['start_from']) && $context['start_from'] == $counter, 'is_ignored' => !empty($modSettings['enable_buddylist']) && !empty($options['posts_apply_ignore_list']) && in_array($message['id_member'], $context['user']['ignoreusers']), 'can_approve' => !$message['approved'] && $context['can_approve'], 'can_unapprove' => $message['approved'] && $context['can_unapprove'], 'can_modify' => (!$message['locked'] || $context['can_moderate_board']) && ((!$context['is_locked'] || $context['can_moderate_board']) && ($context['can_modify_any'] || $context['can_modify_replies'] && $context['user']['started'] || $context['can_modify_own'] && $message['id_member'] == $user_info['id'] && (empty($modSettings['edit_disable_time']) || !$message['approved'] || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 > time()))), 'can_remove' => (!$message['locked'] || $context['can_moderate_board']) && ($context['can_delete_any'] || $context['can_delete_replies'] && $context['user']['started'] || $context['can_delete_own'] && $message['id_member'] == $user_info['id'] && (empty($modSettings['edit_disable_time']) || $message['poster_time'] + $modSettings['edit_disable_time'] * 60 > time())), 'can_see_ip' => $context['can_moderate_forum'] || $message['id_member'] == $user_info['id'] && !empty($user_info['id']), 'likes_count' => $message['likes_count'], 'like_status' => $message['like_status'], 'liked' => $message['liked'], 'like_updated' => $message['like_updated'], 'id_member' => $message['id_member'], 'postbit_callback' => $message['approved'] ? $message['id_msg'] == $context['first_message'] ? $context['postbit_callbacks']['firstpost'] : $context['postbit_callbacks']['post'] : 'template_postbit_comment', 'postbit_template_class' => $message['approved'] ? $message['id_msg'] == $context['first_message'] ? $context['postbit_template_class']['firstpost'] : $context['postbit_template_class']['post'] : 'c', 'mq_marked' => in_array($message['id_msg'], $context['multiquote_posts']), 'header_class' => $context['can_moderate_member'] && ($memberContext[$message['id_member']]['is_banned_from_topic'] || $memberContext[$message['id_member']]['can_see_warning']) ? ' watched' : ''); if ($context['can_see_like']) { Ratings::addContent($output, $context['can_give_like'], $context['time_cutoff_ref']); } else { $output['likes_count'] = 0; } // Is this user the message author? $output['is_message_author'] = $message['id_member'] == $user_info['id']; $counter += empty($options['view_newest_first']) ? 1 : -1; // hooks can populate these fields with additional content $output['template_hook'] = array('before_sig' => '', 'after_sig' => '', 'postbit_below' => '', 'poster_details' => ''); HookAPI::callHook('display_postbit', array(&$output)); if (isset($output['member']['can_see_warning']) && !empty($output['member']['can_see_warning'])) { $output['member']['warning_status_desc'] = isset($output['member']['warning_status']) ? $txt['user_warn_' . $output['member']['warning_status']] : ''; $output['member']['warning_status_desc1'] = isset($output['member']['warning_status']) ? $txt['warn_' . $output['member']['warning_status']] : ''; } $output['member']['allow_show_email'] = $output['member']['is_guest'] ? !empty($output['member']['email']) && in_array($output['member']['show_email'], array('yes', 'yes_permission_override', 'no_through_forum')) : false; //$context['current_message'] = &$output; if ($output['can_remove']) { $context['removableMessageIDs'][] = $output['id']; } //return $output; }
/** * Actually do the search of personal messages and show the results * * What it does: * - accessed with ?action=pm;sa=search2 * - checks user input and searches the pm table for messages matching the query. * - uses the search_results sub template of the PersonalMessage template. * - show the results of the search query. */ public function action_search2() { global $scripturl, $modSettings, $context, $txt, $memberContext; $db = database(); // Make sure the server is able to do this right now if (!empty($modSettings['loadavg_search']) && $modSettings['current_load'] >= $modSettings['loadavg_search']) { fatal_lang_error('loadavg_search_disabled', false); } // Some useful general permissions. $context['can_send_pm'] = allowedTo('pm_send'); // Some hardcoded variables that can be tweaked if required. $maxMembersToSearch = 500; // Extract all the search parameters. $search_params = array(); if (isset($_REQUEST['params'])) { $temp_params = explode('|"|', base64_decode(strtr($_REQUEST['params'], array(' ' => '+')))); foreach ($temp_params as $i => $data) { @(list($k, $v) = explode('|\'|', $data)); $search_params[$k] = $v; } } $context['start'] = isset($_GET['start']) ? (int) $_GET['start'] : 0; // Store whether simple search was used (needed if the user wants to do another query). if (!isset($search_params['advanced'])) { $search_params['advanced'] = empty($_REQUEST['advanced']) ? 0 : 1; } // 1 => 'allwords' (default, don't set as param) / 2 => 'anywords'. if (!empty($search_params['searchtype']) || !empty($_REQUEST['searchtype']) && $_REQUEST['searchtype'] == 2) { $search_params['searchtype'] = 2; } // Minimum age of messages. Default to zero (don't set param in that case). if (!empty($search_params['minage']) || !empty($_REQUEST['minage']) && $_REQUEST['minage'] > 0) { $search_params['minage'] = !empty($search_params['minage']) ? (int) $search_params['minage'] : (int) $_REQUEST['minage']; } // Maximum age of messages. Default to infinite (9999 days: param not set). if (!empty($search_params['maxage']) || !empty($_REQUEST['maxage']) && $_REQUEST['maxage'] < 9999) { $search_params['maxage'] = !empty($search_params['maxage']) ? (int) $search_params['maxage'] : (int) $_REQUEST['maxage']; } // Search modifiers $search_params['subject_only'] = !empty($search_params['subject_only']) || !empty($_REQUEST['subject_only']); $search_params['show_complete'] = !empty($search_params['show_complete']) || !empty($_REQUEST['show_complete']); $search_params['sent_only'] = !empty($search_params['sent_only']) || !empty($_REQUEST['sent_only']); $context['folder'] = empty($search_params['sent_only']) ? 'inbox' : 'sent'; // Default the user name to a wildcard matching every user (*). if (!empty($search_params['userspec']) || !empty($_REQUEST['userspec']) && $_REQUEST['userspec'] != '*') { $search_params['userspec'] = isset($search_params['userspec']) ? $search_params['userspec'] : $_REQUEST['userspec']; } // This will be full of all kinds of parameters! $searchq_parameters = array(); // If there's no specific user, then don't mention it in the main query. if (empty($search_params['userspec'])) { $userQuery = ''; } else { // Set up so we can seach by user name, wildcards, like, etc $userString = strtr(Util::htmlspecialchars($search_params['userspec'], ENT_QUOTES), array('"' => '"')); $userString = strtr($userString, array('%' => '\\%', '_' => '\\_', '*' => '%', '?' => '_')); preg_match_all('~"([^"]+)"~', $userString, $matches); $possible_users = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $userString))); require_once SUBSDIR . '/Members.subs.php'; // Who matches those criteria? $members = membersBy('member_names', array('member_names' => $possible_users)); foreach ($possible_users as $key => $possible_user) { $searchq_parameters['guest_user_name_implode_' . $key] = defined('DB_CASE_SENSITIVE') ? strtolower($possible_user) : $possible_user; } // Simply do nothing if there are too many members matching the criteria. if (count($members) > $maxMembersToSearch) { $userQuery = ''; } elseif (count($members) == 0) { if ($context['folder'] === 'inbox') { $uq = array(); $name = defined('DB_CASE_SENSITIVE') ? 'LOWER(pm.from_name)' : 'pm.from_name'; foreach (array_keys($possible_users) as $key) { $uq[] = 'AND pm.id_member_from = 0 AND (' . $name . ' LIKE {string:guest_user_name_implode_' . $key . '})'; } $userQuery = implode(' ', $uq); $searchq_parameters['pm_from_name'] = defined('DB_CASE_SENSITIVE') ? 'LOWER(pm.from_name)' : 'pm.from_name'; } else { $userQuery = ''; } } else { $memberlist = array(); foreach ($members as $id) { $memberlist[] = $id; } // Use the name as as sent from or sent to if ($context['folder'] === 'inbox') { $uq = array(); $name = defined('DB_CASE_SENSITIVE') ? 'LOWER(pm.from_name)' : 'pm.from_name'; foreach (array_keys($possible_users) as $key) { $uq[] = 'AND (pm.id_member_from IN ({array_int:member_list}) OR (pm.id_member_from = 0 AND (' . $name . ' LIKE {string:guest_user_name_implode_' . $key . '})))'; } $userQuery = implode(' ', $uq); } else { $userQuery = 'AND (pmr.id_member IN ({array_int:member_list}))'; } $searchq_parameters['pm_from_name'] = defined('DB_CASE_SENSITIVE') ? 'LOWER(pm.from_name)' : 'pm.from_name'; $searchq_parameters['member_list'] = $memberlist; } } // Setup the sorting variables... $sort_columns = array('pm.id_pm'); if (empty($search_params['sort']) && !empty($_REQUEST['sort'])) { list($search_params['sort'], $search_params['sort_dir']) = array_pad(explode('|', $_REQUEST['sort']), 2, ''); } $search_params['sort'] = !empty($search_params['sort']) && in_array($search_params['sort'], $sort_columns) ? $search_params['sort'] : 'pm.id_pm'; $search_params['sort_dir'] = !empty($search_params['sort_dir']) && $search_params['sort_dir'] == 'asc' ? 'asc' : 'desc'; // Sort out any labels we may be searching by. $labelQuery = ''; if ($context['folder'] == 'inbox' && !empty($search_params['advanced']) && $context['currently_using_labels']) { // Came here from pagination? Put them back into $_REQUEST for sanitization. if (isset($search_params['labels'])) { $_REQUEST['searchlabel'] = explode(',', $search_params['labels']); } // Assuming we have some labels - make them all integers. if (!empty($_REQUEST['searchlabel']) && is_array($_REQUEST['searchlabel'])) { $_REQUEST['searchlabel'] = array_map('intval', $_REQUEST['searchlabel']); } else { $_REQUEST['searchlabel'] = array(); } // Now that everything is cleaned up a bit, make the labels a param. $search_params['labels'] = implode(',', $_REQUEST['searchlabel']); // No labels selected? That must be an error! if (empty($_REQUEST['searchlabel'])) { $context['search_errors']['no_labels_selected'] = true; } elseif (count($_REQUEST['searchlabel']) != count($context['labels'])) { $labelQuery = ' AND {raw:label_implode}'; $labelStatements = array(); foreach ($_REQUEST['searchlabel'] as $label) { $labelStatements[] = $db->quote('FIND_IN_SET({string:label}, pmr.labels) != 0', array('label' => $label)); } $searchq_parameters['label_implode'] = '(' . implode(' OR ', $labelStatements) . ')'; } } // Unfortunately, searching for words like this is going to be slow, so we're blacklisting them. $blacklisted_words = array('quote', 'the', 'is', 'it', 'are', 'if'); // What are we actually searching for? $search_params['search'] = !empty($search_params['search']) ? $search_params['search'] : (isset($_REQUEST['search']) ? $_REQUEST['search'] : ''); // If nothing is left to search on - we set an error! if (!isset($search_params['search']) || $search_params['search'] == '') { $context['search_errors']['invalid_search_string'] = true; } // Change non-word characters into spaces. $stripped_query = preg_replace('~(?:[\\x0B\\0\\x{A0}\\t\\r\\s\\n(){}\\[\\]<>!@$%^*.,:+=`\\~\\?/\\\\]+|&(?:amp|lt|gt|quot);)+~u', ' ', $search_params['search']); // Make the query lower case since it will case insensitive anyway. $stripped_query = un_htmlspecialchars(Util::strtolower($stripped_query)); // Extract phrase parts first (e.g. some words "this is a phrase" some more words.) preg_match_all('/(?:^|\\s)([-]?)"([^"]+)"(?:$|\\s)/', $stripped_query, $matches, PREG_PATTERN_ORDER); $phraseArray = $matches[2]; // Remove the phrase parts and extract the words. $wordArray = preg_replace('~(?:^|\\s)(?:[-]?)"(?:[^"]+)"(?:$|\\s)~u', ' ', $search_params['search']); $wordArray = explode(' ', Util::htmlspecialchars(un_htmlspecialchars($wordArray), ENT_QUOTES)); // A minus sign in front of a word excludes the word.... so... $excludedWords = array(); // Check for things like -"some words", but not "-some words". foreach ($matches[1] as $index => $word) { if ($word === '-') { if (($word = trim($phraseArray[$index], '-_\' ')) !== '' && !in_array($word, $blacklisted_words)) { $excludedWords[] = $word; } unset($phraseArray[$index]); } } // Now we look for -test, etc foreach ($wordArray as $index => $word) { if (strpos(trim($word), '-') === 0) { if (($word = trim($word, '-_\' ')) !== '' && !in_array($word, $blacklisted_words)) { $excludedWords[] = $word; } unset($wordArray[$index]); } } // The remaining words and phrases are all included. $searchArray = array_merge($phraseArray, $wordArray); // Trim everything and make sure there are no words that are the same. foreach ($searchArray as $index => $value) { // Skip anything thats close to empty. if (($searchArray[$index] = trim($value, '-_\' ')) === '') { unset($searchArray[$index]); } elseif (in_array($searchArray[$index], $blacklisted_words)) { $foundBlackListedWords = true; unset($searchArray[$index]); } $searchArray[$index] = Util::strtolower(trim($value)); if ($searchArray[$index] == '') { unset($searchArray[$index]); } else { // Sort out entities first. $searchArray[$index] = Util::htmlspecialchars($searchArray[$index]); } } $searchArray = array_slice(array_unique($searchArray), 0, 10); // Create an array of replacements for highlighting. $context['mark'] = array(); foreach ($searchArray as $word) { $context['mark'][$word] = '<strong class="highlight">' . $word . '</strong>'; } // This contains *everything* $searchWords = array_merge($searchArray, $excludedWords); // Make sure at least one word is being searched for. if (empty($searchArray)) { $context['search_errors']['invalid_search_string' . (!empty($foundBlackListedWords) ? '_blacklist' : '')] = true; } // Sort out the search query so the user can edit it - if they want. $context['search_params'] = $search_params; if (isset($context['search_params']['search'])) { $context['search_params']['search'] = Util::htmlspecialchars($context['search_params']['search']); } if (isset($context['search_params']['userspec'])) { $context['search_params']['userspec'] = Util::htmlspecialchars($context['search_params']['userspec']); } // Now we have all the parameters, combine them together for pagination and the like... $context['params'] = array(); foreach ($search_params as $k => $v) { $context['params'][] = $k . '|\'|' . $v; } $context['params'] = base64_encode(implode('|"|', $context['params'])); // Compile the subject query part. $andQueryParts = array(); foreach ($searchWords as $index => $word) { if ($word == '') { continue; } if ($search_params['subject_only']) { $andQueryParts[] = 'pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . ' LIKE {string:search_' . $index . '}'; } else { $andQueryParts[] = '(pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . ' LIKE {string:search_' . $index . '} ' . (in_array($word, $excludedWords) ? 'AND pm.body NOT' : 'OR pm.body') . ' LIKE {string:search_' . $index . '})'; } $searchq_parameters['search_' . $index] = '%' . strtr($word, array('_' => '\\_', '%' => '\\%')) . '%'; } $searchQuery = ' 1=1'; if (!empty($andQueryParts)) { $searchQuery = implode(!empty($search_params['searchtype']) && $search_params['searchtype'] == 2 ? ' OR ' : ' AND ', $andQueryParts); } // Age limits? $timeQuery = ''; if (!empty($search_params['minage'])) { $timeQuery .= ' AND pm.msgtime < ' . (time() - $search_params['minage'] * 86400); } if (!empty($search_params['maxage'])) { $timeQuery .= ' AND pm.msgtime > ' . (time() - $search_params['maxage'] * 86400); } // If we have errors - return back to the first screen... if (!empty($context['search_errors'])) { $_REQUEST['params'] = $context['params']; return $this->action_search(); } // Get the number of results. $numResults = numPMSeachResults($userQuery, $labelQuery, $timeQuery, $searchQuery, $searchq_parameters); // Get all the matching message ids, senders and head pm nodes list($foundMessages, $posters, $head_pms) = loadPMSearchMessages($userQuery, $labelQuery, $timeQuery, $searchQuery, $searchq_parameters, $search_params); // Find the real head pm when in converstaion view if ($context['display_mode'] == 2 && !empty($head_pms)) { $real_pm_ids = loadPMSearchHeads($head_pms); } // Load the found user data $posters = array_unique($posters); if (!empty($posters)) { loadMemberData($posters); } // Sort out the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=pm;sa=search2;params=' . $context['params'], $_GET['start'], $numResults, $modSettings['search_results_per_page'], false); $context['message_labels'] = array(); $context['message_replied'] = array(); $context['personal_messages'] = array(); $context['first_label'] = array(); // If we have results, we have work to do! if (!empty($foundMessages)) { $recipients = array(); list($context['message_labels'], $context['message_replied'], $context['message_unread'], $context['first_label']) = loadPMRecipientInfo($foundMessages, $recipients, $context['folder'], true); // Prepare for the callback! $search_results = loadPMSearchResults($foundMessages, $search_params); $counter = 0; foreach ($search_results as $row) { // If there's no subject, use the default. $row['subject'] = $row['subject'] == '' ? $txt['no_subject'] : $row['subject']; // Load this posters context info, if its not there then fill in the essentials... if (!loadMemberContext($row['id_member_from'], true)) { $memberContext[$row['id_member_from']]['name'] = $row['from_name']; $memberContext[$row['id_member_from']]['id'] = 0; $memberContext[$row['id_member_from']]['group'] = $txt['guest_title']; $memberContext[$row['id_member_from']]['link'] = $row['from_name']; $memberContext[$row['id_member_from']]['email'] = ''; $memberContext[$row['id_member_from']]['show_email'] = showEmailAddress(true, 0); $memberContext[$row['id_member_from']]['is_guest'] = true; } // Censor anything we don't want to see... censorText($row['body']); censorText($row['subject']); // Parse out any BBC... $row['body'] = parse_bbc($row['body'], true, 'pm' . $row['id_pm']); // Highlight the hits $body_highlighted = ''; $subject_highlighted = ''; foreach ($searchArray as $query) { // Fix the international characters in the keyword too. $query = un_htmlspecialchars($query); $query = trim($query, '\\*+'); $query = strtr(Util::htmlspecialchars($query), array('\\\'' => '\'')); $body_highlighted = preg_replace_callback('/((<[^>]*)|' . preg_quote(strtr($query, array('\'' => ''')), '/') . ')/iu', array($this, '_highlighted_callback'), $row['body']); $subject_highlighted = preg_replace('/(' . preg_quote($query, '/') . ')/iu', '<strong class="highlight">$1</strong>', $row['subject']); } // Set a link using the first label information $href = $scripturl . '?action=pm;f=' . $context['folder'] . (isset($context['first_label'][$row['id_pm']]) ? ';l=' . $context['first_label'][$row['id_pm']] : '') . ';pmid=' . ($context['display_mode'] == 2 && isset($real_pm_ids[$head_pms[$row['id_pm']]]) && $context['folder'] == 'inbox' ? $real_pm_ids[$head_pms[$row['id_pm']]] : $row['id_pm']) . '#msg_' . $row['id_pm']; $context['personal_messages'][] = array('id' => $row['id_pm'], 'member' => &$memberContext[$row['id_member_from']], 'subject' => $subject_highlighted, 'body' => $body_highlighted, 'time' => standardTime($row['msgtime']), 'html_time' => htmlTime($row['msgtime']), 'timestamp' => forum_time(true, $row['msgtime']), 'recipients' => &$recipients[$row['id_pm']], 'labels' => &$context['message_labels'][$row['id_pm']], 'fully_labeled' => count($context['message_labels'][$row['id_pm']]) == count($context['labels']), 'is_replied_to' => &$context['message_replied'][$row['id_pm']], 'href' => $href, 'link' => '<a href="' . $href . '">' . $subject_highlighted . '</a>', 'counter' => ++$counter); } } // Finish off the context. $context['page_title'] = $txt['pm_search_title']; $context['sub_template'] = 'search_results'; $context['menu_data_' . $context['pm_menu_id']]['current_area'] = 'search'; $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=search', 'name' => $txt['pm_search_bar_title']); }
/** * Actually do the search of personal messages. */ function MessageSearch2() { global $scripturl, $modSettings, $user_info, $context, $txt; global $memberContext, $smcFunc; if (!empty($context['load_average']) && !empty($modSettings['loadavg_search']) && $context['load_average'] >= $modSettings['loadavg_search']) { fatal_lang_error('loadavg_search_disabled', false); } /** * @todo For the moment force the folder to the inbox. * @todo Maybe set the inbox based on a cookie or theme setting? */ $context['folder'] = 'inbox'; // Some useful general permissions. $context['can_send_pm'] = allowedTo('pm_send'); // Some hardcoded veriables that can be tweaked if required. $maxMembersToSearch = 500; // Extract all the search parameters. $search_params = array(); if (isset($_REQUEST['params'])) { $temp_params = explode('|"|', base64_decode(strtr($_REQUEST['params'], array(' ' => '+')))); foreach ($temp_params as $i => $data) { @(list($k, $v) = explode('|\'|', $data)); $search_params[$k] = $v; } } $context['start'] = isset($_GET['start']) ? (int) $_GET['start'] : 0; // Store whether simple search was used (needed if the user wants to do another query). if (!isset($search_params['advanced'])) { $search_params['advanced'] = empty($_REQUEST['advanced']) ? 0 : 1; } // 1 => 'allwords' (default, don't set as param) / 2 => 'anywords'. if (!empty($search_params['searchtype']) || !empty($_REQUEST['searchtype']) && $_REQUEST['searchtype'] == 2) { $search_params['searchtype'] = 2; } // Minimum age of messages. Default to zero (don't set param in that case). if (!empty($search_params['minage']) || !empty($_REQUEST['minage']) && $_REQUEST['minage'] > 0) { $search_params['minage'] = !empty($search_params['minage']) ? (int) $search_params['minage'] : (int) $_REQUEST['minage']; } // Maximum age of messages. Default to infinite (9999 days: param not set). if (!empty($search_params['maxage']) || !empty($_REQUEST['maxage']) && $_REQUEST['maxage'] != 9999) { $search_params['maxage'] = !empty($search_params['maxage']) ? (int) $search_params['maxage'] : (int) $_REQUEST['maxage']; } $search_params['subject_only'] = !empty($search_params['subject_only']) || !empty($_REQUEST['subject_only']); $search_params['show_complete'] = !empty($search_params['show_complete']) || !empty($_REQUEST['show_complete']); // Default the user name to a wildcard matching every user (*). if (!empty($search_params['user_spec']) || !empty($_REQUEST['userspec']) && $_REQUEST['userspec'] != '*') { $search_params['userspec'] = isset($search_params['userspec']) ? $search_params['userspec'] : $_REQUEST['userspec']; } // This will be full of all kinds of parameters! $searchq_parameters = array(); // If there's no specific user, then don't mention it in the main query. if (empty($search_params['userspec'])) { $userQuery = ''; } else { $userString = strtr($smcFunc['htmlspecialchars']($search_params['userspec'], ENT_QUOTES), array('"' => '"')); $userString = strtr($userString, array('%' => '\\%', '_' => '\\_', '*' => '%', '?' => '_')); preg_match_all('~"([^"]+)"~', $userString, $matches); $possible_users = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $userString))); for ($k = 0, $n = count($possible_users); $k < $n; $k++) { $possible_users[$k] = trim($possible_users[$k]); if (strlen($possible_users[$k]) == 0) { unset($possible_users[$k]); } } // Who matches those criteria? // @todo This doesn't support sent item searching. $request = $smcFunc['db_query']('', ' SELECT id_member FROM {db_prefix}members WHERE real_name LIKE {raw:real_name_implode}', array('real_name_implode' => '\'' . implode('\' OR real_name LIKE \'', $possible_users) . '\'')); // Simply do nothing if there're too many members matching the criteria. if ($smcFunc['db_num_rows']($request) > $maxMembersToSearch) { $userQuery = ''; } elseif ($smcFunc['db_num_rows']($request) == 0) { $userQuery = 'AND pm.id_member_from = 0 AND (pm.from_name LIKE {raw:guest_user_name_implode})'; $searchq_parameters['guest_user_name_implode'] = '\'' . implode('\' OR pm.from_name LIKE \'', $possible_users) . '\''; } else { $memberlist = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $memberlist[] = $row['id_member']; } $userQuery = 'AND (pm.id_member_from IN ({array_int:member_list}) OR (pm.id_member_from = 0 AND (pm.from_name LIKE {raw:guest_user_name_implode})))'; $searchq_parameters['guest_user_name_implode'] = '\'' . implode('\' OR pm.from_name LIKE \'', $possible_users) . '\''; $searchq_parameters['member_list'] = $memberlist; } $smcFunc['db_free_result']($request); } // Setup the sorting variables... // @todo Add more in here! $sort_columns = array('pm.id_pm'); if (empty($search_params['sort']) && !empty($_REQUEST['sort'])) { list($search_params['sort'], $search_params['sort_dir']) = array_pad(explode('|', $_REQUEST['sort']), 2, ''); } $search_params['sort'] = !empty($search_params['sort']) && in_array($search_params['sort'], $sort_columns) ? $search_params['sort'] : 'pm.id_pm'; $search_params['sort_dir'] = !empty($search_params['sort_dir']) && $search_params['sort_dir'] == 'asc' ? 'asc' : 'desc'; // Sort out any labels we may be searching by. $labelQuery = ''; if ($context['folder'] == 'inbox' && !empty($search_params['advanced']) && $context['currently_using_labels']) { // Came here from pagination? Put them back into $_REQUEST for sanitization. if (isset($search_params['labels'])) { $_REQUEST['searchlabel'] = explode(',', $search_params['labels']); } // Assuming we have some labels - make them all integers. if (!empty($_REQUEST['searchlabel']) && is_array($_REQUEST['searchlabel'])) { foreach ($_REQUEST['searchlabel'] as $key => $id) { $_REQUEST['searchlabel'][$key] = (int) $id; } } else { $_REQUEST['searchlabel'] = array(); } // Now that everything is cleaned up a bit, make the labels a param. $search_params['labels'] = implode(',', $_REQUEST['searchlabel']); // No labels selected? That must be an error! if (empty($_REQUEST['searchlabel'])) { $context['search_errors']['no_labels_selected'] = true; } elseif (count($_REQUEST['searchlabel']) != count($context['labels'])) { $labelQuery = ' AND {raw:label_implode}'; $labelStatements = array(); foreach ($_REQUEST['searchlabel'] as $label) { $labelStatements[] = $smcFunc['db_quote']('FIND_IN_SET({string:label}, pmr.labels) != 0', array('label' => $label)); } $searchq_parameters['label_implode'] = '(' . implode(' OR ', $labelStatements) . ')'; } } // What are we actually searching for? $search_params['search'] = !empty($search_params['search']) ? $search_params['search'] : (isset($_REQUEST['search']) ? $_REQUEST['search'] : ''); // If we ain't got nothing - we should error! if (!isset($search_params['search']) || $search_params['search'] == '') { $context['search_errors']['invalid_search_string'] = true; } // Extract phrase parts first (e.g. some words "this is a phrase" some more words.) preg_match_all('~(?:^|\\s)([-]?)"([^"]+)"(?:$|\\s)~' . ($context['utf8'] ? 'u' : ''), $search_params['search'], $matches, PREG_PATTERN_ORDER); $searchArray = $matches[2]; // Remove the phrase parts and extract the words. $tempSearch = explode(' ', preg_replace('~(?:^|\\s)(?:[-]?)"(?:[^"]+)"(?:$|\\s)~' . ($context['utf8'] ? 'u' : ''), ' ', $search_params['search'])); // A minus sign in front of a word excludes the word.... so... $excludedWords = array(); // .. first, we check for things like -"some words", but not "-some words". foreach ($matches[1] as $index => $word) { if ($word == '-') { $word = $smcFunc['strtolower'](trim($searchArray[$index])); if (strlen($word) > 0) { $excludedWords[] = $word; } unset($searchArray[$index]); } } // Now we look for -test, etc.... normaller. foreach ($tempSearch as $index => $word) { if (strpos(trim($word), '-') === 0) { $word = substr($smcFunc['strtolower']($word), 1); if (strlen($word) > 0) { $excludedWords[] = $word; } unset($tempSearch[$index]); } } $searchArray = array_merge($searchArray, $tempSearch); // Trim everything and make sure there are no words that are the same. foreach ($searchArray as $index => $value) { $searchArray[$index] = $smcFunc['strtolower'](trim($value)); if ($searchArray[$index] == '') { unset($searchArray[$index]); } else { // Sort out entities first. $searchArray[$index] = $smcFunc['htmlspecialchars']($searchArray[$index]); } } $searchArray = array_unique($searchArray); // Create an array of replacements for highlighting. $context['mark'] = array(); foreach ($searchArray as $word) { $context['mark'][$word] = '<strong class="highlight">' . $word . '</strong>'; } // This contains *everything* $searchWords = array_merge($searchArray, $excludedWords); // Make sure at least one word is being searched for. if (empty($searchArray)) { $context['search_errors']['invalid_search_string'] = true; } // Sort out the search query so the user can edit it - if they want. $context['search_params'] = $search_params; if (isset($context['search_params']['search'])) { $context['search_params']['search'] = htmlspecialchars($context['search_params']['search']); } if (isset($context['search_params']['userspec'])) { $context['search_params']['userspec'] = htmlspecialchars($context['search_params']['userspec']); } // Now we have all the parameters, combine them together for pagination and the like... $context['params'] = array(); foreach ($search_params as $k => $v) { $context['params'][] = $k . '|\'|' . $v; } $context['params'] = base64_encode(implode('|"|', $context['params'])); // Compile the subject query part. $andQueryParts = array(); foreach ($searchWords as $index => $word) { if ($word == '') { continue; } if ($search_params['subject_only']) { $andQueryParts[] = 'pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . ' LIKE {string:search_' . $index . '}'; } else { $andQueryParts[] = '(pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . ' LIKE {string:search_' . $index . '} ' . (in_array($word, $excludedWords) ? 'AND pm.body NOT' : 'OR pm.body') . ' LIKE {string:search_' . $index . '})'; } $searchq_parameters['search_' . $index] = '%' . strtr($word, array('_' => '\\_', '%' => '\\%')) . '%'; } $searchQuery = ' 1=1'; if (!empty($andQueryParts)) { $searchQuery = implode(!empty($search_params['searchtype']) && $search_params['searchtype'] == 2 ? ' OR ' : ' AND ', $andQueryParts); } // Age limits? $timeQuery = ''; if (!empty($search_params['minage'])) { $timeQuery .= ' AND pm.msgtime < ' . (time() - $search_params['minage'] * 86400); } if (!empty($search_params['maxage'])) { $timeQuery .= ' AND pm.msgtime > ' . (time() - $search_params['maxage'] * 86400); } // If we have errors - return back to the first screen... if (!empty($context['search_errors'])) { $_REQUEST['params'] = $context['params']; return MessageSearch(); } // Get the amount of results. $request = $smcFunc['db_query']('', ' SELECT COUNT(*) FROM {db_prefix}pm_recipients AS pmr INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm) WHERE ' . ($context['folder'] == 'inbox' ? ' pmr.id_member = {int:current_member} AND pmr.deleted = {int:not_deleted}' : ' pm.id_member_from = {int:current_member} AND pm.deleted_by_sender = {int:not_deleted}') . ' ' . $userQuery . $labelQuery . $timeQuery . ' AND (' . $searchQuery . ')', array_merge($searchq_parameters, array('current_member' => $user_info['id'], 'not_deleted' => 0))); list($numResults) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // Get all the matching messages... using standard search only (No caching and the like!) // @todo This doesn't support sent item searching yet. $request = $smcFunc['db_query']('', ' SELECT pm.id_pm, pm.id_pm_head, pm.id_member_from FROM {db_prefix}pm_recipients AS pmr INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm) WHERE ' . ($context['folder'] == 'inbox' ? ' pmr.id_member = {int:current_member} AND pmr.deleted = {int:not_deleted}' : ' pm.id_member_from = {int:current_member} AND pm.deleted_by_sender = {int:not_deleted}') . ' ' . $userQuery . $labelQuery . $timeQuery . ' AND (' . $searchQuery . ') ORDER BY ' . $search_params['sort'] . ' ' . $search_params['sort_dir'] . ' LIMIT ' . $context['start'] . ', ' . $modSettings['search_results_per_page'], array_merge($searchq_parameters, array('current_member' => $user_info['id'], 'not_deleted' => 0))); $foundMessages = array(); $posters = array(); $head_pms = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $foundMessages[] = $row['id_pm']; $posters[] = $row['id_member_from']; $head_pms[$row['id_pm']] = $row['id_pm_head']; } $smcFunc['db_free_result']($request); // Find the real head pms! if ($context['display_mode'] == 2 && !empty($head_pms)) { $request = $smcFunc['db_query']('', ' SELECT MAX(pm.id_pm) AS id_pm, pm.id_pm_head FROM {db_prefix}personal_messages AS pm INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm) WHERE pm.id_pm_head IN ({array_int:head_pms}) AND pmr.id_member = {int:current_member} AND pmr.deleted = {int:not_deleted} GROUP BY pm.id_pm_head LIMIT {int:limit}', array('head_pms' => array_unique($head_pms), 'current_member' => $user_info['id'], 'not_deleted' => 0, 'limit' => count($head_pms))); $real_pm_ids = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $real_pm_ids[$row['id_pm_head']] = $row['id_pm']; } $smcFunc['db_free_result']($request); } // Load the users... $posters = array_unique($posters); if (!empty($posters)) { loadMemberData($posters); } // Sort out the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=pm;sa=search2;params=' . $context['params'], $_GET['start'], $numResults, $modSettings['search_results_per_page'], false); $context['message_labels'] = array(); $context['message_replied'] = array(); $context['personal_messages'] = array(); if (!empty($foundMessages)) { // Now get recipients (but don't include bcc-recipients for your inbox, you're not supposed to know :P!) $request = $smcFunc['db_query']('', ' SELECT pmr.id_pm, mem_to.id_member AS id_member_to, mem_to.real_name AS to_name, pmr.bcc, pmr.labels, pmr.is_read FROM {db_prefix}pm_recipients AS pmr LEFT JOIN {db_prefix}members AS mem_to ON (mem_to.id_member = pmr.id_member) WHERE pmr.id_pm IN ({array_int:message_list})', array('message_list' => $foundMessages)); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($context['folder'] == 'sent' || empty($row['bcc'])) { $recipients[$row['id_pm']][empty($row['bcc']) ? 'to' : 'bcc'][] = empty($row['id_member_to']) ? $txt['guest_title'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_to'] . '">' . $row['to_name'] . '</a>'; } if ($row['id_member_to'] == $user_info['id'] && $context['folder'] != 'sent') { $context['message_replied'][$row['id_pm']] = $row['is_read'] & 2; $row['labels'] = $row['labels'] == '' ? array() : explode(',', $row['labels']); // This is a special need for linking to messages. foreach ($row['labels'] as $v) { if (isset($context['labels'][(int) $v])) { $context['message_labels'][$row['id_pm']][(int) $v] = array('id' => $v, 'name' => $context['labels'][(int) $v]['name']); } // Here we find the first label on a message - for linking to posts in results if (!isset($context['first_label'][$row['id_pm']]) && !in_array('-1', $row['labels'])) { $context['first_label'][$row['id_pm']] = (int) $v; } } } } // Prepare the query for the callback! $request = $smcFunc['db_query']('', ' SELECT pm.id_pm, pm.subject, pm.id_member_from, pm.body, pm.msgtime, pm.from_name FROM {db_prefix}personal_messages AS pm WHERE pm.id_pm IN ({array_int:message_list}) ORDER BY ' . $search_params['sort'] . ' ' . $search_params['sort_dir'] . ' LIMIT ' . count($foundMessages), array('message_list' => $foundMessages)); $counter = 0; while ($row = $smcFunc['db_fetch_assoc']($request)) { // If there's no message subject, use the default. $row['subject'] = $row['subject'] == '' ? $txt['no_subject'] : $row['subject']; // Load this posters context info, if it ain't there then fill in the essentials... if (!loadMemberContext($row['id_member_from'], true)) { $memberContext[$row['id_member_from']]['name'] = $row['from_name']; $memberContext[$row['id_member_from']]['id'] = 0; $memberContext[$row['id_member_from']]['group'] = $txt['guest_title']; $memberContext[$row['id_member_from']]['link'] = $row['from_name']; $memberContext[$row['id_member_from']]['email'] = ''; $memberContext[$row['id_member_from']]['show_email'] = showEmailAddress(true, 0); $memberContext[$row['id_member_from']]['is_guest'] = true; } // Censor anything we don't want to see... censorText($row['body']); censorText($row['subject']); // Parse out any BBC... $row['body'] = parse_bbc($row['body'], true, 'pm' . $row['id_pm']); $href = $scripturl . '?action=pm;f=' . $context['folder'] . (isset($context['first_label'][$row['id_pm']]) ? ';l=' . $context['first_label'][$row['id_pm']] : '') . ';pmid=' . ($context['display_mode'] == 2 && isset($real_pm_ids[$head_pms[$row['id_pm']]]) ? $real_pm_ids[$head_pms[$row['id_pm']]] : $row['id_pm']) . '#msg' . $row['id_pm']; $context['personal_messages'][] = array('id' => $row['id_pm'], 'member' => &$memberContext[$row['id_member_from']], 'subject' => $row['subject'], 'body' => $row['body'], 'time' => timeformat($row['msgtime']), 'recipients' => &$recipients[$row['id_pm']], 'labels' => &$context['message_labels'][$row['id_pm']], 'fully_labeled' => count($context['message_labels'][$row['id_pm']]) == count($context['labels']), 'is_replied_to' => &$context['message_replied'][$row['id_pm']], 'href' => $href, 'link' => '<a href="' . $href . '">' . $row['subject'] . '</a>', 'counter' => ++$counter); } $smcFunc['db_free_result']($request); } // Finish off the context. $context['page_title'] = $txt['pm_search_title']; $context['sub_template'] = 'search_results'; $context['menu_data_' . $context['pm_menu_id']]['current_area'] = 'search'; $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=search', 'name' => $txt['pm_search_bar_title']); }
function getXmlProfile($xml_format) { global $scripturl, $memberContext, $user_profile, $modSettings, $user_info; // You must input a valid user.... if (empty($_GET['u']) || loadMemberData((int) $_GET['u']) === false) { return array(); } // Make sure the id is a number and not "I like trying to hack the database". $_GET['u'] = (int) $_GET['u']; // Load the member's contextual information! if (!loadMemberContext($_GET['u']) || !allowedTo('profile_view_any')) { return array(); } // Okay, I admit it, I'm lazy. Stupid $_GET['u'] is long and hard to type. $profile =& $memberContext[$_GET['u']]; if ($xml_format == 'rss' || $xml_format == 'rss2') { $data = array(array('title' => cdata_parse($profile['name']), 'link' => $scripturl . '?action=profile;u=' . $profile['id'], 'description' => cdata_parse(isset($profile['group']) ? $profile['group'] : $profile['post_group']), 'comments' => $scripturl . '?action=pm;sa=send;u=' . $profile['id'], 'pubDate' => gmdate('D, d M Y H:i:s \\G\\M\\T', $user_profile[$profile['id']]['date_registered']), 'guid' => $scripturl . '?action=profile;u=' . $profile['id'])); } elseif ($xml_format == 'rdf') { $data = array(array('title' => cdata_parse($profile['name']), 'link' => $scripturl . '?action=profile;u=' . $profile['id'], 'description' => cdata_parse(isset($profile['group']) ? $profile['group'] : $profile['post_group']))); } elseif ($xml_format == 'atom') { $data[] = array('title' => cdata_parse($profile['name']), 'link' => $scripturl . '?action=profile;u=' . $profile['id'], 'summary' => cdata_parse(isset($profile['group']) ? $profile['group'] : $profile['post_group']), 'author' => array('name' => $profile['real_name'], 'email' => in_array(showEmailAddress(!empty($profile['hide_email']), $profile['id']), array('yes', 'yes_permission_override')) ? $profile['email'] : null), 'published' => gmstrftime('%Y-%m-%dT%H:%M:%SZ', $user_profile[$profile['id']]['date_registered']), 'updated' => gmstrftime('%Y-%m-%dT%H:%M:%SZ', $user_profile[$profile['id']]['last_login']), 'id' => $scripturl . '?action=profile;u=' . $profile['id'], 'logo' => !empty($profile['avatar']) ? $profile['avatar']['url'] : ''); } else { $data = array('username' => $user_info['is_admin'] || $user_info['id'] == $profile['id'] ? cdata_parse($profile['username']) : '', 'name' => cdata_parse($profile['name']), 'link' => $scripturl . '?action=profile;u=' . $profile['id'], 'posts' => $profile['posts'], 'post-group' => cdata_parse($profile['post_group']), 'language' => cdata_parse($profile['language']), 'last-login' => gmdate('D, d M Y H:i:s \\G\\M\\T', $user_profile[$profile['id']]['last_login']), 'registered' => gmdate('D, d M Y H:i:s \\G\\M\\T', $user_profile[$profile['id']]['date_registered'])); // Everything below here might not be set, and thus maybe shouldn't be displayed. if ($profile['gender']['name'] != '') { $data['gender'] = cdata_parse($profile['gender']['name']); } if ($profile['avatar']['name'] != '') { $data['avatar'] = $profile['avatar']['url']; } // If they are online, show an empty tag... no reason to put anything inside it. if ($profile['online']['is_online']) { $data['online'] = ''; } if ($profile['signature'] != '') { $data['signature'] = cdata_parse($profile['signature']); } if ($profile['blurb'] != '') { $data['blurb'] = cdata_parse($profile['blurb']); } if ($profile['location'] != '') { $data['location'] = cdata_parse($profile['location']); } if ($profile['title'] != '') { $data['title'] = cdata_parse($profile['title']); } if ($profile['group'] != '') { $data['position'] = cdata_parse($profile['group']); } if (in_array($profile['show_email'], array('yes', 'yes_permission_override'))) { $data['email'] = $profile['email']; } if (!empty($profile['birth_date']) && substr($profile['birth_date'], 0, 4) != '0000') { list($birth_year, $birth_month, $birth_day) = sscanf($profile['birth_date'], '%d-%d-%d'); $datearray = getdate(forum_time()); $data['age'] = $datearray['year'] - $birth_year - ($datearray['mon'] > $birth_month || $datearray['mon'] == $birth_month && $datearray['mday'] >= $birth_day ? 0 : 1); } } // Save some memory. unset($profile, $memberContext[$_GET['u']]); return $data; }
function prepareDisplayContext($reset = false) { global $settings, $txt, $modSettings, $scripturl, $options, $user_info, $smcFunc; global $memberContext, $context, $messages_request, $topic, $attachments, $topicinfo; static $counter = null; // If the query returned false, bail. if ($messages_request == false) { return false; } // Remember which message this is. (ie. reply #83) if ($counter === null || $reset) { $counter = empty($options['view_newest_first']) ? $context['start'] : $context['total_visible_posts'] - $context['start']; } // Start from the beginning... if ($reset) { return @$smcFunc['db_data_seek']($messages_request, 0); } // Attempt to get the next message. $message = $smcFunc['db_fetch_assoc']($messages_request); if (!$message) { $smcFunc['db_free_result']($messages_request); return false; } // $context['icon_sources'] says where each icon should come from - here we set up the ones which will always exist! if (empty($context['icon_sources'])) { $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless', 'clip'); $context['icon_sources'] = array(); foreach ($stable_icons as $icon) { $context['icon_sources'][$icon] = 'images_url'; } } // Message Icon Management... check the images exist. if (empty($modSettings['messageIconChecks_disable'])) { // If the current icon isn't known, then we need to do something... if (!isset($context['icon_sources'][$message['icon']])) { $context['icon_sources'][$message['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $message['icon'] . '.gif') ? 'images_url' : 'default_images_url'; } } elseif (!isset($context['icon_sources'][$message['icon']])) { $context['icon_sources'][$message['icon']] = 'images_url'; } // If you're a lazy bum, you probably didn't give a subject... $message['subject'] = $message['subject'] != '' ? $message['subject'] : $txt['no_subject']; // Are you allowed to remove at least a single reply? $context['can_remove_post'] |= allowedTo('delete_own') && (empty($modSettings['edit_disable_time']) || max($message['modified_time'], $message['poster_time']) + $modSettings['edit_disable_time'] * 60 >= time()) && $message['id_member'] == $user_info['id']; // If it couldn't load, or the user was a guest.... someday may be done with a guest table. if (!loadMemberContext($message['id_member'], true)) { // Notice this information isn't used anywhere else.... $memberContext[$message['id_member']]['name'] = $message['poster_name']; $memberContext[$message['id_member']]['id'] = 0; $memberContext[$message['id_member']]['group'] = $txt['guest_title']; $memberContext[$message['id_member']]['link'] = $message['poster_name']; $memberContext[$message['id_member']]['email'] = $message['poster_email']; $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0); $memberContext[$message['id_member']]['is_guest'] = true; } else { $memberContext[$message['id_member']]['can_view_profile'] = allowedTo('profile_view_any') || $message['id_member'] == $user_info['id'] && allowedTo('profile_view_own'); $memberContext[$message['id_member']]['is_topic_starter'] = $message['id_member'] == $context['topic_starter_id']; $memberContext[$message['id_member']]['can_see_warning'] = !isset($context['disabled_fields']['warning_status']) && $memberContext[$message['id_member']]['warning_status'] && ($context['user']['can_mod'] || !$user_info['is_guest'] && !empty($modSettings['warning_show']) && ($modSettings['warning_show'] > 1 || $message['id_member'] == $user_info['id'])); } $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; // Do the censor thang. censorText($message['body']); censorText($message['subject']); // Run BBC interpreter on the message. $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg']); // Compose the memory eat- I mean message array. $output = array('attachment' => loadAttachmentContext($message['id_msg']), 'alternate' => $counter % 2, 'id' => $message['id_msg'], 'href' => $scripturl . '?topic=' . $topic . '.msg' . $message['id_msg'] . '#msg' . $message['id_msg'], 'link' => '<a href="' . $scripturl . '?topic=' . $topic . '.msg' . $message['id_msg'] . '#msg' . $message['id_msg'] . '" rel="nofollow">' . $message['subject'] . '</a>', 'member' => &$memberContext[$message['id_member']], 'icon' => $message['icon'], 'icon_url' => $settings[$context['icon_sources'][$message['icon']]] . '/post/' . $message['icon'] . '.gif', 'subject' => $message['subject'], 'time' => timeformat($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'counter' => $counter, 'modified' => array('time' => timeformat($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'name' => $message['modified_name']), 'body' => $message['body'], 'new' => empty($message['is_read']), 'approved' => $message['approved'], 'first_new' => isset($context['start_from']) && $context['start_from'] == $counter, 'is_ignored' => !empty($modSettings['enable_buddylist']) && !empty($options['posts_apply_ignore_list']) && in_array($message['id_member'], $context['user']['ignoreusers']), 'can_approve' => !$message['approved'] && $context['can_approve'], 'can_unapprove' => $message['approved'] && $context['can_approve'], 'can_modify' => (!$context['is_locked'] || allowedTo('moderate_board')) && (allowedTo('modify_any') || allowedTo('modify_replies') && $context['user']['started'] || allowedTo('modify_own') && $message['id_member'] == $user_info['id'] && (empty($modSettings['edit_disable_time']) || !$message['approved'] || max($message['modified_time'], $message['poster_time']) + $modSettings['edit_disable_time'] * 60 > time())), 'can_remove' => allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'] || allowedTo('delete_own') && $message['id_member'] == $user_info['id'] && (empty($modSettings['edit_disable_time']) || max($message['modified_time'], $message['poster_time']) + $modSettings['edit_disable_time'] * 60 > time()), 'can_see_ip' => allowedTo('moderate_forum') || $message['id_member'] == $user_info['id'] && !empty($user_info['id'])); // Is this user the message author? $output['is_message_author'] = $message['id_member'] == $user_info['id']; if (empty($options['view_newest_first'])) { $counter++; } else { $counter--; } return $output; }
/** * Display members of a group, and allow adding of members to a group. * * What it does: * - It can be called from ManageMembergroups if it needs templating within the admin environment. * - It shows a list of members that are part of a given membergroup. * - It is called by ?action=moderate;area=viewgroups;sa=members;group=x * - It requires the manage_membergroups permission. * - It allows to add and remove members from the selected membergroup. * - It allows sorting on several columns. * - It redirects to itself. * @uses ManageMembergroups template, group_members sub template. */ public function action_members() { global $txt, $scripturl, $context, $modSettings, $user_info, $settings; $current_group = isset($_REQUEST['group']) ? (int) $_REQUEST['group'] : 0; // These will be needed require_once SUBSDIR . '/Membergroups.subs.php'; require_once SUBSDIR . '/Members.subs.php'; // Load up the group details. $context['group'] = membergroupById($current_group, true, true); // No browsing of guests, membergroup 0 or moderators or non-existing groups. if ($context['group'] === false || in_array($current_group, array(-1, 0, 3))) { fatal_lang_error('membergroup_does_not_exist', false); } $context['group']['id'] = $context['group']['id_group']; $context['group']['name'] = $context['group']['group_name']; // Fix the membergroup icons. $context['group']['icons'] = explode('#', $context['group']['icons']); $context['group']['icons'] = !empty($context['group']['icons'][0]) && !empty($context['group']['icons'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/group_icons/' . $context['group']['icons'][1] . '" alt="*" />', $context['group']['icons'][0]) : ''; $context['group']['can_moderate'] = allowedTo('manage_membergroups') && (allowedTo('admin_forum') || $context['group']['group_type'] != 1); // The template is very needy $context['linktree'][] = array('url' => $scripturl . '?action=groups;sa=members;group=' . $context['group']['id'], 'name' => $context['group']['name']); $context['can_send_email'] = allowedTo('send_email_to_members'); $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up'; $context['start'] = $_REQUEST['start']; $context['can_moderate_forum'] = allowedTo('moderate_forum'); // @todo: use createList // Load all the group moderators, for fun. $context['group']['moderators'] = array(); $moderators = getGroupModerators($current_group); foreach ($moderators as $id_member => $name) { $context['group']['moderators'][] = array('id' => $id_member, 'name' => $name); if ($user_info['id'] == $id_member && $context['group']['group_type'] != 1) { $context['group']['can_moderate'] = true; } } // If this group is hidden then it can only "exist" if the user can moderate it! if ($context['group']['hidden'] && !$context['group']['can_moderate']) { fatal_lang_error('membergroup_does_not_exist', false); } // You can only assign membership if you are the moderator and/or can manage groups! if (!$context['group']['can_moderate']) { $context['group']['assignable'] = 0; } elseif ($context['group']['id'] == 1 && !allowedTo('admin_forum')) { $context['group']['assignable'] = 0; } // Removing member from group? if (isset($_POST['remove']) && !empty($_REQUEST['rem']) && is_array($_REQUEST['rem']) && $context['group']['assignable']) { // Security first checkSession(); validateToken('mod-mgm'); // Make sure we're dealing with integers only. foreach ($_REQUEST['rem'] as $key => $group) { $_REQUEST['rem'][$key] = (int) $group; } removeMembersFromGroups($_REQUEST['rem'], $current_group, true); } elseif (isset($_REQUEST['add']) && (!empty($_REQUEST['toAdd']) || !empty($_REQUEST['member_add'])) && $context['group']['assignable']) { // Make sure you can do this checkSession(); validateToken('mod-mgm'); $member_query = array(array('and' => 'not_in_group')); $member_parameters = array('not_in_group' => $current_group); // Get all the members to be added... taking into account names can be quoted ;) $_REQUEST['toAdd'] = strtr(Util::htmlspecialchars($_REQUEST['toAdd'], ENT_QUOTES), array('"' => '"')); preg_match_all('~"([^"]+)"~', $_REQUEST['toAdd'], $matches); $member_names = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_REQUEST['toAdd'])))); foreach ($member_names as $index => $member_name) { $member_names[$index] = trim(Util::strtolower($member_names[$index])); if (strlen($member_names[$index]) == 0) { unset($member_names[$index]); } } // Any members passed by ID? $member_ids = array(); if (!empty($_REQUEST['member_add'])) { foreach ($_REQUEST['member_add'] as $id) { if ($id > 0) { $member_ids[] = (int) $id; } } } // Construct the query pelements, first for adds by name if (!empty($member_ids)) { $member_query[] = array('or' => 'member_ids'); $member_parameters['member_ids'] = $member_ids; } // And then adds by ID if (!empty($member_names)) { $member_query[] = array('or' => 'member_names'); $member_parameters['member_names'] = $member_names; } // Get back the ones that were not already in the group $members = membersBy($member_query, $member_parameters); // Do the updates... if (!empty($members)) { addMembersToGroup($members, $current_group, $context['group']['hidden'] ? 'only_additional' : 'auto', true); } } // Sort out the sorting! $sort_methods = array('name' => 'real_name', 'email' => allowedTo('moderate_forum') ? 'email_address' : 'hide_email ' . (isset($_REQUEST['desc']) ? 'DESC' : 'ASC') . ', email_address', 'active' => 'last_login', 'registered' => 'date_registered', 'posts' => 'posts'); // They didn't pick one, or tried a wrong one, so default to by name.. if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) { $context['sort_by'] = 'name'; $querySort = 'real_name' . (isset($_REQUEST['desc']) ? ' DESC' : ' ASC'); } else { $context['sort_by'] = $_REQUEST['sort']; $querySort = $sort_methods[$_REQUEST['sort']] . (isset($_REQUEST['desc']) ? ' DESC' : ' ASC'); } // The where on the query is interesting. Non-moderators should only see people who are in this group as primary. if ($context['group']['can_moderate']) { $where = $context['group']['is_post_group'] ? 'in_post_group' : 'in_group'; } else { $where = $context['group']['is_post_group'] ? 'in_post_group' : 'in_group_no_add'; } // Count members of the group. $context['total_members'] = countMembersBy($where, array($where => $current_group)); $context['total_members'] = comma_format($context['total_members']); // Create the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=' . ($context['group']['can_moderate'] ? 'moderate;area=viewgroups' : 'groups') . ';sa=members;group=' . $current_group . ';sort=' . $context['sort_by'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $context['total_members'], $modSettings['defaultMaxMembers']); // Fetch the members that meet the where criteria $context['members'] = membersBy($where, array($where => $current_group, 'order' => $querySort), true); foreach ($context['members'] as $id => $row) { $last_online = empty($row['last_login']) ? $txt['never'] : standardTime($row['last_login']); // Italicize the online note if they aren't activated. if ($row['is_activated'] % 10 != 1) { $last_online = '<em title="' . $txt['not_activated'] . '">' . $last_online . '</em>'; } $context['members'][$id] = array('id' => $row['id_member'], 'name' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>', 'email' => $row['email_address'], 'show_email' => showEmailAddress(!empty($row['hide_email']), $row['id_member']), 'ip' => '<a href="' . $scripturl . '?action=trackip;searchip=' . $row['member_ip'] . '">' . $row['member_ip'] . '</a>', 'registered' => standardTime($row['date_registered']), 'last_online' => $last_online, 'posts' => comma_format($row['posts']), 'is_activated' => $row['is_activated'] % 10 == 1); } if (!empty($context['group']['assignable'])) { loadJavascriptFile('suggest.js', array('defer' => true)); } // Select the template. $context['sub_template'] = 'group_members'; $context['page_title'] = $txt['membergroups_members_title'] . ': ' . $context['group']['name']; createToken('mod-mgm'); }