Esempio n. 1
0
/**
 * 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);
}
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&amp;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;
}
Esempio n. 3
0
 /**
  * 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;
 }
/**
 * Upload an attachment in to the file system
 *
 * @param array $attachment Attachment data (as fed by PHPs $_FILE)
 * @param boolean $update_attachment Whether or not we are updating a current attachment or inserting a new one
 * @return array Array of attachment data if successful, otherwise array of error data
 */
function upload_attachment($attachment, $update_attachment = false)
{
    global $mybb, $db, $theme, $templates, $posthash, $pid, $tid, $forum, $mybb, $lang, $plugins, $cache;
    $posthash = $db->escape_string($mybb->get_input('posthash'));
    $pid = (int) $pid;
    if (isset($attachment['error']) && $attachment['error'] != 0) {
        $ret['error'] = $lang->error_uploadfailed . $lang->error_uploadfailed_detail;
        switch ($attachment['error']) {
            case 1:
                // UPLOAD_ERR_INI_SIZE
                $ret['error'] .= $lang->error_uploadfailed_php1;
                break;
            case 2:
                // UPLOAD_ERR_FORM_SIZE
                $ret['error'] .= $lang->error_uploadfailed_php2;
                break;
            case 3:
                // UPLOAD_ERR_PARTIAL
                $ret['error'] .= $lang->error_uploadfailed_php3;
                break;
            case 4:
                // UPLOAD_ERR_NO_FILE
                $ret['error'] .= $lang->error_uploadfailed_php4;
                break;
            case 6:
                // UPLOAD_ERR_NO_TMP_DIR
                $ret['error'] .= $lang->error_uploadfailed_php6;
                break;
            case 7:
                // UPLOAD_ERR_CANT_WRITE
                $ret['error'] .= $lang->error_uploadfailed_php7;
                break;
            default:
                $ret['error'] .= $lang->sprintf($lang->error_uploadfailed_phpx, $attachment['error']);
                break;
        }
        return $ret;
    }
    if (!is_uploaded_file($attachment['tmp_name']) || empty($attachment['tmp_name'])) {
        $ret['error'] = $lang->error_uploadfailed . $lang->error_uploadfailed_php4;
        return $ret;
    }
    $attachtypes = $cache->read('attachtypes');
    $attachment = $plugins->run_hooks("upload_attachment_start", $attachment);
    $ext = get_extension($attachment['name']);
    // Check if we have a valid extension
    if (!isset($attachtypes[$ext])) {
        $ret['error'] = $lang->error_attachtype;
        return $ret;
    } else {
        $attachtype = $attachtypes[$ext];
    }
    // Check the size
    if ($attachment['size'] > $attachtype['maxsize'] * 1024 && $attachtype['maxsize'] != "") {
        $ret['error'] = $lang->sprintf($lang->error_attachsize, $attachtype['maxsize']);
        return $ret;
    }
    // Double check attachment space usage
    if ($mybb->usergroup['attachquota'] > 0) {
        $query = $db->simple_select("attachments", "SUM(filesize) AS ausage", "uid='" . $mybb->user['uid'] . "'");
        $usage = $db->fetch_array($query);
        $usage = $usage['ausage'] + $attachment['size'];
        if ($usage > $mybb->usergroup['attachquota'] * 1024) {
            $friendlyquota = get_friendly_size($mybb->usergroup['attachquota'] * 1024);
            $ret['error'] = $lang->sprintf($lang->error_reachedattachquota, $friendlyquota);
            return $ret;
        }
    }
    // Gather forum permissions
    $forumpermissions = forum_permissions($forum['fid']);
    // Check if an attachment with this name is already in the post
    if ($pid != 0) {
        $uploaded_query = "pid='{$pid}'";
    } else {
        $uploaded_query = "posthash='{$posthash}'";
    }
    $query = $db->simple_select("attachments", "*", "filename='" . $db->escape_string($attachment['name']) . "' AND " . $uploaded_query);
    $prevattach = $db->fetch_array($query);
    if ($prevattach['aid'] && $update_attachment == false) {
        if (!$mybb->usergroup['caneditattachments'] && !$forumpermissions['caneditattachments']) {
            $ret['error'] = $lang->error_alreadyuploaded_perm;
            return $ret;
        }
        $ret['error'] = $lang->error_alreadyuploaded;
        return $ret;
    }
    // Check to see how many attachments exist for this post already
    if ($mybb->settings['maxattachments'] > 0 && $update_attachment == false) {
        $query = $db->simple_select("attachments", "COUNT(aid) AS numattachs", $uploaded_query);
        $attachcount = $db->fetch_field($query, "numattachs");
        if ($attachcount >= $mybb->settings['maxattachments']) {
            $ret['error'] = $lang->sprintf($lang->error_maxattachpost, $mybb->settings['maxattachments']);
            return $ret;
        }
    }
    $month_dir = '';
    if ($mybb->safemode == false) {
        // Check if the attachment directory (YYYYMM) exists, if not, create it
        $month_dir = gmdate("Ym");
        if (!@is_dir($mybb->settings['uploadspath'] . "/" . $month_dir)) {
            @mkdir($mybb->settings['uploadspath'] . "/" . $month_dir);
            // Still doesn't exist - oh well, throw it in the main directory
            if (!@is_dir($mybb->settings['uploadspath'] . "/" . $month_dir)) {
                $month_dir = '';
            }
        }
    }
    // All seems to be good, lets move the attachment!
    $filename = "post_" . $mybb->user['uid'] . "_" . TIME_NOW . "_" . md5(random_str()) . ".attach";
    $file = upload_file($attachment, $mybb->settings['uploadspath'] . "/" . $month_dir, $filename);
    // Failed to create the attachment in the monthly directory, just throw it in the main directory
    if (!empty($file['error']) && $month_dir) {
        $file = upload_file($attachment, $mybb->settings['uploadspath'] . '/', $filename);
    } elseif ($month_dir) {
        $filename = $month_dir . "/" . $filename;
    }
    if (!empty($file['error'])) {
        $ret['error'] = $lang->error_uploadfailed . $lang->error_uploadfailed_detail;
        switch ($file['error']) {
            case 1:
                $ret['error'] .= $lang->error_uploadfailed_nothingtomove;
                break;
            case 2:
                $ret['error'] .= $lang->error_uploadfailed_movefailed;
                break;
        }
        return $ret;
    }
    // Lets just double check that it exists
    if (!file_exists($mybb->settings['uploadspath'] . "/" . $filename)) {
        $ret['error'] = $lang->error_uploadfailed . $lang->error_uploadfailed_detail . $lang->error_uploadfailed_lost;
        return $ret;
    }
    // Generate the array for the insert_query
    $attacharray = array("pid" => $pid, "posthash" => $posthash, "uid" => $mybb->user['uid'], "filename" => $db->escape_string($file['original_filename']), "filetype" => $db->escape_string($file['type']), "filesize" => (int) $file['size'], "attachname" => $filename, "downloads" => 0, "dateuploaded" => TIME_NOW);
    // If we're uploading an image, check the MIME type compared to the image type and attempt to generate a thumbnail
    if ($ext == "gif" || $ext == "png" || $ext == "jpg" || $ext == "jpeg" || $ext == "jpe") {
        // Check a list of known MIME types to establish what kind of image we're uploading
        switch (my_strtolower($file['type'])) {
            case "image/gif":
                $img_type = 1;
                break;
            case "image/jpeg":
            case "image/x-jpg":
            case "image/x-jpeg":
            case "image/pjpeg":
            case "image/jpg":
                $img_type = 2;
                break;
            case "image/png":
            case "image/x-png":
                $img_type = 3;
                break;
            default:
                $img_type = 0;
        }
        $supported_mimes = array();
        foreach ($attachtypes as $attachtype) {
            if (!empty($attachtype['mimetype'])) {
                $supported_mimes[] = $attachtype['mimetype'];
            }
        }
        // Check if the uploaded file type matches the correct image type (returned by getimagesize)
        $img_dimensions = @getimagesize($mybb->settings['uploadspath'] . "/" . $filename);
        $mime = "";
        $file_path = $mybb->settings['uploadspath'] . "/" . $filename;
        if (function_exists("finfo_open")) {
            $file_info = finfo_open(FILEINFO_MIME);
            list($mime, ) = explode(';', finfo_file($file_info, MYBB_ROOT . $file_path), 1);
            finfo_close($file_info);
        } else {
            if (function_exists("mime_content_type")) {
                $mime = mime_content_type(MYBB_ROOT . $file_path);
            }
        }
        if (!is_array($img_dimensions) || $img_dimensions[2] != $img_type && !in_array($mime, $supported_mimes)) {
            delete_uploaded_file($mybb->settings['uploadspath'] . "/" . $filename);
            $ret['error'] = $lang->error_uploadfailed;
            return $ret;
        }
        require_once MYBB_ROOT . "inc/functions_image.php";
        $thumbname = str_replace(".attach", "_thumb.{$ext}", $filename);
        $attacharray = $plugins->run_hooks("upload_attachment_thumb_start", $attacharray);
        $thumbnail = generate_thumbnail($mybb->settings['uploadspath'] . "/" . $filename, $mybb->settings['uploadspath'], $thumbname, $mybb->settings['attachthumbh'], $mybb->settings['attachthumbw']);
        if ($thumbnail['filename']) {
            $attacharray['thumbnail'] = $thumbnail['filename'];
        } elseif ($thumbnail['code'] == 4) {
            $attacharray['thumbnail'] = "SMALL";
        }
    }
    if ($forumpermissions['modattachments'] == 1 && !is_moderator($forum['fid'], "canapproveunapproveattachs")) {
        $attacharray['visible'] = 0;
    } else {
        $attacharray['visible'] = 1;
    }
    $attacharray = $plugins->run_hooks("upload_attachment_do_insert", $attacharray);
    if ($prevattach['aid'] && $update_attachment == true) {
        unset($attacharray['downloads']);
        // Keep our download count if we're updating an attachment
        $db->update_query("attachments", $attacharray, "aid='" . $db->escape_string($prevattach['aid']) . "'");
        // Remove old attachment file
        // Check if this attachment is referenced in any other posts. If it isn't, then we are safe to delete the actual file.
        $query = $db->simple_select("attachments", "COUNT(aid) as numreferences", "attachname='" . $db->escape_string($prevattach['attachname']) . "'");
        if ($db->fetch_field($query, "numreferences") == 0) {
            delete_uploaded_file($mybb->settings['uploadspath'] . "/" . $prevattach['attachname']);
            if ($prevattach['thumbnail']) {
                delete_uploaded_file($mybb->settings['uploadspath'] . "/" . $prevattach['thumbnail']);
            }
            $date_directory = explode('/', $prevattach['attachname']);
            if (@is_dir($mybb->settings['uploadspath'] . "/" . $date_directory[0])) {
                delete_upload_directory($mybb->settings['uploadspath'] . "/" . $date_directory[0]);
            }
        }
        $aid = $prevattach['aid'];
    } else {
        $aid = $db->insert_query("attachments", $attacharray);
        if ($pid) {
            update_thread_counters($tid, array("attachmentcount" => "+1"));
        }
    }
    $ret['aid'] = $aid;
    return $ret;
}
Esempio n. 5
0
/**
 * Completely rebuild the counters for a particular thread (useful if they become out of sync)
 * 
 * @param int The thread ID 
 * @param array Optional thread array so we don't have to query it 
 */
