public function submit_post_end($event)
    {
        if ($event['mode'] == 'edit') {
            // we need to ensure that what we are resetting is appropriate
            // do we care about when someone edits the first post of a topic?
            // $event['data']['topic_first_post_id'] == $event['data']['post_id'] $post_mode = 'edit_first_post'
            $ext_post_mode = '';
            if ($event['data']['topic_posts_approved'] + $event['data']['topic_posts_unapproved'] + $event['data']['topic_posts_softdeleted'] == 1) {
                $ext_post_mode = 'edit_topic';
            } else {
                if ($event['data']['topic_last_post_id'] == $event['data']['post_id']) {
                    $ext_post_mode = 'edit_last_post';
                }
            }
            if ($ext_post_mode == 'edit_last_post' || $ext_post_mode == 'edit_topic') {
                $sql = 'UPDATE ' . POSTS_TABLE . '
					SET post_time = ' . time() . '
					WHERE post_id = ' . $event['data']['post_id'] . '
						AND topic_id = ' . $event['data']['topic_id'];
                $this->db->sql_query($sql);
                $sql = 'UPDATE ' . TOPICS_TABLE . '
					SET topic_last_post_time = ' . time() . '
					WHERE topic_id = ' . $event['data']['topic_id'];
                $this->db->sql_query($sql);
                if (!function_exists('update_post_information')) {
                    include $this->root_path . 'includes/functions_posting.' . $this->php_ext;
                }
                update_post_information('forum', $event['data']['forum_id']);
                markread('post', $event['data']['forum_id'], $event['data']['topic_id'], $event['data']['post_time']);
            }
        }
    }
