/** * @return void * * marks one ore more notifications as read */ function aStreamMarkNotificationRead() { global $user_info; $xml = isset($_REQUEST['xml']) ? true : false; if ($user_info['is_guest']) { return; } if (isset($_REQUEST['act'])) { $new_act_ids = array(); if ($_REQUEST['act'] === 'all') { $where = 'id_member = {int:id_member}'; $markallread = true; } else { $act_ids = explode(',', $_REQUEST['act']); foreach ($act_ids as $act) { if ((int) $act > 0) { $new_act_ids[] = (int) $act; } } $new_act = join(',', $new_act_ids); $where = 'id_member = {int:id_member} AND id_act IN(' . $new_act . ')'; $markallread = false; } if ($markallread || count($new_act_ids) > 0) { $query = 'UPDATE {db_prefix}log_notifications SET unread = 0 WHERE ' . $where; smf_db_query($query, array('id_member' => $user_info['id'])); invalidateMemberData($user_info['id']); } if ($xml) { // construct xml response for the JavaScript markread handler header('Content-Type: text/xml; charset=UTF-8'); echo '<', '?xml version="1.0" encoding="UTF-8', '"?', '> <response>'; if ($markallread) { echo ' <markedread name="markedread"><![CDATA[all]]></markedread> '; } else { foreach ($new_act_ids as $act) { echo ' <markedread name="markedread"><![CDATA[', $act, ']]></markedread> '; } } echo ' </response> '; obExit(false); } } redirectexit(); }
/** * @param $mid = int message (or content) id * * handle the ajax request for rating a post. Also handles deletion of * * TODO: remove likes from the database when a user is deleted * TODO: make it work without AJAX and JavaScript */ public static function rateIt($mid) { global $context, $user_info, $sourcedir, $txt, $modSettings; $total = array(); $content_type = 1; // > post content type, we should define them elsewhere later when we have more than just this one if ((int) $mid > 0) { $uid = $user_info['id']; $remove_it = isset($_REQUEST['remove']) ? true : false; $repair = isset($_REQUEST['repair']) && $user_info['is_admin'] ? true : false; $is_xmlreq = $_REQUEST['action'] == 'xmlhttp' ? true : false; $update_mode = false; $like_type = isset($_REQUEST['r']) && (int) $_REQUEST['r'] > 0 ? $_REQUEST['r'] : '1'; $comment = isset($_REQUEST['comment']) ? strip_tags($_REQUEST['comment']) : ''; $rtypes = explode(',', $like_type); foreach ($rtypes as $rtype) { if (!isset($modSettings['ratings'][$rtype])) { AjaxErrorMsg($txt['unknown_rating_type']); } } if ($user_info['is_guest']) { AjaxErrorMsg($txt['no_like_for_guests']); } $request = smf_db_query('SELECT m.id_msg, m.id_member, m.id_board, m.id_topic, m.subject, l.id_msg AS like_message, l.rtype, l.id_user FROM {db_prefix}messages AS m LEFT JOIN {db_prefix}likes AS l ON (l.id_msg = m.id_msg AND l.ctype = {int:content_type} AND l.id_user = {int:id_user}) WHERE m.id_msg = {int:id_msg} LIMIT 1', array('content_type' => $content_type, 'id_msg' => $mid, 'id_user' => $uid)); $row = mysql_fetch_assoc($request); mysql_free_result($request); $like_owner = $row['id_user']; if ($row['id_user'] > 0 && !$remove_it && !$repair) { // duplicate like (but not when removing it) AjaxErrorMsg($txt['like_verify_error']); } $like_receiver = $row['id_member']; EoS_Smarty::loadTemplate('xml_blocks'); $context['template_functions'] = 'rating_response'; $context['ratings_output']['mid'] = $mid; /* * this is a debugging feature and allows the admin to repair * the likes for a post. * it may go away at a later time. */ if ($repair) { if (!$user_info['is_admin']) { obExit(false); } $total = self::updateForContent($mid); $output = ''; self::generateOutput($total['status'], $output, $mid, $row['id_user'] > 0 ? $row['rtype'] : 0); // fix like stats for the like_giver and like_receiver. This might be a very slow query, but // since this feature will most likely go away, right now I do not care. /* smf_db_query('UPDATE {db_prefix}members AS m SET m.likes_given = (SELECT COUNT(l.id_user) FROM {db_prefix}likes AS l WHERE l.id_user = m.id_member), m.likes_received = (SELECT COUNT(l1.id_receiver) FROM {db_prefix}likes AS l1 WHERE l1.id_receiver = m.id_member) WHERE m.id_member = {int:owner} OR m.id_member = {int:receiver}', array('owner' => $like_owner, 'receiver' => $like_receiver)); */ invalidateMemberData(array($like_owner, $like_receiver)); if ($is_xmlreq) { $context['ratings_output']['output'] = $output; $context['ratings_output']['likebar'] = ''; $context['postratings'] = json_encode($context['ratings_output']); return; } else { redirectexit(); } } if ($like_receiver == $uid) { AjaxErrorMsg($txt['cannot_like_own']); } if (!allowedTo('like_give', $row['id_board'])) { // no permission to give likes in this board AjaxErrorMsg($txt['like_no_permission']); } if ($remove_it && $row['id_user'] > 0) { // remove a rating if ($like_owner == $uid) { smf_db_query('DELETE FROM {db_prefix}likes WHERE id_msg = {int:id_msg} AND id_user = {int:id_user} AND ctype = {int:ctype}', array('id_msg' => $mid, 'id_user' => $uid, 'ctype' => $content_type)); if ($like_receiver) { smf_db_query('UPDATE {db_prefix}members SET likes_received = likes_received - 1 WHERE id_member = {int:id_member}', array('id_member' => $like_receiver)); } smf_db_query('UPDATE {db_prefix}members SET likes_given = likes_given - 1 WHERE id_member = {int:id_member}', array('id_member' => $uid)); // if we remove a like (unlike) a post, also delete the corresponding activity smf_db_query('DELETE a.*, n.* FROM {db_prefix}log_activities AS a LEFT JOIN {db_prefix}log_notifications AS n ON(n.id_act = a.id_act) WHERE a.id_member = {int:id_member} AND a.id_type = 1 AND a.id_content = {int:id_content}', array('id_member' => $uid, 'id_content' => $mid)); $context['ratings_output']['likebar'] = self::$rate_bar; } } else { /* store the rating */ global $memberContext; if ($like_receiver) { // we do have a member, but still allow to like posts made by guests loadMemberData($like_receiver); // but banned users shall not receive likes loadMemberContext($like_receiver); } if ($like_receiver && !$memberContext[$like_receiver]['is_banned'] || $like_receiver == 0) { // posts by guests can be liked smf_db_query('INSERT INTO {db_prefix}likes(id_msg, id_user, id_receiver, updated, ctype, rtype, comment) VALUES({int:id_message}, {int:id_user}, {int:id_receiver}, {int:updated}, {int:ctype}, {string:rtype}, {string:comment})', array('id_message' => $mid, 'id_user' => $uid, 'id_receiver' => $like_receiver, 'updated' => time(), 'ctype' => $content_type, 'rtype' => $like_type, 'comment' => $comment)); if ($like_receiver) { smf_db_query('UPDATE {db_prefix}members SET likes_received = likes_received + 1 WHERE id_member = {int:id_member}', array('id_member' => $like_receiver)); } smf_db_query('UPDATE {db_prefix}members SET likes_given = likes_given + 1 WHERE id_member = {int:uid}', array('uid' => $uid)); $update_mode = $like_type; if ($modSettings['astream_active']) { @(require_once $sourcedir . '/lib/Subs-Activities.php'); aStreamAdd($uid, ACT_LIKE, array('member_name' => $context['user']['name'], 'topic_title' => $row['subject'], 'rtype' => $like_type), $row['id_board'], $row['id_topic'], $mid, $like_receiver); } } else { AjaxErrorMsg($txt['like_cannot_like']); } $context['ratings_output']['likebar'] = '<a rel="nofollow" class="givelike" data-fn="remove" href="#" data-id="' . $mid . '">' . $txt['unlike_label'] . '</a>'; } if ($user_info['is_admin'] && self::$show_repair_link) { $context['ratings_output']['likebar'] .= ' <a rel="nofollow" class="givelike" data-fn="repair" href="#" data-id="' . $mid . '">Repair ratings</a>'; } $total = self::updateForContent($mid); $output = ''; self::generateOutput($total['status'], $output, $mid, $update_mode); $context['ratings_output']['output'] = $output; $context['postratings'] = json_encode($context['ratings_output']); } }
function MessageFolder() { global $txt, $scripturl, $modSettings, $context, $subjects_request; global $messages_request, $user_info, $recipients, $options, $smcFunc, $memberContext, $user_settings; $_ctx = new PMContext(); // Changing view? if (isset($_GET['view'])) { $context['display_mode'] = $context['display_mode'] > 1 ? 0 : $context['display_mode'] + 1; updateMemberData($user_info['id'], array('pm_prefs' => $user_settings['pm_prefs'] & 252 | $context['display_mode'])); } // Make sure the starting location is valid. if (isset($_GET['start']) && $_GET['start'] != 'new') { $_GET['start'] = (int) $_GET['start']; } elseif (!isset($_GET['start']) && !empty($options['view_newest_pm_first'])) { $_GET['start'] = 0; } else { $_GET['start'] = 'new'; } // we read pms now, so mark all notifications regarding pms as read if ($modSettings['astream_active'] && $user_info['notify_count'] > 0) { smf_db_query('UPDATE {db_prefix}log_notifications AS n LEFT JOIN {db_prefix}log_activities AS a ON(n.id_act = a.id_act) SET n.unread = 0 WHERE n.id_member = {int:member} AND n.unread = 1 AND a.id_type = {int:type}', array('member' => $user_info['id'], 'type' => 6)); invalidateMemberData($user_info['id']); } // Set up some basic theme stuff. $context['from_or_to'] = $context['folder'] != 'sent' ? 'from' : 'to'; $context['get_pmessage'] = 'prepareMessageContext'; $context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1; //$context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array(); $labelQuery = $context['folder'] != 'sent' ? ' AND FIND_IN_SET(' . $context['current_label_id'] . ', pmr.labels) != 0' : ''; // Set the index bar correct! messageIndexBar($context['current_label_id'] == -1 ? $context['folder'] : 'label' . $context['current_label_id']); // Sorting the folder. $sort_methods = array('date' => 'pm.id_pm', 'name' => 'IFNULL(mem.real_name, \'\')', 'subject' => 'pm.subject'); // They didn't pick one, use the forum default. if (!isset($_GET['sort']) || !isset($sort_methods[$_GET['sort']])) { $context['sort_by'] = 'date'; $_GET['sort'] = 'pm.id_pm'; // An overriding setting? $descending = !empty($options['view_newest_pm_first']); } else { $context['sort_by'] = $_GET['sort']; $_GET['sort'] = $sort_methods[$_GET['sort']]; $descending = isset($_GET['desc']); } $context['sort_direction'] = $descending ? 'down' : 'up'; // Why would you want access to your sent items if you're not allowed to send anything? if ($context['folder'] == 'sent') { isAllowedTo('pm_send'); } // Set the text to resemble the current folder. $pmbox = $context['folder'] != 'sent' ? $txt['inbox'] : $txt['sent_items']; $txt['delete_all'] = str_replace('PMBOX', $pmbox, $txt['delete_all']); // Now, build the link tree! if ($context['current_label_id'] == -1) { $context['linktree'][] = array('url' => $scripturl . '?action=pm;f=' . $context['folder'], 'name' => $pmbox); } // Build it further for a label. if ($context['current_label_id'] != -1) { $context['linktree'][] = array('url' => $scripturl . '?action=pm;f=' . $context['folder'] . ';l=' . $context['current_label_id'], 'name' => $txt['pm_current_label'] . ': ' . $context['current_label']); } // Figure out how many messages there are. if ($context['folder'] == 'sent') { $request = smf_db_query(' SELECT COUNT(' . ($context['display_mode'] == 2 ? 'DISTINCT pm.id_pm_head' : '*') . ') FROM {db_prefix}personal_messages AS pm WHERE pm.id_member_from = {int:current_member} AND pm.deleted_by_sender = {int:not_deleted}', array('current_member' => $user_info['id'], 'not_deleted' => 0)); } else { $request = smf_db_query(' SELECT COUNT(' . ($context['display_mode'] == 2 ? 'DISTINCT pm.id_pm_head' : '*') . ') FROM {db_prefix}pm_recipients AS pmr' . ($context['display_mode'] == 2 ? ' INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm)' : '') . ' WHERE pmr.id_member = {int:current_member} AND pmr.deleted = {int:not_deleted}' . $labelQuery, array('current_member' => $user_info['id'], 'not_deleted' => 0)); } list($max_messages) = mysql_fetch_row($request); mysql_free_result($request); // Only show the button if there are messages to delete. $context['show_delete'] = $max_messages > 0; $last = end($context['linktree']); reset($context['linktree']); $context['pmboxname'] = $last['name']; // Start on the last page. if (!is_numeric($_GET['start']) || $_GET['start'] >= $max_messages) { $_GET['start'] = $max_messages - 1 - ($max_messages - 1) % $modSettings['defaultMaxMessages']; } elseif ($_GET['start'] < 0) { $_GET['start'] = 0; } // ... but wait - what if we want to start from a specific message? if (isset($_GET['pmid'])) { $pmID = (int) $_GET['pmid']; // Make sure you have access to this PM. if (!isAccessiblePM($pmID, $context['folder'] == 'sent' ? 'outbox' : 'inbox')) { fatal_lang_error('no_access', false); } $context['current_pm'] = $pmID; // With only one page of PM's we're gonna want page 1. if ($max_messages <= $modSettings['defaultMaxMessages']) { $_GET['start'] = 0; } elseif (!isset($_GET['kstart'])) { if ($context['folder'] == 'sent') { $request = smf_db_query(' SELECT COUNT(' . ($context['display_mode'] == 2 ? 'DISTINCT pm.id_pm_head' : '*') . ') FROM {db_prefix}personal_messages WHERE id_member_from = {int:current_member} AND deleted_by_sender = {int:not_deleted} AND id_pm ' . ($descending ? '>' : '<') . ' {int:id_pm}', array('current_member' => $user_info['id'], 'not_deleted' => 0, 'id_pm' => $pmID)); } else { $request = smf_db_query(' SELECT COUNT(' . ($context['display_mode'] == 2 ? 'DISTINCT pm.id_pm_head' : '*') . ') FROM {db_prefix}pm_recipients AS pmr' . ($context['display_mode'] == 2 ? ' INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm)' : '') . ' WHERE pmr.id_member = {int:current_member} AND pmr.deleted = {int:not_deleted}' . $labelQuery . ' AND pmr.id_pm ' . ($descending ? '>' : '<') . ' {int:id_pm}', array('current_member' => $user_info['id'], 'not_deleted' => 0, 'id_pm' => $pmID)); } list($_GET['start']) = mysql_fetch_row($request); mysql_free_result($request); // To stop the page index's being abnormal, start the page on the page the message would normally be located on... $_GET['start'] = $modSettings['defaultMaxMessages'] * (int) ($_GET['start'] / $modSettings['defaultMaxMessages']); } } // Sanitize and validate pmsg variable if set. if (isset($_GET['pmsg'])) { $pmsg = (int) $_GET['pmsg']; if (!isAccessiblePM($pmsg, $context['folder'] == 'sent' ? 'outbox' : 'inbox')) { fatal_lang_error('no_access', false); } } // Set up the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=pm;f=' . $context['folder'] . (isset($_REQUEST['l']) ? ';l=' . (int) $_REQUEST['l'] : '') . ';sort=' . $context['sort_by'] . ($descending ? ';desc' : ''), $_GET['start'], $max_messages, $modSettings['defaultMaxMessages']); $context['start'] = $_GET['start']; // Determine the navigation context (especially useful for the wireless template). $context['links'] = array('first' => $_GET['start'] >= $modSettings['defaultMaxMessages'] ? $scripturl . '?action=pm;start=0' : '', 'prev' => $_GET['start'] >= $modSettings['defaultMaxMessages'] ? $scripturl . '?action=pm;start=' . ($_GET['start'] - $modSettings['defaultMaxMessages']) : '', 'next' => $_GET['start'] + $modSettings['defaultMaxMessages'] < $max_messages ? $scripturl . '?action=pm;start=' . ($_GET['start'] + $modSettings['defaultMaxMessages']) : '', 'last' => $_GET['start'] + $modSettings['defaultMaxMessages'] < $max_messages ? $scripturl . '?action=pm;start=' . floor(($max_messages - 1) / $modSettings['defaultMaxMessages']) * $modSettings['defaultMaxMessages'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_GET['start'] / $modSettings['defaultMaxMessages'] + 1, 'num_pages' => floor(($max_messages - 1) / $modSettings['defaultMaxMessages']) + 1); // First work out what messages we need to see - if grouped is a little trickier... if ($context['display_mode'] == 2) { $request = smf_db_query(' SELECT MAX(pm.id_pm) AS id_pm, pm.id_pm_head FROM {db_prefix}personal_messages AS pm' . ($context['folder'] == 'sent' ? $context['sort_by'] == 'name' ? ' LEFT JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm)' : '' : ' INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm AND pmr.id_member = {int:current_member} AND pmr.deleted = {int:deleted_by} ' . $labelQuery . ')') . ($context['sort_by'] == 'name' ? ' LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = {raw:pm_member})' : '') . ' WHERE ' . ($context['folder'] == 'sent' ? 'pm.id_member_from = {int:current_member} AND pm.deleted_by_sender = {int:deleted_by}' : '1=1') . (empty($pmsg) ? '' : ' AND pm.id_pm = {int:pmsg}') . ' GROUP BY pm.id_pm_head ORDER BY ' . ($_GET['sort'] == 'pm.id_pm' && $context['folder'] != 'sent' ? 'id_pm' : '{raw:sort}') . ($descending ? ' DESC' : ' ASC') . (empty($_GET['pmsg']) ? ' LIMIT ' . $_GET['start'] . ', ' . $modSettings['defaultMaxMessages'] : ''), array('current_member' => $user_info['id'], 'deleted_by' => 0, 'sort' => $_GET['sort'], 'pm_member' => $context['folder'] == 'sent' ? 'pmr.id_member' : 'pm.id_member_from', 'pmsg' => isset($pmsg) ? (int) $pmsg : 0)); } else { // !!!SLOW This query uses a filesort. (inbox only.) $request = smf_db_query(' SELECT pm.id_pm, pm.id_pm_head, pm.id_member_from FROM {db_prefix}personal_messages AS pm' . ($context['folder'] == 'sent' ? '' . ($context['sort_by'] == 'name' ? ' LEFT JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm)' : '') : ' INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm AND pmr.id_member = {int:current_member} AND pmr.deleted = {int:is_deleted} ' . $labelQuery . ')') . ($context['sort_by'] == 'name' ? ' LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = {raw:pm_member})' : '') . ' WHERE ' . ($context['folder'] == 'sent' ? 'pm.id_member_from = {raw:current_member} AND pm.deleted_by_sender = {int:is_deleted}' : '1=1') . (empty($pmsg) ? '' : ' AND pm.id_pm = {int:pmsg}') . ' ORDER BY ' . ($_GET['sort'] == 'pm.id_pm' && $context['folder'] != 'sent' ? 'pmr.id_pm' : '{raw:sort}') . ($descending ? ' DESC' : ' ASC') . (empty($pmsg) ? ' LIMIT ' . $_GET['start'] . ', ' . $modSettings['defaultMaxMessages'] : ''), array('current_member' => $user_info['id'], 'is_deleted' => 0, 'sort' => $_GET['sort'], 'pm_member' => $context['folder'] == 'sent' ? 'pmr.id_member' : 'pm.id_member_from', 'pmsg' => isset($pmsg) ? (int) $pmsg : 0)); } // Load the id_pms and initialize recipients. $pms = array(); $lastData = array(); $posters = $context['folder'] == 'sent' ? array($user_info['id']) : array(); $recipients = array(); while ($row = mysql_fetch_assoc($request)) { if (!isset($recipients[$row['id_pm']])) { if (isset($row['id_member_from'])) { $posters[$row['id_pm']] = $row['id_member_from']; } $pms[$row['id_pm']] = $row['id_pm']; $recipients[$row['id_pm']] = array('to' => array(), 'bcc' => array()); } // Keep track of the last message so we know what the head is without another query! if (empty($pmID) && (empty($options['view_newest_pm_first']) || !isset($lastData)) || empty($lastData) || !empty($pmID) && $pmID == $row['id_pm']) { $lastData = array('id' => $row['id_pm'], 'head' => $row['id_pm_head']); } } mysql_free_result($request); // Make sure that we have been given a correct head pm id! if ($context['display_mode'] == 2 && !empty($pmID) && $pmID != $lastData['id']) { fatal_lang_error('no_access', false); } if (!empty($pms)) { // Select the correct current message. if (empty($pmID)) { $context['current_pm'] = $lastData['id']; } // This is a list of the pm's that are used for "full" display. if ($context['display_mode'] == 0) { $display_pms = $pms; } else { $display_pms = array($context['current_pm']); } // At this point we know the main id_pm's. But - if we are looking at conversations we need the others! if ($context['display_mode'] == 2) { $request = smf_db_query(' SELECT pm.id_pm, pm.id_member_from, pm.deleted_by_sender, pmr.id_member, pmr.deleted 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 = {int:id_pm_head} AND ((pm.id_member_from = {int:current_member} AND pm.deleted_by_sender = {int:not_deleted}) OR (pmr.id_member = {int:current_member} AND pmr.deleted = {int:not_deleted})) ORDER BY pm.id_pm', array('current_member' => $user_info['id'], 'id_pm_head' => $lastData['head'], 'not_deleted' => 0)); while ($row = mysql_fetch_assoc($request)) { // This is, frankly, a joke. We will put in a workaround for people sending to themselves - yawn! if ($context['folder'] == 'sent' && $row['id_member_from'] == $user_info['id'] && $row['deleted_by_sender'] == 1) { continue; } elseif ($row['id_member'] == $user_info['id'] & $row['deleted'] == 1) { continue; } if (!isset($recipients[$row['id_pm']])) { $recipients[$row['id_pm']] = array('to' => array(), 'bcc' => array()); } $display_pms[] = $row['id_pm']; $posters[$row['id_pm']] = $row['id_member_from']; } mysql_free_result($request); } // This is pretty much EVERY pm! $all_pms = array_merge($pms, $display_pms); $all_pms = array_unique($all_pms); // Get recipients (don't include bcc-recipients for your inbox, you're not supposed to know :P). $request = smf_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:pm_list})', array('pm_list' => $all_pms)); $context['message_labels'] = array(); $context['message_replied'] = array(); $context['message_unread'] = array(); while ($row = mysql_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; $context['message_unread'][$row['id_pm']] = $row['is_read'] == 0; $row['labels'] = $row['labels'] == '' ? array() : explode(',', $row['labels']); 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']); } } } } mysql_free_result($request); // Make sure we don't load unnecessary data. if ($context['display_mode'] == 1) { foreach ($posters as $k => $v) { if (!in_array($k, $display_pms)) { unset($posters[$k]); } } } // Load any users.... $posters = array_unique($posters); if (!empty($posters)) { loadMemberData($posters); } // If we're on grouped/restricted view get a restricted list of messages. if ($context['display_mode'] != 0) { // Get the order right. $orderBy = array(); foreach (array_reverse($pms) as $pm) { $orderBy[] = 'pm.id_pm = ' . $pm; } // Seperate query for these bits! $subjects_request = smf_db_query(' SELECT pm.id_pm, pm.subject, pm.id_member_from, pm.msgtime, IFNULL(mem.real_name, pm.from_name) AS from_name, IFNULL(mem.id_member, 0) AS not_guest FROM {db_prefix}personal_messages AS pm LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from) WHERE pm.id_pm IN ({array_int:pm_list}) ORDER BY ' . implode(', ', $orderBy) . ' LIMIT ' . count($pms), array('pm_list' => $pms)); } // Execute the query! $messages_request = smf_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' . ($context['folder'] == 'sent' ? ' LEFT JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm)' : '') . ($context['sort_by'] == 'name' ? ' LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = {raw:id_member})' : '') . ' WHERE pm.id_pm IN ({array_int:display_pms})' . ($context['folder'] == 'sent' ? ' GROUP BY pm.id_pm, pm.subject, pm.id_member_from, pm.body, pm.msgtime, pm.from_name' : '') . ' ORDER BY ' . ($context['display_mode'] == 2 ? 'pm.id_pm' : $_GET['sort']) . ($descending ? ' DESC' : ' ASC') . ' LIMIT ' . count($display_pms), array('display_pms' => $display_pms, 'id_member' => $context['folder'] == 'sent' ? 'pmr.id_member' : 'pm.id_member_from')); } else { $messages_request = false; } $context['can_send_pm'] = allowedTo('pm_send'); $context['page_title'] = $txt['pm_inbox']; if (isset($context['current_pm'])) { $context['conversation_buttons'] = array('reply' => array('text' => 'reply_to_all', 'image' => 'reply.gif', 'lang' => true, 'url' => $scripturl . '?action=pm;sa=send;f=' . $context['folder'] . ($context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '') . ';pmsg=' . $context['current_pm'] . ';u=all', 'active' => true), 'delete' => array('text' => 'delete_conversation', 'image' => 'delete.gif', 'lang' => true, 'url' => $scripturl . '?action=pm;sa=pmactions;pm_actions[' . $context['current_pm'] . ']=delete;conversation;f=' . $context['folder'] . ';start=' . $context['start'] . ($context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '') . ';' . $context['session_var'] . '=' . $context['session_id'], 'custom' => 'onclick="return confirm(\'' . addslashes($txt['remove_message']) . '?\');"')); } else { $context['conversation_buttons'] = array(); } // Finally mark the relevant messages as read. if ($context['folder'] != 'sent' && !empty($context['labels'][(int) $context['current_label_id']]['unread_messages'])) { // If the display mode is "old sk00l" do them all... if ($context['display_mode'] == 0) { markMessages(null, $context['current_label_id']); } elseif (!empty($context['current_pm'])) { markMessages($display_pms, $context['current_label_id']); } } }
/** * @param $users array member_id or array of member_ids * @param $id_act int id of the activity to send as notification * @param $id_type int (type of notification) * * this takes a single id_member or an array of such ids plus an activity id * and sends out notifications to the members. * respects members.notify_optout to skip members who do not want to see notifications of $id_type */ function aStreamAddNotification(&$users, $id_act, $id_type) { global $user_profile; if ((int) $id_act && (int) $id_type) { $my_users = !is_array($users) ? array($users) : array_unique($users); loadMemberData($my_users, false, 'minimal'); $members_to_update = array(); $values = array(); foreach ($my_users as $user) { if ((int) $user) { $optout = isset($user_profile[$user]) && !empty($user_profile[$user]['notify_optout']) ? explode(',', $user_profile[$user]['notify_optout']) : array(0); if (isset($user_profile[$user]) && false === in_array((int) $id_type, $optout)) { $values[] = '(' . (int) $user . ', ' . (int) $id_act . ')'; $members_to_update[] = $user; } } } if (count($values)) { $q = 'INSERT INTO {db_prefix}log_notifications (id_member, id_act) VALUES ' . implode(',', $values); smf_db_query($q); invalidateMemberData($members_to_update); } } }
function updateMemberData($members, $data) { global $modSettings, $user_info; $parameters = array(); if (is_array($members)) { $condition = 'id_member IN ({array_int:members})'; $parameters['members'] = $members; } elseif ($members === null) { $condition = '1=1'; } else { $condition = 'id_member = {int:member}'; $parameters['member'] = $members; } if (!empty($modSettings['integrate_change_member_data'])) { // Only a few member variables are really interesting for integration. $integration_vars = array('member_name', 'real_name', 'email_address', 'id_group', 'gender', 'birthdate', 'location', 'hide_email', 'time_format', 'time_offset', 'avatar', 'lngfile'); $vars_to_integrate = array_intersect($integration_vars, array_keys($data)); // Only proceed if there are any variables left to call the integration function. if (count($vars_to_integrate) != 0) { // Fetch a list of member_names if necessary if (!is_array($members) && $members === $user_info['id'] || is_array($members) && count($members) == 1 && in_array($user_info['id'], $members)) { $member_names = array($user_info['username']); } else { $member_names = array(); $request = smf_db_query(' SELECT member_name FROM {db_prefix}members WHERE ' . $condition, $parameters); while ($row = mysql_fetch_assoc($request)) { $member_names[] = $row['member_name']; } mysql_free_result($request); } if (!empty($member_names)) { foreach ($vars_to_integrate as $var) { HookAPI::callHook('integrate_change_member_data', array($member_names, $var, $data[$var])); } } } } // Everything is assumed to be a string unless it's in the below. $knownInts = array('date_registered', 'posts', 'id_group', 'last_login', 'instant_messages', 'unread_messages', 'new_pm', 'pm_prefs', 'gender', 'hide_email', 'show_online', 'pm_email_notify', 'pm_receive_from', 'karma_good', 'karma_bad', 'notify_announcements', 'notify_send_body', 'notify_regularity', 'notify_types', 'id_theme', 'is_activated', 'id_msg_last_visit', 'id_post_group', 'total_time_logged_in', 'warning'); $knownFloats = array('time_offset'); $setString = ''; foreach ($data as $var => $val) { $type = 'string'; if (in_array($var, $knownInts)) { $type = 'int'; } elseif (in_array($var, $knownFloats)) { $type = 'float'; } elseif ($var == 'birthdate') { $type = 'date'; } // Doing an increment? if ($type == 'int' && ($val === '+' || $val === '-')) { $val = $var . ' ' . $val . ' 1'; $type = 'raw'; } // Ensure posts, instant_messages, and unread_messages don't overflow or underflow. if (in_array($var, array('posts', 'instant_messages', 'unread_messages'))) { if (preg_match('~^' . $var . ' (\\+ |- |\\+ -)([\\d]+)~', $val, $match)) { if ($match[1] != '+ ') { $val = 'CASE WHEN ' . $var . ' <= ' . abs($match[2]) . ' THEN 0 ELSE ' . $val . ' END'; } $type = 'raw'; } } $setString .= ' ' . $var . ' = {' . $type . ':p_' . $var . '},'; $parameters['p_' . $var] = $val; } smf_db_query(' UPDATE {db_prefix}members SET' . substr($setString, 0, -1) . ' WHERE ' . $condition, $parameters); updateStats('postgroups', $members, array_keys($data)); // Clear any caching? invalidateMemberData($members); }