function rebuild_thread_counters($tid)
{
    global $db;
    if (!$thread['tid']) {
        $thread = get_thread($tid);
    }
    $query = $db->simple_select("posts", "COUNT(*) AS replies", "tid='{$tid}' AND pid!='{$thread['firstpost']}' AND visible='1'");
    $count['replies'] = $db->fetch_field($query, "replies");
    if ($count['replies'] < 0) {
        $count['replies'] = 0;
    }
    // Unapproved posts
    $query = $db->simple_select("posts", "COUNT(pid) AS totunposts", "tid='{$tid}' AND pid != '{$thread['firstpost']}' AND visible='0'");
    $count['unapprovedposts'] = $db->fetch_field($query, "totunposts");
    if (!$count['unapprovedposts']) {
        $count['unapprovedposts'] = 0;
    }
    // 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}'\n\t");
    $count['attachmentcount'] = $db->fetch_field($query, "attachment_count");
    if (!$count['attachmentcount']) {
        $count['attachmentcount'] = 0;
    }
    update_thread_counters($tid, $count);
}
Esempio n. 6
0
function save_raw_post_func($xmlrpc_params)
{
    global $db, $lang, $theme, $plugins, $mybb, $session, $settings, $cache, $time, $mybbgroups;
    $lang->load("editpost");
    $input = Tapatalk_Input::filterXmlInput(array('post_id' => Tapatalk_Input::INT, 'post_title' => Tapatalk_Input::STRING, 'post_content' => Tapatalk_Input::STRING, 'return_html' => Tapatalk_Input::INT, 'attachment_id_array' => Tapatalk_Input::RAW, 'group_id' => Tapatalk_Input::STRING, 'editreason' => Tapatalk_Input::STRING), $xmlrpc_params);
    $parser = new postParser();
    // No permission for guests
    if (!$mybb->user['uid']) {
        return tt_no_permission();
    }
    // Get post info
    $pid = $input['post_id'];
    $query = $db->simple_select("posts", "*", "pid='{$pid}'");
    $post = $db->fetch_array($query);
    if (empty($input['post_title'])) {
        $input['post_title'] = $post['subject'];
    }
    if (!$post['pid']) {
        return xmlrespfalse($lang->error_invalidpost);
    }
    // Get thread info
    $tid = $post['tid'];
    $thread = get_thread($tid);
    if (!$thread['tid']) {
        return xmlrespfalse($lang->error_invalidthread);
    }
    $thread['subject'] = htmlspecialchars_uni($thread['subject']);
    // Get forum info
    $fid = $post['fid'];
    $forum = get_forum($fid);
    if (!$forum || $forum['type'] != "f") {
        return xmlrespfalse($lang->error_closedinvalidforum);
    }
    if ($forum['open'] == 0 || $mybb->user['suspendposting'] == 1) {
        return tt_no_permission();
    }
    $forumpermissions = forum_permissions($fid);
    if (!is_moderator($fid, "caneditposts")) {
        if ($thread['closed'] == 1) {
            return xmlrespfalse($lang->redirect_threadclosed);
        }
        if ($forumpermissions['caneditposts'] == 0) {
            return tt_no_permission();
        }
        if ($mybb->user['uid'] != $post['uid']) {
            return tt_no_permission();
        }
        // Edit time limit
        $time = TIME_NOW;
        if ($mybb->settings['edittimelimit'] != 0 && $post['dateline'] < $time - $mybb->settings['edittimelimit'] * 60) {
            $lang->edit_time_limit = $lang->sprintf($lang->edit_time_limit, $mybb->settings['edittimelimit']);
            return xmlrespfalse($lang->edit_time_limit);
        }
    }
    // Check if this forum is password protected and we have a valid password
    tt_check_forum_password($forum['fid']);
    // Set up posthandler.
    require_once MYBB_ROOT . "inc/datahandlers/post.php";
    $posthandler = new PostDataHandler("update");
    $posthandler->action = "post";
    // Set the post data that came from the input to the $post array.
    $post = array("pid" => $pid, "subject" => $input['post_title'], "uid" => $mybb->user['uid'], "username" => $mybb->user['username'], "edit_uid" => $mybb->user['uid'], "message" => $input['post_content']);
    if (version_compare($mybb->version, '1.8.0', '>=') && !empty($input['editreason'])) {
        $post["editreason"] = $input['editreason'];
    }
    // get subscription status
    $query = $db->simple_select("threadsubscriptions", 'notification', "uid='" . intval($mybb->user['uid']) . "' AND tid='" . intval($tid) . "'");
    $substatus = $db->fetch_array($query);
    // Set up the post options from the input.
    $post['options'] = array("signature" => 1, "subscriptionmethod" => isset($substatus['notification']) ? $substatus['notification'] == 1 ? 'instant' : 'none' : '', "disablesmilies" => 0);
    $posthandler->set_data($post);
    // Now let the post handler do all the hard work.
    if (!$posthandler->validate_post()) {
        $post_errors = $posthandler->get_friendly_errors();
        return xmlrespfalse(implode(" :: ", $post_errors));
    } else {
        $postinfo = $posthandler->update_post();
        $visible = $postinfo['visible'];
        $first_post = $postinfo['first_post'];
        // Help keep our attachments table clean.
        $db->delete_query("attachments", "filename='' OR filesize<1");
        if ($visible == 0 && $first_post && !is_moderator($fid, "", $mybb->user['uid'])) {
            $state = 1;
        } else {
            if ($visible == 0 && !is_moderator($fid, "", $mybb->user['uid'])) {
                $state = 1;
            } else {
                $state = 0;
            }
        }
    }
    $pid = intval($pid);
    if (!empty($input['group_id_esc'])) {
        $db->update_query("attachments", array("pid" => $pid), "posthash='{$input['group_id_esc']}'");
    }
    // update thread attachment account
    if (count($input['attachment_id_array']) > 0) {
        update_thread_counters($tid, array("attachmentcount" => "+" . count($input['attachment_id_array'])));
    }
    $post = get_post($pid);
    $parser_options = array();
    $parser_options['allow_html'] = false;
    $parser_options['allow_mycode'] = true;
    $parser_options['allow_smilies'] = false;
    $parser_options['allow_imgcode'] = true;
    $parser_options['allow_videocode'] = true;
    $parser_options['nl2br'] = (bool) $input['return_html'];
    $parser_options['filter_badwords'] = 1;
    if (!$post['username']) {
        $post['username'] = $lang->guest;
    }
    if ($post['userusername']) {
        $parser_options['me_username'] = $post['userusername'];
    } else {
        $parser_options['me_username'] = $post['username'];
    }
    $post['message'] = $parser->parse_message($post['message'], $parser_options);
    $post['subject'] = $parser->parse_badwords($post['subject']);
    $result = new xmlrpcval(array('result' => new xmlrpcval(true, 'boolean'), 'result_text' => new xmlrpcval('', 'base64'), 'state' => new xmlrpcval($state, 'int'), 'post_title' => new xmlrpcval($post['subject'], 'base64'), 'post_content' => new xmlrpcval(process_post($post['message'], $input['return_html']), 'base64')), 'struct');
    return new xmlrpcresp($result);
}
 /**
  * Restore multiple posts
  *
  * @param array $pids PIDs
  * @return boolean
  */
 function restore_posts($pids)
 {
     global $db, $cache, $plugins;
     $num_posts = 0;
     if (empty($pids)) {
         return false;
     }
     // Make sure we only have valid values
     $pids = array_map('intval', $pids);
     $pid_list = implode(',', $pids);
     $pids = $threads_to_update = array();
     // Make visible
     $update = array("visible" => 1);
     // We have three cases we deal with in these code segments:
     // 1) We're approving specific restored posts
     // 1.1) if the thread is deleted
     // 1.2) if the thread is restored
     // 2) We're restoring the firstpost of the thread, therefore restoring 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 approving the whole thread.
         $threads_to_update[] = $post['tid'];
     }
     if (!empty($threads_to_update)) {
         $this->restore_threads($threads_to_update);
     }
     $thread_counters = $forum_counters = $user_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'];
         if (!isset($thread_counters[$post['tid']])) {
             $thread_counters[$post['tid']] = array('replies' => 0);
         }
         ++$thread_counters[$post['tid']]['replies'];
         // If the thread of this post is deleted then we've already taken into account this counter as implied.
         // Updating it again would cause it to double count
         if ($post['threadvisible'] == 1) {
             if (!isset($forum_counters[$post['fid']])) {
                 $forum_counters[$post['fid']] = array('num_posts' => 0);
             }
             ++$forum_counters[$post['fid']]['num_posts'];
         }
         // If post counts enabled in this forum and the thread is approved, add 1
         if ($post['usepostcounts'] != 0 && $post['threadvisible'] == 1) {
             if (!isset($user_counters[$post['uid']])) {
                 $user_counters[$post['uid']] = 0;
             }
             ++$user_counters[$post['uid']];
         }
     }
     if (empty($pids) && empty($threads_to_update)) {
         return false;
     }
     if (!empty($pids)) {
         $where = "pid IN (" . implode(',', $pids) . ")";
         $db->update_query("posts", $update, $where);
     }
     $plugins->run_hooks("class_moderation_restore_posts", $pids);
     if (is_array($thread_counters)) {
         foreach ($thread_counters as $tid => $counters) {
             $counters_update = array("deletedposts" => "-" . $counters['replies'], "replies" => "+" . $counters['replies']);
             update_thread_counters($tid, $counters_update);
             update_last_post($tid);
         }
     }
     if (is_array($forum_counters)) {
         foreach ($forum_counters as $fid => $counters) {
             $updated_forum_stats = array('posts' => "+{$counters['num_posts']}", 'deletedposts' => "-{$counters['num_posts']}");
             update_forum_counters($fid, $updated_forum_stats);
             update_forum_lastpost($fid);
         }
     }
     if (!empty($user_counters)) {
         foreach ($user_counters as $uid => $counter) {
             update_user_counters($uid, array('postnum' => "+{$counter}"));
         }
     }
     return true;
 }