Example #2
0
/**
* Delete Post
*/
function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $softdelete_reason = '')
{
    global $db, $user, $auth, $phpbb_container;
    global $config, $phpEx, $phpbb_root_path;
    // Specify our post mode
    $post_mode = 'delete';
    if ($data['topic_first_post_id'] === $data['topic_last_post_id'] && $data['topic_posts_approved'] + $data['topic_posts_unapproved'] + $data['topic_posts_softdeleted'] == 1) {
        $post_mode = 'delete_topic';
    } else {
        if ($data['topic_first_post_id'] == $post_id) {
            $post_mode = 'delete_first_post';
        } else {
            if ($data['topic_last_post_id'] == $post_id) {
                $post_mode = 'delete_last_post';
            }
        }
    }
    $sql_data = array();
    $next_post_id = false;
    include_once $phpbb_root_path . 'includes/functions_admin.' . $phpEx;
    $db->sql_transaction('begin');
    // we must make sure to update forums that contain the shadow'd topic
    if ($post_mode == 'delete_topic') {
        $shadow_forum_ids = array();
        $sql = 'SELECT forum_id
			FROM ' . TOPICS_TABLE . '
			WHERE ' . $db->sql_in_set('topic_moved_id', $topic_id);
        $result = $db->sql_query($sql);
        while ($row = $db->sql_fetchrow($result)) {
            if (!isset($shadow_forum_ids[(int) $row['forum_id']])) {
                $shadow_forum_ids[(int) $row['forum_id']] = 1;
            } else {
                $shadow_forum_ids[(int) $row['forum_id']]++;
            }
        }
        $db->sql_freeresult($result);
    }
    /* @var $phpbb_content_visibility \phpbb\content_visibility */
    $phpbb_content_visibility = $phpbb_container->get('content.visibility');
    // (Soft) delete the post
    if ($is_soft && $post_mode != 'delete_topic') {
        $phpbb_content_visibility->set_post_visibility(ITEM_DELETED, $post_id, $topic_id, $forum_id, $user->data['user_id'], time(), $softdelete_reason, $data['topic_first_post_id'] == $post_id, $data['topic_last_post_id'] == $post_id);
    } else {
        if (!$is_soft) {
            if (!delete_posts('post_id', array($post_id), false, false, false)) {
                // Try to delete topic, we may had an previous error causing inconsistency
                if ($post_mode == 'delete_topic') {
                    delete_topics('topic_id', array($topic_id), false);
                }
                trigger_error('ALREADY_DELETED');
            }
        }
    }
    $db->sql_transaction('commit');
    // Collect the necessary information for updating the tables
    $sql_data[FORUMS_TABLE] = $sql_data[TOPICS_TABLE] = '';
    switch ($post_mode) {
        case 'delete_topic':
            foreach ($shadow_forum_ids as $updated_forum => $topic_count) {
                // counting is fun! we only have to do sizeof($forum_ids) number of queries,
                // even if the topic is moved back to where its shadow lives (we count how many times it is in a forum)
                $sql = 'UPDATE ' . FORUMS_TABLE . '
					SET forum_topics_approved = forum_topics_approved - ' . $topic_count . '
					WHERE forum_id = ' . $updated_forum;
                $db->sql_query($sql);
                update_post_information('forum', $updated_forum);
            }
            if ($is_soft) {
                $topic_row = array();
                $phpbb_content_visibility->set_topic_visibility(ITEM_DELETED, $topic_id, $forum_id, $user->data['user_id'], time(), $softdelete_reason);
            } else {
                delete_topics('topic_id', array($topic_id), false);
                $phpbb_content_visibility->remove_topic_from_statistic($data, $sql_data);
                $update_sql = update_post_information('forum', $forum_id, true);
                if (sizeof($update_sql)) {
                    $sql_data[FORUMS_TABLE] .= $sql_data[FORUMS_TABLE] ? ', ' : '';
                    $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
                }
            }
            break;
        case 'delete_first_post':
            $sql = 'SELECT p.post_id, p.poster_id, p.post_time, p.post_username, u.username, u.user_colour
				FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u\n\t\t\t\tWHERE p.topic_id = {$topic_id}\n\t\t\t\t\tAND p.poster_id = u.user_id\n\t\t\t\t\tAND p.post_visibility = " . ITEM_APPROVED . '
				ORDER BY p.post_time ASC, p.post_id ASC';
            $result = $db->sql_query_limit($sql, 1);
            $row = $db->sql_fetchrow($result);
            $db->sql_freeresult($result);
            if (!$row) {
                // No approved post, so the first is a not-approved post (unapproved or soft deleted)
                $sql = 'SELECT p.post_id, p.poster_id, p.post_time, p.post_username, u.username, u.user_colour
					FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u\n\t\t\t\t\tWHERE p.topic_id = {$topic_id}\n\t\t\t\t\t\tAND p.poster_id = u.user_id\n\t\t\t\t\tORDER BY p.post_time ASC, p.post_id ASC";
                $result = $db->sql_query_limit($sql, 1);
                $row = $db->sql_fetchrow($result);
                $db->sql_freeresult($result);
            }
            $next_post_id = (int) $row['post_id'];
            $sql_data[TOPICS_TABLE] = $db->sql_build_array('UPDATE', array('topic_poster' => (int) $row['poster_id'], 'topic_first_post_id' => (int) $row['post_id'], 'topic_first_poster_colour' => $row['user_colour'], 'topic_first_poster_name' => $row['poster_id'] == ANONYMOUS ? $row['post_username'] : $row['username'], 'topic_time' => (int) $row['post_time']));
            break;
        case 'delete_last_post':
            if (!$is_soft) {
                // Update last post information when hard deleting. Soft delete already did that by itself.
                $update_sql = update_post_information('forum', $forum_id, true);
                if (sizeof($update_sql)) {
                    $sql_data[FORUMS_TABLE] = ($sql_data[FORUMS_TABLE] ? $sql_data[FORUMS_TABLE] . ', ' : '') . implode(', ', $update_sql[$forum_id]);
                }
                $sql_data[TOPICS_TABLE] = ($sql_data[TOPICS_TABLE] ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_bumped = 0, topic_bumper = 0';
                $update_sql = update_post_information('topic', $topic_id, true);
                if (!empty($update_sql)) {
                    $sql_data[TOPICS_TABLE] .= ', ' . implode(', ', $update_sql[$topic_id]);
                    $next_post_id = (int) str_replace('topic_last_post_id = ', '', $update_sql[$topic_id][0]);
                }
            }
            if (!$next_post_id) {
                $sql = 'SELECT MAX(post_id) as last_post_id
					FROM ' . POSTS_TABLE . "\n\t\t\t\t\tWHERE topic_id = {$topic_id}\n\t\t\t\t\t\tAND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id);
                $result = $db->sql_query($sql);
                $next_post_id = (int) $db->sql_fetchfield('last_post_id');
                $db->sql_freeresult($result);
            }
            break;
        case 'delete':
            $sql = 'SELECT post_id
				FROM ' . POSTS_TABLE . "\n\t\t\t\tWHERE topic_id = {$topic_id}\n\t\t\t\t\tAND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id) . '
					AND post_time > ' . $data['post_time'] . '
				ORDER BY post_time ASC, post_id ASC';
            $result = $db->sql_query_limit($sql, 1);
            $next_post_id = (int) $db->sql_fetchfield('post_id');
            $db->sql_freeresult($result);
            break;
    }
    if ($post_mode == 'delete' || $post_mode == 'delete_last_post' || $post_mode == 'delete_first_post') {
        if (!$is_soft) {
            $phpbb_content_visibility->remove_post_from_statistic($data, $sql_data);
        }
        $sql = 'SELECT 1 AS has_attachments
			FROM ' . ATTACHMENTS_TABLE . '
			WHERE topic_id = ' . $topic_id;
        $result = $db->sql_query_limit($sql, 1);
        $has_attachments = (int) $db->sql_fetchfield('has_attachments');
        $db->sql_freeresult($result);
        if (!$has_attachments) {
            $sql_data[TOPICS_TABLE] = ($sql_data[TOPICS_TABLE] ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_attachment = 0';
        }
    }
    $db->sql_transaction('begin');
    $where_sql = array(FORUMS_TABLE => "forum_id = {$forum_id}", TOPICS_TABLE => "topic_id = {$topic_id}", USERS_TABLE => 'user_id = ' . $data['poster_id']);
    foreach ($sql_data as $table => $update_sql) {
        if ($update_sql) {
            $db->sql_query("UPDATE {$table} SET {$update_sql} WHERE " . $where_sql[$table]);
        }
    }
    // Adjust posted info for this user by looking for a post by him/her within this topic...
    if ($post_mode != 'delete_topic' && $config['load_db_track'] && $data['poster_id'] != ANONYMOUS) {
        $sql = 'SELECT poster_id
			FROM ' . POSTS_TABLE . '
			WHERE topic_id = ' . $topic_id . '
				AND poster_id = ' . $data['poster_id'];
        $result = $db->sql_query_limit($sql, 1);
        $poster_id = (int) $db->sql_fetchfield('poster_id');
        $db->sql_freeresult($result);
        // The user is not having any more posts within this topic
        if (!$poster_id) {
            $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . '
				WHERE topic_id = ' . $topic_id . '
					AND user_id = ' . $data['poster_id'];
            $db->sql_query($sql);
        }
    }
    $db->sql_transaction('commit');
    if ($data['post_reported'] && $post_mode != 'delete_topic') {
        sync('topic_reported', 'topic_id', array($topic_id));
    }
    return $next_post_id;
}
Example #3
0
/**
* Disapprove Post/Topic
*/
function disapprove_post($post_id_list, $id, $mode)
{
    global $db, $template, $user, $config;
    global $phpEx, $phpbb_root_path;
    if (!check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve'))) {
        trigger_error('NOT_AUTHORISED');
    }
    $redirect = request_var('redirect', build_url(array('t', 'mode', 'quickmod')) . "&mode={$mode}");
    $reason = utf8_normalize_nfc(request_var('reason', '', true));
    $reason_id = request_var('reason_id', 0);
    $success_msg = $additional_msg = '';
    $s_hidden_fields = build_hidden_fields(array('i' => $id, 'mode' => $mode, 'post_id_list' => $post_id_list, 'action' => 'disapprove', 'redirect' => $redirect));
    $notify_poster = isset($_REQUEST['notify_poster']) ? true : false;
    $disapprove_reason = '';
    if ($reason_id) {
        $sql = 'SELECT reason_title, reason_description
			FROM ' . REPORTS_REASONS_TABLE . "\n\t\t\tWHERE reason_id = {$reason_id}";
        $result = $db->sql_query($sql);
        $row = $db->sql_fetchrow($result);
        $db->sql_freeresult($result);
        if (!$row || !$reason && strtolower($row['reason_title']) == 'other') {
            $additional_msg = $user->lang['NO_REASON_DISAPPROVAL'];
            unset($_POST['confirm']);
        } else {
            // If the reason is defined within the language file, we will use the localized version, else just use the database entry...
            $disapprove_reason = strtolower($row['reason_title']) != 'other' ? isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])] : $row['reason_description'] : '';
            $disapprove_reason .= $reason ? "\n\n" . $reason : '';
            if (isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) {
                $disapprove_reason_lang = strtoupper($row['reason_title']);
            }
            $email_disapprove_reason = $disapprove_reason;
        }
    }
    $post_info = get_post_data($post_id_list, 'm_approve');
    if (confirm_box(true)) {
        // If Topic -> forum_topics_real -= 1
        // If Post -> topic_replies_real -= 1
        $num_disapproved = 0;
        $forum_topics_real = $topic_id_list = $forum_id_list = $topic_replies_real_sql = $post_disapprove_sql = $disapprove_log = array();
        foreach ($post_info as $post_id => $post_data) {
            $topic_id_list[$post_data['topic_id']] = 1;
            if ($post_data['forum_id']) {
                $forum_id_list[$post_data['forum_id']] = 1;
            }
            // Topic or Post. ;)
            /**
             * @todo this probably is a different method than the one used by delete_posts, does this cause counter inconsistency?
             */
            if ($post_data['topic_first_post_id'] == $post_id && $post_data['topic_last_post_id'] == $post_id) {
                if ($post_data['forum_id']) {
                    if (!isset($forum_topics_real[$post_data['forum_id']])) {
                        $forum_topics_real[$post_data['forum_id']] = 0;
                    }
                    $forum_topics_real[$post_data['forum_id']]++;
                    $num_disapproved++;
                }
                $disapprove_log[] = array('type' => 'topic', 'post_subject' => $post_data['post_subject'], 'forum_id' => $post_data['forum_id'], 'topic_id' => 0);
            } else {
                if (!isset($topic_replies_real_sql[$post_data['topic_id']])) {
                    $topic_replies_real_sql[$post_data['topic_id']] = 0;
                }
                $topic_replies_real_sql[$post_data['topic_id']]++;
                $disapprove_log[] = array('type' => 'post', 'post_subject' => $post_data['post_subject'], 'forum_id' => $post_data['forum_id'], 'topic_id' => $post_data['topic_id']);
            }
            $post_disapprove_sql[] = $post_id;
        }
        unset($post_data);
        if (sizeof($forum_topics_real)) {
            foreach ($forum_topics_real as $forum_id => $topics_real) {
                $sql = 'UPDATE ' . FORUMS_TABLE . "\n\t\t\t\t\tSET forum_topics_real = forum_topics_real - {$topics_real}\n\t\t\t\t\tWHERE forum_id = {$forum_id}";
                $db->sql_query($sql);
            }
        }
        if (sizeof($topic_replies_real_sql)) {
            foreach ($topic_replies_real_sql as $topic_id => $num_replies) {
                $sql = 'UPDATE ' . TOPICS_TABLE . "\n\t\t\t\t\tSET topic_replies_real = topic_replies_real - {$num_replies}\n\t\t\t\t\tWHERE topic_id = {$topic_id}";
                $db->sql_query($sql);
            }
        }
        if (sizeof($post_disapprove_sql)) {
            if (!function_exists('delete_posts')) {
                include_once $phpbb_root_path . 'includes/functions_admin.' . $phpEx;
            }
            // We do not check for permissions here, because the moderator allowed approval/disapproval should be allowed to delete the disapproved posts
            delete_posts('post_id', $post_disapprove_sql);
            foreach ($disapprove_log as $log_data) {
                add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $log_data['type'] == 'topic' ? 'LOG_TOPIC_DISAPPROVED' : 'LOG_POST_DISAPPROVED', $log_data['post_subject'], $disapprove_reason);
            }
        }
        unset($post_disapprove_sql, $topic_replies_real_sql);
        update_post_information('topic', array_keys($topic_id_list));
        if (sizeof($forum_id_list)) {
            update_post_information('forum', array_keys($forum_id_list));
        }
        unset($topic_id_list, $forum_id_list);
        $messenger = new messenger();
        // Notify Poster?
        if ($notify_poster) {
            $lang_reasons = array();
            foreach ($post_info as $post_id => $post_data) {
                if ($post_data['poster_id'] == ANONYMOUS) {
                    continue;
                }
                if (isset($disapprove_reason_lang)) {
                    // Okay we need to get the reason from the posters language
                    if (!isset($lang_reasons[$post_data['user_lang']])) {
                        // Assign the current users translation as the default, this is not ideal but getting the board default adds another layer of complexity.
                        $lang_reasons[$post_data['user_lang']] = $user->lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang];
                        // Only load up the language pack if the language is different to the current one
                        if ($post_data['user_lang'] != $user->lang_name && file_exists($phpbb_root_path . '/language/' . $post_data['user_lang'] . '/mcp.' . $phpEx)) {
                            // Load up the language pack
                            $lang = array();
                            @(include $phpbb_root_path . '/language/' . $post_data['user_lang'] . '/mcp.' . $phpEx);
                            // If we find the reason in this language pack use it
                            if (isset($lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang])) {
                                $lang_reasons[$post_data['user_lang']] = $lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang];
                            }
                            unset($lang);
                            // Free memory
                        }
                    }
                    $email_disapprove_reason = $lang_reasons[$post_data['user_lang']];
                    $email_disapprove_reason .= $reason ? "\n\n" . $reason : '';
                }
                $email_template = $post_data['post_id'] == $post_data['topic_first_post_id'] && $post_data['post_id'] == $post_data['topic_last_post_id'] ? 'topic_disapproved' : 'post_disapproved';
                $messenger->template($email_template, $post_data['user_lang']);
                $messenger->to($post_data['user_email'], $post_data['username']);
                $messenger->im($post_data['user_jabber'], $post_data['username']);
                $messenger->assign_vars(array('USERNAME' => htmlspecialchars_decode($post_data['username']), 'REASON' => htmlspecialchars_decode($email_disapprove_reason), 'POST_SUBJECT' => htmlspecialchars_decode(censor_text($post_data['post_subject'])), 'TOPIC_TITLE' => htmlspecialchars_decode(censor_text($post_data['topic_title']))));
                $messenger->send($post_data['user_notify_type']);
            }
            unset($lang_reasons);
        }
        unset($post_info, $disapprove_reason, $email_disapprove_reason, $disapprove_reason_lang);
        $messenger->save_queue();
        if (sizeof($forum_topics_real)) {
            $success_msg = $num_disapproved == 1 ? 'TOPIC_DISAPPROVED_SUCCESS' : 'TOPICS_DISAPPROVED_SUCCESS';
        } else {
            $success_msg = sizeof($post_id_list) == 1 ? 'POST_DISAPPROVED_SUCCESS' : 'POSTS_DISAPPROVED_SUCCESS';
        }
    } else {
        include_once $phpbb_root_path . 'includes/functions_display.' . $phpEx;
        display_reasons($reason_id);
        $show_notify = false;
        foreach ($post_info as $post_data) {
            if ($post_data['poster_id'] == ANONYMOUS) {
                continue;
            } else {
                $show_notify = true;
                break;
            }
        }
        $template->assign_vars(array('S_NOTIFY_POSTER' => $show_notify, 'S_APPROVE' => false, 'REASON' => $reason, 'ADDITIONAL_MSG' => $additional_msg));
        confirm_box(false, 'DISAPPROVE_POST' . (sizeof($post_id_list) == 1 ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html');
    }
    $redirect = request_var('redirect', "index.{$phpEx}");
    $redirect = reapply_sid($redirect);
    if (!$success_msg) {
        redirect($redirect);
    } else {
        meta_refresh(3, $redirect);
        trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], "<a href=\"{$redirect}\">", '</a>'));
    }
}
/**
* Delete Post
*/
function delete_post($forum_id, $topic_id, $post_id, &$data)
{
    global $db, $user, $auth;
    global $config, $phpEx, $phpbb_root_path;
    // Specify our post mode
    $post_mode = 'delete';
    if ($data['topic_first_post_id'] === $data['topic_last_post_id'] && $data['topic_replies_real'] == 0) {
        $post_mode = 'delete_topic';
    } else {
        if ($data['topic_first_post_id'] == $post_id) {
            $post_mode = 'delete_first_post';
        } else {
            if ($data['topic_last_post_id'] == $post_id) {
                $post_mode = 'delete_last_post';
            }
        }
    }
    $sql_data = array();
    $next_post_id = false;
    include_once $phpbb_root_path . 'includes/functions_admin.' . $phpEx;
    $db->sql_transaction('begin');
    // we must make sure to update forums that contain the shadow'd topic
    if ($post_mode == 'delete_topic') {
        $shadow_forum_ids = array();
        $sql = 'SELECT forum_id
			FROM ' . TOPICS_TABLE . '
			WHERE ' . $db->sql_in_set('topic_moved_id', $topic_id);
        $result = $db->sql_query($sql);
        while ($row = $db->sql_fetchrow($result)) {
            if (!isset($shadow_forum_ids[(int) $row['forum_id']])) {
                $shadow_forum_ids[(int) $row['forum_id']] = 1;
            } else {
                $shadow_forum_ids[(int) $row['forum_id']]++;
            }
        }
        $db->sql_freeresult($result);
    }
    if (!delete_posts('post_id', array($post_id), false, false)) {
        // Try to delete topic, we may had an previous error causing inconsistency
        if ($post_mode == 'delete_topic') {
            delete_topics('topic_id', array($topic_id), false);
        }
        trigger_error('ALREADY_DELETED');
    }
    $db->sql_transaction('commit');
    // Collect the necessary information for updating the tables
    $sql_data[FORUMS_TABLE] = '';
    switch ($post_mode) {
        case 'delete_topic':
            foreach ($shadow_forum_ids as $updated_forum => $topic_count) {
                // counting is fun! we only have to do sizeof($forum_ids) number of queries,
                // even if the topic is moved back to where its shadow lives (we count how many times it is in a forum)
                $db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET forum_topics_real = forum_topics_real - ' . $topic_count . ', forum_topics = forum_topics - ' . $topic_count . ' WHERE forum_id = ' . $updated_forum);
                update_post_information('forum', $updated_forum);
            }
            delete_topics('topic_id', array($topic_id), false);
            if ($data['topic_type'] != POST_GLOBAL) {
                $sql_data[FORUMS_TABLE] .= 'forum_topics_real = forum_topics_real - 1';
                $sql_data[FORUMS_TABLE] .= $data['topic_approved'] ? ', forum_posts = forum_posts - 1, forum_topics = forum_topics - 1' : '';
            }
            $update_sql = update_post_information('forum', $forum_id, true);
            if (sizeof($update_sql)) {
                $sql_data[FORUMS_TABLE] .= $sql_data[FORUMS_TABLE] ? ', ' : '';
                $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
            }
            break;
        case 'delete_first_post':
            $sql = 'SELECT p.post_id, p.poster_id, p.post_time, p.post_username, u.username, u.user_colour
				FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u\n\t\t\t\tWHERE p.topic_id = {$topic_id}\n\t\t\t\t\tAND p.poster_id = u.user_id\n\t\t\t\tORDER BY p.post_time ASC";
            $result = $db->sql_query_limit($sql, 1);
            $row = $db->sql_fetchrow($result);
            $db->sql_freeresult($result);
            if ($data['topic_type'] != POST_GLOBAL) {
                $sql_data[FORUMS_TABLE] = $data['post_approved'] ? 'forum_posts = forum_posts - 1' : '';
            }
            $sql_data[TOPICS_TABLE] = 'topic_poster = ' . intval($row['poster_id']) . ', topic_first_post_id = ' . intval($row['post_id']) . ", topic_first_poster_colour = '" . $db->sql_escape($row['user_colour']) . "', topic_first_poster_name = '" . ($row['poster_id'] == ANONYMOUS ? $db->sql_escape($row['post_username']) : $db->sql_escape($row['username'])) . "', topic_time = " . (int) $row['post_time'];
            // Decrementing topic_replies here is fine because this case only happens if there is more than one post within the topic - basically removing one "reply"
            $sql_data[TOPICS_TABLE] .= ', topic_replies_real = topic_replies_real - 1' . ($data['post_approved'] ? ', topic_replies = topic_replies - 1' : '');
            $next_post_id = (int) $row['post_id'];
            break;
        case 'delete_last_post':
            if ($data['topic_type'] != POST_GLOBAL) {
                $sql_data[FORUMS_TABLE] = $data['post_approved'] ? 'forum_posts = forum_posts - 1' : '';
            }
            $update_sql = update_post_information('forum', $forum_id, true);
            if (sizeof($update_sql)) {
                $sql_data[FORUMS_TABLE] .= $sql_data[FORUMS_TABLE] ? ', ' : '';
                $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]);
            }
            $sql_data[TOPICS_TABLE] = 'topic_bumped = 0, topic_bumper = 0, topic_replies_real = topic_replies_real - 1' . ($data['post_approved'] ? ', topic_replies = topic_replies - 1' : '');
            $update_sql = update_post_information('topic', $topic_id, true);
            if (sizeof($update_sql)) {
                $sql_data[TOPICS_TABLE] .= ', ' . implode(', ', $update_sql[$topic_id]);
                $next_post_id = (int) str_replace('topic_last_post_id = ', '', $update_sql[$topic_id][0]);
            } else {
                $sql = 'SELECT MAX(post_id) as last_post_id
					FROM ' . POSTS_TABLE . "\n\t\t\t\t\tWHERE topic_id = {$topic_id} " . (!$auth->acl_get('m_approve', $forum_id) ? 'AND post_approved = 1' : '');
                $result = $db->sql_query($sql);
                $row = $db->sql_fetchrow($result);
                $db->sql_freeresult($result);
                $next_post_id = (int) $row['last_post_id'];
            }
            break;
        case 'delete':
            $sql = 'SELECT post_id
				FROM ' . POSTS_TABLE . "\n\t\t\t\tWHERE topic_id = {$topic_id} " . (!$auth->acl_get('m_approve', $forum_id) ? 'AND post_approved = 1' : '') . '
					AND post_time > ' . $data['post_time'] . '
				ORDER BY post_time ASC';
            $result = $db->sql_query_limit($sql, 1);
            $row = $db->sql_fetchrow($result);
            $db->sql_freeresult($result);
            if ($data['topic_type'] != POST_GLOBAL) {
                $sql_data[FORUMS_TABLE] = $data['post_approved'] ? 'forum_posts = forum_posts - 1' : '';
            }
            $sql_data[TOPICS_TABLE] = 'topic_replies_real = topic_replies_real - 1' . ($data['post_approved'] ? ', topic_replies = topic_replies - 1' : '');
            $next_post_id = (int) $row['post_id'];
            break;
    }
    if ($post_mode == 'delete' || $post_mode == 'delete_last_post' || $post_mode == 'delete_first_post') {
        $sql = 'SELECT 1 AS has_attachments
			FROM ' . ATTACHMENTS_TABLE . '
			WHERE topic_id = ' . $topic_id;
        $result = $db->sql_query_limit($sql, 1);
        $has_attachments = (int) $db->sql_fetchfield('has_attachments');
        $db->sql_freeresult($result);
        if (!$has_attachments) {
            $sql_data[TOPICS_TABLE] .= ', topic_attachment = 0';
        }
    }
    //	$sql_data[USERS_TABLE] = ($data['post_postcount']) ? 'user_posts = user_posts - 1' : '';
    $db->sql_transaction('begin');
    $where_sql = array(FORUMS_TABLE => "forum_id = {$forum_id}", TOPICS_TABLE => "topic_id = {$topic_id}", USERS_TABLE => 'user_id = ' . $data['poster_id']);
    foreach ($sql_data as $table => $update_sql) {
        if ($update_sql) {
            $db->sql_query("UPDATE {$table} SET {$update_sql} WHERE " . $where_sql[$table]);
        }
    }
    // Adjust posted info for this user by looking for a post by him/her within this topic...
    if ($post_mode != 'delete_topic' && $config['load_db_track'] && $data['poster_id'] != ANONYMOUS) {
        $sql = 'SELECT poster_id
			FROM ' . POSTS_TABLE . '
			WHERE topic_id = ' . $topic_id . '
				AND poster_id = ' . $data['poster_id'];
        $result = $db->sql_query_limit($sql, 1);
        $poster_id = (int) $db->sql_fetchfield('poster_id');
        $db->sql_freeresult($result);
        // The user is not having any more posts within this topic
        if (!$poster_id) {
            $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . '
				WHERE topic_id = ' . $topic_id . '
					AND user_id = ' . $data['poster_id'];
            $db->sql_query($sql);
        }
    }
    $db->sql_transaction('commit');
    if ($data['post_reported'] && $post_mode != 'delete_topic') {
        sync('topic_reported', 'topic_id', array($topic_id));
    }
    return $next_post_id;
}
Example #5
0
/**
* Disapprove Post/Topic
*/
function disapprove_post($post_id_list, $mode)
{
    global $db, $template, $user, $config;
    global $phpEx, $phpbb_root_path;
    if (!($forum_id = check_ids($post_id_list, POSTS_TABLE, 'post_id', 'm_approve'))) {
        trigger_error('NOT_AUTHORIZED');
    }
    $redirect = request_var('redirect', build_url(array('t', 'mode')) . '&amp;mode=unapproved_topics');
    $reason = request_var('reason', '', true);
    $reason_id = request_var('reason_id', 0);
    $success_msg = $additional_msg = '';
    $s_hidden_fields = build_hidden_fields(array('i' => 'queue', 'mode' => $mode, 'post_id_list' => $post_id_list, 'f' => $forum_id, 'action' => 'disapprove', 'redirect' => $redirect));
    $notify_poster = isset($_REQUEST['notify_poster']) ? true : false;
    $disapprove_reason = '';
    if ($reason_id) {
        $sql = 'SELECT reason_title, reason_description
			FROM ' . REPORTS_REASONS_TABLE . "\n\t\t\tWHERE reason_id = {$reason_id}";
        $result = $db->sql_query($sql);
        $row = $db->sql_fetchrow($result);
        $db->sql_freeresult($result);
        if (!$row || !$reason && $row['reason_title'] == 'other') {
            $additional_msg = $user->lang['NO_REASON_DISAPPROVAL'];
            unset($_POST['confirm']);
        } else {
            // If the reason is defined within the language file, we will use the localized version, else just use the database entry...
            $disapprove_reason = $row['reason_title'] != 'other' ? isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])] : $row['reason_description'] : '';
            $disapprove_reason .= $reason ? "\n\n" . $reason : '';
        }
    }
    if (confirm_box(true)) {
        $post_info = get_post_data($post_id_list, 'm_approve');
        // If Topic -> forum_topics_real -= 1
        // If Post -> topic_replies_real -= 1
        $forum_topics_real = 0;
        $topic_replies_real_sql = $post_disapprove_sql = $topic_id_list = array();
        foreach ($post_info as $post_id => $post_data) {
            $topic_id_list[$post_data['topic_id']] = 1;
            // Topic or Post. ;)
            if ($post_data['topic_first_post_id'] == $post_id && $post_data['topic_last_post_id'] == $post_id) {
                if ($post_data['forum_id']) {
                    $forum_topics_real++;
                }
            } else {
                if (!isset($topic_replies_real_sql[$post_data['topic_id']])) {
                    $topic_replies_real_sql[$post_data['topic_id']] = 1;
                } else {
                    $topic_replies_real_sql[$post_data['topic_id']]++;
                }
            }
            $post_disapprove_sql[] = $post_id;
        }
        if ($forum_topics_real) {
            $sql = 'UPDATE ' . FORUMS_TABLE . "\n\t\t\t\tSET forum_topics_real = forum_topics_real - {$forum_topics_real}\n\t\t\t\tWHERE forum_id = {$forum_id}";
            $db->sql_query($sql);
        }
        if (sizeof($topic_replies_real_sql)) {
            foreach ($topic_replies_real_sql as $topic_id => $num_replies) {
                $sql = 'UPDATE ' . TOPICS_TABLE . "\n\t\t\t\t\tSET topic_replies_real = topic_replies_real - {$num_replies}\n\t\t\t\t\tWHERE topic_id = {$topic_id}";
                $db->sql_query($sql);
            }
        }
        if (sizeof($post_disapprove_sql)) {
            if (!function_exists('delete_posts')) {
                include_once $phpbb_root_path . 'includes/functions_admin.' . $phpEx;
            }
            // We do not check for permissions here, because the moderator allowed approval/disapproval should be allowed to delete the disapproved posts
            delete_posts('post_id', $post_disapprove_sql);
        }
        unset($post_disapprove_sql, $topic_replies_real_sql);
        update_post_information('topic', array_keys($topic_id_list));
        update_post_information('forum', $forum_id);
        unset($topic_id_list);
        $messenger = new messenger();
        // Notify Poster?
        if ($notify_poster) {
            $email_sig = str_replace('<br />', "\n", "-- \n" . $config['board_email_sig']);
            foreach ($post_info as $post_id => $post_data) {
                if ($post_data['poster_id'] == ANONYMOUS) {
                    continue;
                }
                $email_template = $post_data['post_id'] == $post_data['topic_first_post_id'] && $post_data['post_id'] == $post_data['topic_last_post_id'] ? 'topic_disapproved' : 'post_disapproved';
                $messenger->template($email_template, $post_data['user_lang']);
                $messenger->replyto($config['board_email']);
                $messenger->to($post_data['user_email'], $post_data['username']);
                $messenger->im($post_data['user_jabber'], $post_data['username']);
                $messenger->assign_vars(array('EMAIL_SIG' => $email_sig, 'SITENAME' => $config['sitename'], 'USERNAME' => html_entity_decode($post_data['username']), 'REASON' => html_entity_decode($disapprove_reason), 'POST_SUBJECT' => html_entity_decode(censor_text($post_data['post_subject'])), 'TOPIC_TITLE' => html_entity_decode(censor_text($post_data['topic_title']))));
                $messenger->send($post_data['user_notify_type']);
                $messenger->reset();
            }
            $messenger->save_queue();
        }
        unset($post_info, $disapprove_reason);
        if ($forum_topics_real) {
            $success_msg = $forum_topics_real == 1 ? 'TOPIC_DISAPPROVED_SUCCESS' : 'TOPICS_DISAPPROVED_SUCCESS';
        } else {
            $success_msg = sizeof($post_id_list) == 1 ? 'POST_DISAPPROVED_SUCCESS' : 'POSTS_DISAPPROVED_SUCCESS';
        }
    } else {
        include_once $phpbb_root_path . 'includes/functions_display.' . $phpEx;
        display_reasons($reason_id);
        $template->assign_vars(array('S_NOTIFY_POSTER' => true, 'S_APPROVE' => false, 'REASON' => $reason, 'ADDITIONAL_MSG' => $additional_msg));
        confirm_box(false, 'DISAPPROVE_POST' . (sizeof($post_id_list) == 1 ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html');
    }
    $redirect = request_var('redirect', "index.{$phpEx}");
    $redirect = reapply_sid($redirect);
    if (!$success_msg) {
        redirect($redirect);
    } else {
        meta_refresh(3, $redirect);
        trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], "<a href=\"{$redirect}\">", '</a>'));
    }
}
    function update_first_last_post()
    {
        global $db;
        //topic_first_post
        $this->topic_first_post = array_unique($this->topic_first_post);
        foreach ($this->topic_first_post as $topic_id) {
            $sql = 'SELECT p.post_id, p.post_visibility, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour
					FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
					WHERE p.topic_id=' . $topic_id . '
					AND u.user_id = p.poster_id
					ORDER BY post_time ASC';
            $result = $db->sql_query_limit($sql, 1);
            if ($row = $db->sql_fetchrow($result)) {
                $this->set('topic', $topic_id, array('topic_time' => $row['post_time'], 'topic_poster' => $row['poster_id'], 'topic_visibility' => $row['post_visibility'], 'topic_first_post_id' => $row['post_id'], 'topic_first_poster_name' => $row['poster_id'] == ANONYMOUS ? $row['post_username'] : $row['username'], 'topic_first_poster_colour' => $row['user_colour']));
            }
        }
        //topic_last_post
        if (count($this->topic_last_post)) {
            $update_sql = update_post_information('topic', $this->topic_last_post, true);
            foreach ($update_sql as $topic_id => $sql) {
                $this->init('topic', $topic_id);
                $this->data['topic'][$topic_id]['sql'] += $sql;
            }
        }
        //forum_last_post
        if (count($this->forum_last_post)) {
            $update_sql = update_post_information('forum', $this->forum_last_post, true);
            foreach ($update_sql as $forum_id => $sql) {
                $this->init('forum', $forum_id);
                $this->data['forum'][$forum_id]['sql'] += $sql;
            }
        }
    }
