/** * Completely rebuild the counters for a particular thread (useful if they become out of sync) * * @param int The thread ID */ function rebuild_thread_counters($tid) { global $db; $thread = get_thread($tid); $count = array(); $query = $db->simple_select("posts", "COUNT(pid) AS replies", "tid='{$tid}' AND pid!='{$thread['firstpost']}' AND visible='1'"); $count['replies'] = $db->fetch_field($query, "replies"); // Unapproved posts $query = $db->simple_select("posts", "COUNT(pid) AS unapprovedposts", "tid='{$tid}' AND pid != '{$thread['firstpost']}' AND visible='0'"); $count['unapprovedposts'] = $db->fetch_field($query, "unapprovedposts"); // Soft deleted posts $query = $db->simple_select("posts", "COUNT(pid) AS deletedposts", "tid='{$tid}' AND pid != '{$thread['firstpost']}' AND visible='-1'"); $count['deletedposts'] = $db->fetch_field($query, "deletedposts"); // Attachment count $query = $db->query("\n\t\t\tSELECT COUNT(aid) AS attachment_count\n\t\t\tFROM " . TABLE_PREFIX . "attachments a\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "posts p ON (a.pid=p.pid)\n\t\t\tWHERE p.tid='{$tid}' AND a.visible=1\n\t"); $count['attachmentcount'] = $db->fetch_field($query, "attachment_count"); update_thread_counters($tid, $count); update_thread_data($tid); }
/** * Updates the thread counters with a specific value (or addition/subtraction of the previous value) * * @param int The thread ID * @param array Array of items being updated (replies, unapprovedposts, attachmentcount) and their value (ex, 1, +1, -1) */ function update_thread_counters($tid, $changes = array()) { global $db; $update_query = array(); $counters = array('replies', 'unapprovedposts', 'attachmentcount', 'attachmentcount'); // Fetch above counters for this thread $query = $db->simple_select("threads", implode(",", $counters), "tid='{$tid}'"); $thread = $db->fetch_array($query); foreach ($counters as $counter) { if (array_key_exists($counter, $changes)) { // Adding or subtracting from previous value? if (substr($changes[$counter], 0, 1) == "+" || substr($changes[$counter], 0, 1) == "-") { $update_query[$counter] = $thread[$counter] + $changes[$counter]; } else { $update_query[$counter] = $changes[$counter]; } // Less than 0? That's bad if ($update_query[$counter] < 0) { $update_query[$counter] = 0; } } } $db->free_result($query); // Only update if we're actually doing something if (count($update_query) > 0) { $db->update_query("threads", $update_query, "tid='" . intval($tid) . "'"); } unset($update_query, $thread); update_thread_data($tid); }
/** * Move/copy thread * * @param int $tid Thread to be moved * @param int $new_fid Destination forum * @param string $method Method of movement (redirect, copy, move) * @param int $redirect_expire Expiry timestamp for redirect * @return int Thread ID */ function move_thread($tid, $new_fid, $method = "redirect", $redirect_expire = 0) { global $db, $plugins; // Get thread info $tid = (int) $tid; $new_fid = (int) $new_fid; $redirect_expire = (int) $redirect_expire; $thread = get_thread($tid, true); $newforum = get_forum($new_fid); if (!$thread || !$newforum) { return false; } $fid = $thread['fid']; $forum = get_forum($fid); $num_threads = $num_unapproved_threads = $num_posts = $num_unapproved_posts = $num_deleted_posts = $num_deleted_threads = 0; if ($thread['visible'] == 1) { $num_threads++; $num_posts = $thread['replies'] + 1; $num_unapproved_posts = $thread['unapprovedposts']; $num_deleted_posts = $thread['deletedposts']; } elseif ($thread['visible'] == -1) { $num_deleted_threads++; // Implied forum deleted count for deleted threads $num_deleted_posts = $thread['replies'] + $thread['deletedposts'] + $thread['unapprovedposts'] + 1; } else { $num_unapproved_threads++; // Implied forum unapproved count for unapproved threads $num_unapproved_posts = $thread['replies'] + $thread['unapprovedposts'] + $thread['deletedposts'] + 1; } switch ($method) { case "redirect": // move (and leave redirect) thread $arguments = array("tid" => $tid, "new_fid" => $new_fid); $plugins->run_hooks("class_moderation_move_thread_redirect", $arguments); $query = $db->simple_select('threads', 'tid', "closed='moved|{$tid}' AND fid='{$new_fid}'"); while ($redirect_tid = $db->fetch_field($query, 'tid')) { $this->delete_thread($redirect_tid); } $changefid = array("fid" => $new_fid); $db->update_query("threads", $changefid, "tid='{$tid}'"); $db->update_query("posts", $changefid, "tid='{$tid}'"); // If the thread has a prefix and the destination forum doesn't accept that prefix, remove the prefix if ($thread['prefix'] != 0) { switch ($db->type) { case "pgsql": case "sqlite": $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(','||forums||',' LIKE '%,{$new_fid},%' OR forums='-1') AND pid='" . $thread['prefix'] . "'"); break; default: $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,{$new_fid},%' OR forums='-1') AND pid='" . $thread['prefix'] . "'"); } if ($db->fetch_field($query, "num_prefixes") == 0) { $sqlarray = array("prefix" => 0); $db->update_query("threads", $sqlarray, "tid='{$tid}'"); } } $threadarray = array("fid" => $thread['fid'], "subject" => $db->escape_string($thread['subject']), "icon" => $thread['icon'], "uid" => $thread['uid'], "username" => $db->escape_string($thread['username']), "dateline" => $thread['dateline'], "lastpost" => $thread['lastpost'], "lastposteruid" => $thread['lastposteruid'], "lastposter" => $db->escape_string($thread['lastposter']), "views" => 0, "replies" => 0, "closed" => "moved|{$tid}", "sticky" => $thread['sticky'], "visible" => (int) $thread['visible'], "notes" => ''); $redirect_tid = $db->insert_query("threads", $threadarray); if ($redirect_expire) { $this->expire_thread($redirect_tid, $redirect_expire); } // If we're moving back to a forum where we left a redirect, delete the rediect $query = $db->simple_select("threads", "tid", "closed LIKE 'moved|" . (int) $tid . "' AND fid='" . (int) $new_fid . "'"); while ($redirect_tid = $db->fetch_field($query, 'tid')) { $this->delete_thread($redirect_tid); } break; case "copy": // copy thread $threadarray = array("fid" => $new_fid, "subject" => $db->escape_string($thread['subject']), "icon" => $thread['icon'], "uid" => $thread['uid'], "username" => $db->escape_string($thread['username']), "dateline" => $thread['dateline'], "firstpost" => 0, "lastpost" => $thread['lastpost'], "lastposteruid" => $thread['lastposteruid'], "lastposter" => $db->escape_string($thread['lastposter']), "views" => $thread['views'], "replies" => $thread['replies'], "closed" => $thread['closed'], "sticky" => $thread['sticky'], "visible" => (int) $thread['visible'], "unapprovedposts" => $thread['unapprovedposts'], "deletedposts" => $thread['deletedposts'], "attachmentcount" => $thread['attachmentcount'], "prefix" => $thread['prefix'], "notes" => ''); $arguments = array("tid" => $tid, "new_fid" => $new_fid); $plugins->run_hooks("class_moderation_copy_thread", $arguments); // If the thread has a prefix and the destination forum doesn't accept that prefix, don't copy the prefix if ($threadarray['prefix'] != 0) { switch ($db->type) { case "pgsql": case "sqlite": $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(','||forums||',' LIKE '%,{$new_fid},%' OR forums='-1') AND pid='" . $thread['prefix'] . "'"); break; default: $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,{$new_fid},%' OR forums='-1') AND pid='" . $thread['prefix'] . "'"); } if ($db->fetch_field($query, "num_prefixes") == 0) { $threadarray['prefix'] = 0; } } $newtid = $db->insert_query("threads", $threadarray); if ($thread['poll'] != 0) { $query = $db->simple_select("polls", "*", "tid = '{$thread['tid']}'"); $poll = $db->fetch_array($query); $poll_array = array('tid' => $newtid, 'question' => $db->escape_string($poll['question']), 'dateline' => $poll['dateline'], 'options' => $db->escape_string($poll['options']), 'votes' => $poll['votes'], 'numoptions' => $poll['numoptions'], 'numvotes' => $poll['numvotes'], 'timeout' => $poll['timeout'], 'closed' => $poll['closed'], 'multiple' => $poll['multiple'], 'public' => $poll['public']); $new_pid = $db->insert_query("polls", $poll_array); $query = $db->simple_select("pollvotes", "*", "pid = '{$poll['pid']}'"); while ($pollvote = $db->fetch_array($query)) { $pollvote_array = array('pid' => $new_pid, 'uid' => $pollvote['uid'], 'voteoption' => $pollvote['voteoption'], 'dateline' => $pollvote['dateline']); $db->insert_query("pollvotes", $pollvote_array); } $db->update_query("threads", array('poll' => $new_pid), "tid='{$newtid}'"); } $query = $db->simple_select("posts", "*", "tid = '{$thread['tid']}'"); while ($post = $db->fetch_array($query)) { $post_array = array('tid' => $newtid, 'fid' => $new_fid, 'subject' => $db->escape_string($post['subject']), 'icon' => $post['icon'], 'uid' => $post['uid'], 'username' => $db->escape_string($post['username']), 'dateline' => $post['dateline'], 'ipaddress' => $db->escape_binary($post['ipaddress']), 'includesig' => $post['includesig'], 'smilieoff' => $post['smilieoff'], 'edituid' => $post['edituid'], 'edittime' => $post['edittime'], 'visible' => $post['visible'], 'message' => $db->escape_string($post['message'])); $pid = $db->insert_query("posts", $post_array); // Properly set our new firstpost in our new thread if ($thread['firstpost'] == $post['pid']) { $db->update_query("threads", array('firstpost' => $pid), "tid='{$newtid}'"); } // Insert attachments for this post $query2 = $db->simple_select("attachments", "*", "pid = '{$post['pid']}'"); while ($attachment = $db->fetch_array($query2)) { $attachment_array = array('pid' => $pid, 'uid' => $attachment['uid'], 'filename' => $db->escape_string($attachment['filename']), 'filetype' => $attachment['filetype'], 'filesize' => $attachment['filesize'], 'attachname' => $attachment['attachname'], 'downloads' => $attachment['downloads'], 'visible' => $attachment['visible'], 'thumbnail' => $attachment['thumbnail']); $new_aid = $db->insert_query("attachments", $attachment_array); $post['message'] = str_replace("[attachment={$attachment['aid']}]", "[attachment={$new_aid}]", $post['message']); } if (strpos($post['message'], "[attachment=") !== false) { $db->update_query("posts", array('message' => $db->escape_string($post['message'])), "pid='{$pid}'"); } } update_thread_data($newtid); $the_thread = $newtid; break; default: case "move": // plain move thread $arguments = array("tid" => $tid, "new_fid" => $new_fid); $plugins->run_hooks("class_moderation_move_simple", $arguments); $sqlarray = array("fid" => $new_fid); $db->update_query("threads", $sqlarray, "tid='{$tid}'"); $db->update_query("posts", $sqlarray, "tid='{$tid}'"); // If the thread has a prefix and the destination forum doesn't accept that prefix, remove the prefix if ($thread['prefix'] != 0) { switch ($db->type) { case "pgsql": case "sqlite": $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(','||forums||',' LIKE '%,{$new_fid},%' OR forums='-1') AND pid='" . $thread['prefix'] . "'"); break; default: $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,{$new_fid},%' OR forums='-1') AND pid='" . $thread['prefix'] . "'"); } if ($db->fetch_field($query, "num_prefixes") == 0) { $sqlarray = array("prefix" => 0); $db->update_query("threads", $sqlarray, "tid='{$tid}'"); } } // If we're moving back to a forum where we left a redirect, delete the rediect $query = $db->simple_select("threads", "tid", "closed LIKE 'moved|" . (int) $tid . "' AND fid='" . (int) $new_fid . "'"); while ($redirect_tid = $db->fetch_field($query, 'tid')) { $this->delete_thread($redirect_tid); } break; } // Do post and thread count changes if changing between countable and non-countable forums $query = $db->query("\n\t\t\tSELECT COUNT(p.pid) AS posts, u.uid\n\t\t\tFROM " . TABLE_PREFIX . "posts p\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "users u ON (u.uid=p.uid)\n\t\t\tWHERE p.tid='{$tid}' AND p.visible=1\n\t\t\tGROUP BY u.uid\n\t\t\tORDER BY posts DESC\n\t\t"); while ($posters = $db->fetch_array($query)) { $pcount = 0; if ($forum['usepostcounts'] == 1 && $method != 'copy' && $newforum['usepostcounts'] == 0 && $thread['visible'] == 1) { $pcount -= $posters['posts']; } if (($forum['usepostcounts'] == 0 || $method == 'copy') && $newforum['usepostcounts'] == 1 && $thread['visible'] == 1) { $pcount += $posters['posts']; } if ($pcount > 0) { update_user_counters($posters['uid'], array('postnum' => "+{$pcount}")); } elseif ($pcount < 0) { update_user_counters($posters['uid'], array('postnum' => $pcount)); } } if ($forum['usethreadcounts'] == 1 && $method != 'copy' && $newforum['usethreadcounts'] == 0 && $thread['visible'] == 1) { update_user_counters($thread['uid'], array('threadnum' => "-1")); } elseif (($forum['usethreadcounts'] == 0 || $method == 'copy') && $newforum['usethreadcounts'] == 1 && $thread['visible'] == 1) { update_user_counters($thread['uid'], array('threadnum' => "+1")); } // Update forum counts $update_array = array("threads" => "+{$num_threads}", "unapprovedthreads" => "+{$num_unapproved_threads}", "posts" => "+{$num_posts}", "unapprovedposts" => "+{$num_unapproved_posts}", "deletedthreads" => "+{$num_deleted_threads}", "deletedposts" => "+{$num_deleted_posts}"); update_forum_counters($new_fid, $update_array); update_forum_lastpost($new_fid); if ($method != "copy") { // The redirect needs to be counted, too if ($method == "redirect") { if ($thread['visible'] == -1) { --$num_deleted_threads; --$num_deleted_posts; } elseif ($thread['visible'] == 0) { --$num_unapproved_threads; --$num_unapproved_posts; } else { --$num_threads; --$num_posts; } } $update_array = array("threads" => "-{$num_threads}", "unapprovedthreads" => "-{$num_unapproved_threads}", "posts" => "-{$num_posts}", "unapprovedposts" => "-{$num_unapproved_posts}", "deletedthreads" => "-{$num_deleted_threads}", "deletedposts" => "-{$num_deleted_posts}"); update_forum_counters($fid, $update_array); update_forum_lastpost($fid); } if (isset($newtid)) { return $newtid; } else { // Remove thread subscriptions for the users who no longer have permission to view the thread $this->remove_thread_subscriptions($tid, false, $new_fid); return $tid; } }
/** * Unapprove multiple posts * * @param array PIDs * @return boolean true */ function unapprove_posts($pids) { global $db, $cache; // Make sure we only have valid values $pids = array_map('intval', $pids); $pid_list = implode(',', $pids); $pids = $threads_to_update = array(); // Make invisible $approve = array("visible" => 0); // We have three cases we deal with in these code segments: // 1) We're unapproving specific approved posts // 1.1) if the thread is approved // 1.2) if the thread is unapproved // 2) We're unapproving the firstpost of the thread, therefore unapproving the thread itself // 3) We're doing both 1 and 2 $query = $db->query("\n\t\t\tSELECT p.tid\n\t\t\tFROM " . TABLE_PREFIX . "posts p\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "threads t ON (t.tid=p.tid)\n\t\t\tWHERE p.pid IN ({$pid_list}) AND p.visible = '1' AND t.firstpost = p.pid AND t.visible = 1\n\t\t"); while ($post = $db->fetch_array($query)) { // This is the first post in the thread so we're unapproving the whole thread. $threads_to_update[] = $post['tid']; } if (!empty($threads_to_update)) { $this->unapprove_threads($threads_to_update); } $thread_counters = array(); $forum_counters = array(); $query = $db->query("\n\t\t\tSELECT p.pid, p.tid, f.fid, f.usepostcounts, p.uid, t.visible AS threadvisible\n\t\t\tFROM " . TABLE_PREFIX . "posts p\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "threads t ON (t.tid=p.tid)\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "forums f ON (f.fid=p.fid)\n\t\t\tWHERE p.pid IN ({$pid_list}) AND p.visible = '1' AND t.firstpost != p.pid\n\t\t"); while ($post = $db->fetch_array($query)) { $pids[] = $post['pid']; ++$thread_counters[$post['tid']]['unapprovedposts']; ++$thread_counters[$post['tid']]['replies']; // If the thread of this post is unapproved then we've already taken into account this counter as implied. // Updating it again would cause it to double count if ($post['threadvisible'] != 0) { ++$forum_counters[$post['fid']]['num_posts']; } // If post counts enabled in this forum and the thread is approved, subtract 1 if ($post['usepostcounts'] != 0 && $post['threadvisible'] == 1) { $db->update_query("users", array("postnum" => "postnum-1"), "uid='{$post['uid']}'", 1, true); } } if (empty($pids) && empty($threads_to_update)) { return false; } if (!empty($pids)) { $where = "pid IN (" . implode(',', $pids) . ")"; $db->update_query("posts", $approve, $where); } if (is_array($thread_counters)) { foreach ($thread_counters as $tid => $counters) { $counters_update = array("unapprovedposts" => "+" . $counters['unapprovedposts'], "replies" => "-" . $counters['replies']); update_thread_counters($tid, $counters_update); update_thread_data($tid); } } if (is_array($forum_counters)) { foreach ($forum_counters as $fid => $counters) { $updated_forum_stats = array("posts" => "-{$counters['num_posts']}", "unapprovedposts" => "+{$counters['num_posts']}", "threads" => "-{$counters['num_threads']}", "unapprovedthreads" => "+{$counters['num_threads']}"); update_forum_counters($fid, $updated_forum_stats); } } return true; }
/** * Updates a post that is already in the database. * */ function update_post() { global $db, $mybb, $plugins; // Yes, validating is required. if ($this->get_validated() != true) { die("The post needs to be validated before inserting it into the DB."); } if (count($this->get_errors()) > 0) { die("The post is not valid."); } $post =& $this->data; $post['pid'] = intval($post['pid']); $existing_post = get_post($post['pid']); $post['tid'] = $existing_post['tid']; $post['fid'] = $existing_post['fid']; $forum = get_forum($post['fid']); // Decide on the visibility of this post. if (isset($post['visible']) && $post['visible'] != $existing_post['visible']) { if ($forum['mod_edit_posts'] == 1 && !is_moderator($post['fid'], "", $post['uid'])) { if ($existing_post['visible'] == 1) { update_thread_data($existing_post['tid']); update_thread_counters($existing_post['tid'], array('replies' => '-1', 'unapprovedposts' => '+1')); update_forum_counters($existing_post['fid'], array('unapprovedthreads' => '+1', 'unapprovedposts' => '+1')); // Subtract from the users post count // Update the post count if this forum allows post counts to be tracked if ($forum['usepostcounts'] != 0) { $db->write_query("UPDATE " . TABLE_PREFIX . "users SET postnum=postnum-1 WHERE uid='{$existing_post['uid']}'"); } } $visible = 0; } else { if ($existing_post['visible'] == 0) { update_thread_data($existing_post['tid']); update_thread_counters($existing_post['tid'], array('replies' => '+1', 'unapprovedposts' => '-1')); update_forum_counters($existing_post['fid'], array('unapprovedthreads' => '-1', 'unapprovedposts' => '-1')); // Update the post count if this forum allows post counts to be tracked if ($forum['usepostcounts'] != 0) { $db->write_query("UPDATE " . TABLE_PREFIX . "users SET postnum=postnum+1 WHERE uid='{$existing_post['uid']}'"); } } $visible = 1; } } else { $visible = 0; if ($forum['mod_edit_posts'] != 1 || is_moderator($post['fid'], "", $post['uid'])) { $visible = 1; } } // Check if this is the first post in a thread. $options = array("order_by" => "dateline", "order_dir" => "asc", "limit_start" => 0, "limit" => 1); $query = $db->simple_select("posts", "pid", "tid='" . intval($post['tid']) . "'", $options); $first_post_check = $db->fetch_array($query); if ($first_post_check['pid'] == $post['pid']) { $first_post = true; } else { $first_post = false; } if ($existing_post['visible'] == 0) { $visible = 0; } // Update the thread details that might have been changed first. if ($first_post) { $this->tid = $post['tid']; $this->thread_update_data['visible'] = $visible; if (isset($post['prefix'])) { $this->thread_update_data['prefix'] = intval($post['prefix']); } if (isset($post['subject'])) { $this->thread_update_data['subject'] = $db->escape_string($post['subject']); } if (isset($post['icon'])) { $this->thread_update_data['icon'] = intval($post['icon']); } if (count($this->thread_update_data) > 0) { $plugins->run_hooks("datahandler_post_update_thread", $this); $db->update_query("threads", $this->thread_update_data, "tid='" . intval($post['tid']) . "'"); } } // Prepare array for post updating. $this->pid = $post['pid']; if (isset($post['subject'])) { $this->post_update_data['subject'] = $db->escape_string($post['subject']); } if (isset($post['message'])) { $this->post_update_data['message'] = $db->escape_string($post['message']); } if (isset($post['icon'])) { $this->post_update_data['icon'] = intval($post['icon']); } if (isset($post['options'])) { if (isset($post['options']['disablesmilies'])) { $this->post_update_data['smilieoff'] = $db->escape_string($post['options']['disablesmilies']); } if (isset($post['options']['signature'])) { $this->post_update_data['includesig'] = $db->escape_string($post['options']['signature']); } } // If we need to show the edited by, let's do so. if ($mybb->settings['showeditedby'] == 1 && !is_moderator($post['fid'], "caneditposts", $post['edit_uid']) || $mybb->settings['showeditedbyadmin'] == 1 && is_moderator($post['fid'], "caneditposts", $post['edit_uid'])) { $this->post_update_data['edituid'] = intval($post['edit_uid']); $this->post_update_data['edittime'] = TIME_NOW; } $this->post_update_data['visible'] = $visible; $plugins->run_hooks("datahandler_post_update", $this); $db->update_query("posts", $this->post_update_data, "pid='" . intval($post['pid']) . "'"); // Automatic subscription to the thread if ($post['options']['subscriptionmethod'] != "" && $post['uid'] > 0) { switch ($post['options']['subscriptionmethod']) { case "instant": $notification = 1; break; default: $notification = 0; } require_once MYBB_ROOT . "inc/functions_user.php"; add_subscribed_thread($post['tid'], $notification, $post['uid']); } else { $db->delete_query("threadsubscriptions", "uid='" . intval($post['uid']) . "' AND tid='" . intval($post['tid']) . "'"); } update_forum_lastpost($post['fid']); return array('visible' => $visible, 'first_post' => $first_post); }
/** * Unapprove multiple posts * * @param array PIDs * @return boolean true */ function unapprove_posts($pids) { global $db, $cache; // Make sure we only have valid values $pids = array_map('intval', $pids); $pid_list = implode(',', $pids); $pids = $threads_to_update = array(); // Make invisible $approve = array("visible" => 0); $query = $db->query("\n\t\t\tSELECT p.pid, p.tid, f.fid, f.usepostcounts, p.uid, p.visible, t.visible AS threadvisible, t.replies AS threadreplies, t.firstpost AS threadfirstpost, t.unapprovedposts AS threadunapprovedposts\n\t\t\tFROM " . TABLE_PREFIX . "posts p\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "threads t ON (t.tid=p.tid)\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "forums f ON (f.fid=p.fid)\n\t\t\tWHERE p.pid IN ({$pid_list}) AND p.visible = '1'\n\t\t"); while ($post = $db->fetch_array($query)) { if ($post['threadfirstpost'] == $post['pid'] && $post['threadvisible'] == 1) { $threads_to_update[] = $post['tid']; } if (in_array($post['tid'], $threads_to_update)) { continue; } // If post counts enabled in this forum and the post hasn't already been unapproved, subtract 1 if ($post['usepostcounts'] != 0 && $post['threadvisible'] == 1) { $db->write_query("UPDATE " . TABLE_PREFIX . "users SET postnum=postnum-1 WHERE uid='" . $post['uid'] . "'"); } $pids[] = $post['pid']; if (!$thread_counters[$post['tid']]['unapprovedposts']) { $thread_counters[$post['tid']]['unapprovedposts'] = $post['threadunapprovedposts']; } ++$thread_counters[$post['tid']]['unapprovedposts']; if ($post['threadfirstpost'] != $post['pid']) { if (!$thread_counters[$post['tid']]['replies']) { $thread_counters[$post['tid']]['replies'] = $post['threadreplies']; } $thread_counters[$post['tid']]['replies'] = $thread_counters[$post['tid']]['replies'] - 1; } if ($post['threadvisible'] == 1) { ++$forum_counters[$post['fid']]['num_posts']; } } if (!empty($threads_to_update)) { $this->unapprove_threads($threads_to_update); } if (!count($pids)) { return false; } $where = "pid IN (" . implode(',', $pids) . ")"; $db->update_query("posts", $approve, $where); if (is_array($thread_counters)) { foreach ($thread_counters as $tid => $counters) { $db->update_query("threads", $counters, "tid='{$tid}'"); update_thread_data($tid); } } if (is_array($forum_counters)) { foreach ($forum_counters as $fid => $counters) { $updated_forum_stats = array("posts" => "-{$counters['num_posts']}", "unapprovedposts" => "+{$counters['num_posts']}", "threads" => "-{$counters['num_threads']}", "unapprovedthreads" => "+{$counters['num_threads']}"); update_forum_counters($fid, $updated_forum_stats); } } return true; }
/** * Changes the author of the post. * * */ function accountswitcher_author_change() { global $mybb, $db, $eas; // Change action if ($mybb->input['action'] == "do_author" && $mybb->request_method == "post" && ($mybb->settings['aj_changeauthor'] == 1 || $mybb->settings['aj_admin_changeauthor'] == 1)) { // Verify incoming POST request verify_post_check($mybb->get_input('my_post_key')); // Get the current author of the post $pid = $mybb->get_input('pid', MyBB::INPUT_INT); $post = get_post($pid); $tid = (int) $post['tid']; $forum = get_forum($post['fid']); // Get the new user if (is_numeric($mybb->input['authorswitch'])) { // Input is uid from change author $newuid = $mybb->get_input('authorswitch', MyBB::INPUT_INT); $newauthor = get_user($newuid); } else { // Input is username from author moderation $newname = htmlspecialchars_uni($mybb->get_input('authorswitch')); $newauthor = get_user_by_username($newname); $newauthor = get_user((int) $newauthor['uid']); } // New user doesn't exist? Redirect back to the post without changes if ($newauthor['uid'] == 0) { redirect(htmlentities($_POST['p_link'])); return; } // Subtract from the users post count // Update the post count if this forum allows post counts to be tracked if ($forum['usepostcounts'] != 0) { $db->write_query("UPDATE " . TABLE_PREFIX . "users SET postnum=postnum-1 WHERE uid='" . (int) $post['uid'] . "'"); $db->write_query("UPDATE " . TABLE_PREFIX . "users SET postnum=postnum+1 WHERE uid='" . (int) $newauthor['uid'] . "'"); } $updated_record = array("uid" => (int) $newauthor['uid'], "username" => $db->escape_string($newauthor['username'])); if ($db->update_query("posts", $updated_record, "pid='" . (int) $post['pid'] . "'")) { global $lang; if (!isset($lang->aj_author_change_log)) { $lang->load("accountswitcher"); } // Update first/last post info, log moderator action, redirect back to the post update_thread_data($tid); update_forum_lastpost((int) $post['fid']); $lang->aj_author_change_log = $lang->sprintf($lang->aj_author_change_log, (int) $post['pid'], htmlspecialchars_uni($post['username']), htmlspecialchars_uni($newauthor['username'])); log_moderator_action(array("pid" => $post['pid']), $lang->aj_author_change_log); // Send pm to old and new author after moderation if ($post['uid'] != $mybb->user['uid'] && $mybb->settings['aj_admin_changeauthor'] == 1) { if ($mybb->settings['aj_authorpm'] == 1) { // Send PM require_once MYBB_ROOT . "inc/datahandlers/pm.php"; $pmhandler = new PMDataHandler(); $lang->aj_author_change_pm_body = $lang->sprintf($lang->aj_author_change_pm_body, htmlspecialchars_uni($mybb->user['username']), $mybb->settings['bburl'] . '/' . htmlentities($_POST['p_link']), htmlspecialchars_uni($post['subject']), htmlspecialchars_uni($post['username']), htmlspecialchars_uni($newauthor['username'])); $subject = $lang->aj_author_change_pm_subject; $body = $lang->aj_author_change_pm_body; $pm = array('subject' => $subject, 'message' => $body, 'icon' => '', 'toid' => array($post['uid'], $newauthor['uid']), 'fromid' => $mybb->user['uid'], "do" => '', "pmid" => ''); $pm['options'] = array('signature' => '0', 'savecopy' => '0', 'disablesmilies' => '0', 'readreceipt' => '0'); $pmhandler->set_data($pm); $valid_pm = $pmhandler->validate_pm(); if ($valid_pm) { $pmhandler->insert_pm(); } } // Show alert if ($mybb->settings['aj_myalerts'] == 1 && isset($mybb->user['myalerts_disabled_alert_types'])) { $alertType = MybbStuff_MyAlerts_AlertTypeManager::getInstance()->getByCode('accountswitcher_author'); $alerts = array(); $subject = htmlspecialchars_uni($post['subject']); $alert_old = new MybbStuff_MyAlerts_Entity_Alert((int) $post['uid'], $alertType, $tid); $alert_old->setExtraDetails(array('thread_title' => $subject, 'pid' => $pid, 'tid' => $tid, 'olduser' => htmlspecialchars_uni($post['username']), 'newuser' => htmlspecialchars_uni($newauthor['username']))); $alerts[] = $alert_old; $alert_new = new MybbStuff_MyAlerts_Entity_Alert((int) $newauthor['uid'], $alertType, $tid); $alert_new->setExtraDetails(array('thread_title' => $subject, 'pid' => $pid, 'tid' => $tid, 'olduser' => htmlspecialchars_uni($post['username']), 'newuser' => htmlspecialchars_uni($newauthor['username']))); $alerts[] = $alert_new; if (!empty($alerts)) { MybbStuff_MyAlerts_AlertManager::getInstance()->addAlerts($alerts); } } } $eas->update_accountswitcher_cache(); redirect(htmlentities($_POST['p_link'])); } } else { return; } }