Esempio n. 8
0
    }
}
if ($mybb->input['attachmentaid'] && isset($mybb->input['attachmentact']) && $mybb->input['action'] == "do_editpost" && $mybb->request_method == "post") {
    // Verify incoming POST request
    verify_post_check($mybb->input['my_post_key']);
    $mybb->input['attachmentaid'] = intval($mybb->input['attachmentaid']);
    if ($mybb->input['attachmentact'] == "remove") {
        remove_attachment($pid, "", $mybb->input['attachmentaid']);
    } elseif ($mybb->input['attachmentact'] == "approve" && is_moderator($fid, 'caneditposts')) {
        $update_sql = array("visible" => 1);
        $db->update_query("attachments", $update_sql, "aid='{$mybb->input['attachmentaid']}'");
        update_thread_counters($post['tid'], array('attachmentcount' => "+1"));
    } elseif ($mybb->input['attachmentact'] == "unapprove" && is_moderator($fid, 'caneditposts')) {
        $update_sql = array("visible" => 0);
        $db->update_query("attachments", $update_sql, "aid='{$mybb->input['attachmentaid']}'");
        update_thread_counters($post['tid'], array('attachmentcount' => "-1"));
    }
    if (!$mybb->input['submit']) {
        $mybb->input['action'] = "editpost";
    }
}
if ($mybb->input['action'] == "deletepost" && $mybb->request_method == "post") {
    // Verify incoming POST request
    verify_post_check($mybb->input['my_post_key']);
    $plugins->run_hooks("editpost_deletepost");
    if ($mybb->input['delete'] == 1) {
        $query = $db->simple_select("posts", "pid", "tid='{$tid}'", array("limit" => 1, "order_by" => "dateline", "order_dir" => "asc"));
        $firstcheck = $db->fetch_array($query);
        if ($firstcheck['pid'] == $pid) {
            $firstpost = 1;
        } else {
Esempio n. 9
0
 /**
  * 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);
 }
Esempio n. 11
0
function reply_post_func($xmlrpc_params)
{
    global $db, $lang, $theme, $plugins, $mybb, $session, $settings, $cache, $time, $mybbgroups, $tid, $pid, $visible, $thread, $post;
    $input = Tapatalk_Input::filterXmlInput(array('forum_id' => Tapatalk_Input::INT, 'topic_id' => Tapatalk_Input::INT, 'subject' => Tapatalk_Input::STRING, 'text_body' => Tapatalk_Input::STRING, 'attachment_id_array' => Tapatalk_Input::RAW, 'group_id' => Tapatalk_Input::STRING, 'return_html' => Tapatalk_Input::INT), $xmlrpc_params);
    $lang->load("newreply");
    $parser = new Tapatalk_Parser();
    $tid = $input['topic_id'];
    $options = array("limit" => 1);
    $query = $db->simple_select("threads", "*", "tid='" . $tid . "'");
    if ($db->num_rows($query) == 0) {
        return xmlrespfalse($lang->error_invalidthread);
    }
    $thread = $db->fetch_array($query);
    $fid = $thread['fid'];
    // Get forum info
    $forum = get_forum($fid);
    if (!$forum) {
        return xmlrespfalse($lang->error_invalidforum);
    }
    $forumpermissions = forum_permissions($fid);
    if ($thread['visible'] == 0 && !is_moderator($fid) || $thread['visible'] < 0) {
        return xmlrespfalse($lang->error_invalidthread);
    }
    if ($forum['open'] == 0 || $forum['type'] != "f") {
        return xmlrespfalse($lang->error_closedinvalidforum);
    }
    if ($mybb->user['uid'] < 1 || $forumpermissions['canview'] == 0 || $forumpermissions['canpostreplys'] == 0 || $mybb->user['suspendposting'] == 1) {
        return tt_no_permission();
    }
    if ($forumpermissions['canonlyviewthreads'] == 1 && $thread['uid'] != $mybb->user['uid']) {
        return tt_no_permission();
    }
    tt_check_forum_password($forum['fid']);
    // Check to see if the thread is closed, and if the user is a mod.
    if (!is_moderator($fid, "caneditposts")) {
        if ($thread['closed'] == 1) {
            return xmlrespfalse($lang->redirect_threadclosed);
        }
    }
    // Is the currently logged in user a moderator of this forum?
    if (is_moderator($fid)) {
        $ismod = true;
    } else {
        $ismod = false;
    }
    if (!empty($input['group_id'])) {
        $posthash = $input['group_id'];
    } else {
        $posthash = md5($thread['tid'] . $mybb->user['uid'] . random_str());
    }
    if ($mybb->settings['maxposts'] > 0 && $mybb->usergroup['cancp'] != 1) {
        $daycut = TIME_NOW - 60 * 60 * 24;
        $query = $db->simple_select("posts", "COUNT(*) AS posts_today", "uid='{$mybb->user['uid']}' AND visible='1' AND dateline>{$daycut}");
        $post_count = $db->fetch_field($query, "posts_today");
        if ($post_count >= $mybb->settings['maxposts']) {
            $lang->error_maxposts = $lang->sprintf($lang->error_maxposts, $mybb->settings['maxposts']);
            return xmlrespfalse($lang->error_maxposts);
        }
    }
    $username = $mybb->user['username'];
    $uid = $mybb->user['uid'];
    $user_check = "p.uid='{$uid}'";
    if (version_compare($mybb->version, '1.8.0', '<')) {
        $query = $db->simple_select("posts p", "p.pid, p.visible", "{$user_check} AND p.tid='{$thread['tid']}' AND p.subject='" . $db->escape_string($mybb->input['subject']) . "' AND p.message='" . $db->escape_string($mybb->input['message']) . "' AND p.posthash='" . $db->escape_string($mybb->input['posthash']) . "' AND p.visible != '-2'");
    } else {
        $query = $db->simple_select("posts p", "p.pid, p.visible", "{$user_check} AND p.tid='{$thread['tid']}' AND p.subject='" . $db->escape_string($mybb->get_input('subject')) . "' AND p.message='" . $db->escape_string($mybb->get_input('message')) . "' AND p.visible != '-2' AND p.dateline>" . (TIME_NOW - 600));
    }
    $duplicate_check = $db->fetch_field($query, "pid");
    if ($duplicate_check) {
        return xmlrespfalse($lang->error_post_already_submitted);
    }
    require_once MYBB_ROOT . "inc/datahandlers/post.php";
    $posthandler = new PostDataHandler("insert");
    $post = array("tid" => $input['topic_id'], "replyto" => 0, "fid" => $thread['fid'], "subject" => $input['subject'], "icon" => 0, "uid" => $uid, "username" => $username, "message" => $input['text_body'], "ipaddress" => get_ip(), "posthash" => $posthash);
    if ($mybb->input['pid']) {
        $post['pid'] = $mybb->input['pid'];
    }
    $post['savedraft'] = 0;
    // Set up the post options from the input.
    $post['options'] = array("signature" => 1, "subscriptionmethod" => $mybb->user['subscriptionmethod'] == 0 ? '' : $mybb->user['subscriptionmethod'], "disablesmilies" => 0);
    $post['modoptions']['stickthread'] = $thread['sticky'];
    $post['modoptions']['closethread'] = $thread['closed'];
    $posthandler->set_data($post);
    // Now let the post handler do all the hard work.
    $valid_post = $posthandler->validate_post();
    $post_errors = array();
    // Fetch friendly error messages if this is an invalid post
    if (!$valid_post) {
        $post_errors = $posthandler->get_friendly_errors();
    }
    // Mark thread as read
    require_once MYBB_ROOT . "inc/functions_indicators.php";
    mark_thread_read($tid, $fid);
    // One or more errors returned, fetch error list and throw to newreply page
    if (count($post_errors) > 0) {
        return xmlrespfalse(implode(" :: ", $post_errors));
    } else {
        $postinfo = $posthandler->insert_post();
        $pid = $postinfo['pid'];
        $visible = $postinfo['visible'];
        tapatalk_push_reply();
        tapatalk_push_quote();
        tapatalk_push_tag();
        // Deciding the fate
        if ($visible == -2) {
            $state = 1;
        } elseif ($visible == 1) {
            $state = 0;
        } else {
            $state = 1;
        }
    }
    $pid = intval($pid);
    if (!empty($input['group_id_esc'])) {
        $db->update_query("attachments", array("pid" => $pid), "posthash='{$input['group_id_esc']}'");
    }
    // update thread attachment account
    if (count($input['attachment_id_array']) > 0) {
        update_thread_counters($tid, array("attachmentcount" => "+" . count($input['attachment_id_array'])));
    }
    $post = get_post($pid);
    $parser_options = array();
    $parser_options['allow_html'] = false;
    $parser_options['allow_mycode'] = true;
    $parser_options['allow_smilies'] = false;
    $parser_options['allow_imgcode'] = true;
    $parser_options['allow_videocode'] = true;
    $parser_options['nl2br'] = (bool) $input['return_html'];
    $parser_options['filter_badwords'] = 1;
    if (!$post['username']) {
        $post['username'] = $lang->guest;
    }
    if ($post['userusername']) {
        $parser_options['me_username'] = $post['userusername'];
    } else {
        $parser_options['me_username'] = $post['username'];
    }
    $post['message'] = post_bbcode_clean($post['message']);
    $post['message'] = $parser->parse_message($post['message'], $parser_options);
    global $attachcache;
    $attachcache = array();
    if ($thread['attachmentcount'] > 0) {
        // Now lets fetch all of the attachments for these posts.
        $query = $db->simple_select("attachments", "*", "pid='{$pid}'");
        while ($attachment = $db->fetch_array($query)) {
            $attachcache[$attachment['pid']][$attachment['aid']] = $attachment;
        }
    }
    $attachment_list = process_post_attachments($post['pid'], $post);
    $can_delete = 0;
    if ($mybb->user['uid'] == $post['uid']) {
        if ($forumpermissions['candeletethreads'] == 1 && $postcounter == 1) {
            $can_delete = 1;
        } else {
            if ($forumpermissions['candeleteposts'] == 1 && $postcounter != 1) {
                $can_delete = 1;
            }
        }
    }
    $can_delete = (is_moderator($fid, "candeleteposts") || $can_delete == 1) && $mybb->user['uid'] != 0;
    $result = new xmlrpcval(array('result' => new xmlrpcval(true, 'boolean'), 'result_text' => new xmlrpcval('', 'base64'), 'post_id' => new xmlrpcval($postinfo['pid'], 'string'), 'state' => new xmlrpcval($state, 'int'), 'post_author_id' => new xmlrpcval($mybb->user['uid'], 'string'), 'post_author_name' => new xmlrpcval(basic_clean($mybb->user['username']), 'base64'), 'icon_url' => new xmlrpcval(absolute_url($mybb->user['avatar']), 'string'), 'post_content' => new xmlrpcval(process_post($post['message'], $input['return_html']), 'base64'), 'can_edit' => new xmlrpcval(is_moderator($fid, "caneditposts") || $thread['closed'] == 0 && $forumpermissions['caneditposts'] == 1, 'boolean'), 'can_delete' => new xmlrpcval($can_delete, 'boolean'), 'post_time' => new xmlrpcval(mobiquo_iso8601_encode(TIME_NOW), 'dateTime.iso8601'), 'timestamp' => new xmlrpcval(TIME_NOW, 'string'), 'attachments' => new xmlrpcval($attachment_list, 'array')), 'struct');
    return new xmlrpcresp($result);
}
 /**
  * Merge one thread into another
  *
  * @param int Thread that will be merged into destination
  * @param int Destination thread
  * @param string New thread subject
  * @return boolean true
  */
 function merge_threads($mergetid, $tid, $subject)
 {
     global $db, $mybb, $mergethread, $thread, $plugins;
     $mergetid = intval($mergetid);
     $tid = intval($tid);
     if (!isset($mergethread['tid']) || $mergethread['tid'] != $mergetid) {
         $query = $db->simple_select("threads", "*", "tid='{$mergetid}'");
         $mergethread = $db->fetch_array($query);
     }
     if (!isset($thread['tid']) || $thread['tid'] != $tid) {
         $query = $db->simple_select("threads", "*", "tid='{$tid}'");
         $thread = $db->fetch_array($query);
     }
     $pollsql = '';
     if ($mergethread['poll']) {
         $pollsql['poll'] = $mergethread['poll'];
         $sqlarray = array("tid" => $tid);
         $db->update_query("polls", $sqlarray, "tid='" . intval($mergethread['tid']) . "'");
     } else {
         $query = $db->simple_select("threads", "*", "poll='{$mergethread['poll']}' AND tid != '{$mergetid}'");
         $pollcheck = $db->fetch_array($query);
         if (!$pollcheck['poll']) {
             $db->delete_query("polls", "pid='{$mergethread['poll']}'");
             $db->delete_query("pollvotes", "pid='{$mergethread['poll']}'");
         }
     }
     $subject = $db->escape_string($subject);
     $sqlarray = array("tid" => $tid, "fid" => $thread['fid'], "replyto" => 0);
     $db->update_query("posts", $sqlarray, "tid='{$mergetid}'");
     $pollsql['subject'] = $subject;
     $db->update_query("threads", $pollsql, "tid='{$tid}'");
     $sqlarray = array("closed" => "moved|{$tid}");
     $db->update_query("threads", $sqlarray, "closed='moved|{$mergetid}'");
     $sqlarray = array("tid" => $tid);
     $db->update_query("threadsubscriptions", $sqlarray, "tid='{$mergetid}'");
     update_first_post($tid);
     $arguments = array("mergetid" => $mergetid, "tid" => $tid, "subject" => $subject);
     $plugins->run_hooks("class_moderation_merge_threads", $arguments);
     $this->delete_thread($mergetid);
     $updated_stats = array("replies" => '+' . ($mergethread['replies'] + 1), "unapprovedposts" => "+{$mergethread['unapprovedposts']}", "attachmentcount" => "+{$mergethread['attachmentcount']}");
     update_thread_counters($tid, $updated_stats);
     // Thread is not in current forum
     if ($mergethread['fid'] != $thread['fid']) {
         // If new thread is unapproved, implied counter comes in to effect
         if ($thread['visible'] == 0) {
             $updated_stats = array("unapprovedposts" => '+' . ($mergethread['replies'] + $mergethread['unapprovedposts']));
         } else {
             $updated_stats = array("posts" => '+' . ($mergethread['replies'] + 1), "unapprovedposts" => "+{$mergethread['unapprovedposts']}");
         }
         update_forum_counters($thread['fid'], $updated_stats);
     }
     return true;
 }
/**
 * Upload an attachment in to the file system
 *
 * @param array Attachment data (as fed by PHPs $_FILE)
 * @return array Array of attachment data if successful, otherwise array of error data
 */
function upload_attachment($attachment)
{
    global $db, $theme, $templates, $posthash, $pid, $tid, $forum, $mybb, $lang, $plugins, $cache;
    $posthash = $db->escape_string($mybb->input['posthash']);
    if (isset($attachment['error']) && $attachment['error'] != 0) {
        $ret['error'] = $lang->error_uploadfailed . $lang->error_uploadfailed_detail;
        switch ($attachment['error']) {
            case 1:
                // UPLOAD_ERR_INI_SIZE
                $ret['error'] .= $lang->error_uploadfailed_php1;
                break;
            case 2:
                // UPLOAD_ERR_FORM_SIZE
                $ret['error'] .= $lang->error_uploadfailed_php2;
                break;
            case 3:
                // UPLOAD_ERR_PARTIAL
                $ret['error'] .= $lang->error_uploadfailed_php3;
                break;
            case 4:
                // UPLOAD_ERR_NO_FILE
                $ret['error'] .= $lang->error_uploadfailed_php4;
                break;
            case 6:
                // UPLOAD_ERR_NO_TMP_DIR
                $ret['error'] .= $lang->error_uploadfailed_php6;
                break;
            case 7:
                // UPLOAD_ERR_CANT_WRITE
                $ret['error'] .= $lang->error_uploadfailed_php7;
                break;
            default:
                $ret['error'] .= $lang->sprintf($lang->error_uploadfailed_phpx, $attachment['error']);
                break;
        }
        return $ret;
    }
    if (!is_uploaded_file($attachment['tmp_name']) || empty($attachment['tmp_name'])) {
        $ret['error'] = $lang->error_uploadfailed . $lang->error_uploadfailed_php4;
        return $ret;
    }
    $ext = get_extension($attachment['name']);
    // Check if we have a valid extension
    $query = $db->simple_select("attachtypes", "*", "extension='" . $db->escape_string($ext) . "'");
    $attachtype = $db->fetch_array($query);
    if (!$attachtype['atid']) {
        $ret['error'] = $lang->error_attachtype;
        return $ret;
    }
    // Check the size
    if ($attachment['size'] > $attachtype['maxsize'] * 1024 && $attachtype['maxsize'] != "") {
        $ret['error'] = $lang->sprintf($lang->error_attachsize, $attachtype['maxsize']);
        return $ret;
    }
    // Double check attachment space usage
    if ($mybb->usergroup['attachquota'] > 0) {
        $query = $db->simple_select("attachments", "SUM(filesize) AS ausage", "uid='" . $mybb->user['uid'] . "'");
        $usage = $db->fetch_array($query);
        $usage = $usage['ausage'] + $attachment['size'];
        if ($usage > $mybb->usergroup['attachquota'] * 1024) {
            $friendlyquota = get_friendly_size($mybb->usergroup['attachquota'] * 1024);
            $ret['error'] = $lang->sprintf($lang->error_reachedattachquota, $friendlyquota);
            return $ret;
        }
    }
    // Check if an attachment with this name is already in the post
    $query = $db->simple_select("attachments", "*", "filename='" . $db->escape_string($attachment['name']) . "' AND (posthash='{$posthash}' OR (pid='" . intval($pid) . "' AND pid!='0'))");
    $prevattach = $db->fetch_array($query);
    if ($prevattach['aid']) {
        $ret['error'] = $lang->error_alreadyuploaded;
        return $ret;
    }
    // Check if the attachment directory (YYYYMM) exists, if not, create it
    $month_dir = gmdate("Ym");
    if (!@is_dir($mybb->settings['uploadspath'] . "/" . $month_dir)) {
        @mkdir($mybb->settings['uploadspath'] . "/" . $month_dir);
        // Still doesn't exist - oh well, throw it in the main directory
        if (!@is_dir($mybb->settings['uploadspath'] . "/" . $month_dir)) {
            $month_dir = '';
        }
    }
    // If safe_mode is enabled, don't attempt to use the monthly directories as it won't work
    if (ini_get('safe_mode') == 1 || strtolower(ini_get('safe_mode')) == 'on') {
        $month_dir = '';
    }
    // All seems to be good, lets move the attachment!
    $filename = "post_" . $mybb->user['uid'] . "_" . TIME_NOW . "_" . md5(random_str()) . ".attach";
    $file = upload_file($attachment, $mybb->settings['uploadspath'] . "/" . $month_dir, $filename);
    // Failed to create the attachment in the monthly directory, just throw it in the main directory
    if ($file['error'] && $month_dir) {
        $file = upload_file($attachment, $mybb->settings['uploadspath'] . '/', $filename);
    }
    if ($month_dir) {
        $filename = $month_dir . "/" . $filename;
    }
    if ($file['error']) {
        $ret['error'] = $lang->error_uploadfailed . $lang->error_uploadfailed_detail;
        switch ($file['error']) {
            case 1:
                $ret['error'] .= $lang->error_uploadfailed_nothingtomove;
                break;
            case 2:
                $ret['error'] .= $lang->error_uploadfailed_movefailed;
                break;
        }
        return $ret;
    }
    // Lets just double check that it exists
    if (!file_exists($mybb->settings['uploadspath'] . "/" . $filename)) {
        $ret['error'] = $lang->error_uploadfailed . $lang->error_uploadfailed_detail . $lang->error_uploadfailed_lost;
        return $ret;
    }
    // Generate the array for the insert_query
    $attacharray = array("pid" => intval($pid), "posthash" => $posthash, "uid" => $mybb->user['uid'], "filename" => $db->escape_string($file['original_filename']), "filetype" => $db->escape_string($file['type']), "filesize" => intval($file['size']), "attachname" => $filename, "downloads" => 0, "dateuploaded" => TIME_NOW);
    // If we're uploading an image, check the MIME type compared to the image type and attempt to generate a thumbnail
    if ($ext == "gif" || $ext == "png" || $ext == "jpg" || $ext == "jpeg" || $ext == "jpe") {
        // Check a list of known MIME types to establish what kind of image we're uploading
        switch (my_strtolower($file['type'])) {
            case "image/gif":
                $img_type = 1;
                break;
            case "image/jpeg":
            case "image/x-jpg":
            case "image/x-jpeg":
            case "image/pjpeg":
            case "image/jpg":
                $img_type = 2;
                break;
            case "image/png":
            case "image/x-png":
                $img_type = 3;
                break;
            default:
                $img_type = 0;
        }
        $supported_mimes = array();
        $attachtypes = $cache->read("attachtypes");
        foreach ($attachtypes as $attachtype) {
            if (!empty($attachtype['mimetype'])) {
                $supported_mimes[] = $attachtype['mimetype'];
            }
        }
        // Check if the uploaded file type matches the correct image type (returned by getimagesize)
        $img_dimensions = @getimagesize($mybb->settings['uploadspath'] . "/" . $filename);
        if (!is_array($img_dimensions) || $img_dimensions[2] != $img_type && !in_array(mime_content_type($filename), $supported_mimes)) {
            @unlink($mybb->settings['uploadspath'] . "/" . $filename);
            $ret['error'] = $lang->error_uploadfailed;
            return $ret;
        }
        require_once MYBB_ROOT . "inc/functions_image.php";
        $thumbname = str_replace(".attach", "_thumb.{$ext}", $filename);
        $thumbnail = generate_thumbnail($mybb->settings['uploadspath'] . "/" . $filename, $mybb->settings['uploadspath'], $thumbname, $mybb->settings['attachthumbh'], $mybb->settings['attachthumbw']);
        if ($thumbnail['filename']) {
            $attacharray['thumbnail'] = $thumbnail['filename'];
        } elseif ($thumbnail['code'] == 4) {
            $attacharray['thumbnail'] = "SMALL";
        }
    }
    if ($forum['modattachments'] == 1 && !is_moderator($forum['fid'], "", $mybb->user['uid'])) {
        $attacharray['visible'] = 0;
    } else {
        $attacharray['visible'] = 1;
    }
    $plugins->run_hooks_by_ref("upload_attachment_do_insert", $attacharray);
    $aid = $db->insert_query("attachments", $attacharray);
    if ($tid) {
        update_thread_counters($tid, array("attachmentcount" => "+1"));
    }
    $ret['aid'] = $aid;
    return $ret;
}