Example #7
0
		$db->sql_transaction('begin');

		$sql = 'UPDATE ' . POSTS_TABLE . "
			SET post_time = $current_time
			WHERE post_id = {$post_data['topic_last_post_id']}
				AND topic_id = $topic_id";
		$db->sql_query($sql);

		$sql = 'UPDATE ' . TOPICS_TABLE . "
			SET topic_last_post_time = $current_time,
				topic_bumped = 1,
				topic_bumper = " . $user->data['user_id'] . "
			WHERE topic_id = $topic_id";
		$db->sql_query($sql);

		update_post_information('forum', $forum_id);

		$sql = 'UPDATE ' . USERS_TABLE . "
			SET user_lastpost_time = $current_time
			WHERE user_id = " . $user->data['user_id'];
		$db->sql_query($sql);

		$db->sql_transaction('commit');

		markread('post', $forum_id, $topic_id, $current_time);

		add_log('mod', $forum_id, $topic_id, 'LOG_BUMP_TOPIC', $post_data['topic_title']);

		$meta_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;p={$post_data['topic_last_post_id']}") . "#p{$post_data['topic_last_post_id']}";
		meta_refresh(3, $meta_url);
function disapprove_post($post_id_list)
{
    global $_CLASS, $_CORE_CONFIG, $config;
    if (!($forum_id = check_ids($post_id_list, POSTS_TABLE, 'post_id', 'm_approve'))) {
        trigger_error('NOT_AUTHORIZED');
    }
    $redirect = request_var('redirect', $_CLASS['core_user']->data['session_page']);
    $reason = request_var('reason', '');
    $reason_id = request_var('reason_id', 0);
    $success_msg = $additional_msg = '';
    $s_hidden_fields = build_hidden_fields(array('post_id_list' => $post_id_list, 'f' => $forum_id, 'mode' => 'disapprove', 'redirect' => $redirect));
    $notify_poster = isset($_REQUEST['notify_poster']) ? true : false;
    if ($reason_id) {
        $sql = 'SELECT reason_name 
			FROM ' . REASONS_TABLE . " \n\t\t\tWHERE reason_id = {$reason_id}";
        $result = $_CLASS['core_db']->query($sql);
        if (!($row = $_CLASS['core_db']->fetch_row_assoc($result)) || !$reason && $row['reason_name'] == 'other') {
            $additional_msg = 'Please give an appropiate reason for disapproval';
            unset($_POST['confirm']);
        } else {
            $disapprove_reason = $row['reason_name'] != 'other' ? $_CLASS['core_user']->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_name'])] : '';
            $disapprove_reason .= $reason ? "\n\n" . $_REQUEST['reason'] : '';
            unset($reason);
        }
        $_CLASS['core_db']->free_result($result);
    }
    if (confirm_box(true)) {
        $post_info = get_post_data($post_id_list, 'm_approve');
        // If Topic -> forum_topics_real -= 1
        // If Post -> topic_replies_real -= 1
        $forum_topics_real = 0;
        $topic_replies_real_sql = $post_disapprove_sql = $topic_id_list = array();
        foreach ($post_info as $post_id => $post_data) {
            $topic_id_list[$post_data['topic_id']] = 1;
            // Topic or Post. ;)
            if ($post_data['topic_first_post_id'] == $post_id && $post_data['topic_last_post_id'] == $post_id) {
                if ($post_data['forum_id']) {
                    $forum_topics_real++;
                }
            } else {
                if (!isset($topic_replies_real_sql[$post_data['topic_id']])) {
                    $topic_replies_real_sql[$post_data['topic_id']] = 1;
                } else {
                    $topic_replies_real_sql[$post_data['topic_id']]++;
                }
            }
            $post_disapprove_sql[] = $post_id;
        }
        if ($forum_topics_real) {
            $sql = 'UPDATE ' . FORUMS_TABLE . "\n\t\t\t\tSET forum_topics_real = forum_topics_real - {$forum_topics_real}\n\t\t\t\tWHERE forum_id = {$forum_id}";
            $_CLASS['core_db']->query($sql);
        }
        if (sizeof($topic_replies_real_sql)) {
            foreach ($topic_replies_real_sql as $topic_id => $num_replies) {
                $sql = 'UPDATE ' . TOPICS_TABLE . "\n\t\t\t\t\tSET topic_replies_real = topic_replies_real - {$num_replies}\n\t\t\t\t\tWHERE topic_id = {$topic_id}";
                $_CLASS['core_db']->query($sql);
            }
        }
        if (sizeof($post_disapprove_sql)) {
            // We do not check for permissions here, because the moderator allowed approval/disapproval should be allowed to delete the disapproved posts
            delete_posts('post_id', $post_disapprove_sql);
        }
        unset($post_disapprove_sql, $topic_replies_real_sql);
        update_post_information('topic', array_keys($topic_id_list));
        update_post_information('forum', $forum_id);
        unset($topic_id_list);
        $messenger = new messenger();
        // Notify Poster?
        if ($notify_poster) {
            $email_sig = str_replace('<br />', "\n", "-- \n" . $config['board_email_sig']);
            foreach ($post_info as $post_id => $post_data) {
                if ($post_data['poster_id'] == ANONYMOUS) {
                    continue;
                }
                $email_template = $post_data['post_id'] == $post_data['topic_first_post_id'] && $post_data['post_id'] == $post_data['topic_last_post_id'] ? 'topic_disapproved' : 'post_disapproved';
                $messenger->template($email_template, $post_data['user_lang']);
                $messenger->replyto($config['board_email']);
                $messenger->to($post_data['user_email'], $post_data['username']);
                $messenger->im($post_data['user_jabber'], $post_data['username']);
                $messenger->assign_vars(array('EMAIL_SIG' => $email_sig, 'SITENAME' => $_CORE_CONFIG['global']['sitename'], 'USERNAME' => $post_data['username'], 'REASON' => stripslashes($disapprove_reason), 'POST_SUBJECT' => censor_text($post_data['post_subject']), 'TOPIC_TITLE' => censor_text($post_data['topic_title'])));
                $messenger->send($post_data['user_notify_type']);
                $messenger->reset();
            }
            $messenger->save_queue();
        }
        unset($post_info, $disapprove_reason);
        if ($forum_topics_real) {
            $success_msg = $forum_topics_real == 1 ? 'TOPIC_DISAPPROVED_SUCCESS' : 'TOPICS_DISAPPROVED_SUCCESS';
        } else {
            $success_msg = sizeof($post_id_list) == 1 ? 'POST_DISAPPROVED_SUCCESS' : 'POSTS_DISAPPROVED_SUCCESS';
        }
    } else {
        $sql = 'SELECT * 
			FROM ' . REASONS_TABLE . ' 
			ORDER BY reason_priority ASC';
        $result = $_CLASS['core_db']->query($sql);
        while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) {
            $row['reason_name'] = strtoupper($row['reason_name']);
            $reason_title = !empty($_CLASS['core_user']->lang['report_reasons']['TITLE'][$row['reason_name']]) ? $_CLASS['core_user']->lang['report_reasons']['TITLE'][$row['reason_name']] : ucwords(str_replace('_', ' ', $row['reason_name']));
            $reason_desc = !empty($_CLASS['core_user']->lang['report_reasons']['DESCRIPTION'][$row['reason_name']]) ? $_CLASS['core_user']->lang['report_reasons']['DESCRIPTION'][$row['reason_name']] : $row['reason_desc'];
            $_CLASS['core_template']->assign_vars_array('reason', array('ID' => $row['reason_id'], 'NAME' => htmlspecialchars($reason_title), 'DESCRIPTION' => htmlspecialchars($reason_desc), 'S_SELECTED' => $row['reason_id'] == $reason_id ? true : false));
        }
        $_CLASS['core_db']->free_result($result);
        $_CLASS['core_template']->assign_array(array('S_NOTIFY_POSTER' => true, 'S_APPROVE' => false, 'REASON' => $reason, 'ADDITIONAL_MSG' => $additional_msg));
        confirm_box(false, 'DISAPPROVE_POST' . (sizeof($post_id_list) == 1 ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html');
    }
    $redirect = request_var('redirect', generate_link('Forums'));
    if (!$success_msg) {
        url_redirect($redirect);
    } else {
        $_CLASS['core_display']->meta_refresh(3, generate_link("Forums&amp;file=viewforum&amp;f={$forum_id}"));
        trigger_error($_CLASS['core_user']->lang[$success_msg] . '<br /><br />' . sprintf($_CLASS['core_user']->lang['RETURN_FORUM'], '<a href="' . generate_link('Forums&amp;file=viewforum&amp;f=' . $forum_id) . '">', '</a>'));
    }
}
Example #9
0
    /**
     * Change visibility status of one post or all posts of a topic
     *
     * @param $visibility	int		Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
     * @param $post_id		mixed	Post ID or array of post IDs to act on,
     *								if it is empty, all posts of topic_id will be modified
     * @param $topic_id		int		Topic where $post_id is found
     * @param $forum_id		int		Forum where $topic_id is found
     * @param $user_id		int		User performing the action
     * @param $time			int		Timestamp when the action is performed
     * @param $reason		string	Reason why the visibility was changed.
     * @param $is_starter	bool	Is this the first post of the topic changed?
     * @param $is_latest		bool	Is this the last post of the topic changed?
     * @param $limit_visibility	mixed	Limit updating per topic_id to a certain visibility
     * @param $limit_delete_time	mixed	Limit updating per topic_id to a certain deletion time
     * @return array		Changed post data, empty array if an error occurred.
     */
    public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false)
    {
        if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) {
            return array();
        }
        if ($post_id) {
            if (is_array($post_id)) {
                $where_sql = $this->db->sql_in_set('post_id', array_map('intval', $post_id));
            } else {
                $where_sql = 'post_id = ' . (int) $post_id;
            }
            $where_sql .= ' AND topic_id = ' . (int) $topic_id;
        } else {
            $where_sql = 'topic_id = ' . (int) $topic_id;
            // Limit the posts to a certain visibility and deletion time
            // This allows us to only restore posts, that were approved
            // when the topic got soft deleted. So previous soft deleted
            // and unapproved posts are still soft deleted/unapproved
            if ($limit_visibility !== false) {
                $where_sql .= ' AND post_visibility = ' . (int) $limit_visibility;
            }
            if ($limit_delete_time !== false) {
                $where_sql .= ' AND post_delete_time = ' . (int) $limit_delete_time;
            }
        }
        $sql = 'SELECT poster_id, post_id, post_postcount, post_visibility
			FROM ' . $this->posts_table . '
			WHERE ' . $where_sql;
        $result = $this->db->sql_query($sql);
        $post_ids = $poster_postcounts = $postcounts = $postcount_visibility = array();
        while ($row = $this->db->sql_fetchrow($result)) {
            $post_ids[] = (int) $row['post_id'];
            if ($row['post_visibility'] != $visibility) {
                if ($row['post_postcount'] && !isset($poster_postcounts[(int) $row['poster_id']])) {
                    $poster_postcounts[(int) $row['poster_id']] = 1;
                } else {
                    if ($row['post_postcount']) {
                        $poster_postcounts[(int) $row['poster_id']]++;
                    }
                }
                if (!isset($postcount_visibility[$row['post_visibility']])) {
                    $postcount_visibility[$row['post_visibility']] = 1;
                } else {
                    $postcount_visibility[$row['post_visibility']]++;
                }
            }
        }
        $this->db->sql_freeresult($result);
        if (empty($post_ids)) {
            return array();
        }
        $data = array('post_visibility' => (int) $visibility, 'post_delete_user' => (int) $user_id, 'post_delete_time' => (int) $time ?: time(), 'post_delete_reason' => truncate_string($reason, 255, 255, false));
        $sql = 'UPDATE ' . $this->posts_table . '
			SET ' . $this->db->sql_build_array('UPDATE', $data) . '
			WHERE ' . $this->db->sql_in_set('post_id', $post_ids);
        $this->db->sql_query($sql);
        // Group the authors by post count, to reduce the number of queries
        foreach ($poster_postcounts as $poster_id => $num_posts) {
            $postcounts[$num_posts][] = $poster_id;
        }
        // Update users postcounts
        foreach ($postcounts as $num_posts => $poster_ids) {
            if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED))) {
                $sql = 'UPDATE ' . $this->users_table . '
					SET user_posts = 0
					WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . '
						AND user_posts < ' . $num_posts;
                $this->db->sql_query($sql);
                $sql = 'UPDATE ' . $this->users_table . '
					SET user_posts = user_posts - ' . $num_posts . '
					WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . '
						AND user_posts >= ' . $num_posts;
                $this->db->sql_query($sql);
            } else {
                $sql = 'UPDATE ' . $this->users_table . '
					SET user_posts = user_posts + ' . $num_posts . '
					WHERE ' . $this->db->sql_in_set('user_id', $poster_ids);
                $this->db->sql_query($sql);
            }
        }
        $update_topic_postcount = true;
        // Sync the first/last topic information if needed
        if (!$is_starter && $is_latest) {
            if (!function_exists('update_post_information')) {
                include $this->src_root_path . 'includes/functions_posting.' . $this->php_ext;
            }
            // update_post_information can only update the last post info ...
            if ($topic_id) {
                update_post_information('topic', $topic_id, false);
            }
            if ($forum_id) {
                update_post_information('forum', $forum_id, false);
            }
        } else {
            if ($is_starter && $topic_id) {
                if (!function_exists('sync')) {
                    include $this->src_root_path . 'includes/functions_admin.' . $this->php_ext;
                }
                // ... so we need to use sync, if the first post is changed.
                // The forum is resynced recursive by sync() itself.
                sync('topic', 'topic_id', $topic_id, true);
                // sync recalculates the topic replies and forum posts by itself, so we don't do that.
                $update_topic_postcount = false;
            }
        }
        $topic_update_array = array();
        // Update the topic's reply count and the forum's post count
        if ($update_topic_postcount) {
            $field_alias = array(ITEM_APPROVED => 'posts_approved', ITEM_UNAPPROVED => 'posts_unapproved', ITEM_DELETED => 'posts_softdeleted', ITEM_REAPPROVE => 'posts_unapproved');
            $cur_posts = array_fill_keys($field_alias, 0);
            foreach ($postcount_visibility as $post_visibility => $visibility_posts) {
                $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts;
            }
            $sql_ary = array();
            $recipient_field = $field_alias[$visibility];
            foreach ($cur_posts as $field => $count) {
                // Decrease the count for the old statuses.
                if ($count && $field != $recipient_field) {
                    $sql_ary[$field] = " - {$count}";
                }
            }
            // Add up the count from all statuses excluding the recipient status.
            $count_increase = array_sum(array_diff($cur_posts, array($recipient_field)));
            if ($count_increase) {
                $sql_ary[$recipient_field] = " + {$count_increase}";
            }
            if (sizeof($sql_ary)) {
                $forum_sql = array();
                foreach ($sql_ary as $field => $value_change) {
                    $topic_update_array[] = 'topic_' . $field . ' = topic_' . $field . $value_change;
                    $forum_sql[] = 'forum_' . $field . ' = forum_' . $field . $value_change;
                }
                $sql = 'UPDATE ' . $this->forums_table . '
					SET ' . implode(', ', $forum_sql) . '
					WHERE forum_id = ' . (int) $forum_id;
                $this->db->sql_query($sql);
            }
        }
        if ($post_id) {
            $sql = 'SELECT 1 AS has_attachments
				FROM ' . POSTS_TABLE . '
				WHERE topic_id = ' . (int) $topic_id . '
					AND post_attachment = 1
					AND post_visibility = ' . ITEM_APPROVED . '
					AND ' . $this->db->sql_in_set('post_id', $post_id, true);
            $result = $this->db->sql_query_limit($sql, 1);
            $has_attachment = (bool) $this->db->sql_fetchfield('has_attachments');
            $this->db->sql_freeresult($result);
            if ($has_attachment && $visibility == ITEM_APPROVED) {
                $topic_update_array[] = 'topic_attachment = 1';
            } else {
                if (!$has_attachment && $visibility != ITEM_APPROVED) {
                    $topic_update_array[] = 'topic_attachment = 0';
                }
            }
        }
        if (!empty($topic_update_array)) {
            // Update the number for replies and posts, and update the attachments flag
            $sql = 'UPDATE ' . $this->topics_table . '
				SET ' . implode(', ', $topic_update_array) . '
				WHERE topic_id = ' . (int) $topic_id;
            $this->db->sql_query($sql);
        }
        return $data;
    }
