/** * Completely rebuild the counters for a particular forum (useful if they become out of sync) */ function rebuild_forum_counters($fid) { global $db; // Fetch the number of threads and replies in this forum (Approved only) $query = $db->query("\n\t\tSELECT COUNT(tid) AS threads, SUM(replies) AS replies\n\t\tFROM " . TABLE_PREFIX . "threads\n\t\tWHERE fid='{$fid}' AND visible='1' AND closed\tNOT LIKE 'moved|%'\n\t"); $count = $db->fetch_array($query); $count['posts'] = $count['threads'] + $count['replies']; if (!$count['posts']) { $count['posts'] = 0; } // Fetch the number of threads and replies in this forum (Unapproved only) $query = $db->query("\n\t\tSELECT COUNT(tid) AS threads, SUM(replies) AS impliedunapproved\n\t\tFROM " . TABLE_PREFIX . "threads\n\t\tWHERE fid='{$fid}' AND visible='0' AND closed NOT LIKE 'moved|%'\n\t"); $count2 = $db->fetch_array($query); $count['unapprovedthreads'] = $count2['threads']; $count['unapprovedposts'] = $count2['impliedunapproved'] + $count2['threads']; if (!$count['unapprovedthreads']) { $count['unapprovedthreads'] = 0; } $query = $db->query("\n\t\tSELECT SUM(unapprovedposts) AS posts\n\t\tFROM " . TABLE_PREFIX . "threads\n\t\tWHERE fid='{$fid}' AND closed NOT LIKE 'moved|%'\n\t"); $count['unapprovedposts'] += $db->fetch_field($query, "posts"); if (!$count['unapprovedposts']) { $count['unapprovedposts'] = 0; } update_forum_counters($fid, $count); }
/** * Completely rebuild the counters for a particular forum (useful if they become out of sync) * * @param int The forum ID */ function rebuild_forum_counters($fid) { global $db; // Fetch the number of threads and replies in this forum (Approved only) $query = $db->simple_select('threads', 'COUNT(tid) AS threads, SUM(replies) AS replies, SUM(unapprovedposts) AS unapprovedposts, SUM(deletedposts) AS deletedposts', "fid='{$fid}' AND visible='1'"); $count = $db->fetch_array($query); $count['posts'] = $count['threads'] + $count['replies']; // Fetch the number of threads and replies in this forum (Unapproved only) $query = $db->simple_select('threads', 'COUNT(tid) AS threads, SUM(replies)+SUM(unapprovedposts)+SUM(deletedposts) AS impliedunapproved', "fid='{$fid}' AND visible='0'"); $count2 = $db->fetch_array($query); $count['unapprovedthreads'] = $count2['threads']; $count['unapprovedposts'] += $count2['impliedunapproved'] + $count2['threads']; // Fetch the number of threads and replies in this forum (Soft deleted only) $query = $db->simple_select('threads', 'COUNT(tid) AS threads, SUM(replies)+SUM(unapprovedposts)+SUM(deletedposts) AS implieddeleted', "fid='{$fid}' AND visible='-1'"); $count3 = $db->fetch_array($query); $count['deletedthreads'] = $count3['threads']; $count['deletedposts'] += $count3['implieddeleted'] + $count3['threads']; update_forum_counters($fid, $count); update_forum_lastpost($fid); }
function akismet_admin() { global $mybb, $db, $page, $lang; if ($page->active_action != "akismet") { return; } $page->add_breadcrumb_item($lang->akismet); if ($mybb->input['delete_all'] && $mybb->request_method == "post") { // User clicked no if ($mybb->input['no']) { admin_redirect("index.php?module=forum-akismet"); } if ($mybb->request_method == "post") { // Delete the template $db->delete_query("posts", "visible = '-4'"); // Log admin action log_admin_action(); flash_message($lang->success_deleted_spam, 'success'); admin_redirect("index.php?module=forum-akismet"); } else { $page->output_confirm_action("index.php?module=forum-akismet&delete_all=1", $lang->confirm_spam_deletion); } } if ($mybb->input['unmark'] && $mybb->request_method == "post") { $unmark = $mybb->input['akismet']; if (empty($unmark)) { flash_message($lang->error_unmark, 'error'); admin_redirect("index.php?module=forum-akismet"); } $posts_in = ''; $comma = ''; foreach ($unmark as $key => $val) { $posts_in .= $comma . intval($key); $comma = ','; } $query = $db->simple_select("posts", "pid, tid", "pid IN ({$posts_in}) AND replyto = '0'"); while ($post = $db->fetch_array($query)) { $threadp[] = $post['tid']; } if (!is_array($threadp)) { $threadp = array(); } $thread_list = implode(',', $threadp); $query = $db->query("\r\n\t\t\tSELECT p.tid, f.usepostcounts, p.uid, p.fid, p.dateline, p.replyto, t.lastpost, t.lastposter, t.lastposteruid, t.subject\r\n\t\t\tFROM " . TABLE_PREFIX . "posts p\r\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "threads t ON (t.tid=p.tid)\r\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "forums f ON (f.fid=p.fid)\r\n\t\t\tWHERE p.pid IN ({$posts_in}) AND p.visible = '-4'\r\n\t\t"); while ($post = $db->fetch_array($query)) { // Fetch the last post for this forum $query2 = $db->query("\r\n\t\t\t\tSELECT tid, lastpost, lastposter, lastposteruid, subject\r\n\t\t\t\tFROM " . TABLE_PREFIX . "threads\r\n\t\t\t\tWHERE fid='{$post['fid']}' AND visible='1' AND closed NOT LIKE 'moved|%'\r\n\t\t\t\tORDER BY lastpost DESC\r\n\t\t\t\tLIMIT 0, 1\r\n\t\t\t"); $lastpost = $db->fetch_array($query2); if ($post['lastpost'] > $lastpost['lastpost']) { $lastpost['lastpost'] = $post['lastpost']; $lastpost['lastposter'] = $post['lastposter']; $lastpost['lastposteruid'] = $post['lastposteruid']; $lastpost['subject'] = $post['subject']; $lastpost['tid'] = $post['tid']; } $update_count = array("lastpost" => intval($lastpost['lastpost']), "lastposter" => $db->escape_string($lastpost['lastposter']), "lastposteruid" => intval($lastpost['lastposteruid']), "lastposttid" => intval($lastpost['tid']), "lastpostsubject" => $db->escape_string($lastpost['subject'])); $db->update_query("forums", $update_count, "fid='{$post['fid']}'"); $query2 = $db->query("\r\n\t\t\t\tSELECT u.uid, u.username, p.username AS postusername, p.dateline\r\n\t\t\t\tFROM " . TABLE_PREFIX . "posts p\r\n\t\t\t\tLEFT JOIN " . TABLE_PREFIX . "users u ON (u.uid=p.uid)\r\n\t\t\t\tWHERE p.tid='{$post['tid']}' AND p.visible='1' OR p.pid = '{$post['pid']}'\r\n\t\t\t\tORDER BY p.dateline DESC\r\n\t\t\t\tLIMIT 1"); $lastpost = $db->fetch_array($query2); $query2 = $db->query("\r\n\t\t\t\tSELECT u.uid, u.username, p.username AS postusername, p.dateline\r\n\t\t\t\tFROM " . TABLE_PREFIX . "posts p\r\n\t\t\t\tLEFT JOIN " . TABLE_PREFIX . "users u ON (u.uid=p.uid)\r\n\t\t\t\tWHERE p.tid='{$post['tid']}'\r\n\t\t\t\tORDER BY p.dateline ASC\r\n\t\t\t\tLIMIT 0,1\r\n\t\t\t"); $firstpost = $db->fetch_array($query2); if (!$firstpost['username']) { $firstpost['username'] = $firstpost['postusername']; } if (!$lastpost['username']) { $lastpost['username'] = $lastpost['postusername']; } if (!$lastpost['dateline']) { $lastpost['username'] = $firstpost['username']; $lastpost['uid'] = $firstpost['uid']; $lastpost['dateline'] = $firstpost['dateline']; } $lastpost['username'] = $db->escape_string($lastpost['username']); $firstpost['username'] = $db->escape_string($firstpost['username']); $query2 = $db->simple_select("users", "akismetstopped", "uid='{$post['uid']}'"); $akismetstopped = $db->fetch_field($query2, "akismetstopped") - 1; if ($akismetstopped < 0) { $akismetstopped = 0; } $db->update_query("users", array('akismetstopped' => $akismetstopped), "uid='{$post['uid']}'"); $update_array = array('username' => $firstpost['username'], 'uid' => intval($firstpost['uid']), 'lastpost' => intval($lastpost['dateline']), 'lastposter' => $lastpost['username'], 'lastposteruid' => intval($lastpost['uid'])); $db->update_query("threads", $update_array, "tid='{$post['tid']}'"); if ($post['usepostcounts'] != 0) { $db->write_query("UPDATE " . TABLE_PREFIX . "users SET postnum=postnum+1 WHERE uid = '{$post['uid']}'"); } $newthreads = $newreplies = 0; if ($post['replyto'] == 0) { ++$newthreads; } else { ++$newreplies; } update_thread_counters($post['tid'], array('replies' => '+' . $newreplies)); update_forum_counters($post['fid'], array('threads' => '+' . $newthreads, 'posts' => '+1')); } $approve = array("visible" => 1); if ($thread_list) { $db->update_query("threads", $approve, "tid IN ({$thread_list})"); } $db->update_query("posts", $approve, "pid IN ({$posts_in})"); // Log admin action log_admin_action(); flash_message($lang->success_unmarked, 'success'); admin_redirect("index.php?module=forum-akismet"); } if ($mybb->input['delete'] && $mybb->request_method == "post") { $deletepost = $mybb->input['akismet']; if (empty($deletepost)) { flash_message($lang->error_deletepost, 'error'); admin_redirect("index.php?module=forum-akismet"); } $posts_in = ''; $comma = ''; foreach ($deletepost as $key => $val) { $posts_in .= $comma . intval($key); $comma = ','; } $query = $db->simple_select("posts", "pid, tid", "pid IN ({$posts_in}) AND replyto = '0'"); while ($post = $db->fetch_array($query)) { $threadp[$post['pid']] = $post['tid']; } if (!is_array($threadp)) { $threadp = array(); } require_once MYBB_ROOT . "inc/functions_upload.php"; foreach ($deletepost as $pid => $val) { if (array_key_exists($pid, $threadp)) { $db->delete_query("posts", "pid IN ({$posts_in})"); $db->delete_query("attachments", "pid IN ({$posts_in})"); // Get thread info $query = $db->simple_select("threads", "poll", "tid='" . $threadp[$pid] . "'"); $poll = $db->fetch_field($query, 'poll'); // Delete threads, redirects, favorites, polls, and poll votes $db->delete_query("threads", "tid='" . $threadp[$pid] . "'"); $db->delete_query("threads", "closed='moved|" . $threadp[$pid] . "'"); $db->delete_query("threadsubscriptions", "tid='" . $threadp[$pid] . "'"); $db->delete_query("polls", "tid='" . $threadp[$pid] . "'"); $db->delete_query("pollvotes", "pid='{$poll}'"); } // Remove attachments remove_attachments($pid); // Delete the post $db->delete_query("posts", "pid='{$pid}'"); } // Log admin action log_admin_action(); flash_message($lang->success_spam_deleted, 'success'); admin_redirect("index.php?module=forum-akismet"); } if (!$mybb->input['action']) { require MYBB_ROOT . "inc/class_parser.php"; $parser = new postParser(); $page->output_header($lang->akismet); $form = new Form("index.php?module=forum-akismet", "post"); $table = new Table(); $table->construct_header($form->generate_check_box("checkall", 1, '', array('class' => 'checkall')), array('width' => '5%')); $table->construct_header("Title / Username / Post", array('class' => 'align_center')); $mybb->input['page'] = intval($mybb->input['page']); if ($mybb->input['page'] > 0) { $start = $mybb->input['page'] * 20; } else { $start = 0; } $query = $db->simple_select("posts", "COUNT(pid) as spam", "visible = '-4'"); $total_rows = $db->fetch_field($query, 'spam'); if ($start > $total_rows) { $start = $total_rows - 20; } if ($start < 0) { $start = 0; } $query = $db->simple_select("posts", "*", "visible = '-4'", array('limit_start' => $start, 'limit' => '20', 'order_by' => 'dateline', 'order_dir' => 'desc')); while ($post = $db->fetch_array($query)) { if ($post['uid'] != 0) { $username = "******"../" . str_replace("{uid}", $post['uid'], PROFILE_URL) . "\" target=\"_blank\">" . format_name($post['username'], $post['usergroup'], $post['displaygroup']) . "</a>"; } else { $username = $post['username']; } $table->construct_cell($form->generate_check_box("akismet[{$post['pid']}]", 1, '')); $table->construct_cell("<span style=\"float: right;\">{$lang->username} {$username}</span> <span style=\"float: left;\">{$lang->title}: " . htmlspecialchars_uni($post['subject']) . " <strong>(" . my_date($mybb->settings['dateformat'], $post['dateline']) . ", " . my_date($mybb->settings['timeformat'], $post['dateline']) . ")</strong></span>"); $table->construct_row(); $parser_options = array("allow_html" => 0, "allow_mycode" => 0, "allow_smilies" => 0, "allow_imgcode" => 0, "me_username" => $post['username'], "filter_badwords" => 1); $post['message'] = $parser->parse_message($post['message'], $parser_options); $table->construct_cell($post['message'], array("colspan" => 2)); $table->construct_row(); } $num_rows = $table->num_rows(); if ($num_rows == 0) { $table->construct_cell($lang->no_spam_found, array("class" => "align_center", "colspan" => 2)); $table->construct_row(); } $table->output($lang->detected_spam_messages); echo "<br />" . draw_admin_pagination($mybb->input['page'], 20, $total_rows, "index.php?module=forum-akismet&page={page}"); $buttons[] = $form->generate_submit_button($lang->unmark_selected, array('name' => 'unmark')); $buttons[] = $form->generate_submit_button($lang->deleted_selected, array('name' => 'delete')); if ($num_rows > 0) { $buttons[] = $form->generate_submit_button($lang->delete_all, array('name' => 'delete_all', 'onclick' => "return confirm('{$lang->confirm_spam_deletion}');")); } $form->output_submit_wrapper($buttons); $form->end(); $page->output_footer(); } exit; }
/** * Insert a thread into the database. * * @return array Array of new thread details, tid and visibility. */ function insert_thread() { global $db, $mybb, $plugins, $cache, $lang; // Yes, validating is required. if (!$this->get_validated()) { die("The thread needs to be validated before inserting it into the DB."); } if (count($this->get_errors()) > 0) { die("The thread is not valid."); } $thread =& $this->data; // Fetch the forum this thread is being made in $forum = get_forum($thread['fid']); // This thread is being saved as a draft. if ($thread['savedraft']) { $visible = -2; } else { $forumpermissions = forum_permissions($thread['fid'], $thread['uid']); // Decide on the visibility of this post. if ($forumpermissions['modthreads'] == 1 && !is_moderator($thread['fid'], "", $thread['uid'])) { $visible = 0; } else { $visible = 1; } // Are posts from this user being moderated? Change visibility if ($mybb->user['uid'] == $thread['uid'] && $mybb->user['moderateposts'] == 1) { $visible = 0; } } // Have a post ID but not a thread ID - fetch thread ID if (!empty($thread['pid']) && !$thread['tid']) { $query = $db->simple_select("posts", "tid", "pid='{$thread['pid']}"); $thread['tid'] = $db->fetch_field($query, "tid"); } if (isset($thread['pid']) && $thread['pid'] > 0) { $query = $db->simple_select("posts", "pid", "pid='{$thread['pid']}' AND uid='{$thread['uid']}' AND visible='-2'"); $draft_check = $db->fetch_field($query, "pid"); } else { $draft_check = false; } // Are we updating a post which is already a draft? Perhaps changing it into a visible post? if ($draft_check) { $this->thread_insert_data = array("subject" => $db->escape_string($thread['subject']), "icon" => (int) $thread['icon'], "username" => $db->escape_string($thread['username']), "dateline" => (int) $thread['dateline'], "lastpost" => (int) $thread['dateline'], "lastposter" => $db->escape_string($thread['username']), "visible" => $visible); $plugins->run_hooks("datahandler_post_insert_thread", $this); $db->update_query("threads", $this->thread_insert_data, "tid='{$thread['tid']}'"); $this->post_insert_data = array("subject" => $db->escape_string($thread['subject']), "icon" => (int) $thread['icon'], "username" => $db->escape_string($thread['username']), "dateline" => (int) $thread['dateline'], "message" => $db->escape_string($thread['message']), "ipaddress" => $db->escape_binary(my_inet_pton(get_ip())), "includesig" => $thread['options']['signature'], "smilieoff" => $thread['options']['disablesmilies'], "visible" => $visible); $plugins->run_hooks("datahandler_post_insert_thread_post", $this); $db->update_query("posts", $this->post_insert_data, "pid='{$thread['pid']}'"); $this->tid = $thread['tid']; $this->pid = $thread['pid']; } else { $this->thread_insert_data = array("fid" => $thread['fid'], "subject" => $db->escape_string($thread['subject']), "prefix" => (int) $thread['prefix'], "icon" => (int) $thread['icon'], "uid" => $thread['uid'], "username" => $db->escape_string($thread['username']), "dateline" => (int) $thread['dateline'], "lastpost" => (int) $thread['dateline'], "lastposter" => $db->escape_string($thread['username']), "views" => 0, "replies" => 0, "visible" => $visible, "notes" => ''); $plugins->run_hooks("datahandler_post_insert_thread", $this); $this->tid = $db->insert_query("threads", $this->thread_insert_data); $this->post_insert_data = array("tid" => $this->tid, "fid" => $thread['fid'], "subject" => $db->escape_string($thread['subject']), "icon" => (int) $thread['icon'], "uid" => $thread['uid'], "username" => $db->escape_string($thread['username']), "dateline" => (int) $thread['dateline'], "message" => $db->escape_string($thread['message']), "ipaddress" => $db->escape_binary(my_inet_pton(get_ip())), "includesig" => $thread['options']['signature'], "smilieoff" => $thread['options']['disablesmilies'], "visible" => $visible); $plugins->run_hooks("datahandler_post_insert_thread_post", $this); $this->pid = $db->insert_query("posts", $this->post_insert_data); // Now that we have the post id for this first post, update the threads table. $firstpostup = array("firstpost" => $this->pid); $db->update_query("threads", $firstpostup, "tid='{$this->tid}'"); } // If we're not saving a draft there are some things we need to check now if (!$thread['savedraft']) { if ($thread['options']['subscriptionmethod'] != "" && $thread['uid'] > 0) { switch ($thread['options']['subscriptionmethod']) { case "pm": $notification = 2; break; case "email": $notification = 1; break; default: $notification = 0; } require_once MYBB_ROOT . "inc/functions_user.php"; add_subscribed_thread($this->tid, $notification, $thread['uid']); } // Perform any selected moderation tools. if (is_moderator($thread['fid'], "", $thread['uid']) && is_array($thread['modoptions'])) { $lang->load($this->language_file, true); $modoptions = $thread['modoptions']; $modlogdata['fid'] = $thread['fid']; if (isset($thread['tid'])) { $modlogdata['tid'] = $thread['tid']; } $modoptions_update = array(); // Close the thread. if (!empty($modoptions['closethread'])) { $modoptions_update['closed'] = 1; log_moderator_action($modlogdata, $lang->thread_closed); } // Stick the thread. if (!empty($modoptions['stickthread'])) { $modoptions_update['sticky'] = 1; log_moderator_action($modlogdata, $lang->thread_stuck); } // Execute moderation options. if ($modoptions_update) { $db->update_query('threads', $modoptions_update, "tid='{$this->tid}'"); } } if ($visible == 1) { // If we have a registered user then update their post count and last post times. if ($thread['uid'] > 0) { $user = get_user($thread['uid']); $update_query = array(); // Only update the lastpost column of the user if the date of the thread is newer than their last post. if ($thread['dateline'] > $user['lastpost']) { // Yes this has a single quote within a double quote. It's not a bug. $update_query['lastpost'] = "'{$thread['dateline']}'"; } // Update the post count if this forum allows post counts to be tracked if ($forum['usepostcounts'] != 0) { $update_query['postnum'] = "postnum+1"; } if ($forum['usethreadcounts'] != 0) { $update_query['threadnum'] = 'threadnum+1'; } // Only update the table if we need to. if (!empty($update_query)) { $db->update_query("users", $update_query, "uid='{$thread['uid']}'", 1, true); } } if (!isset($forum['lastpost'])) { $forum['lastpost'] = 0; } $done_users = array(); // Queue up any forum subscription notices to users who are subscribed to this forum. $excerpt = my_substr($thread['message'], 0, $mybb->settings['subscribeexcerpt']) . $lang->emailbit_viewthread; // Parse badwords require_once MYBB_ROOT . "inc/class_parser.php"; $parser = new postParser(); $excerpt = $parser->parse_badwords($excerpt); $query = $db->query("\n\t\t\t\t\tSELECT u.username, u.email, u.uid, u.language, u.loginkey, u.salt, u.regdate\n\t\t\t\t\tFROM " . TABLE_PREFIX . "forumsubscriptions fs\n\t\t\t\t\tLEFT JOIN " . TABLE_PREFIX . "users u ON (u.uid=fs.uid)\n\t\t\t\t\tLEFT JOIN " . TABLE_PREFIX . "usergroups g ON (g.gid=u.usergroup)\n\t\t\t\t\tWHERE fs.fid='" . (int) $thread['fid'] . "'\n\t\t\t\t\tAND fs.uid != '" . (int) $thread['uid'] . "'\n\t\t\t\t\tAND u.lastactive > '{$forum['lastpost']}'\n\t\t\t\t\tAND g.isbannedgroup != 1\n\t\t\t\t"); while ($subscribedmember = $db->fetch_array($query)) { if ($done_users[$subscribedmember['uid']]) { continue; } $done_users[$subscribedmember['uid']] = 1; $forumpermissions = forum_permissions($thread['fid'], $subscribedmember['uid']); if ($forumpermissions['canview'] == 0 || $forumpermissions['canviewthreads'] == 0) { continue; } if (!is_moderator($thread['fid'], "", $subscribedmember['uid']) && $forumpermissions['canonlyviewownthreads'] == 1) { // In a 'view own only' forum and not a moderator continue; } // Determine the language pack we'll be using to send this email in and load it if it isn't already. if ($subscribedmember['language'] != '' && $lang->language_exists($subscribedmember['language'])) { $uselang = $subscribedmember['language']; } else { if ($mybb->settings['bblanguage']) { $uselang = $mybb->settings['bblanguage']; } else { $uselang = "english"; } } if ($uselang == $mybb->settings['bblanguage']) { $emailsubject = $lang->emailsubject_forumsubscription; $emailmessage = $lang->email_forumsubscription; } else { if (!isset($langcache[$uselang]['emailsubject_forumsubscription'])) { $userlang = new MyLanguage(); $userlang->set_path(MYBB_ROOT . "inc/languages"); $userlang->set_language($uselang); $userlang->load("messages"); $langcache[$uselang]['emailsubject_forumsubscription'] = $userlang->emailsubject_forumsubscription; $langcache[$uselang]['email_forumsubscription'] = $userlang->email_forumsubscription; unset($userlang); } $emailsubject = $langcache[$uselang]['emailsubject_forumsubscription']; $emailmessage = $langcache[$uselang]['email_forumsubscription']; } $emailsubject = $lang->sprintf($emailsubject, $forum['name']); $post_code = md5($subscribedmember['loginkey'] . $subscribedmember['salt'] . $subscribedmember['regdate']); $emailmessage = $lang->sprintf($emailmessage, $subscribedmember['username'], $thread['username'], $forum['name'], $mybb->settings['bbname'], $thread['subject'], $excerpt, $mybb->settings['bburl'], get_thread_link($this->tid), $thread['fid'], $post_code); $new_email = array("mailto" => $db->escape_string($subscribedmember['email']), "mailfrom" => '', "subject" => $db->escape_string($emailsubject), "message" => $db->escape_string($emailmessage), "headers" => ''); $db->insert_query("mailqueue", $new_email); unset($userlang); $queued_email = 1; } // Have one or more emails been queued? Update the queue count if (isset($queued_email) && $queued_email == 1) { $cache->update_mailqueue(); } } } // Assign any uploaded attachments with the specific posthash to the newly created post. if ($thread['posthash']) { $thread['posthash'] = $db->escape_string($thread['posthash']); $attachmentassign = array("pid" => $this->pid, "posthash" => ''); $db->update_query("attachments", $attachmentassign, "posthash='{$thread['posthash']}' AND pid='0'"); } if ($visible == 1) { update_last_post($this->tid); update_forum_counters($thread['fid'], array("threads" => "+1", "posts" => "+1")); update_forum_lastpost($thread['fid']); } else { if ($visible == 0) { update_forum_counters($thread['fid'], array("unapprovedthreads" => "+1", "unapprovedposts" => "+1")); } } $query = $db->simple_select("attachments", "COUNT(aid) AS attachmentcount", "pid='{$this->pid}' AND visible='1'"); $attachmentcount = $db->fetch_field($query, "attachmentcount"); if ($attachmentcount > 0) { update_thread_counters($this->tid, array("attachmentcount" => "+{$attachmentcount}")); } // Return the post's pid and whether or not it is visible. $this->return_values = array("pid" => $this->pid, "tid" => $this->tid, "visible" => $visible); $plugins->run_hooks("datahandler_post_insert_thread_end", $this); return $this->return_values; }
/** * Soft delete one or more threads * * @param array|int Thread ID(s) * @return boolean */ function soft_delete_threads($tids) { global $db, $cache, $plugins; if (!is_array($tids)) { $tids = array($tids); } if (empty($tids)) { return false; } // Make sure we only have valid values $tids = array_map('intval', $tids); $tid_list = implode(',', $tids); $tid_moved_list = ""; $comma = ""; foreach ($tids as $tid) { $tid_moved_list .= "{$comma}'moved|{$tid}'"; $comma = ","; } $forum_counters = $user_counters = $posts_to_delete = array(); foreach ($tids as $tid) { $thread = get_thread($tid); $forum = get_forum($thread['fid']); if ($thread['visible'] == 1 || $thread['visible'] == 0) { if (!isset($forum_counters[$forum['fid']])) { $forum_counters[$forum['fid']] = array('num_posts' => 0, 'num_threads' => 0, 'num_deleted_threads' => 0, 'num_deleted_posts' => 0, 'unapproved_threads' => 0, 'unapproved_posts' => 0); } if (!isset($user_counters[$thread['uid']])) { $user_counters[$thread['uid']] = array('num_posts' => 0, 'num_threads' => 0); } ++$forum_counters[$forum['fid']]['num_deleted_threads']; $forum_counters[$forum['fid']]['num_deleted_posts'] += $thread['replies'] + $thread['unapprovedposts'] + 1; if ($thread['visible'] == 1) { ++$forum_counters[$forum['fid']]['num_threads']; $forum_counters[$forum['fid']]['num_posts'] += $thread['replies'] + 1; // Add implied invisible to count $forum_counters[$forum['fid']]['unapproved_posts'] += $thread['unapprovedposts']; } else { ++$forum_counters[$forum['fid']]['unapproved_threads']; $forum_counters[$forum['fid']]['unapproved_posts'] += $thread['replies'] + $thread['deletedposts'] + $thread['unapprovedposts'] + 1; // Add implied invisible to count $forum_counters[$forum['fid']]['num_deleted_posts'] += $thread['deletedposts']; } // On unapproving thread update user post counts if ($thread['visible'] == 1 && $forum['usepostcounts'] != 0) { $query = $db->simple_select("posts", "COUNT(pid) AS posts, uid", "tid='{$tid}' AND (visible='1' OR pid='{$thread['firstpost']}') AND uid > 0 GROUP BY uid"); while ($counter = $db->fetch_array($query)) { if (!isset($user_counters[$counter['uid']]['num_posts'])) { $user_counters[$counter['uid']]['num_posts'] = 0; } $user_counters[$counter['uid']]['num_posts'] += $counter['posts']; } } if ($thread['visible'] == 1 && $forum['usethreadcounts'] != 0 && substr($thread['closed'], 0, 6) != 'moved|') { ++$user_counters[$thread['uid']]['num_threads']; } } $posts_to_delete[] = $thread['firstpost']; } $update = array("visible" => -1); $db->update_query("threads", $update, "tid IN ({$tid_list})"); // Soft delete redirects, too $redirect_tids = array(); $query = $db->simple_select('threads', 'tid', "closed IN ({$tid_moved_list})"); mark_reports($tids, "threads"); while ($redirect_tid = $db->fetch_field($query, 'tid')) { $redirect_tids[] = $redirect_tid; } if (!empty($redirect_tids)) { $this->soft_delete_threads($redirect_tids); } if (!empty($posts_to_delete)) { $db->update_query("posts", $update, "pid IN (" . implode(',', $posts_to_delete) . ")"); } $plugins->run_hooks("class_moderation_soft_delete_threads", $tids); if (is_array($forum_counters)) { foreach ($forum_counters as $fid => $counters) { // Update stats $update_array = array("threads" => "-{$counters['num_threads']}", "unapprovedthreads" => "-{$counters['unapproved_threads']}", "posts" => "-{$counters['num_posts']}", "unapprovedposts" => "-{$counters['unapproved_posts']}", "deletedposts" => "+{$counters['num_deleted_posts']}", "deletedthreads" => "+{$counters['num_deleted_threads']}"); update_forum_counters($fid, $update_array); update_forum_lastpost($fid); } } if (!empty($user_counters)) { foreach ($user_counters as $uid => $counters) { $update_array = array("postnum" => "-{$counters['num_posts']}", "threadnum" => "-{$counters['num_threads']}"); update_user_counters($uid, $update_array); } } return true; }
/** * 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; }