/**
* Submit Post
*/
function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true)
{
    global $config, $_CORE_CONFIG, $_CLASS;
    // We do not handle erasing posts here
    if ($mode == 'delete') {
        return false;
    }
    $current_time = $_CLASS['core_user']->time;
    if ($mode == 'post') {
        $post_mode = 'post';
        $update_message = true;
    } else {
        if ($mode != 'edit') {
            $post_mode = 'reply';
            $update_message = true;
        } else {
            if ($mode == 'edit') {
                $post_mode = $data['topic_first_post_id'] == $data['topic_last_post_id'] ? 'edit_topic' : ($data['topic_first_post_id'] == $data['post_id'] ? 'edit_first_post' : ($data['topic_last_post_id'] == $data['post_id'] ? 'edit_last_post' : 'edit'));
            }
        }
    }
    // Collect some basic informations about which tables and which rows to update/insert
    $sql_data = array();
    $poster_id = $mode == 'edit' ? $data['poster_id'] : (int) $_CLASS['core_user']->data['user_id'];
    // Collect Informations
    switch ($post_mode) {
        case 'post':
        case 'reply':
            $sql_data[FORUMS_POSTS_TABLE]['sql'] = array('forum_id' => $topic_type == POST_GLOBAL ? 0 : $data['forum_id'], 'poster_id' => (int) $_CLASS['core_user']->data['user_id'], 'icon_id' => $data['icon_id'], 'poster_ip' => $_CLASS['core_user']->ip, 'post_time' => $current_time, 'post_approved' => !$_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) && !$_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']) ? 0 : 1, 'enable_html' => $data['enable_html'], 'enable_bbcode' => $data['enable_bbcode'], 'enable_smilies' => $data['enable_smilies'], 'enable_magic_url' => $data['enable_urls'], 'enable_sig' => $data['enable_sig'], 'post_username' => !$_CLASS['core_user']->is_user ? $username : '', 'post_subject' => $subject, 'post_text' => $data['message'], 'post_checksum' => $data['message_md5'], 'post_attachment' => empty($data['attachment_data']) ? 0 : 1, 'bbcode_bitfield' => $data['bbcode_bitfield'], 'bbcode_uid' => $data['bbcode_uid'], 'post_postcount' => $_CLASS['forums_auth']->acl_get('f_postcount', $data['forum_id']) ? 1 : 0, 'post_edit_locked' => $data['post_edit_locked']);
            break;
        case 'edit_first_post':
        case 'edit':
            if (!$_CLASS['forums_auth']->acl_get('m_edit', $data['forum_id']) || $data['post_edit_reason']) {
                $sql_data[FORUMS_POSTS_TABLE]['sql'] = array('post_edit_time' => $current_time);
                $sql_data[FORUMS_POSTS_TABLE]['stat'][] = 'post_edit_count = post_edit_count + 1';
            }
            // no break
        // no break
        case 'edit_last_post':
        case 'edit_topic':
            if (($post_mode == 'edit_last_post' || $post_mode == 'edit_topic') && $data['post_edit_reason']) {
                $sql_data[FORUMS_POSTS_TABLE]['sql'] = array('post_edit_time' => $current_time);
                $sql_data[FORUMS_POSTS_TABLE]['stat'][] = 'post_edit_count = post_edit_count + 1';
            }
            if (!isset($sql_data[FORUMS_POSTS_TABLE]['sql'])) {
                $sql_data[FORUMS_POSTS_TABLE]['sql'] = array();
            }
            $sql_data[FORUMS_POSTS_TABLE]['sql'] = array_merge($sql_data[FORUMS_POSTS_TABLE]['sql'], array('forum_id' => $topic_type == POST_GLOBAL ? 0 : $data['forum_id'], 'poster_id' => $data['poster_id'], 'icon_id' => $data['icon_id'], 'post_approved' => !$_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) && !$_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']) ? 0 : 1, 'enable_html' => $data['enable_html'], 'enable_bbcode' => $data['enable_bbcode'], 'enable_smilies' => $data['enable_smilies'], 'enable_magic_url' => $data['enable_urls'], 'enable_sig' => $data['enable_sig'], 'post_username' => $username && $data['poster_id'] == ANONYMOUS ? $username : '', 'post_subject' => $subject, 'post_edit_reason' => $data['post_edit_reason'], 'post_edit_user' => (int) $data['post_edit_user'], 'post_checksum' => $data['message_md5'], 'post_attachment' => empty($data['attachment_data']) ? 0 : 1, 'bbcode_bitfield' => $data['bbcode_bitfield'], 'bbcode_uid' => $data['bbcode_uid'], 'post_edit_locked' => $data['post_edit_locked']));
            if ($update_message) {
                $sql_data[FORUMS_POSTS_TABLE]['sql']['post_text'] = $data['message'];
            }
            break;
    }
    // And the topic ladies and gentlemen
    switch ($post_mode) {
        case 'post':
            $sql_data[FORUMS_TOPICS_TABLE]['sql'] = array('topic_poster' => (int) $_CLASS['core_user']->data['user_id'], 'topic_time' => $current_time, 'forum_id' => $topic_type == POST_GLOBAL ? 0 : $data['forum_id'], 'icon_id' => $data['icon_id'], 'topic_approved' => !$_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) && !$_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']) ? 0 : 1, 'topic_title' => $subject, 'topic_first_poster_name' => !$_CLASS['core_user']->is_user && $username ? $username : ($_CLASS['core_user']->data['user_id'] != ANONYMOUS ? $_CLASS['core_user']->data['username'] : ''), 'topic_type' => $topic_type, 'topic_time_limit' => $topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE ? $data['topic_time_limit'] * 86400 : 0, 'topic_attachment' => empty($data['attachment_data']) ? 0 : 1, 'topic_status' => 0, 'topic_replies_real' => 0, 'topic_replies' => 0, 'topic_views' => 0, 'topic_moved_id' => 0);
            if (isset($poll['poll_options']) && !empty($poll['poll_options'])) {
                $sql_data[FORUMS_TOPICS_TABLE]['sql'] = array_merge($sql_data[FORUMS_TOPICS_TABLE]['sql'], array('poll_title' => $poll['poll_title'], 'poll_start' => $poll['poll_start'] ? $poll['poll_start'] : $current_time, 'poll_max_options' => $poll['poll_max_options'], 'poll_length' => $poll['poll_length'] * 86400, 'poll_vote_change' => $poll['poll_vote_change']));
            }
            $sql_data[CORE_USERS_TABLE]['stat'][] = "user_last_post_time = {$current_time}" . ($_CLASS['forums_auth']->acl_get('f_postcount', $data['forum_id']) ? ', user_posts = user_posts + 1' : '');
            if ($topic_type != POST_GLOBAL) {
                if ($_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) || $_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id'])) {
                    $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
                }
                $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . ($_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) || $_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']) ? ', forum_topics = forum_topics + 1' : '');
            }
            break;
        case 'reply':
            $sql_data[FORUMS_TOPICS_TABLE]['stat'][] = 'topic_replies_real = topic_replies_real + 1, topic_bumped = 0, topic_bumper = 0' . ($_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) || $_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']) ? ', topic_replies = topic_replies + 1' : '');
            $sql_data[CORE_USERS_TABLE]['stat'][] = "user_last_post_time = {$current_time}" . ($_CLASS['forums_auth']->acl_get('f_postcount', $data['forum_id']) ? ', user_posts = user_posts + 1' : '');
            if (($_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) || $_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id'])) && $topic_type != POST_GLOBAL) {
                $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
            }
            break;
        case 'edit_topic':
        case 'edit_first_post':
            $sql_data[FORUMS_TOPICS_TABLE]['sql'] = array('forum_id' => $topic_type == POST_GLOBAL ? 0 : $data['forum_id'], 'icon_id' => $data['icon_id'], 'topic_approved' => !$_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) && !$_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']) ? 0 : 1, 'topic_title' => $subject, 'topic_first_poster_name' => $username, 'topic_type' => $topic_type, 'topic_time_limit' => $topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE ? $data['topic_time_limit'] * 86400 : 0, 'poll_title' => isset($poll['poll_options']) ? $poll['poll_title'] : '', 'poll_start' => isset($poll['poll_options']) ? $poll['poll_start'] ? $poll['poll_start'] : $current_time : 0, 'poll_max_options' => isset($poll['poll_options']) ? $poll['poll_max_options'] : 1, 'poll_length' => isset($poll['poll_options']) ? $poll['poll_length'] * 86400 : 0, 'poll_vote_change' => isset($poll['poll_vote_change']) ? $poll['poll_vote_change'] : 0, 'topic_attachment' => empty($data['attachment_data']) ? 0 : 1);
            break;
    }
    $_CLASS['core_db']->transaction();
    // Submit new topic
    if ($post_mode === 'post') {
        $sql = 'INSERT INTO ' . FORUMS_TOPICS_TABLE . ' ' . $_CLASS['core_db']->sql_build_array('INSERT', $sql_data[FORUMS_TOPICS_TABLE]['sql']);
        $_CLASS['core_db']->query($sql);
        $data['topic_id'] = $_CLASS['core_db']->insert_id(FORUMS_TOPICS_TABLE, 'topic_id');
        $sql_data[FORUMS_POSTS_TABLE]['sql'] = array_merge($sql_data[FORUMS_POSTS_TABLE]['sql'], array('topic_id' => $data['topic_id']));
        unset($sql_data[FORUMS_TOPICS_TABLE]['sql']);
    }
    // Submit new post
    if ($post_mode === 'post' || $post_mode === 'reply') {
        if ($post_mode === 'reply') {
            $sql_data[FORUMS_POSTS_TABLE]['sql'] = array_merge($sql_data[FORUMS_POSTS_TABLE]['sql'], array('topic_id' => $data['topic_id']));
        }
        $_CLASS['core_db']->sql_query_build('INSERT', $sql_data[FORUMS_POSTS_TABLE]['sql'], FORUMS_POSTS_TABLE);
        unset($sql_data[FORUMS_POSTS_TABLE]['sql']);
        $data['post_id'] = $_CLASS['core_db']->insert_id(FORUMS_POSTS_TABLE, 'post_id');
        if ($post_mode === 'post') {
            $sql_data[FORUMS_TOPICS_TABLE]['sql'] = array('topic_first_post_id' => $data['post_id'], 'topic_last_post_id' => $data['post_id'], 'topic_last_post_time' => $current_time, 'topic_last_poster_id' => (int) $_CLASS['core_user']->data['user_id'], 'topic_last_poster_name' => !$_CLASS['core_user']->is_user && $username ? $username : ($_CLASS['core_user']->data['user_id'] != ANONYMOUS ? $_CLASS['core_user']->data['username'] : ''));
        }
    }
    $make_global = false;
    // Are we globalising or unglobalising?
    if ($post_mode === 'edit_first_post' || $post_mode === 'edit_topic') {
        $sql = 'SELECT topic_type, topic_replies_real, topic_approved
			FROM ' . FORUMS_TOPICS_TABLE . '
			WHERE topic_id = ' . $data['topic_id'];
        $result = $_CLASS['core_db']->query($sql);
        $row = $_CLASS['core_db']->fetch_row_assoc($result);
        $_CLASS['core_db']->free_result($result);
        // globalise
        if ($row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL) {
            // Decrement topic/post count
            $make_global = true;
            $sql_data[FORUMS_FORUMS_TABLE]['stat'] = array();
            $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($row['topic_replies_real'] + 1);
            $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real - 1' . ($row['topic_approved'] ? ', forum_topics = forum_topics - 1' : '');
            // Update forum_ids for all posts
            $sql = 'UPDATE ' . FORUMS_POSTS_TABLE . '
				SET forum_id = 0
				WHERE topic_id = ' . $data['topic_id'];
            $_CLASS['core_db']->query($sql);
        } else {
            if ($row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL) {
                // Increment topic/post count
                $make_global = true;
                $sql_data[FORUMS_FORUMS_TABLE]['stat'] = array();
                $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + ' . ($row['topic_replies_real'] + 1);
                $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . ($row['topic_approved'] ? ', forum_topics = forum_topics + 1' : '');
                // Update forum_ids for all posts
                $sql = 'UPDATE ' . FORUMS_POSTS_TABLE . '
				SET forum_id = ' . $data['forum_id'] . '
				WHERE topic_id = ' . $data['topic_id'];
                $_CLASS['core_db']->query($sql);
            }
        }
    }
    // Update the topics table
    if (isset($sql_data[FORUMS_TOPICS_TABLE]['sql'])) {
        $sql = 'UPDATE ' . FORUMS_TOPICS_TABLE . '
			SET ' . $_CLASS['core_db']->sql_build_array('UPDATE', $sql_data[FORUMS_TOPICS_TABLE]['sql']) . '
			WHERE topic_id = ' . $data['topic_id'];
        $_CLASS['core_db']->query($sql);
    }
    // Update the posts table
    if (isset($sql_data[FORUMS_POSTS_TABLE]['sql'])) {
        $sql = 'UPDATE ' . FORUMS_POSTS_TABLE . '
			SET ' . $_CLASS['core_db']->sql_build_array('UPDATE', $sql_data[FORUMS_POSTS_TABLE]['sql']) . '
			WHERE post_id = ' . $data['post_id'];
        $_CLASS['core_db']->query($sql);
    }
    // Update Poll Tables
    if (isset($poll['poll_options']) && !empty($poll['poll_options'])) {
        $cur_poll_options = array();
        if ($poll['poll_start'] && $mode == 'edit') {
            $sql = 'SELECT * FROM ' . FORUMS_POLL_OPTIONS_TABLE . '
				WHERE topic_id = ' . $data['topic_id'] . '
				ORDER BY poll_option_id';
            $result = $_CLASS['core_db']->query($sql);
            $cur_poll_options = array();
            while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) {
                $cur_poll_options[] = $row;
            }
            $_CLASS['core_db']->free_result($result);
        }
        $sql_insert_ary = array();
        for ($i = 0, $size = sizeof($poll['poll_options']); $i < $size; $i++) {
            if (trim($poll['poll_options'][$i])) {
                if (empty($cur_poll_options[$i])) {
                    $sql_insert_ary[] = array('poll_option_id' => (int) $i, 'topic_id' => (int) $data['topic_id'], 'poll_option_text' => (string) $poll['poll_options'][$i], 'poll_option_total' => 0);
                } else {
                    if ($poll['poll_options'][$i] != $cur_poll_options[$i]) {
                        $sql = "UPDATE " . FORUMS_POLL_OPTIONS_TABLE . "\r\n\t\t\t\t\t\tSET poll_option_text = '" . $_CLASS['core_db']->escape($poll['poll_options'][$i]) . "'\r\n\t\t\t\t\t\tWHERE poll_option_id = " . $cur_poll_options[$i]['poll_option_id'] . "\r\n\t\t\t\t\t\t\tAND topic_id = " . $data['topic_id'];
                        $_CLASS['core_db']->query($sql);
                    }
                }
            }
        }
        if (!empty($sql_insert_ary)) {
            $_CLASS['core_db']->sql_query_build('MULTI_INSERT', $sql_insert_ary, FORUMS_POLL_OPTIONS_TABLE);
            unset($sql_insert_ary);
        }
        if (count($poll['poll_options']) < count($cur_poll_options)) {
            $sql = 'DELETE FROM ' . FORUMS_POLL_OPTIONS_TABLE . '
				WHERE poll_option_id >= ' . count($poll['poll_options']) . '
					AND topic_id = ' . $data['topic_id'];
            $_CLASS['core_db']->query($sql);
        }
    }
    // Submit Attachments
    if (count($data['attachment_data']) && $data['post_id'] && in_array($mode, array('post', 'reply', 'quote', 'edit'))) {
        $space_taken = $files_added = $files_updated = 0;
        $orphan_rows = array();
        foreach ($data['attachment_data'] as $pos => $attach_row) {
            $orphan_rows[(int) $attach_row['attach_id']] = array();
        }
        if (sizeof($orphan_rows)) {
            $sql = 'SELECT attach_id, filesize, physical_filename
				FROM ' . FORUMS_ATTACHMENTS_TABLE . '
				WHERE attach_id IN (' . implode(', ', array_keys($orphan_rows)) . ')
					AND is_orphan = 1
					AND poster_id = ' . $_CLASS['core_user']->data['user_id'];
            $result = $_CLASS['core_db']->query($sql);
            $orphan_rows = array();
            while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) {
                $orphan_rows[$row['attach_id']] = $row;
            }
            $_CLASS['core_db']->free_result($result);
        }
        foreach ($data['attachment_data'] as $pos => $attach_row) {
            if ($attach_row['is_orphan'] && !in_array($attach_row['attach_id'], array_keys($orphan_rows))) {
                continue;
            }
            if (!$attach_row['is_orphan']) {
                // update entry in db if attachment already stored in db and filespace
                $sql = 'UPDATE ' . FORUMS_ATTACHMENTS_TABLE . "\r\n\t\t\t\t\tSET attach_comment = '" . $_CLASS['core_db']->escape($attach_row['attach_comment']) . "'\r\n\t\t\t\t\tWHERE attach_id = " . (int) $attach_row['attach_id'] . '
						AND is_orphan = 0';
                $_CLASS['core_db']->query($sql);
            } else {
                // insert attachment into db
                if (!@file_exists(SITE_FILE_ROOT . $config['upload_path'] . '/' . basename($orphan_rows[$attach_row['attach_id']]['physical_filename']))) {
                    continue;
                }
                $space_taken += $orphan_rows[$attach_row['attach_id']]['filesize'];
                $files_added++;
                $attach_sql = array('post_msg_id' => $data['post_id'], 'topic_id' => $data['topic_id'], 'is_orphan' => 0, 'poster_id' => $poster_id, 'attach_comment' => $attach_row['attach_comment']);
                $sql = 'UPDATE ' . FORUMS_ATTACHMENTS_TABLE . ' SET ' . $_CLASS['core_db']->sql_build_array('UPDATE', $attach_sql) . '
					WHERE attach_id = ' . $attach_row['attach_id'] . '
						AND is_orphan = 1
						AND poster_id = ' . $user->data['user_id'];
                $_CLASS['core_db']->query($sql);
            }
        }
        if ($files_updated || $files_added) {
            set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true);
            set_config('num_files', $config['num_files'] + $files_added, true);
        }
    }
    $_CLASS['core_db']->transaction('commit');
    if ($post_mode === 'post' || $post_mode === 'reply' || $post_mode === 'edit_last_post') {
        if ($topic_type != POST_GLOBAL) {
            $update_sql = update_post_information('forum', $data['forum_id'], true);
            if (sizeof($update_sql)) {
                $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = implode(', ', $update_sql[$data['forum_id']]);
            }
        }
        $update_sql = update_post_information('topic', $data['topic_id'], true);
        if (sizeof($update_sql)) {
            $sql_data[FORUMS_TOPICS_TABLE]['stat'][] = implode(', ', $update_sql[$data['topic_id']]);
        }
    }
    if ($make_global) {
        $update_sql = update_post_information('forum', $data['forum_id'], true);
        if (sizeof($update_sql)) {
            $sql_data[FORUMS_FORUMS_TABLE]['stat'][] = implode(', ', $update_sql[$data['forum_id']]);
        }
    }
    if ($post_mode === 'edit_topic') {
        $update_sql = update_post_information('topic', $data['topic_id'], true);
        if (sizeof($update_sql)) {
            $sql_data[FORUMS_TOPICS_TABLE]['stat'][] = implode(', ', $update_sql[$data['topic_id']]);
        }
    }
    // Update total post count, do not consider moderated posts/topics
    if ($_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) || $_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id'])) {
        if ($post_mode === 'post') {
            set_config('num_topics', $config['num_topics'] + 1, true);
            set_config('num_posts', $config['num_posts'] + 1, true);
        }
        if ($post_mode === 'reply') {
            set_config('num_posts', $config['num_posts'] + 1, true);
        }
    }
    // Update forum stats
    $_CLASS['core_db']->transaction();
    $where_sql = array(FORUMS_POSTS_TABLE => 'post_id = ' . $data['post_id'], FORUMS_TOPICS_TABLE => 'topic_id = ' . $data['topic_id'], FORUMS_FORUMS_TABLE => 'forum_id = ' . $data['forum_id'], CORE_USERS_TABLE => 'user_id = ' . $_CLASS['core_user']->data['user_id']);
    foreach ($sql_data as $table => $update_ary) {
        if (isset($update_ary['stat']) && implode('', $update_ary['stat'])) {
            $_CLASS['core_db']->query("UPDATE {$table} SET " . implode(', ', $update_ary['stat']) . ' WHERE ' . $where_sql[$table]);
        }
    }
    // Delete topic shadows (if any exist). We do not need a shadow topic for an global announcement
    if ($make_global) {
        $sql = 'DELETE FROM ' . FORUMS_TOPICS_TABLE . '
			WHERE topic_moved_id = ' . $data['topic_id'];
        $_CLASS['core_db']->query($sql);
    }
    // Index message contents
    if (false && $update_message && $data['enable_indexing']) {
        // Select the search method and do some additional checks to ensure it can actually be utilised
        $search_type = basename($config['search_type']);
        if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) {
            trigger_error('NO_SUCH_SEARCH_MODULE');
        }
        require "{$phpbb_root_path}includes/search/{$search_type}.{$phpEx}";
        $error = false;
        $search = new $search_type($error);
        if ($error) {
            trigger_error($error);
        }
        $search->index($mode, $data['post_id'], $data['message'], $subject, $poster_id, $topic_type == POST_GLOBAL ? 0 : $data['forum_id']);
    }
    $_CLASS['core_db']->transaction('commit');
    // Delete draft if post was loaded...
    $draft_id = request_var('draft_loaded', 0);
    if ($draft_id) {
        $sql = 'DELETE FROM ' . FORUMS_DRAFTS_TABLE . "\r\n\t\t\tWHERE draft_id = {$draft_id}\r\n\t\t\t\tAND user_id = {$_CLASS['core_user']->data['user_id']}";
        $_CLASS['core_db']->query($sql);
    }
    // Topic Notification, do not change if moderator is changing other users posts...
    if ($_CLASS['core_user']->data['user_id'] == $poster_id) {
        if (!$data['notify_set'] && $data['notify']) {
            $notify_sql = array('user_id' => $_CLASS['core_user']->data['user_id'], 'forum_id' => $data['forum_id'], 'topic_id' => $data['topic_id'], 'notify_type' => $poster_id, 'notify_status' => 0);
            $_CLASS['core_db']->sql_query_build('INSERT', $notify_sql, FORUMS_WATCH_TABLE);
            unset($notify_sql);
        } else {
            if ($data['notify_set'] && !$data['notify']) {
                $sql = 'DELETE FROM ' . FORUMS_TOPICS_WATCH_TABLE . '
				WHERE user_id = ' . $_CLASS['core_user']->data['user_id'] . '
					AND topic_id = ' . $data['topic_id'];
                $_CLASS['core_db']->query($sql);
            }
        }
    }
    if ($mode == 'post' || $mode == 'reply' || $mode == 'quote') {
        // Mark this topic as posted to
        markread('post', $data['forum_id'], $data['topic_id'], $data['post_time']);
    }
    // Mark this topic as read
    // We do not use post_time here, this is intended (post_time can have a date in the past if editing a message)
    markread('topic', $data['forum_id'], $data['topic_id'], $_CLASS['core_user']->time);
    // Send Notifications
    if ($mode !== 'edit' && $mode !== 'delete' && ($_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) || $_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']))) {
        user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id']);
    }
    if ($mode === 'post') {
        $url = $_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) || $_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']) ? generate_link('forums&amp;file=viewtopic&amp;f=' . $data['forum_id'] . '&amp;t=' . $data['topic_id']) : generate_link('forums&amp;file=viewforum&amp;f=' . $data['forum_id']);
    } else {
        $url = $_CLASS['forums_auth']->acl_get('f_noapprove', $data['forum_id']) || $_CLASS['forums_auth']->acl_get('m_approve', $data['forum_id']) ? generate_link("forums&amp;file=viewtopic&amp;f={$data['forum_id']}&amp;t={$data['topic_id']}&amp;p={$data['post_id']}") . "#p{$data['post_id']}" : generate_link("forums&amp;file=viewtopic&amp;f={$data['forum_id']}&amp;t={$data['topic_id']}");
    }
    return $url;
}
/**
* Disapprove Post/Topic
*/
function disapprove_post($post_id_list, $mode)
{
    global $_CLASS, $_CORE_CONFIG, $config;
    $forum_id = request_var('f', 0);
    if (!check_ids($post_id_list, FORUMS_POSTS_TABLE, 'post_id', 'm_approve')) {
        trigger_error('NOT_AUTHORIZED');
    }
    $redirect = request_var('redirect', $_CLASS['core_user']->data['session_page']);
    $reason = request_var('reason', '', true);
    $reason_id = request_var('reason_id', 0);
    $success_msg = $additional_msg = '';
    $s_hidden_fields = build_hidden_fields(array('i' => 'queue', 'f' => $forum_id, 'mode' => $mode, 'post_id_list' => $post_id_list, 'mode' => 'disapprove', 'redirect' => $redirect));
    $notify_poster = isset($_REQUEST['notify_poster']);
    $disapprove_reason = '';
    if ($reason_id) {
        $sql = 'SELECT reason_title, reason_description
			FROM ' . FORUMS_REPORTS_REASONS_TABLE . " \n\t\t\tWHERE reason_id = {$reason_id}";
        $result = $_CLASS['core_db']->query($sql);
        $row = $_CLASS['core_db']->fetch_row_assoc($result);
        $_CLASS['core_db']->free_result($result);
        if (!$row || !$reason && $row['reason_name'] === 'other') {
            $additional_msg = $_CLASS['core_user']->lang['NO_REASON_DISAPPROVAL'];
            unset($_POST['confirm']);
        } else {
            $disapprove_reason = $row['reason_title'] != 'other' ? isset($_CLASS['core_user']->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]) ? $_CLASS['core_user']->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])] : $row['reason_description'] : '';
            $disapprove_reason .= $reason ? "\n\n" . $reason : '';
            unset($reason);
        }
    }
    require_once SITE_FILE_ROOT . 'includes/forums/functions_display.php';
    $reason = display_reasons($reason_id);
    $_CLASS['core_template']->assign_array(array('S_NOTIFY_POSTER' => true, 'S_APPROVE' => false, 'REASON' => $reason, 'ADDITIONAL_MSG' => $additional_msg));
    if (display_confirmation($_CLASS['core_user']->get_lang('DISAPPROVE_POST' . (sizeof($post_id_list) == 1 ? '' : 'S')), $s_hidden_fields, 'modules/forums/mcp_approve.html')) {
        $post_info = get_post_data($post_id_list, 'm_approve');
        // If Topic -> forum_topics_real -= 1
        // If Post -> topic_replies_real -= 1
        $forum_topics_real = 0;
        $topic_replies_real_sql = $post_disapprove_sql = $topic_id_list = array();
        foreach ($post_info as $post_id => $post_data) {
            $topic_id_list[$post_data['topic_id']] = 1;
            // Topic or Post. ;)
            if ($post_data['topic_first_post_id'] == $post_id && $post_data['topic_last_post_id'] == $post_id) {
                if ($post_data['forum_id']) {
                    $forum_topics_real++;
                }
            } else {
                if (!isset($topic_replies_real_sql[$post_data['topic_id']])) {
                    $topic_replies_real_sql[$post_data['topic_id']] = 1;
                } else {
                    $topic_replies_real_sql[$post_data['topic_id']]++;
                }
            }
            $post_disapprove_sql[] = $post_id;
        }
        if ($forum_topics_real) {
            $sql = 'UPDATE ' . FORUMS_FORUMS_TABLE . "\n\t\t\t\tSET forum_topics_real = forum_topics_real - {$forum_topics_real}\n\t\t\t\tWHERE forum_id = {$forum_id}";
            $_CLASS['core_db']->query($sql);
        }
        if (!empty($topic_replies_real_sql)) {
            foreach ($topic_replies_real_sql as $topic_id => $num_replies) {
                $sql = 'UPDATE ' . FORUMS_TOPICS_TABLE . "\n\t\t\t\t\tSET topic_replies_real = topic_replies_real - {$num_replies}\n\t\t\t\t\tWHERE topic_id = {$topic_id}";
                $_CLASS['core_db']->query($sql);
            }
        }
        if (sizeof($post_disapprove_sql)) {
            if (!function_exists('delete_posts')) {
                require_once SITE_FILE_ROOT . 'includes/forums/functions_admin.php';
            }
            // We do not check for permissions here, because the moderator allowed approval/disapproval should be allowed to delete the disapproved posts
            delete_posts('post_id', $post_disapprove_sql);
        }
        unset($post_disapprove_sql, $topic_replies_real_sql);
        update_post_information('topic', array_keys($topic_id_list));
        update_post_information('forum', $forum_id);
        unset($topic_id_list);
        // Notify Poster?
        if ($notify_poster) {
            require_once SITE_FILE_ROOT . 'includes/mailer.php';
            $mailer = new core_mailer();
            foreach ($post_info as $post_id => $post_data) {
                if ($post_data['poster_id'] == ANONYMOUS) {
                    continue;
                }
                $post_data['post_subject'] = censor_text($post_data['post_subject'], true);
                $post_data['topic_title'] = censor_text($post_data['topic_title'], true);
                if ($post_data['post_id'] == $post_data['topic_first_post_id'] && $post_data['post_id'] == $post_data['topic_last_post_id']) {
                    $email_template = 'topic_disapproved.txt';
                    $subject = 'Topic Disapproved - ' . $post_data['topic_title'];
                } else {
                    $email_template = 'post_disapproved.txt';
                    $subject = 'Post Disapproved - ' . $post_data['post_subject'];
                }
                $mailer->to($post_data['user_email'], $post_data['username']);
                //$mailer->reply_to($_CORE_CONFIG['email']['site_email']);
                $mailer->subject($subject);
                //$messenger->im($post_data['user_jabber'], $post_data['username']);
                $_CLASS['core_template']->assign_array(array('SITENAME' => $_CORE_CONFIG['global']['site_name'], 'USERNAME' => $post_data['username'], 'REASON' => stripslashes($disapprove_reason), 'POST_SUBJECT' => $post_data['post_subject'], 'TOPIC_TITLE' => $post_data['topic_title']));
                $mailer->message = trim($_CLASS['core_template']->display('email/forums/' . $email_template, true));
                $mailer->send();
            }
        }
        unset($post_info, $disapprove_reason);
        if ($forum_topics_real) {
            $success_msg = $forum_topics_real == 1 ? 'TOPIC_DISAPPROVED_SUCCESS' : 'TOPICS_DISAPPROVED_SUCCESS';
        } else {
            $success_msg = sizeof($post_id_list) == 1 ? 'POST_DISAPPROVED_SUCCESS' : 'POSTS_DISAPPROVED_SUCCESS';
        }
    }
    $redirect = request_var('redirect', generate_link('forums'));
    if (!$success_msg) {
        redirect($redirect);
    } else {
        $_CLASS['core_display']->meta_refresh(3, generate_link("forums&amp;file=viewforum&amp;f={$forum_id}"));
        trigger_error($_CLASS['core_user']->lang[$success_msg] . '<br /><br />' . sprintf($_CLASS['core_user']->lang['RETURN_FORUM'], '<a href="' . generate_link('forums&amp;file=viewforum&amp;f=' . $forum_id) . '">', '</a>'));
    }
}
Example #12
0
 /**
  * bumps the topic
  *
  * @param
  */
 function bump($user_id = 0)
 {
     global $db, $user;
     $current_time = time();
     if ($user_id == 0) {
         $user_id = $user->data['user_id'];
     }
     $db->sql_transaction('begin');
     $sql = 'UPDATE ' . POSTS_TABLE . "\n\t\tSET post_time = {$current_time}\n\t\tWHERE post_id = {$this->topic_last_post_id}\n\t\tAND topic_id = {$this->topic_id}";
     $db->sql_query($sql);
     $this->topic_bumped = 1;
     $this->topic_bumper = $user_id;
     $this->topic_last_post_time = $current_time;
     $sql = 'UPDATE ' . TOPICS_TABLE . "\n\t\tSET topic_last_post_time = {$current_time},\n\t\ttopic_bumped = 1,\n\t\ttopic_bumper = {$user_id}\n\t\tWHERE topic_id = {$topic_id}";
     $db->sql_query($sql);
     update_post_information('forum', $this->forum_id);
     $sql = 'UPDATE ' . USERS_TABLE . "\n\t\tSET user_lastpost_time = {$current_time}\n\t\tWHERE user_id = {$user_id}";
     $db->sql_query($sql);
     $db->sql_transaction('commit');
     markread('post', $this->forum_id, $this->topic_id, $current_time, $user_id);
     add_log('mod', $this->forum_id, $this->topic_id, 'LOG_BUMP_TOPIC', $this->topic_title);
 }