Example #1
0
/**
 * Save a new draft, or update an existing draft.
 */
function saveDraft()
{
    global $smcFunc, $topic, $board, $user_info, $options;
    if (!isset($_REQUEST['draft']) || $user_info['is_guest'] || empty($options['use_drafts'])) {
        return false;
    }
    $msgid = isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0;
    // Clean up what we may or may not have
    $subject = isset($_POST['subject']) ? $_POST['subject'] : '';
    $message = isset($_POST['message']) ? $_POST['message'] : '';
    $icon = isset($_POST['icon']) ? preg_replace('~[\\./\\\\*:"\'<>]~', '', $_POST['icon']) : 'xx';
    // Sanitise what we do have
    $subject = commonAPI::htmltrim(commonAPI::htmlspecialchars($subject));
    $message = commonAPI::htmlspecialchars($message, ENT_QUOTES);
    preparsecode($message);
    if (commonAPI::htmltrim(commonAPI::htmlspecialchars($subject)) === '' && commonAPI::htmltrim(commonAPI::htmlspecialchars($_POST['message']), ENT_QUOTES) === '') {
        fatal_lang_error('empty_draft', false);
    }
    // Hrm, so is this a new draft or not?
    if (isset($_REQUEST['draft_id']) && (int) $_REQUEST['draft_id'] > 0 || $msgid) {
        $_REQUEST['draft_id'] = (int) $_REQUEST['draft_id'];
        $id_cond = $msgid ? ' 1=1 ' : ' id_draft = {int:draft} ';
        $id_sel = $msgid ? ' AND id_msg = {int:message} ' : ' AND id_board = {int:board} AND id_topic = {int:topic} ';
        // Does this draft exist?
        smf_db_query('
			UPDATE {db_prefix}drafts
			SET subject = {string:subject},
				body = {string:body},
				updated = {int:post_time},
				icon = {string:post_icon},
				smileys = {int:smileys_enabled},
				is_locked = {int:locked},
				is_sticky = {int:sticky}
			WHERE ' . $id_cond . '
				AND id_member = {int:member}
				' . $id_sel . '
			LIMIT 1', array('draft' => $_REQUEST['draft_id'], 'board' => $board, 'topic' => $topic, 'message' => $msgid, 'member' => $user_info['id'], 'subject' => $subject, 'body' => $message, 'post_time' => time(), 'post_icon' => $icon, 'smileys_enabled' => !isset($_POST['ns']) ? 1 : 0, 'locked' => !empty($_POST['lock_draft']) ? 1 : 0, 'sticky' => isset($_POST['sticky']) ? 1 : 0));
        if (smf_db_affected_rows() != 0) {
            return $_REQUEST['draft_id'];
        }
    }
    smf_db_insert('insert', '{db_prefix}drafts', array('id_board' => 'int', 'id_topic' => 'int', 'id_msg' => 'int', 'id_member' => 'int', 'subject' => 'string', 'body' => 'string', 'updated' => 'int', 'icon' => 'string', 'smileys' => 'int', 'is_locked' => 'int', 'is_sticky' => 'int'), array($board, $topic, $msgid, $user_info['id'], $subject, $message, time(), $icon, !isset($_POST['ns']) ? 1 : 0, !empty($_POST['lock_draft']) ? 1 : 0, isset($_POST['sticky']) ? 1 : 0), array('id_draft'));
    return smf_db_insert_id('{db_prefix}drafts');
}
Example #2
0
function createBoard($boardOptions)
{
    global $boards, $modSettings, $smcFunc;
    // Trigger an error if one of the required values is not set.
    if (!isset($boardOptions['board_name']) || trim($boardOptions['board_name']) == '' || !isset($boardOptions['move_to']) || !isset($boardOptions['target_category'])) {
        trigger_error('createBoard(): One or more of the required options is not set', E_USER_ERROR);
    }
    if (in_array($boardOptions['move_to'], array('child', 'before', 'after')) && !isset($boardOptions['target_board'])) {
        trigger_error('createBoard(): Target board is not set', E_USER_ERROR);
    }
    // Set every optional value to its default value.
    $boardOptions += array('posts_count' => true, 'override_theme' => false, 'board_theme' => 0, 'access_groups' => array(), 'board_description' => '', 'profile' => 1, 'moderators' => '', 'inherit_permissions' => true, 'dont_log' => true, 'allow_topics' => 1, 'automerge' => 0, 'boardicon' => '');
    // Insert a board, the settings are dealt with later.
    smf_db_insert('', '{db_prefix}boards', array('id_cat' => 'int', 'name' => 'string-255', 'description' => 'string', 'board_order' => 'int', 'member_groups' => 'string', 'redirect' => 'string'), array($boardOptions['target_category'], $boardOptions['board_name'], '', 0, '-1,0', ''), array('id_board'));
    $board_id = smf_db_insert_id('{db_prefix}boards', 'id_board');
    if (empty($board_id)) {
        return 0;
    }
    // Change the board according to the given specifications.
    modifyBoard($board_id, $boardOptions);
    // Do we want the parent permissions to be inherited?
    if ($boardOptions['inherit_permissions']) {
        getBoardTree();
        if (!empty($boards[$board_id]['parent'])) {
            $request = smf_db_query('
				SELECT id_profile
				FROM {db_prefix}boards
				WHERE id_board = {int:board_parent}
				LIMIT 1', array('board_parent' => (int) $boards[$board_id]['parent']));
            list($boardOptions['profile']) = mysql_fetch_row($request);
            mysql_free_result($request);
            smf_db_query('
				UPDATE {db_prefix}boards
				SET id_profile = {int:new_profile}
				WHERE id_board = {int:current_board}', array('new_profile' => $boardOptions['profile'], 'current_board' => $board_id));
        }
    }
    // Clean the data cache.
    clean_cache('data');
    // Created it.
    logAction('add_board', array('board' => $board_id), 'admin');
    // Here you are, a new board, ready to be spammed.
    return $board_id;
}
Example #3
0
function loadAttachmentContext($id_msg)
{
    global $attachments, $modSettings, $txt, $scripturl, $topic, $sourcedir, $backend_subdir;
    // Set up the attachment info - based on code by Meriadoc.
    $attachmentData = array();
    $have_unapproved = false;
    if (isset($attachments[$id_msg]) && !empty($modSettings['attachmentEnable'])) {
        foreach ($attachments[$id_msg] as $i => $attachment) {
            $attachmentData[$i] = array('id' => $attachment['id_attach'], 'name' => preg_replace('~&amp;#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($attachment['filename'])), 'downloads' => $attachment['downloads'], 'size' => round($attachment['filesize'] / 1024, 2) . ' ' . $txt['kilobyte'], 'byte_size' => $attachment['filesize'], 'href' => $scripturl . '?action=dlattach;topic=' . $topic . '.0;attach=' . $attachment['id_attach'], 'link' => '<a href="' . $scripturl . '?action=dlattach;topic=' . $topic . '.0;attach=' . $attachment['id_attach'] . '">' . htmlspecialchars($attachment['filename']) . '</a>', 'is_image' => !empty($attachment['width']) && !empty($attachment['height']) && !empty($modSettings['attachmentShowImages']), 'is_approved' => $attachment['approved']);
            // If something is unapproved we'll note it so we can sort them.
            if (!$attachment['approved']) {
                $have_unapproved = true;
            }
            if (!$attachmentData[$i]['is_image']) {
                continue;
            }
            $attachmentData[$i]['real_width'] = $attachment['width'];
            $attachmentData[$i]['width'] = $attachment['width'];
            $attachmentData[$i]['real_height'] = $attachment['height'];
            $attachmentData[$i]['height'] = $attachment['height'];
            // Let's see, do we want thumbs?
            if (!empty($modSettings['attachmentThumbnails']) && !empty($modSettings['attachmentThumbWidth']) && !empty($modSettings['attachmentThumbHeight']) && ($attachment['width'] > $modSettings['attachmentThumbWidth'] || $attachment['height'] > $modSettings['attachmentThumbHeight']) && strlen($attachment['filename']) < 249) {
                // A proper thumb doesn't exist yet? Create one!
                if (empty($attachment['id_thumb']) || $attachment['thumb_width'] > $modSettings['attachmentThumbWidth'] || $attachment['thumb_height'] > $modSettings['attachmentThumbHeight'] || $attachment['thumb_width'] < $modSettings['attachmentThumbWidth'] && $attachment['thumb_height'] < $modSettings['attachmentThumbHeight']) {
                    $filename = getAttachmentFilename($attachment['filename'], $attachment['id_attach'], $attachment['id_folder']);
                    require_once $sourcedir . '/lib/Subs-Graphics.php';
                    if (createThumbnail($filename, $modSettings['attachmentThumbWidth'], $modSettings['attachmentThumbHeight'])) {
                        // So what folder are we putting this image in?
                        if (!empty($modSettings['currentAttachmentUploadDir'])) {
                            if (!is_array($modSettings['attachmentUploadDir'])) {
                                $modSettings['attachmentUploadDir'] = @unserialize($modSettings['attachmentUploadDir']);
                            }
                            $path = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
                            $id_folder_thumb = $modSettings['currentAttachmentUploadDir'];
                        } else {
                            $path = $modSettings['attachmentUploadDir'];
                            $id_folder_thumb = 1;
                        }
                        // Calculate the size of the created thumbnail.
                        $size = @getimagesize($filename . '_thumb');
                        list($attachment['thumb_width'], $attachment['thumb_height']) = $size;
                        $thumb_size = filesize($filename . '_thumb');
                        // These are the only valid image types for SMF.
                        $validImageTypes = array(1 => 'gif', 2 => 'jpeg', 3 => 'png', 5 => 'psd', 6 => 'bmp', 7 => 'tiff', 8 => 'tiff', 9 => 'jpeg', 14 => 'iff');
                        // What about the extension?
                        $thumb_ext = isset($validImageTypes[$size[2]]) ? $validImageTypes[$size[2]] : '';
                        // Figure out the mime type.
                        if (!empty($size['mime'])) {
                            $thumb_mime = $size['mime'];
                        } else {
                            $thumb_mime = 'image/' . $thumb_ext;
                        }
                        $thumb_filename = $attachment['filename'] . '_thumb';
                        $thumb_hash = getAttachmentFilename($thumb_filename, false, null, true);
                        // Add this beauty to the database.
                        smf_db_insert('', '{db_prefix}attachments', array('id_folder' => 'int', 'id_msg' => 'int', 'attachment_type' => 'int', 'filename' => 'string', 'file_hash' => 'string', 'size' => 'int', 'width' => 'int', 'height' => 'int', 'fileext' => 'string', 'mime_type' => 'string'), array($id_folder_thumb, $id_msg, 3, $thumb_filename, $thumb_hash, (int) $thumb_size, (int) $attachment['thumb_width'], (int) $attachment['thumb_height'], $thumb_ext, $thumb_mime), array('id_attach'));
                        $old_id_thumb = $attachment['id_thumb'];
                        $attachment['id_thumb'] = smf_db_insert_id('{db_prefix}attachments', 'id_attach');
                        if (!empty($attachment['id_thumb'])) {
                            smf_db_query('
								UPDATE {db_prefix}attachments
								SET id_thumb = {int:id_thumb}
								WHERE id_attach = {int:id_attach}', array('id_thumb' => $attachment['id_thumb'], 'id_attach' => $attachment['id_attach']));
                            $thumb_realname = getAttachmentFilename($thumb_filename, $attachment['id_thumb'], $id_folder_thumb, false, $thumb_hash);
                            rename($filename . '_thumb', $thumb_realname);
                            // Do we need to remove an old thumbnail?
                            if (!empty($old_id_thumb)) {
                                require_once $sourcedir . '/lib/Subs-ManageAttachments.php';
                                removeAttachments(array('id_attach' => $old_id_thumb), '', false, false);
                            }
                        }
                    }
                }
                // Only adjust dimensions on successful thumbnail creation.
                if (!empty($attachment['thumb_width']) && !empty($attachment['thumb_height'])) {
                    $attachmentData[$i]['width'] = $attachment['thumb_width'];
                    $attachmentData[$i]['height'] = $attachment['thumb_height'];
                }
            }
            if (!empty($attachment['id_thumb'])) {
                $attachmentData[$i]['thumbnail'] = array('id' => $attachment['id_thumb'], 'href' => $scripturl . '?action=dlattach;topic=' . $topic . '.0;attach=' . $attachment['id_thumb'] . ';image');
            }
            $attachmentData[$i]['thumbnail']['has_thumb'] = !empty($attachment['id_thumb']);
            // If thumbnails are disabled, check the maximum size of the image.
            if (!$attachmentData[$i]['thumbnail']['has_thumb'] && (!empty($modSettings['max_image_width']) && $attachment['width'] > $modSettings['max_image_width'] || !empty($modSettings['max_image_height']) && $attachment['height'] > $modSettings['max_image_height'])) {
                if (!empty($modSettings['max_image_width']) && (empty($modSettings['max_image_height']) || $attachment['height'] * $modSettings['max_image_width'] / $attachment['width'] <= $modSettings['max_image_height'])) {
                    $attachmentData[$i]['width'] = $modSettings['max_image_width'];
                    $attachmentData[$i]['height'] = floor($attachment['height'] * $modSettings['max_image_width'] / $attachment['width']);
                } elseif (!empty($modSettings['max_image_width'])) {
                    $attachmentData[$i]['width'] = floor($attachment['width'] * $modSettings['max_image_height'] / $attachment['height']);
                    $attachmentData[$i]['height'] = $modSettings['max_image_height'];
                }
            } elseif ($attachmentData[$i]['thumbnail']['has_thumb']) {
                // If the image is too large to show inline, make it a popup.
                if (!empty($modSettings['max_image_width']) && $attachmentData[$i]['real_width'] > $modSettings['max_image_width'] || !empty($modSettings['max_image_height']) && $attachmentData[$i]['real_height'] > $modSettings['max_image_height']) {
                    $attachmentData[$i]['thumbnail']['javascript'] = 'return reqWin(\'' . $attachmentData[$i]['href'] . ';image\', ' . ($attachment['width'] + 20) . ', ' . ($attachment['height'] + 20) . ', true);';
                } else {
                    $attachmentData[$i]['thumbnail']['javascript'] = 'return expandThumb(' . $attachment['id_attach'] . ');';
                }
            }
            if (!$attachmentData[$i]['thumbnail']['has_thumb']) {
                $attachmentData[$i]['downloads']++;
            }
        }
        // sort images to the top
        usort($attachmentData, 'sort_by_type');
    }
    // Do we need to instigate a sort?
    if ($have_unapproved) {
        usort($attachmentData, 'approved_attach_sort');
    }
    return $attachmentData;
}
Example #4
0
/**
 * add a stream activity
 *
 * @param int $id_member	the member id who owns this activity (= who did it)
 * @param int $atype		activity type (numeric)
 * @param $params			array with parameters, mostly for formatting
 * @param int $id_board		the board id where it happened (if applicable)
 * @param int $id_topic		the topic id where it happened (if applicable)
 * @param int $id_content	the content id. this can be a message id but could also be a user id
 * 							(e.g. when a member posts on the profile of another member). depends on the context
 * @param int $id_owner     the content owner (id_member)
 * @param int $priv_level   privacy level for is_private.
 * @param int $dont_notify  do not send the owner a notification for the activity.
 *
 * @return unique id (positive integer) of the inserted activity type, 0 if something went wrong.
 */
function aStreamAdd($id_member, $atype, $params, $id_board = 0, $id_topic = 0, $id_content = 0, $id_owner = 0, $priv_level = 0, $dont_notify = false)
{
    global $user_info;
    $act_must_notify = array(ACT_LIKE, ACT_REPLIED);
    // these activity types will trigger a *mandatory*
    if (0 == $id_member || 0 == $id_owner) {
        // notification for $id_owner unless $dont_notify indicates otherwise
        return 0;
    }
    if (0 == $atype) {
        $_s = sprintf('Warning: tried to add atype==0 with id_member=%d, params=%s, id_board=%d, id_topic=%d', $id_member, @serialize($params), $id_board, $id_topic);
        log_error($_s);
        return 0;
    }
    // respect opt out setting
    if (!empty($user_info['act_optout'])) {
        if (in_array($atype, explode(',', $user_info['act_optout'])) !== false) {
            return 0;
        }
    }
    smf_db_insert('', '{db_prefix}log_activities', array('id_member' => 'int', 'id_type' => 'int', 'updated' => 'int', 'params' => 'string', 'is_private' => 'int', 'id_board' => 'int', 'id_topic' => 'int', 'id_content' => 'int', 'id_owner' => 'int'), array((int) $id_member, (int) $atype, time(), serialize($params), $priv_level, (int) $id_board, (int) $id_topic, (int) $id_content, (int) $id_owner), array('id_act'));
    $id_act = smf_db_insert_id('{db_prefix}log_activities', 'id_act');
    // if this activity triggers a notification for the id_owner, use the $id_act to link it
    // to the notifications table.
    if ($id_act && $id_owner && in_array($atype, $act_must_notify) && !$dont_notify) {
        aStreamAddNotification($id_owner, $id_act, $atype);
    }
    $data = array('id_member' => $id_member, 'type' => $atype, 'params' => $params, 'board' => $id_board, 'topic' => $id_topic, 'content_id' => $id_content, 'id_owner' => $id_owner, 'plevel' => $priv_level, 'event_id' => $id_act);
    HookAPI::callHook('astream_event_added', array(&$data));
    return $id_act;
}
Example #5
0
/**
 * edit news items.
 * todo: this needs LOTS of UX improvements, AJAX inline editing and stuff like that
 * for now, a basic UI is ok to test the feature
 */
function EditNewsItem()
{
    global $txt, $context, $sourcedir, $scripturl;
    require_once $sourcedir . '/lib/Subs-Post.php';
    $id_item = isset($_REQUEST['itemid']) ? (int) $_REQUEST['itemid'] : '0';
    if (isset($_GET['save'])) {
        checkSession();
        $_POST['body'] = commonAPI::htmlspecialchars($_POST['body'], ENT_QUOTES);
        if (stripos($_POST['body'], '[more]') !== false) {
            list($teaser, $body) = explode('[more]', $_POST['body']);
        } else {
            $teaser = '';
            $body =& $_POST['body'];
        }
        preparsecode($teaser);
        preparsecode($body);
        $_POST['showboards'] = isset($_POST['showboards']) ? normalizeCommaDelimitedList($_POST['showboards']) : '';
        $_POST['showtopics'] = isset($_POST['showtopics']) ? normalizeCommaDelimitedList($_POST['showtopics']) : '';
        $_POST['showgroups'] = isset($_POST['showgroups']) ? normalizeCommaDelimitedList($_POST['showgroups']) : '';
        $_POST['showindex'] = isset($_POST['showindex']) ? 1 : 0;
        if (isset($_POST['id']) && !empty($_POST['id'])) {
            // modify existing
            smf_db_query('
				UPDATE {db_prefix}news SET body = {string:body}, teaser = {string:teaser}, groups = {string:groups}, boards = {string:boards},
					topics = {string:topics}, on_index = {int:onindex}, can_dismiss = {int:can_dismiss} WHERE id_news = {int:idnews}', array('body' => $body, 'teaser' => $teaser, 'topics' => $_POST['showtopics'], 'boards' => $_POST['showboards'], 'groups' => $_POST['showgroups'], 'idnews' => $_POST['id'], 'onindex' => $_POST['showindex'], 'can_dismiss' => $_POST['mandatory'] ? 0 : 1));
            $redirect_id = $_POST['id'];
        } else {
            // add new
            smf_db_insert('insert', '{db_prefix}news', array('body' => 'string', 'boards' => 'string', 'topics' => 'string', 'groups' => 'string', 'on_index' => 'int', 'can_dismiss' => 'int'), array($_POST['body'], $_POST['showboards'], $_POST['showtopics'], $_POST['showgroups'], $_POST['showindex'], $_POST['mandatory'] ? 0 : 1), array('id_news'));
            $redirect_id = smf_db_insert_id('{db_prefix}news', 'id_news');
        }
        CacheAPI::putCache('newsitems', null, 360);
        redirectexit($scripturl . '?action=admin;area=news;sa=editnewsitem;itemid=' . $redirect_id);
    }
    if ($id_item) {
        $result = smf_db_query('SELECT * FROM {db_prefix}news WHERE id_news = {int:id_item}', array('id_item' => $id_item));
        $row = mysql_fetch_assoc($result);
        if ($row) {
            $context['news_item'] = array('id' => $row['id_news'], 'teaser' => $row['teaser'], 'body' => $row['body'], 'boards' => $row['boards'], 'topics' => $row['topics'], 'on_index' => $row['on_index'], 'groups' => $row['groups'], 'can_dismiss' => $row['can_dismiss']);
            if (!empty($context['news_item']['teaser'])) {
                $context['news_item']['body'] = $context['news_item']['teaser'] . '[more]' . $context['news_item']['body'];
            }
            $context['news_item']['body'] = un_preparsecode($context['news_item']['body']);
        }
        mysql_free_result($result);
    } else {
        $context['news_item']['id'] = $context['news_item']['on_index'] = 0;
        $context['news_item']['body'] = $context['news_item']['boards'] = $context['news_item']['topics'] = $context['news_item']['groups'] = '';
        $context['news_item']['can_dismiss'] = 1;
    }
    $context['sub_template'] = 'edit_news_item';
    $context['page_title'] = $txt['admin_edit_news'];
    $context['submit_url'] = $scripturl . '?action=admin;area=news;sa=editnewsitem;save';
}
Example #6
0
function EditPoll2()
{
    global $txt, $topic, $board, $context;
    global $modSettings, $user_info, $smcFunc, $sourcedir;
    // Sneaking off, are we?
    if (empty($_POST)) {
        redirectexit('action=editpoll;topic=' . $topic . '.0');
    }
    if (checkSession('post', '', false) != '') {
        $poll_errors[] = 'session_timeout';
    }
    if (isset($_POST['preview'])) {
        return EditPoll();
    }
    // HACKERS (!!) can't edit :P.
    if (empty($topic)) {
        fatal_lang_error('no_access', false);
    }
    // Is this a new poll, or editing an existing?
    $isEdit = isset($_REQUEST['add']) ? 0 : 1;
    // Get the starter and the poll's ID - if it's an edit.
    $request = smf_db_query('
		SELECT t.id_member_started, t.id_poll, p.id_member AS poll_starter, p.expire_time
		FROM {db_prefix}topics AS t
			LEFT JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll)
		WHERE t.id_topic = {int:current_topic}
		LIMIT 1', array('current_topic' => $topic));
    if (mysql_num_rows($request) == 0) {
        fatal_lang_error('no_board');
    }
    $bcinfo = mysql_fetch_assoc($request);
    mysql_free_result($request);
    // Check their adding/editing is valid.
    if (!$isEdit && !empty($bcinfo['id_poll'])) {
        fatal_lang_error('poll_already_exists');
    } elseif ($isEdit && empty($bcinfo['id_poll'])) {
        fatal_lang_error('poll_not_found');
    }
    // Check if they have the power to add or edit the poll.
    if ($isEdit && !allowedTo('poll_edit_any')) {
        isAllowedTo('poll_edit_' . ($user_info['id'] == $bcinfo['id_member_started'] || $bcinfo['poll_starter'] != 0 && $user_info['id'] == $bcinfo['poll_starter'] ? 'own' : 'any'));
    } elseif (!$isEdit && !allowedTo('poll_add_any')) {
        isAllowedTo('poll_add_' . ($user_info['id'] == $bcinfo['id_member_started'] ? 'own' : 'any'));
    }
    $optionCount = 0;
    // Ensure the user is leaving a valid amount of options - there must be at least two.
    foreach ($_POST['options'] as $k => $option) {
        if (trim($option) != '') {
            $optionCount++;
        }
    }
    if ($optionCount < 2) {
        $poll_errors[] = 'poll_few';
    }
    // Also - ensure they are not removing the question.
    if (trim($_POST['question']) == '') {
        $poll_errors[] = 'no_question';
    }
    // Got any errors to report?
    if (!empty($poll_errors)) {
        loadLanguage('Errors');
        // Previewing.
        $_POST['preview'] = true;
        $context['poll_error'] = array('messages' => array());
        foreach ($poll_errors as $poll_error) {
            $context['poll_error'][$poll_error] = true;
            $context['poll_error']['messages'][] = $txt['error_' . $poll_error];
        }
        return EditPoll();
    }
    // Prevent double submission of this form.
    checkSubmitOnce('check');
    // Now we've done all our error checking, let's get the core poll information cleaned... question first.
    $_POST['question'] = commonAPI::htmlspecialchars($_POST['question']);
    $_POST['question'] = commonAPI::truncate($_POST['question'], 255);
    $_POST['poll_hide'] = (int) $_POST['poll_hide'];
    $_POST['poll_expire'] = isset($_POST['poll_expire']) ? (int) $_POST['poll_expire'] : 0;
    $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0;
    $_POST['poll_guest_vote'] = isset($_POST['poll_guest_vote']) ? 1 : 0;
    // Make sure guests are actually allowed to vote generally.
    if ($_POST['poll_guest_vote']) {
        require_once $sourcedir . '/lib/Subs-Members.php';
        $allowedGroups = groupsAllowedTo('poll_vote', $board);
        if (!in_array(-1, $allowedGroups['allowed'])) {
            $_POST['poll_guest_vote'] = 0;
        }
    }
    // Ensure that the number options allowed makes sense, and the expiration date is valid.
    if (!$isEdit || allowedTo('moderate_board')) {
        $_POST['poll_expire'] = $_POST['poll_expire'] > 9999 ? 9999 : ($_POST['poll_expire'] < 0 ? 0 : $_POST['poll_expire']);
        if (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
            $_POST['poll_hide'] = 1;
        } elseif (!$isEdit || $_POST['poll_expire'] != ceil($bcinfo['expire_time'] <= time() ? -1 : ($bcinfo['expire_time'] - time()) / (3600 * 24))) {
            $_POST['poll_expire'] = empty($_POST['poll_expire']) ? '0' : time() + $_POST['poll_expire'] * 3600 * 24;
        } else {
            $_POST['poll_expire'] = $bcinfo['expire_time'];
        }
        if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
            $_POST['poll_max_votes'] = 1;
        } else {
            $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
        }
    }
    // If we're editing, let's commit the changes.
    if ($isEdit) {
        smf_db_query('
			UPDATE {db_prefix}polls
			SET question = {string:question}, change_vote = {int:change_vote},' . (allowedTo('moderate_board') ? '
				hide_results = {int:hide_results}, expire_time = {int:expire_time}, max_votes = {int:max_votes},
				guest_vote = {int:guest_vote}' : '
				hide_results = CASE WHEN expire_time = {int:expire_time_zero} AND {int:hide_results} = 2 THEN 1 ELSE {int:hide_results} END') . '
			WHERE id_poll = {int:id_poll}', array('change_vote' => $_POST['poll_change_vote'], 'hide_results' => $_POST['poll_hide'], 'expire_time' => !empty($_POST['poll_expire']) ? $_POST['poll_expire'] : 0, 'max_votes' => !empty($_POST['poll_max_votes']) ? $_POST['poll_max_votes'] : 0, 'guest_vote' => $_POST['poll_guest_vote'], 'expire_time_zero' => 0, 'id_poll' => $bcinfo['id_poll'], 'question' => $_POST['question']));
    } else {
        // Create the poll.
        smf_db_insert('', '{db_prefix}polls', array('question' => 'string-255', 'hide_results' => 'int', 'max_votes' => 'int', 'expire_time' => 'int', 'id_member' => 'int', 'poster_name' => 'string-255', 'change_vote' => 'int', 'guest_vote' => 'int'), array($_POST['question'], $_POST['poll_hide'], $_POST['poll_max_votes'], $_POST['poll_expire'], $user_info['id'], $user_info['username'], $_POST['poll_change_vote'], $_POST['poll_guest_vote']), array('id_poll'));
        // Set the poll ID.
        $bcinfo['id_poll'] = smf_db_insert_id('{db_prefix}polls', 'id_poll');
        // Link the poll to the topic
        smf_db_query('
			UPDATE {db_prefix}topics
			SET id_poll = {int:id_poll}
			WHERE id_topic = {int:current_topic}', array('current_topic' => $topic, 'id_poll' => $bcinfo['id_poll']));
    }
    // Get all the choices.  (no better way to remove all emptied and add previously non-existent ones.)
    $request = smf_db_query('
		SELECT id_choice
		FROM {db_prefix}poll_choices
		WHERE id_poll = {int:id_poll}', array('id_poll' => $bcinfo['id_poll']));
    $choices = array();
    while ($row = mysql_fetch_assoc($request)) {
        $choices[] = $row['id_choice'];
    }
    mysql_free_result($request);
    $delete_options = array();
    foreach ($_POST['options'] as $k => $option) {
        // Make sure the key is numeric for sanity's sake.
        $k = (int) $k;
        // They've cleared the box.  Either they want it deleted, or it never existed.
        if (trim($option) == '') {
            // They want it deleted.  Bye.
            if (in_array($k, $choices)) {
                $delete_options[] = $k;
            }
            // Skip the rest...
            continue;
        }
        // Dress the option up for its big date with the database.
        $option = commonAPI::htmlspecialchars($option);
        // If it's already there, update it.  If it's not... add it.
        if (in_array($k, $choices)) {
            smf_db_query('
				UPDATE {db_prefix}poll_choices
				SET label = {string:option_name}
				WHERE id_poll = {int:id_poll}
					AND id_choice = {int:id_choice}', array('id_poll' => $bcinfo['id_poll'], 'id_choice' => $k, 'option_name' => $option));
        } else {
            smf_db_insert('', '{db_prefix}poll_choices', array('id_poll' => 'int', 'id_choice' => 'int', 'label' => 'string-255', 'votes' => 'int'), array($bcinfo['id_poll'], $k, $option, 0), array());
        }
    }
    // I'm sorry, but... well, no one was choosing you.  Poor options, I'll put you out of your misery.
    if (!empty($delete_options)) {
        smf_db_query('
			DELETE FROM {db_prefix}log_polls
			WHERE id_poll = {int:id_poll}
				AND id_choice IN ({array_int:delete_options})', array('delete_options' => $delete_options, 'id_poll' => $bcinfo['id_poll']));
        smf_db_query('
			DELETE FROM {db_prefix}poll_choices
			WHERE id_poll = {int:id_poll}
				AND id_choice IN ({array_int:delete_options})', array('delete_options' => $delete_options, 'id_poll' => $bcinfo['id_poll']));
    }
    // Shall I reset the vote count, sir?
    if (isset($_POST['resetVoteCount'])) {
        smf_db_query('
			UPDATE {db_prefix}polls
			SET num_guest_voters = {int:no_votes}, reset_poll = {int:time}
			WHERE id_poll = {int:id_poll}', array('no_votes' => 0, 'id_poll' => $bcinfo['id_poll'], 'time' => time()));
        smf_db_query('
			UPDATE {db_prefix}poll_choices
			SET votes = {int:no_votes}
			WHERE id_poll = {int:id_poll}', array('no_votes' => 0, 'id_poll' => $bcinfo['id_poll']));
        smf_db_query('
			DELETE FROM {db_prefix}log_polls
			WHERE id_poll = {int:id_poll}', array('id_poll' => $bcinfo['id_poll']));
    }
    // Off we go.
    redirectexit('topic=' . $topic . '.' . $_REQUEST['start']);
}
Example #7
0
function createAttachment(&$attachmentOptions)
{
    global $modSettings, $sourcedir, $backend_subdir;
    require_once $sourcedir . '/lib/Subs-Graphics.php';
    // We need to know where this thing is going.
    if (!empty($modSettings['currentAttachmentUploadDir'])) {
        if (!is_array($modSettings['attachmentUploadDir'])) {
            $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
        }
        // Just use the current path for temp files.
        $attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
        $id_folder = $modSettings['currentAttachmentUploadDir'];
    } else {
        $attach_dir = $modSettings['attachmentUploadDir'];
        $id_folder = 1;
    }
    $attachmentOptions['errors'] = array();
    if (!isset($attachmentOptions['post'])) {
        $attachmentOptions['post'] = 0;
    }
    if (!isset($attachmentOptions['approved'])) {
        $attachmentOptions['approved'] = 1;
    }
    $already_uploaded = preg_match('~^post_tmp_' . $attachmentOptions['poster'] . '_\\d+$~', $attachmentOptions['tmp_name']) != 0;
    $file_restricted = @ini_get('open_basedir') != '' && !$already_uploaded;
    if ($already_uploaded) {
        $attachmentOptions['tmp_name'] = $attach_dir . '/' . $attachmentOptions['tmp_name'];
    }
    // Make sure the file actually exists... sometimes it doesn't.
    if (!$file_restricted && !file_exists($attachmentOptions['tmp_name']) || !$already_uploaded && !is_uploaded_file($attachmentOptions['tmp_name'])) {
        $attachmentOptions['errors'] = array('could_not_upload');
        return false;
    }
    // These are the only valid image types for SMF.
    $validImageTypes = array(1 => 'gif', 2 => 'jpeg', 3 => 'png', 5 => 'psd', 6 => 'bmp', 7 => 'tiff', 8 => 'tiff', 9 => 'jpeg', 14 => 'iff');
    if (!$file_restricted || $already_uploaded) {
        $size = @getimagesize($attachmentOptions['tmp_name']);
        list($attachmentOptions['width'], $attachmentOptions['height']) = $size;
        // If it's an image get the mime type right.
        if (empty($attachmentOptions['mime_type']) && $attachmentOptions['width']) {
            // Got a proper mime type?
            if (!empty($size['mime'])) {
                $attachmentOptions['mime_type'] = $size['mime'];
            } elseif (isset($validImageTypes[$size[2]])) {
                $attachmentOptions['mime_type'] = 'image/' . $validImageTypes[$size[2]];
            }
        }
    }
    // Get the hash if no hash has been given yet.
    if (empty($attachmentOptions['file_hash'])) {
        $attachmentOptions['file_hash'] = getAttachmentFilename($attachmentOptions['name'], false, null, true);
    }
    // Is the file too big?
    if (!empty($modSettings['attachmentSizeLimit']) && $attachmentOptions['size'] > $modSettings['attachmentSizeLimit'] * 1024) {
        $attachmentOptions['errors'][] = 'too_large';
    }
    if (!empty($modSettings['attachmentCheckExtensions'])) {
        $allowed = explode(',', strtolower($modSettings['attachmentExtensions']));
        foreach ($allowed as $k => $dummy) {
            $allowed[$k] = trim($dummy);
        }
        if (!in_array(strtolower(substr(strrchr($attachmentOptions['name'], '.'), 1)), $allowed)) {
            $attachmentOptions['errors'][] = 'bad_extension';
        }
    }
    if (!empty($modSettings['attachmentDirSizeLimit'])) {
        // This is a really expensive operation for big numbers of
        // attachments, which is also very easy to cache. Only do it
        // every ten minutes.
        if (empty($modSettings['attachment_dirsize']) || empty($modSettings['attachment_dirsize_time']) || $modSettings['attachment_dirsize_time'] < time() - 600) {
            // It has been cached - just work with this value for now!
            $dirSize = $modSettings['attachment_dirsize'];
        } else {
            // Make sure the directory isn't full.
            $dirSize = 0;
            $dir = @opendir($attach_dir) or fatal_lang_error('cant_access_upload_path', 'critical');
            while ($file = readdir($dir)) {
                if ($file == '.' || $file == '..') {
                    continue;
                }
                if (preg_match('~^post_tmp_\\d+_\\d+$~', $file) != 0) {
                    // Temp file is more than 5 hours old!
                    if (filemtime($attach_dir . '/' . $file) < time() - 18000) {
                        @unlink($attach_dir . '/' . $file);
                    }
                    continue;
                }
                $dirSize += filesize($attach_dir . '/' . $file);
            }
            closedir($dir);
            updateSettings(array('attachment_dirsize' => $dirSize, 'attachment_dirsize_time' => time()));
        }
        // Too big!  Maybe you could zip it or something...
        if ($attachmentOptions['size'] + $dirSize > $modSettings['attachmentDirSizeLimit'] * 1024) {
            $attachmentOptions['errors'][] = 'directory_full';
        } elseif (!isset($modSettings['attachment_full_notified']) && $modSettings['attachmentDirSizeLimit'] > 4000 && $attachmentOptions['size'] + $dirSize > ($modSettings['attachmentDirSizeLimit'] - 2000) * 1024) {
            require_once $sourcedir . '/lib/Subs-Admin.php';
            emailAdmins('admin_attachments_full');
            updateSettings(array('attachment_full_notified' => 1));
        }
    }
    // Check if the file already exists.... (for those who do not encrypt their filenames...)
    if (empty($modSettings['attachmentEncryptFilenames'])) {
        // Make sure they aren't trying to upload a nasty file.
        $disabledFiles = array('con', 'com1', 'com2', 'com3', 'com4', 'prn', 'aux', 'lpt1', '.htaccess', 'index.php');
        if (in_array(strtolower(basename($attachmentOptions['name'])), $disabledFiles)) {
            $attachmentOptions['errors'][] = 'bad_filename';
        }
        // Check if there's another file with that name...
        $request = smf_db_query('
			SELECT id_attach
			FROM {db_prefix}attachments
			WHERE filename = {string:filename}
			LIMIT 1', array('filename' => strtolower($attachmentOptions['name'])));
        if (mysql_num_rows($request) > 0) {
            $attachmentOptions['errors'][] = 'taken_filename';
        }
        mysql_free_result($request);
    }
    if (!empty($attachmentOptions['errors'])) {
        return false;
    }
    if (!is_writable($attach_dir)) {
        fatal_lang_error('attachments_no_write', 'critical');
    }
    // Assuming no-one set the extension let's take a look at it.
    if (empty($attachmentOptions['fileext'])) {
        $attachmentOptions['fileext'] = strtolower(strrpos($attachmentOptions['name'], '.') !== false ? substr($attachmentOptions['name'], strrpos($attachmentOptions['name'], '.') + 1) : '');
        if (strlen($attachmentOptions['fileext']) > 8 || '.' . $attachmentOptions['fileext'] == $attachmentOptions['name']) {
            $attachmentOptions['fileext'] = '';
        }
    }
    smf_db_insert('', '{db_prefix}attachments', array('id_folder' => 'int', 'id_msg' => 'int', 'filename' => 'string-255', 'file_hash' => 'string-40', 'fileext' => 'string-8', 'size' => 'int', 'width' => 'int', 'height' => 'int', 'mime_type' => 'string-20', 'approved' => 'int'), array($id_folder, (int) $attachmentOptions['post'], $attachmentOptions['name'], $attachmentOptions['file_hash'], $attachmentOptions['fileext'], (int) $attachmentOptions['size'], empty($attachmentOptions['width']) ? 0 : (int) $attachmentOptions['width'], empty($attachmentOptions['height']) ? '0' : (int) $attachmentOptions['height'], !empty($attachmentOptions['mime_type']) ? $attachmentOptions['mime_type'] : '', (int) $attachmentOptions['approved']), array('id_attach'));
    $attachmentOptions['id'] = smf_db_insert_id('{db_prefix}attachments', 'id_attach');
    if (empty($attachmentOptions['id'])) {
        return false;
    }
    // If it's not approved add to the approval queue.
    if (!$attachmentOptions['approved']) {
        smf_db_insert('', '{db_prefix}approval_queue', array('id_attach' => 'int', 'id_msg' => 'int'), array($attachmentOptions['id'], (int) $attachmentOptions['post']), array());
    }
    $attachmentOptions['destination'] = getAttachmentFilename(basename($attachmentOptions['name']), $attachmentOptions['id'], $id_folder, false, $attachmentOptions['file_hash']);
    if ($already_uploaded) {
        rename($attachmentOptions['tmp_name'], $attachmentOptions['destination']);
    } elseif (!move_uploaded_file($attachmentOptions['tmp_name'], $attachmentOptions['destination'])) {
        fatal_lang_error('attach_timeout', 'critical');
    }
    // Udate the cached directory size, if we care for it.
    if (!empty($modSettings['attachmentDirSizeLimit'])) {
        updateSettings(array('attachment_dirsize' => $modSettings['attachment_dirsize'] + $attachmentOptions['size'], 'attachment_dirsize_time' => time()));
    }
    // Attempt to chmod it.
    @chmod($attachmentOptions['destination'], 0644);
    $size = @getimagesize($attachmentOptions['destination']);
    list($attachmentOptions['width'], $attachmentOptions['height']) = empty($size) ? array(null, null, null) : $size;
    // We couldn't access the file before...
    if ($file_restricted) {
        // Have a go at getting the right mime type.
        if (empty($attachmentOptions['mime_type']) && $attachmentOptions['width']) {
            if (!empty($size['mime'])) {
                $attachmentOptions['mime_type'] = $size['mime'];
            } elseif (isset($validImageTypes[$size[2]])) {
                $attachmentOptions['mime_type'] = 'image/' . $validImageTypes[$size[2]];
            }
        }
        if (!empty($attachmentOptions['width']) && !empty($attachmentOptions['height'])) {
            smf_db_query('
				UPDATE {db_prefix}attachments
				SET
					width = {int:width},
					height = {int:height},
					mime_type = {string:mime_type}
				WHERE id_attach = {int:id_attach}', array('width' => (int) $attachmentOptions['width'], 'height' => (int) $attachmentOptions['height'], 'id_attach' => $attachmentOptions['id'], 'mime_type' => empty($attachmentOptions['mime_type']) ? '' : $attachmentOptions['mime_type']));
        }
    }
    // Security checks for images
    // Do we have an image? If yes, we need to check it out!
    if (isset($validImageTypes[$size[2]])) {
        if (!checkImageContents($attachmentOptions['destination'], !empty($modSettings['attachment_image_paranoid']))) {
            // It's bad. Last chance, maybe we can re-encode it?
            if (empty($modSettings['attachment_image_reencode']) || !reencodeImage($attachmentOptions['destination'], $size[2])) {
                // Nothing to do: not allowed or not successful re-encoding it.
                require_once $sourcedir . '/lib/Subs-ManageAttachments.php';
                removeAttachments(array('id_attach' => $attachmentOptions['id']));
                $attachmentOptions['id'] = null;
                $attachmentOptions['errors'][] = 'bad_attachment';
                return false;
            }
            // Success! However, successes usually come for a price:
            // we might get a new format for our image...
            $old_format = $size[2];
            $size = @getimagesize($attachmentOptions['destination']);
            if (!empty($size) && $size[2] != $old_format) {
                // Let's update the image information
                // !!! This is becoming a mess: we keep coming back and update the database,
                //  instead of getting it right the first time.
                if (isset($validImageTypes[$size[2]])) {
                    $attachmentOptions['mime_type'] = 'image/' . $validImageTypes[$size[2]];
                    smf_db_query('
						UPDATE {db_prefix}attachments
						SET
							mime_type = {string:mime_type}
						WHERE id_attach = {int:id_attach}', array('id_attach' => $attachmentOptions['id'], 'mime_type' => $attachmentOptions['mime_type']));
                }
            }
        }
    }
    if (!empty($attachmentOptions['skip_thumbnail']) || empty($attachmentOptions['width']) && empty($attachmentOptions['height'])) {
        return true;
    }
    // Like thumbnails, do we?
    if (!empty($modSettings['attachmentThumbnails']) && !empty($modSettings['attachmentThumbWidth']) && !empty($modSettings['attachmentThumbHeight']) && ($attachmentOptions['width'] > $modSettings['attachmentThumbWidth'] || $attachmentOptions['height'] > $modSettings['attachmentThumbHeight'])) {
        if (createThumbnail($attachmentOptions['destination'], $modSettings['attachmentThumbWidth'], $modSettings['attachmentThumbHeight'])) {
            // Figure out how big we actually made it.
            $size = @getimagesize($attachmentOptions['destination'] . '_thumb');
            list($thumb_width, $thumb_height) = $size;
            if (!empty($size['mime'])) {
                $thumb_mime = $size['mime'];
            } elseif (isset($validImageTypes[$size[2]])) {
                $thumb_mime = 'image/' . $validImageTypes[$size[2]];
            } else {
                $thumb_mime = '';
            }
            $thumb_filename = $attachmentOptions['name'] . '_thumb';
            $thumb_size = filesize($attachmentOptions['destination'] . '_thumb');
            $thumb_file_hash = getAttachmentFilename($thumb_filename, false, null, true);
            // To the database we go!
            smf_db_insert('', '{db_prefix}attachments', array('id_folder' => 'int', 'id_msg' => 'int', 'attachment_type' => 'int', 'filename' => 'string-255', 'file_hash' => 'string-40', 'fileext' => 'string-8', 'size' => 'int', 'width' => 'int', 'height' => 'int', 'mime_type' => 'string-20', 'approved' => 'int'), array($id_folder, (int) $attachmentOptions['post'], 3, $thumb_filename, $thumb_file_hash, $attachmentOptions['fileext'], $thumb_size, $thumb_width, $thumb_height, $thumb_mime, (int) $attachmentOptions['approved']), array('id_attach'));
            $attachmentOptions['thumb'] = smf_db_insert_id('{db_prefix}attachments', 'id_attach');
            if (!empty($attachmentOptions['thumb'])) {
                smf_db_query('
					UPDATE {db_prefix}attachments
					SET id_thumb = {int:id_thumb}
					WHERE id_attach = {int:id_attach}', array('id_thumb' => $attachmentOptions['thumb'], 'id_attach' => $attachmentOptions['id']));
                rename($attachmentOptions['destination'] . '_thumb', getAttachmentFilename($thumb_filename, $attachmentOptions['thumb'], $id_folder, false, $thumb_file_hash));
            }
        }
    }
    return true;
}
Example #8
0
function ReportToModerator2()
{
    global $txt, $scripturl, $topic, $board, $user_info, $modSettings, $sourcedir, $language, $context, $smcFunc;
    // You must have the proper permissions!
    isAllowedTo('report_any');
    // Make sure they aren't spamming.
    spamProtection('reporttm');
    require_once $sourcedir . '/lib/Subs-Post.php';
    // No errors, yet.
    $post_errors = array();
    // Check their session.
    if (checkSession('post', '', false) != '') {
        $post_errors[] = 'session_timeout';
    }
    // Make sure we have a comment and it's clean.
    if (!isset($_POST['comment']) || commonAPI::htmltrim($_POST['comment']) === '') {
        $post_errors[] = 'no_comment';
    }
    $poster_comment = strtr(commonAPI::htmlspecialchars($_POST['comment']), array("\r" => '', "\n" => '', "\t" => ''));
    // Guests need to provide their address!
    if ($user_info['is_guest']) {
        $_POST['email'] = !isset($_POST['email']) ? '' : trim($_POST['email']);
        if ($_POST['email'] === '') {
            $post_errors[] = 'no_email';
        } elseif (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['email']) == 0) {
            $post_errors[] = 'bad_email';
        }
        isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt['guest_title']));
        $user_info['email'] = htmlspecialchars($_POST['email']);
    }
    // Could they get the right verification code?
    if ($user_info['is_guest'] && !empty($modSettings['guests_report_require_captcha'])) {
        require_once $sourcedir . '/lib/Subs-Editor.php';
        $verificationOptions = array('id' => 'report');
        $context['require_verification'] = create_control_verification($verificationOptions, true);
        if (is_array($context['require_verification'])) {
            $post_errors = array_merge($post_errors, $context['require_verification']);
        }
    }
    // Any errors?
    if (!empty($post_errors)) {
        loadLanguage('Errors');
        $context['post_errors'] = array();
        foreach ($post_errors as $post_error) {
            $context['post_errors'][] = $txt['error_' . $post_error];
        }
        return ReportToModerator();
    }
    // Get the basic topic information, and make sure they can see it.
    $_POST['msg'] = (int) $_POST['msg'];
    $request = smf_db_query('
		SELECT m.id_topic, m.id_board, m.subject, m.body, m.id_member AS id_poster, m.poster_name, mem.real_name
		FROM {db_prefix}messages AS m
			LEFT JOIN {db_prefix}members AS mem ON (m.id_member = mem.id_member)
		WHERE m.id_msg = {int:id_msg}
			AND m.id_topic = {int:current_topic}
		LIMIT 1', array('current_topic' => $topic, 'id_msg' => $_POST['msg']));
    if (mysql_num_rows($request) == 0) {
        fatal_lang_error('no_board', false);
    }
    $message = mysql_fetch_assoc($request);
    mysql_free_result($request);
    $poster_name = un_htmlspecialchars($message['real_name']) . ($message['real_name'] != $message['poster_name'] ? ' (' . $message['poster_name'] . ')' : '');
    $reporterName = un_htmlspecialchars($user_info['name']) . ($user_info['name'] != $user_info['username'] && $user_info['username'] != '' ? ' (' . $user_info['username'] . ')' : '');
    $subject = un_htmlspecialchars($message['subject']);
    // Get a list of members with the moderate_board permission.
    require_once $sourcedir . '/lib/Subs-Members.php';
    $moderators = membersAllowedTo('moderate_board', $board);
    $request = smf_db_query('
		SELECT id_member, email_address, lngfile, mod_prefs
		FROM {db_prefix}members
		WHERE id_member IN ({array_int:moderator_list})
			AND notify_types != {int:notify_types}
		ORDER BY lngfile', array('moderator_list' => $moderators, 'notify_types' => 4));
    // Check that moderators do exist!
    if (mysql_num_rows($request) == 0) {
        fatal_lang_error('no_mods', false);
    }
    // If we get here, I believe we should make a record of this, for historical significance, yabber.
    if (empty($modSettings['disable_log_report'])) {
        $request2 = smf_db_query('
			SELECT id_report, ignore_all
			FROM {db_prefix}log_reported
			WHERE id_msg = {int:id_msg}
				AND (closed = {int:not_closed} OR ignore_all = {int:ignored})
			ORDER BY ignore_all DESC', array('id_msg' => $_POST['msg'], 'not_closed' => 0, 'ignored' => 1));
        if (mysql_num_rows($request2) != 0) {
            list($id_report, $ignore) = mysql_fetch_row($request2);
        }
        mysql_free_result($request2);
        // If we're just going to ignore these, then who gives a monkeys...
        if (!empty($ignore)) {
            redirectexit('topic=' . $topic . '.msg' . $_POST['msg'] . '#msg' . $_POST['msg']);
        }
        // Already reported? My god, we could be dealing with a real rogue here...
        if (!empty($id_report)) {
            smf_db_query('
				UPDATE {db_prefix}log_reported
				SET num_reports = num_reports + 1, time_updated = {int:current_time}
				WHERE id_report = {int:id_report}', array('current_time' => time(), 'id_report' => $id_report));
        } else {
            if (empty($message['real_name'])) {
                $message['real_name'] = $message['poster_name'];
            }
            smf_db_insert('', '{db_prefix}log_reported', array('id_msg' => 'int', 'id_topic' => 'int', 'id_board' => 'int', 'id_member' => 'int', 'membername' => 'string', 'subject' => 'string', 'body' => 'string', 'time_started' => 'int', 'time_updated' => 'int', 'num_reports' => 'int', 'closed' => 'int'), array($_POST['msg'], $message['id_topic'], $message['id_board'], $message['id_poster'], $message['real_name'], $message['subject'], $message['body'], time(), time(), 1, 0), array('id_report'));
            $id_report = smf_db_insert_id('{db_prefix}log_reported', 'id_report');
        }
        // Now just add our report...
        if ($id_report) {
            smf_db_insert('', '{db_prefix}log_reported_comments', array('id_report' => 'int', 'id_member' => 'int', 'membername' => 'string', 'email_address' => 'string', 'member_ip' => 'string', 'comment' => 'string', 'time_sent' => 'int'), array($id_report, $user_info['id'], $user_info['name'], $user_info['email'], $user_info['ip'], $poster_comment, time()), array('id_comment'));
        }
    }
    // Find out who the real moderators are - for mod preferences.
    $request2 = smf_db_query('
		SELECT id_member
		FROM {db_prefix}moderators
		WHERE id_board = {int:current_board}', array('current_board' => $board));
    $real_mods = array();
    while ($row = mysql_fetch_assoc($request2)) {
        $real_mods[] = $row['id_member'];
    }
    mysql_free_result($request2);
    // Send every moderator an email.
    while ($row = mysql_fetch_assoc($request)) {
        // Maybe they don't want to know?!
        if (!empty($row['mod_prefs'])) {
            list(, , $pref_binary) = explode('|', $row['mod_prefs']);
            if (!($pref_binary & 1) && (!($pref_binary & 2) || !in_array($row['id_member'], $real_mods))) {
                continue;
            }
        }
        $replacements = array('TOPICSUBJECT' => $subject, 'POSTERNAME' => $poster_name, 'REPORTERNAME' => $reporterName, 'TOPICLINK' => $scripturl . '?topic=' . $topic . '.msg' . $_POST['msg'] . '#msg' . $_POST['msg'], 'REPORTLINK' => !empty($id_report) ? $scripturl . '?action=moderate;area=reports;report=' . $id_report : '', 'COMMENT' => $_POST['comment']);
        $emaildata = loadEmailTemplate('report_to_moderator', $replacements, empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']);
        // Send it to the moderator.
        sendmail($row['email_address'], $emaildata['subject'], $emaildata['body'], $user_info['email'], null, false, 2);
    }
    mysql_free_result($request);
    // Keep track of when the mod reports get updated, that way we know when we need to look again.
    updateSettings(array('last_mod_report_action' => time()));
    // Back to the post we reported!
    redirectexit('reportsent;topic=' . $topic . '.msg' . $_POST['msg'] . '#msg' . $_POST['msg']);
}
Example #9
0
function insertEvent(&$eventOptions)
{
    global $modSettings, $smcFunc;
    // Add special chars to the title.
    $eventOptions['title'] = commonAPI::htmlspecialchars($eventOptions['title'], ENT_QUOTES);
    // Add some sanity checking to the span.
    $eventOptions['span'] = isset($eventOptions['span']) && $eventOptions['span'] > 0 ? (int) $eventOptions['span'] : 0;
    // Make sure the start date is in ISO order.
    if (($num_results = sscanf($eventOptions['start_date'], '%d-%d-%d', $year, $month, $day)) !== 3) {
        trigger_error('modifyEvent(): invalid start date format given', E_USER_ERROR);
    }
    // Set the end date (if not yet given)
    if (!isset($eventOptions['end_date'])) {
        $eventOptions['end_date'] = strftime('%Y-%m-%d', mktime(0, 0, 0, $month, $day, $year) + $eventOptions['span'] * 86400);
    }
    // If no topic and board are given, they are not linked to a topic.
    $eventOptions['board'] = isset($eventOptions['board']) ? (int) $eventOptions['board'] : 0;
    $eventOptions['topic'] = isset($eventOptions['topic']) ? (int) $eventOptions['topic'] : 0;
    // Insert the event!
    smf_db_insert('', '{db_prefix}calendar', array('id_board' => 'int', 'id_topic' => 'int', 'title' => 'string-60', 'id_member' => 'int', 'start_date' => 'date', 'end_date' => 'date'), array($eventOptions['board'], $eventOptions['topic'], $eventOptions['title'], $eventOptions['member'], $eventOptions['start_date'], $eventOptions['end_date']), array('id_event'));
    // Store the just inserted id_event for future reference.
    $eventOptions['id'] = smf_db_insert_id('{db_prefix}calendar', 'id_event');
    // Update the settings to show something calendarish was updated.
    updateSettings(array('calendar_updated' => time()));
}
Example #10
0
/**
 * This function is behind the screen for adding new bans and modifying existing ones.
 * Adding new bans:
 * 	- is accesssed by ?action=admin;area=ban;sa=add.
 * 	- uses the ban_edit sub template of the ManageBans template.
 * Modifying existing bans:
 *  - is accesssed by ?action=admin;area=ban;sa=edit;bg=x
 *  - uses the ban_edit sub template of the ManageBans template.
 *  - shows a list of ban triggers for the specified ban.
 *  - handles submitted forms that add, modify or remove ban triggers.
 *
 *  @todo insane number of writing to superglobals here...
 */
function BanEdit()
{
    global $txt, $modSettings, $context, $ban_request, $scripturl;
    $_REQUEST['bg'] = empty($_REQUEST['bg']) ? 0 : (int) $_REQUEST['bg'];
    // Adding or editing a ban trigger?
    if (!empty($_POST['add_new_trigger']) || !empty($_POST['edit_trigger'])) {
        checkSession();
        //validateToken('admin-bet');
        $newBan = !empty($_POST['add_new_trigger']);
        $values = array('id_ban_group' => $_REQUEST['bg'], 'hostname' => '', 'email_address' => '', 'id_member' => 0, 'ip_low1' => 0, 'ip_high1' => 0, 'ip_low2' => 0, 'ip_high2' => 0, 'ip_low3' => 0, 'ip_high3' => 0, 'ip_low4' => 0, 'ip_high4' => 0, 'ip_low5' => 0, 'ip_high5' => 0, 'ip_low6' => 0, 'ip_high6' => 0, 'ip_low7' => 0, 'ip_high7' => 0, 'ip_low8' => 0, 'ip_high8' => 0);
        // Preset all values that are required.
        if ($newBan) {
            $insertKeys = array('id_ban_group' => 'int', 'hostname' => 'string', 'email_address' => 'string', 'id_member' => 'int', 'ip_low1' => 'int', 'ip_high1' => 'int', 'ip_low2' => 'int', 'ip_high2' => 'int', 'ip_low3' => 'int', 'ip_high3' => 'int', 'ip_low4' => 'int', 'ip_high4' => 'int', 'ip_low5' => 'int', 'ip_high5' => 'int', 'ip_low6' => 'int', 'ip_high6' => 'int', 'ip_low7' => 'int', 'ip_high7' => 'int', 'ip_low8' => 'int', 'ip_high8' => 'int');
        } else {
            $updateString = '
				hostname = {string:hostname}, email_address = {string:email_address}, id_member = {int:id_member},
				ip_low1 = {int:ip_low1}, ip_high1 = {int:ip_high1},
				ip_low2 = {int:ip_low2}, ip_high2 = {int:ip_high2},
				ip_low3 = {int:ip_low3}, ip_high3 = {int:ip_high3},
				ip_low4 = {int:ip_low4}, ip_high4 = {int:ip_high4},
				ip_low5 = {int:ip_low5}, ip_high5 = {int:ip_high5},
				ip_low6 = {int:ip_low6}, ip_high6 = {int:ip_high6},
				ip_low7 = {int:ip_low7}, ip_high7 = {int:ip_high7},
				ip_low8 = {int:ip_low8}, ip_high8 = {int:ip_high8}';
        }
        if ($_POST['bantype'] == 'ip_ban') {
            $ip = trim($_POST['ip']);
            $ip_parts = ip2range($ip);
            $ip_check = checkExistingTriggerIP($ip_parts, $ip);
            if (!$ip_check) {
                fatal_lang_error('invalid_ip', false);
            }
            $values = array_merge($values, $ip_check);
            $modlogInfo['ip_range'] = $_POST['ip'];
        } elseif ($_POST['bantype'] == 'hostname_ban') {
            if (preg_match('/[^\\w.\\-*]/', $_POST['hostname']) == 1) {
                fatal_lang_error('invalid_hostname', false);
            }
            // Replace the * wildcard by a MySQL compatible wildcard %.
            $_POST['hostname'] = str_replace('*', '%', $_POST['hostname']);
            $values['hostname'] = $_POST['hostname'];
            $modlogInfo['hostname'] = $_POST['hostname'];
        } elseif ($_POST['bantype'] == 'email_ban') {
            if (preg_match('/[^\\w.\\-\\+*@]/', $_POST['email']) == 1) {
                fatal_lang_error('invalid_email', false);
            }
            $_POST['email'] = strtolower(str_replace('*', '%', $_POST['email']));
            // Check the user is not banning an admin.
            $request = smf_db_query('
				SELECT id_member
				FROM {db_prefix}members
				WHERE (id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0)
					AND email_address LIKE {string:email}
				LIMIT 1', array('admin_group' => 1, 'email' => $_POST['email']));
            if (mysql_num_rows($request) != 0) {
                fatal_lang_error('no_ban_admin', 'critical');
            }
            mysql_free_result($request);
            $values['email_address'] = $_POST['email'];
            $modlogInfo['email'] = $_POST['email'];
        } elseif ($_POST['bantype'] == 'user_ban') {
            $_POST['user'] = preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', CommonAPI::htmlspecialchars($_POST['user'], ENT_QUOTES));
            $request = smf_db_query('
				SELECT id_member, (id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0) AS isAdmin
				FROM {db_prefix}members
				WHERE member_name = {string:user_name} OR real_name = {string:user_name}
				LIMIT 1', array('admin_group' => 1, 'user_name' => $_POST['user']));
            if (mysql_num_rows($request) == 0) {
                fatal_lang_error('invalid_username', false);
            }
            list($memberid, $isAdmin) = mysql_fetch_row($request);
            mysql_free_result($request);
            if ($isAdmin && $isAdmin != 'f') {
                fatal_lang_error('no_ban_admin', 'critical');
            }
            $values['id_member'] = $memberid;
            $modlogInfo['member'] = $memberid;
        } else {
            fatal_lang_error('no_bantype_selected', false);
        }
        if ($newBan) {
            smf_db_insert('', '{db_prefix}ban_items', $insertKeys, $values, array('id_ban'));
        } else {
            smf_db_query('
				UPDATE {db_prefix}ban_items
				SET ' . $updateString . '
				WHERE id_ban = {int:ban_item}
					AND id_ban_group = {int:id_ban_group}', array_merge($values, array('ban_item' => (int) $_REQUEST['bi'])));
        }
        // Log the addion of the ban entry into the moderation log.
        logAction('ban', $modlogInfo + array('new' => $newBan, 'type' => $_POST['bantype']));
        // Register the last modified date.
        updateSettings(array('banLastUpdated' => time()));
        // Update the member table to represent the new ban situation.
        updateBanMembers();
    } elseif (!empty($_POST['remove_selection']) && !empty($_POST['ban_items']) && is_array($_POST['ban_items'])) {
        checkSession();
        //validateToken('admin-bet');
        // Making sure every deleted ban item is an integer.
        foreach ($_POST['ban_items'] as $key => $value) {
            $_POST['ban_items'][$key] = (int) $value;
        }
        smf_db_query('
			DELETE FROM {db_prefix}ban_items
			WHERE id_ban IN ({array_int:ban_list})
				AND id_ban_group = {int:ban_group}', array('ban_list' => $_POST['ban_items'], 'ban_group' => $_REQUEST['bg']));
        // It changed, let the settings and the member table know.
        updateSettings(array('banLastUpdated' => time()));
        updateBanMembers();
    } elseif (!empty($_POST['modify_ban']) || !empty($_POST['add_ban'])) {
        checkSession();
        //validateToken('admin-bet');
        $addBan = !empty($_POST['add_ban']);
        if (empty($_POST['ban_name'])) {
            fatal_lang_error('ban_name_empty', false);
        }
        // Let's not allow HTML in ban names, it's more evil than beneficial.
        $_POST['ban_name'] = CommonAPI::htmlspecialchars($_POST['ban_name'], ENT_QUOTES);
        // Check whether a ban with this name already exists.
        $request = smf_db_query('
			SELECT id_ban_group
			FROM {db_prefix}ban_groups
			WHERE name = {string:new_ban_name}' . ($addBan ? '' : '
				AND id_ban_group != {int:ban_group}') . '
			LIMIT 1', array('ban_group' => $_REQUEST['bg'], 'new_ban_name' => $_POST['ban_name']));
        if (mysql_num_rows($request) == 1) {
            fatal_lang_error('ban_name_exists', false, array($_POST['ban_name']));
        }
        mysql_free_result($request);
        $_POST['reason'] = CommonAPI::htmlspecialchars($_POST['reason'], ENT_QUOTES);
        $_POST['notes'] = CommonAPI::htmlspecialchars($_POST['notes'], ENT_QUOTES);
        $_POST['notes'] = str_replace(array("\r", "\n", '  '), array('', '<br />', '&nbsp; '), $_POST['notes']);
        $_POST['expiration'] = $_POST['expiration'] == 'never' ? 'NULL' : ($_POST['expiration'] == 'expired' ? '0' : ($_POST['expire_date'] != $_POST['old_expire'] ? time() + 24 * 60 * 60 * (int) $_POST['expire_date'] : 'expire_time'));
        $_POST['full_ban'] = empty($_POST['full_ban']) ? '0' : '1';
        $_POST['cannot_post'] = !empty($_POST['full_ban']) || empty($_POST['cannot_post']) ? '0' : '1';
        $_POST['cannot_register'] = !empty($_POST['full_ban']) || empty($_POST['cannot_register']) ? '0' : '1';
        $_POST['cannot_login'] = !empty($_POST['full_ban']) || empty($_POST['cannot_login']) ? '0' : '1';
        if ($addBan) {
            // Adding some ban triggers?
            if ($addBan && !empty($_POST['ban_suggestion']) && is_array($_POST['ban_suggestion'])) {
                $ban_triggers = array();
                $ban_logs = array();
                if (in_array('main_ip', $_POST['ban_suggestion']) && !empty($_POST['main_ip'])) {
                    $ip = trim($_POST['main_ip']);
                    $ip_parts = ip2range($ip);
                    if (!checkExistingTriggerIP($ip_parts, $ip)) {
                        fatal_lang_error('invalid_ip', false);
                    }
                    $ban_triggers[] = array($ip_parts[0]['low'], $ip_parts[0]['high'], $ip_parts[1]['low'], $ip_parts[1]['high'], $ip_parts[2]['low'], $ip_parts[2]['high'], $ip_parts[3]['low'], $ip_parts[3]['high'], $ip_parts[4]['low'], $ip_parts[4]['high'], $ip_parts[5]['low'], $ip_parts[5]['high'], $ip_parts[6]['low'], $ip_parts[6]['high'], $ip_parts[7]['low'], $ip_parts[7]['high'], '', '', 0);
                    $ban_logs[] = array('ip_range' => $_POST['main_ip']);
                }
                if (in_array('hostname', $_POST['ban_suggestion']) && !empty($_POST['hostname'])) {
                    if (preg_match('/[^\\w.\\-*]/', $_POST['hostname']) == 1) {
                        fatal_lang_error('invalid_hostname', false);
                    }
                    // Replace the * wildcard by a MySQL wildcard %.
                    $_POST['hostname'] = str_replace('*', '%', $_POST['hostname']);
                    $ban_triggers[] = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, substr($_POST['hostname'], 0, 255), '', 0);
                    $ban_logs[] = array('hostname' => $_POST['hostname']);
                }
                if (in_array('email', $_POST['ban_suggestion']) && !empty($_POST['email'])) {
                    if (preg_match('/[^\\w.\\-\\+*@]/', $_POST['email']) == 1) {
                        fatal_lang_error('invalid_email', false);
                    }
                    $_POST['email'] = strtolower(str_replace('*', '%', $_POST['email']));
                    $ban_triggers[] = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', substr($_POST['email'], 0, 255), 0);
                    $ban_logs[] = array('email' => $_POST['email']);
                }
                if (in_array('user', $_POST['ban_suggestion']) && (!empty($_POST['bannedUser']) || !empty($_POST['user']))) {
                    // We got a username, let's find its ID.
                    if (empty($_POST['bannedUser'])) {
                        $_POST['user'] = preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', CommonAPI::htmlspecialchars($_POST['user'], ENT_QUOTES));
                        $request = smf_db_query('
							SELECT id_member, (id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0) AS isAdmin
							FROM {db_prefix}members
							WHERE member_name = {string:username} OR real_name = {string:username}
							LIMIT 1', array('admin_group' => 1, 'username' => $_POST['user']));
                        if (mysql_num_rows($request) == 0) {
                            fatal_lang_error('invalid_username', false);
                        }
                        list($_POST['bannedUser'], $isAdmin) = mysql_fetch_row($request);
                        mysql_free_result($request);
                        if ($isAdmin && $isAdmin != 'f') {
                            fatal_lang_error('no_ban_admin', 'critical');
                        }
                    }
                    $ban_triggers[] = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', (int) $_POST['bannedUser']);
                    $ban_logs[] = array('member' => $_POST['bannedUser']);
                }
                if (!empty($_POST['ban_suggestion']['ips']) && is_array($_POST['ban_suggestion']['ips'])) {
                    $_POST['ban_suggestion']['ips'] = array_unique($_POST['ban_suggestion']['ips']);
                    // Don't add the main IP again.
                    if (in_array('main_ip', $_POST['ban_suggestion'])) {
                        $_POST['ban_suggestion']['ips'] = array_diff($_POST['ban_suggestion']['ips'], array($_POST['main_ip']));
                    }
                    foreach ($_POST['ban_suggestion']['ips'] as $ip) {
                        $ip_parts = ip2range($ip);
                        // They should be alright, but just to be sure...
                        if (count($ip_parts) != 4 || count($ip_parts) != 8) {
                            fatal_lang_error('invalid_ip', false);
                        }
                        $ban_triggers[] = array($ip_parts[0]['low'], $ip_parts[0]['high'], $ip_parts[1]['low'], $ip_parts[1]['high'], $ip_parts[2]['low'], $ip_parts[2]['high'], $ip_parts[3]['low'], $ip_parts[3]['high'], $ip_parts[4]['low'], $ip_parts[4]['high'], $ip_parts[5]['low'], $ip_parts[5]['high'], $ip_parts[6]['low'], $ip_parts[6]['high'], $ip_parts[7]['low'], $ip_parts[7]['high'], '', '', 0);
                        $ban_logs[] = array('ip_range' => $ip);
                    }
                }
            }
            // Yes yes, we're ready to add now.
            smf_db_insert('', '{db_prefix}ban_groups', array('name' => 'string-20', 'ban_time' => 'int', 'expire_time' => 'raw', 'cannot_access' => 'int', 'cannot_register' => 'int', 'cannot_post' => 'int', 'cannot_login' => 'int', 'reason' => 'string-255', 'notes' => 'string-65534'), array($_POST['ban_name'], time(), $_POST['expiration'], $_POST['full_ban'], $_POST['cannot_register'], $_POST['cannot_post'], $_POST['cannot_login'], $_POST['reason'], $_POST['notes']), array('id_ban_group'));
            $_REQUEST['bg'] = smf_db_insert_id('{db_prefix}ban_groups', 'id_ban_group');
            // Now that the ban group is added, add some triggers as well.
            if (!empty($ban_triggers) && !empty($_REQUEST['bg'])) {
                // Put in the ban group ID.
                foreach ($ban_triggers as $k => $trigger) {
                    array_unshift($ban_triggers[$k], $_REQUEST['bg']);
                }
                // Log what we are doing!
                foreach ($ban_logs as $log_details) {
                    logAction('ban', $log_details + array('new' => 1));
                }
                smf_db_insert('', '{db_prefix}ban_items', array('id_ban_group' => 'int', 'ip_low1' => 'int', 'ip_high1' => 'int', 'ip_low2' => 'int', 'ip_high2' => 'int', 'ip_low3' => 'int', 'ip_high3' => 'int', 'ip_low4' => 'int', 'ip_high4' => 'int', 'ip_low5' => 'int', 'ip_high5' => 'int', 'ip_low6' => 'int', 'ip_high6' => 'int', 'ip_low7' => 'int', 'ip_high7' => 'int', 'ip_low8' => 'int', 'ip_high8' => 'int', 'hostname' => 'string-255', 'email_address' => 'string-255', 'id_member' => 'int'), $ban_triggers, array('id_ban'));
            }
        } else {
            smf_db_query('
				UPDATE {db_prefix}ban_groups
				SET
					name = {string:ban_name},
					reason = {string:reason},
					notes = {string:notes},
					expire_time = {raw:expiration},
					cannot_access = {int:cannot_access},
					cannot_post = {int:cannot_post},
					cannot_register = {int:cannot_register},
					cannot_login = {int:cannot_login}
				WHERE id_ban_group = {int:id_ban_group}', array('expiration' => $_POST['expiration'], 'cannot_access' => $_POST['full_ban'], 'cannot_post' => $_POST['cannot_post'], 'cannot_register' => $_POST['cannot_register'], 'cannot_login' => $_POST['cannot_login'], 'id_ban_group' => $_REQUEST['bg'], 'ban_name' => $_POST['ban_name'], 'reason' => $_POST['reason'], 'notes' => $_POST['notes']));
        }
        // No more caching, we have something new here.
        updateSettings(array('banLastUpdated' => time()));
        updateBanMembers();
    }
    // If we're editing an existing ban, get it from the database.
    if (!empty($_REQUEST['bg'])) {
        $context['ban_items'] = array();
        $request = smf_db_query('
			SELECT
				bi.id_ban, bi.hostname, bi.email_address, bi.id_member, bi.hits,
				bi.ip_low1, bi.ip_high1, bi.ip_low2, bi.ip_high2, bi.ip_low3, bi.ip_high3, bi.ip_low4, bi.ip_high4,
				bi.ip_low5, bi.ip_high5, bi.ip_low6, bi.ip_high6, bi.ip_low7, bi.ip_high7, bi.ip_low8, bi.ip_high8,
				bg.id_ban_group, bg.name, bg.ban_time, bg.expire_time, bg.reason, bg.notes, bg.cannot_access, bg.cannot_register, bg.cannot_login, bg.cannot_post,
				IFNULL(mem.id_member, 0) AS id_member, mem.member_name, mem.real_name
			FROM {db_prefix}ban_groups AS bg
				LEFT JOIN {db_prefix}ban_items AS bi ON (bi.id_ban_group = bg.id_ban_group)
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = bi.id_member)
			WHERE bg.id_ban_group = {int:current_ban}', array('current_ban' => $_REQUEST['bg']));
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('ban_not_found', false);
        }
        while ($row = mysql_fetch_assoc($request)) {
            if (!isset($context['ban'])) {
                $context['ban'] = array('id' => $row['id_ban_group'], 'name' => $row['name'], 'expiration' => array('status' => $row['expire_time'] === null ? 'never' : ($row['expire_time'] < time() ? 'expired' : 'still_active_but_we_re_counting_the_days'), 'days' => $row['expire_time'] > time() ? floor(($row['expire_time'] - time()) / 86400) : 0), 'reason' => $row['reason'], 'notes' => $row['notes'], 'cannot' => array('access' => !empty($row['cannot_access']), 'post' => !empty($row['cannot_post']), 'register' => !empty($row['cannot_register']), 'login' => !empty($row['cannot_login'])), 'is_new' => false);
            }
            if (!empty($row['id_ban'])) {
                $context['ban_items'][$row['id_ban']] = array('id' => $row['id_ban'], 'hits' => $row['hits']);
                if (!empty($row['ip_high1'])) {
                    $context['ban_items'][$row['id_ban']]['type'] = 'ip';
                    $context['ban_items'][$row['id_ban']]['ip'] = range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4'], $row['ip_low5'], $row['ip_low6'], $row['ip_low7'], $row['ip_low8']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4'], $row['ip_high5'], $row['ip_high6'], $row['ip_high7'], $row['ip_high8']));
                } elseif (!empty($row['hostname'])) {
                    $context['ban_items'][$row['id_ban']]['type'] = 'hostname';
                    $context['ban_items'][$row['id_ban']]['hostname'] = str_replace('%', '*', $row['hostname']);
                } elseif (!empty($row['email_address'])) {
                    $context['ban_items'][$row['id_ban']]['type'] = 'email';
                    $context['ban_items'][$row['id_ban']]['email'] = str_replace('%', '*', $row['email_address']);
                } elseif (!empty($row['id_member'])) {
                    $context['ban_items'][$row['id_ban']]['type'] = 'user';
                    $context['ban_items'][$row['id_ban']]['user'] = array('id' => $row['id_member'], 'name' => $row['real_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>');
                } else {
                    unset($context['ban_items'][$row['id_ban']]);
                    smf_db_query('
						DELETE FROM {db_prefix}ban_items
						WHERE id_ban = {int:current_ban}', array('current_ban' => $row['id_ban']));
                }
            }
        }
        mysql_free_result($request);
    } else {
        $context['ban'] = array('id' => 0, 'name' => '', 'expiration' => array('status' => 'never', 'days' => 0), 'reason' => '', 'notes' => '', 'ban_days' => 0, 'cannot' => array('access' => true, 'post' => false, 'register' => false, 'login' => false), 'is_new' => true);
        $context['ban_suggestions'] = array('main_ip' => '', 'hostname' => '', 'email' => '', 'member' => array('id' => 0));
        // Overwrite some of the default form values if a user ID was given.
        if (!empty($_REQUEST['u'])) {
            $request = smf_db_query('
				SELECT id_member, real_name, member_ip, email_address
				FROM {db_prefix}members
				WHERE id_member = {int:current_user}
				LIMIT 1', array('current_user' => (int) $_REQUEST['u']));
            if (mysql_num_rows($request) > 0) {
                list($context['ban_suggestions']['member']['id'], $context['ban_suggestions']['member']['name'], $context['ban_suggestions']['main_ip'], $context['ban_suggestions']['email']) = mysql_fetch_row($request);
            }
            mysql_free_result($request);
            if (!empty($context['ban_suggestions']['member']['id'])) {
                $context['ban_suggestions']['href'] = $scripturl . '?action=profile;u=' . $context['ban_suggestions']['member']['id'];
                $context['ban_suggestions']['member']['link'] = '<a href="' . $context['ban_suggestions']['href'] . '">' . $context['ban_suggestions']['member']['name'] . '</a>';
                // Default the ban name to the name of the banned member.
                $context['ban']['name'] = $context['ban_suggestions']['member']['name'];
                // Would be nice if we could also ban the hostname.
                if (preg_match('/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/', $context['ban_suggestions']['main_ip']) == 1 && empty($modSettings['disableHostnameLookup'])) {
                    $context['ban_suggestions']['hostname'] = host_from_ip($context['ban_suggestions']['main_ip']);
                }
                // Find some additional IP's used by this member.
                $context['ban_suggestions']['message_ips'] = array();
                $request = smf_db_query('
					SELECT DISTINCT poster_ip
					FROM {db_prefix}messages
					WHERE id_member = {int:current_user}
						AND poster_ip RLIKE {string:poster_ip_regex}
					ORDER BY poster_ip', array('current_user' => (int) $_REQUEST['u'], 'poster_ip_regex' => '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$'));
                while ($row = mysql_fetch_assoc($request)) {
                    $context['ban_suggestions']['message_ips'][] = $row['poster_ip'];
                }
                mysql_free_result($request);
                $context['ban_suggestions']['error_ips'] = array();
                $request = smf_db_query('
					SELECT DISTINCT ip
					FROM {db_prefix}log_errors
					WHERE id_member = {int:current_user}
						AND ip RLIKE {string:poster_ip_regex}
					ORDER BY ip', array('current_user' => (int) $_REQUEST['u'], 'poster_ip_regex' => '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$'));
                while ($row = mysql_fetch_assoc($request)) {
                    $context['ban_suggestions']['error_ips'][] = $row['ip'];
                }
                mysql_free_result($request);
                // Borrowing a few language strings from profile.
                loadLanguage('Profile');
            }
        }
    }
    // Template needs this to show errors using javascript
    loadLanguage('Errors');
    // If we're in wireless mode remove the admin template layer and use a special template.
    if (WIRELESS && WIRELESS_PROTOCOL != 'wap') {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_ban_edit';
        foreach ($context['template_layers'] as $k => $v) {
            if (strpos($v, 'generic_menu') === 0) {
                unset($context['template_layers'][$k]);
            }
        }
    } else {
        $context['sub_template'] = 'ban_edit';
    }
    //createToken('admin-bet');
}
Example #11
0
function removeMessage($message, $decreasePostCount = true)
{
    global $board, $sourcedir, $backend_subdir, $modSettings, $user_info;
    if (empty($message) || !is_numeric($message)) {
        return false;
    }
    $request = smf_db_query('
		SELECT
			m.id_member, m.icon, m.poster_time, m.subject,' . (empty($modSettings['search_custom_index_config']) ? '' : ' m.body,') . '
			m.approved, t.id_topic, t.id_first_msg, t.id_last_msg, t.num_replies, t.id_board,
			t.id_member_started AS id_member_poster,
			b.count_posts
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
		WHERE m.id_msg = {int:id_msg}
		LIMIT 1', array('id_msg' => $message));
    if (mysql_num_rows($request) == 0) {
        return false;
    }
    $row = mysql_fetch_assoc($request);
    mysql_free_result($request);
    if (empty($board) || $row['id_board'] != $board) {
        $delete_any = boardsAllowedTo('delete_any');
        if (!in_array(0, $delete_any) && !in_array($row['id_board'], $delete_any)) {
            $delete_own = boardsAllowedTo('delete_own');
            $delete_own = in_array(0, $delete_own) || in_array($row['id_board'], $delete_own);
            $delete_replies = boardsAllowedTo('delete_replies');
            $delete_replies = in_array(0, $delete_replies) || in_array($row['id_board'], $delete_replies);
            if ($row['id_member'] == $user_info['id']) {
                if (!$delete_own) {
                    if ($row['id_member_poster'] == $user_info['id']) {
                        if (!$delete_replies) {
                            fatal_lang_error('cannot_delete_replies', 'permission');
                        }
                    } else {
                        fatal_lang_error('cannot_delete_own', 'permission');
                    }
                } elseif (($row['id_member_poster'] != $user_info['id'] || !$delete_replies) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + $modSettings['edit_disable_time'] * 60 < time()) {
                    fatal_lang_error('modify_post_time_passed', false);
                }
            } elseif ($row['id_member_poster'] == $user_info['id']) {
                if (!$delete_replies) {
                    fatal_lang_error('cannot_delete_replies', 'permission');
                }
            } else {
                fatal_lang_error('cannot_delete_any', 'permission');
            }
        }
        // Can't delete an unapproved message, if you can't see it!
        if ($modSettings['postmod_active'] && !$row['approved'] && $row['id_member'] != $user_info['id'] && !(in_array(0, $delete_any) || in_array($row['id_board'], $delete_any))) {
            $approve_posts = boardsAllowedTo('approve_posts');
            if (!in_array(0, $approve_posts) && !in_array($row['id_board'], $approve_posts)) {
                return false;
            }
        }
    } else {
        // Check permissions to delete this message.
        if ($row['id_member'] == $user_info['id']) {
            if (!allowedTo('delete_own')) {
                if ($row['id_member_poster'] == $user_info['id'] && !allowedTo('delete_any')) {
                    isAllowedTo('delete_replies');
                } elseif (!allowedTo('delete_any')) {
                    isAllowedTo('delete_own');
                }
            } elseif (!allowedTo('delete_any') && ($row['id_member_poster'] != $user_info['id'] || !allowedTo('delete_replies')) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + $modSettings['edit_disable_time'] * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            }
        } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('delete_any')) {
            isAllowedTo('delete_replies');
        } else {
            isAllowedTo('delete_any');
        }
        if ($modSettings['postmod_active'] && !$row['approved'] && $row['id_member'] != $user_info['id'] && !allowedTo('delete_own')) {
            isAllowedTo('approve_posts');
        }
    }
    // Close any moderation reports for this message.
    smf_db_query('
		UPDATE {db_prefix}log_reported
		SET closed = {int:is_closed}
		WHERE id_msg = {int:id_msg}', array('is_closed' => 1, 'id_msg' => $message));
    if (smf_db_affected_rows() != 0) {
        require_once $sourcedir . '/ModerationCenter.php';
        updateSettings(array('last_mod_report_action' => time()));
        recountOpenReports();
    }
    // Delete the *whole* topic, but only if the topic consists of one message.
    if ($row['id_first_msg'] == $message) {
        if (empty($board) || $row['id_board'] != $board) {
            $remove_any = boardsAllowedTo('remove_any');
            $remove_any = in_array(0, $remove_any) || in_array($row['id_board'], $remove_any);
            if (!$remove_any) {
                $remove_own = boardsAllowedTo('remove_own');
                $remove_own = in_array(0, $remove_own) || in_array($row['id_board'], $remove_own);
            }
            if ($row['id_member'] != $user_info['id'] && !$remove_any) {
                fatal_lang_error('cannot_remove_any', 'permission');
            } elseif (!$remove_any && !$remove_own) {
                fatal_lang_error('cannot_remove_own', 'permission');
            }
        } else {
            // Check permissions to delete a whole topic.
            if ($row['id_member'] != $user_info['id']) {
                isAllowedTo('remove_any');
            } elseif (!allowedTo('remove_any')) {
                isAllowedTo('remove_own');
            }
        }
        // ...if there is only one post.
        if (!empty($row['num_replies'])) {
            fatal_lang_error('delFirstPost', false);
        }
        removeTopics($row['id_topic']);
        return true;
    }
    // Deleting a recycled message can not lower anyone's post count.
    if ($row['icon'] == 'recycled') {
        $decreasePostCount = false;
    }
    // This is the last post, update the last post on the board.
    if ($row['id_last_msg'] == $message) {
        // Find the last message, set it, and decrease the post count.
        $request = smf_db_query('
			SELECT id_msg, id_member
			FROM {db_prefix}messages
			WHERE id_topic = {int:id_topic}
				AND id_msg != {int:id_msg}
			ORDER BY ' . ($modSettings['postmod_active'] ? 'approved DESC, ' : '') . 'id_msg DESC
			LIMIT 1', array('id_topic' => $row['id_topic'], 'id_msg' => $message));
        $row2 = mysql_fetch_assoc($request);
        mysql_free_result($request);
        smf_db_query('
			UPDATE {db_prefix}topics
			SET
				id_last_msg = {int:id_last_msg},
				id_member_updated = {int:id_member_updated}' . (!$modSettings['postmod_active'] || $row['approved'] ? ',
				num_replies = CASE WHEN num_replies = {int:no_replies} THEN 0 ELSE num_replies - 1 END' : ',
				unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . '
			WHERE id_topic = {int:id_topic}', array('id_last_msg' => $row2['id_msg'], 'id_member_updated' => $row2['id_member'], 'no_replies' => 0, 'no_unapproved' => 0, 'id_topic' => $row['id_topic']));
    } else {
        smf_db_query('
			UPDATE {db_prefix}topics
			SET ' . ($row['approved'] ? '
				num_replies = CASE WHEN num_replies = {int:no_replies} THEN 0 ELSE num_replies - 1 END' : '
				unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . '
			WHERE id_topic = {int:id_topic}', array('no_replies' => 0, 'no_unapproved' => 0, 'id_topic' => $row['id_topic']));
    }
    // Default recycle to false.
    $recycle = false;
    // If recycle topics has been set, make a copy of this message in the recycle board.
    // Make sure we're not recycling messages that are already on the recycle board.
    if (!empty($modSettings['recycle_enable']) && $row['id_board'] != $modSettings['recycle_board'] && $row['icon'] != 'recycled') {
        // Check if the recycle board exists and if so get the read status.
        $request = smf_db_query('
			SELECT (IFNULL(lb.id_msg, 0) >= b.id_msg_updated) AS is_seen, id_last_msg
			FROM {db_prefix}boards AS b
				LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member})
			WHERE b.id_board = {int:recycle_board}', array('current_member' => $user_info['id'], 'recycle_board' => $modSettings['recycle_board']));
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('recycle_no_valid_board');
        }
        list($isRead, $last_board_msg) = mysql_fetch_row($request);
        mysql_free_result($request);
        // Is there an existing topic in the recycle board to group this post with?
        $request = smf_db_query('
			SELECT id_topic, id_first_msg, id_last_msg
			FROM {db_prefix}topics
			WHERE id_previous_topic = {int:id_previous_topic}
				AND id_board = {int:recycle_board}', array('id_previous_topic' => $row['id_topic'], 'recycle_board' => $modSettings['recycle_board']));
        list($id_recycle_topic, $first_topic_msg, $last_topic_msg) = mysql_fetch_row($request);
        mysql_free_result($request);
        // Insert a new topic in the recycle board if $id_recycle_topic is empty.
        if (empty($id_recycle_topic)) {
            smf_db_insert('', '{db_prefix}topics', array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'id_previous_topic' => 'int'), array($modSettings['recycle_board'], $row['id_member'], $row['id_member'], $message, $message, 0, 1, $row['id_topic']), array('id_topic'));
        }
        // Capture the ID of the new topic...
        $topicID = empty($id_recycle_topic) ? smf_db_insert_id('{db_prefix}topics', 'id_topic') : $id_recycle_topic;
        // If the topic creation went successful, move the message.
        if ($topicID > 0) {
            smf_db_query('
				UPDATE {db_prefix}messages
				SET
					id_topic = {int:id_topic},
					id_board = {int:recycle_board},
					icon = {string:recycled},
					approved = {int:is_approved}
				WHERE id_msg = {int:id_msg}', array('id_topic' => $topicID, 'recycle_board' => $modSettings['recycle_board'], 'id_msg' => $message, 'recycled' => 'recycled', 'is_approved' => 1));
            // Take any reported posts with us...
            smf_db_query('
				UPDATE {db_prefix}log_reported
				SET
					id_topic = {int:id_topic},
					id_board = {int:recycle_board}
				WHERE id_msg = {int:id_msg}', array('id_topic' => $topicID, 'recycle_board' => $modSettings['recycle_board'], 'id_msg' => $message));
            // Mark recycled topic as read.
            if (!$user_info['is_guest']) {
                smf_db_insert('replace', '{db_prefix}log_topics', array('id_topic' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), array($topicID, $user_info['id'], $modSettings['maxMsgID']), array('id_topic', 'id_member'));
            }
            // Mark recycle board as seen, if it was marked as seen before.
            if (!empty($isRead) && !$user_info['is_guest']) {
                smf_db_insert('replace', '{db_prefix}log_boards', array('id_board' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), array($modSettings['recycle_board'], $user_info['id'], $modSettings['maxMsgID']), array('id_board', 'id_member'));
            }
            // Add one topic and post to the recycle bin board.
            smf_db_query('
				UPDATE {db_prefix}boards
				SET
					num_topics = num_topics + {int:num_topics_inc},
					num_posts = num_posts + 1' . ($message > $last_board_msg ? ', id_last_msg = {int:id_merged_msg}' : '') . '
				WHERE id_board = {int:recycle_board}', array('num_topics_inc' => empty($id_recycle_topic) ? 1 : 0, 'recycle_board' => $modSettings['recycle_board'], 'id_merged_msg' => $message));
            // Lets increase the num_replies, and the first/last message ID as appropriate.
            if (!empty($id_recycle_topic)) {
                smf_db_query('
					UPDATE {db_prefix}topics
					SET num_replies = num_replies + 1' . ($message > $last_topic_msg ? ', id_last_msg = {int:id_merged_msg}' : '') . ($message < $first_topic_msg ? ', id_first_msg = {int:id_merged_msg}' : '') . '
					WHERE id_topic = {int:id_recycle_topic}', array('id_recycle_topic' => $id_recycle_topic, 'id_merged_msg' => $message));
            }
            // Make sure this message isn't getting deleted later on.
            $recycle = true;
            // Make sure we update the search subject index.
            updateStats('subject', $topicID, $row['subject']);
        }
        // If it wasn't approved don't keep it in the queue.
        if (!$row['approved']) {
            smf_db_query('
				DELETE FROM {db_prefix}approval_queue
				WHERE id_msg = {int:id_msg}
					AND id_attach = {int:id_attach}', array('id_msg' => $message, 'id_attach' => 0));
        }
    }
    smf_db_query('
		UPDATE {db_prefix}boards
		SET ' . ($row['approved'] ? '
			num_posts = CASE WHEN num_posts = {int:no_posts} THEN 0 ELSE num_posts - 1 END' : '
			unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . '
		WHERE id_board = {int:id_board}', array('no_posts' => 0, 'no_unapproved' => 0, 'id_board' => $row['id_board']));
    // If the poster was registered and the board this message was on incremented
    // the member's posts when it was posted, decrease his or her post count.
    if (!empty($row['id_member']) && $decreasePostCount && empty($row['count_posts']) && $row['approved']) {
        updateMemberData($row['id_member'], array('posts' => '-'));
    }
    // Only remove posts if they're not recycled.
    if (!$recycle) {
        require_once $sourcedir . '/lib/Subs-Ratings.php';
        require_once $sourcedir . '/lib/Subs-Activities.php';
        // Remove the message + maybe its cached version
        smf_db_query('
			DELETE m.*, c.* FROM {db_prefix}messages AS m LEFT JOIN {db_prefix}messages_cache AS c ON (c.id_msg = m.id_msg)
			WHERE m.id_msg = {int:id_msg}', array('id_msg' => $message));
        if (!empty($modSettings['search_custom_index_config'])) {
            $customIndexSettings = unserialize($modSettings['search_custom_index_config']);
            $words = text2words($row['body'], $customIndexSettings['bytes_per_word'], true);
            if (!empty($words)) {
                smf_db_query('
					DELETE FROM {db_prefix}log_search_words
					WHERE id_word IN ({array_int:word_list})
						AND id_msg = {int:id_msg}', array('word_list' => $words, 'id_msg' => $message));
            }
        }
        // Delete attachment(s) if they exist.
        require_once $sourcedir . '/lib/Subs-ManageAttachments.php';
        $attachmentQuery = array('attachment_type' => 0, 'id_msg' => $message);
        removeAttachments($attachmentQuery);
        // remove likes and like_cache
        $likes_to_remove = array($message);
        Ratings::removeByPosts($likes_to_remove);
        // remove activities related to this post
        aStreamRemoveByContent($likes_to_remove);
    }
    // Update the pesky statistics.
    updateStats('message');
    updateStats('topic');
    updateSettings(array('calendar_updated' => time()));
    // And now to update the last message of each board we messed with.
    require_once $sourcedir . '/lib/Subs-Post.php';
    if ($recycle) {
        updateLastMessages(array($row['id_board'], $modSettings['recycle_board']));
    } else {
        updateLastMessages($row['id_board']);
    }
    return false;
}
Example #12
0
function createSalvageArea()
{
    global $txt, $language, $salvageBoardID, $salvageCatID, $smcFunc;
    static $createOnce = false;
    // Have we already created it?
    if ($createOnce) {
        return;
    } else {
        $createOnce = true;
    }
    // Back to the forum's default language.
    loadLanguage('Admin', $language);
    // Check to see if a 'Salvage Category' exists, if not => insert one.
    $result = smf_db_query('
		SELECT id_cat
		FROM {db_prefix}categories
		WHERE name = {string:cat_name}
		LIMIT 1', array('cat_name' => $txt['salvaged_category_name']));
    if (mysql_num_rows($result) != 0) {
        list($salvageCatID) = mysql_fetch_row($result);
    }
    mysql_free_result($result);
    if (empty($salveageCatID)) {
        smf_db_insert('', '{db_prefix}categories', array('name' => 'string-255', 'cat_order' => 'int'), array($txt['salvaged_category_name'], -1), array('id_cat'));
        if (smf_db_affected_rows() <= 0) {
            loadLanguage('Admin');
            fatal_lang_error('salvaged_category_error', false);
        }
        $salvageCatID = smf_db_insert_id('{db_prefix}categories', 'id_cat');
    }
    // Check to see if a 'Salvage Board' exists, if not => insert one.
    $result = smf_db_query('
		SELECT id_board
		FROM {db_prefix}boards
		WHERE id_cat = {int:id_cat}
			AND name = {string:board_name}
		LIMIT 1', array('id_cat' => $salvageCatID, 'board_name' => $txt['salvaged_board_name']));
    if (mysql_num_rows($result) != 0) {
        list($salvageBoardID) = mysql_fetch_row($result);
    }
    mysql_free_result($result);
    if (empty($salvageBoardID)) {
        smf_db_insert('', '{db_prefix}boards', array('name' => 'string-255', 'description' => 'string-255', 'id_cat' => 'int', 'member_groups' => 'string', 'board_order' => 'int', 'redirect' => 'string'), array($txt['salvaged_board_name'], $txt['salvaged_board_description'], $salvageCatID, '1', -1, ''), array('id_board'));
        if (smf_db_affected_rows() <= 0) {
            loadLanguage('Admin');
            fatal_lang_error('salvaged_board_error', false);
        }
        $salvageBoardID = smf_db_insert_id('{db_prefix}boards', 'id_board');
    }
    smf_db_query('
		ALTER TABLE {db_prefix}boards
		ORDER BY board_order', array());
    // Restore the user's language.
    loadLanguage('Admin');
}
Example #13
0
function EditPermissionProfiles()
{
    global $context, $txt, $smcFunc;
    // Setup the template, first for fun.
    $context['page_title'] = $txt['permissions_profile_edit'];
    $context['sub_template'] = 'edit_profiles';
    // If we're creating a new one do it first.
    if (isset($_POST['create']) && trim($_POST['profile_name']) != '') {
        checkSession();
        $_POST['copy_from'] = (int) $_POST['copy_from'];
        $_POST['profile_name'] = commonAPI::htmlspecialchars($_POST['profile_name']);
        // Insert the profile itself.
        smf_db_insert('', '{db_prefix}permission_profiles', array('profile_name' => 'string'), array($_POST['profile_name']), array('id_profile'));
        $profile_id = smf_db_insert_id('{db_prefix}permission_profiles', 'id_profile');
        // Load the permissions from the one it's being copied from.
        $request = smf_db_query('
			SELECT id_group, permission, add_deny
			FROM {db_prefix}board_permissions
			WHERE id_profile = {int:copy_from}', array('copy_from' => $_POST['copy_from']));
        $inserts = array();
        while ($row = mysql_fetch_assoc($request)) {
            $inserts[] = array($profile_id, $row['id_group'], $row['permission'], $row['add_deny']);
        }
        mysql_free_result($request);
        if (!empty($inserts)) {
            smf_db_insert('insert', '{db_prefix}board_permissions', array('id_profile' => 'int', 'id_group' => 'int', 'permission' => 'string', 'add_deny' => 'int'), $inserts, array('id_profile', 'id_group', 'permission'));
        }
    } elseif (isset($_POST['rename'])) {
        checkSession();
        // Just showing the boxes?
        if (!isset($_POST['rename_profile'])) {
            $context['show_rename_boxes'] = true;
        } else {
            foreach ($_POST['rename_profile'] as $id => $value) {
                $value = commonAPI::htmlspecialchars($value);
                if (trim($value) != '' && $id > 4) {
                    smf_db_query('
						UPDATE {db_prefix}permission_profiles
						SET profile_name = {string:profile_name}
						WHERE id_profile = {int:current_profile}', array('current_profile' => (int) $id, 'profile_name' => $value));
                }
            }
        }
    } elseif (isset($_POST['delete']) && !empty($_POST['delete_profile'])) {
        checkSession('post');
        $profiles = array();
        foreach ($_POST['delete_profile'] as $profile) {
            if ($profile > 4) {
                $profiles[] = (int) $profile;
            }
        }
        // Verify it's not in use...
        $request = smf_db_query('
			SELECT id_board
			FROM {db_prefix}boards
			WHERE id_profile IN ({array_int:profile_list})
			LIMIT 1', array('profile_list' => $profiles));
        if (mysql_num_rows($request) != 0) {
            fatal_lang_error('no_access', false);
        }
        mysql_free_result($request);
        // Oh well, delete.
        smf_db_query('
			DELETE FROM {db_prefix}permission_profiles
			WHERE id_profile IN ({array_int:profile_list})', array('profile_list' => $profiles));
    }
    // Clearly, we'll need this!
    loadPermissionProfiles();
    // Work out what ones are in use.
    $request = smf_db_query('
		SELECT id_profile, COUNT(id_board) AS board_count
		FROM {db_prefix}boards
		GROUP BY id_profile', array());
    while ($row = mysql_fetch_assoc($request)) {
        if (isset($context['profiles'][$row['id_profile']])) {
            $context['profiles'][$row['id_profile']]['in_use'] = true;
            $context['profiles'][$row['id_profile']]['boards'] = $row['board_count'];
            $context['profiles'][$row['id_profile']]['boards_text'] = $row['board_count'] > 1 ? sprintf($txt['permissions_profile_used_by_many'], $row['board_count']) : $txt['permissions_profile_used_by_' . ($row['board_count'] ? 'one' : 'none')];
        }
    }
    mysql_free_result($request);
    // What can we do with these?
    $context['can_edit_something'] = false;
    foreach ($context['profiles'] as $id => $profile) {
        // Can't delete special ones.
        $context['profiles'][$id]['can_edit'] = isset($txt['permissions_profile_' . $profile['unformatted_name']]) ? false : true;
        if ($context['profiles'][$id]['can_edit']) {
            $context['can_edit_something'] = true;
        }
        // You can only delete it if you can edit it AND it's not in use.
        $context['profiles'][$id]['can_delete'] = $context['profiles'][$id]['can_edit'] && empty($profile['in_use']) ? true : false;
    }
}
Example #14
0
function logAction($action, $extra = array(), $log_type = 'moderate')
{
    global $modSettings, $user_info, $sourcedir;
    $log_types = array('moderate' => 1, 'user' => 2, 'admin' => 3);
    if (!is_array($extra)) {
        trigger_error('logAction(): data is not an array with action \'' . $action . '\'', E_USER_NOTICE);
    }
    // Pull out the parts we want to store separately, but also make sure that the data is proper
    if (isset($extra['topic'])) {
        if (!is_numeric($extra['topic'])) {
            trigger_error('logAction(): data\'s topic is not a number', E_USER_NOTICE);
        }
        $topic_id = empty($extra['topic']) ? '0' : (int) $extra['topic'];
        unset($extra['topic']);
    } else {
        $topic_id = '0';
    }
    if (isset($extra['message'])) {
        if (!is_numeric($extra['message'])) {
            trigger_error('logAction(): data\'s message is not a number', E_USER_NOTICE);
        }
        $msg_id = empty($extra['message']) ? '0' : (int) $extra['message'];
        unset($extra['message']);
    } else {
        $msg_id = '0';
    }
    // Is there an associated report on this?
    if (in_array($action, array('move', 'remove', 'split', 'merge'))) {
        $request = smf_db_query('
			SELECT id_report
			FROM {db_prefix}log_reported
			WHERE {raw:column_name} = {int:reported}
			LIMIT 1', array('column_name' => !empty($msg_id) ? 'id_msg' : 'id_topic', 'reported' => !empty($msg_id) ? $msg_id : $topic_id));
        // Alright, if we get any result back, update open reports.
        if (mysql_num_rows($request) > 0) {
            require_once $sourcedir . '/ModerationCenter.php';
            updateSettings(array('last_mod_report_action' => time()));
            recountOpenReports();
        }
        mysql_free_result($request);
    }
    // No point in doing anything else, if the log isn't even enabled.
    if (empty($modSettings['modlog_enabled']) || !isset($log_types[$log_type])) {
        return false;
    }
    if (isset($extra['member']) && !is_numeric($extra['member'])) {
        trigger_error('logAction(): data\'s member is not a number', E_USER_NOTICE);
    }
    if (isset($extra['board'])) {
        if (!is_numeric($extra['board'])) {
            trigger_error('logAction(): data\'s board is not a number', E_USER_NOTICE);
        }
        $board_id = empty($extra['board']) ? '0' : (int) $extra['board'];
        unset($extra['board']);
    } else {
        $board_id = '0';
    }
    if (isset($extra['board_to'])) {
        if (!is_numeric($extra['board_to'])) {
            trigger_error('logAction(): data\'s board_to is not a number', E_USER_NOTICE);
        }
        if (empty($board_id)) {
            $board_id = empty($extra['board_to']) ? '0' : (int) $extra['board_to'];
            unset($extra['board_to']);
        }
    }
    smf_db_insert('', '{db_prefix}log_actions', array('log_time' => 'int', 'id_log' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'action' => 'string', 'id_board' => 'int', 'id_topic' => 'int', 'id_msg' => 'int', 'extra' => 'string-65534'), array(time(), $log_types[$log_type], $user_info['id'], $user_info['ip'], $action, $board_id, $topic_id, $msg_id, serialize($extra)), array('id_action'));
    return smf_db_insert_id('{db_prefix}log_actions', 'id_action');
}
Example #15
0
function Post2()
{
    global $board, $topic, $txt, $modSettings, $sourcedir, $context;
    global $user_info, $board_info, $options, $backend_subdir;
    /*  todo: drafts -> plugin
    	if(in_array('dr', $context['admin_features'])) {
    		require_once($sourcedir . '/lib/Subs-Drafts.php');
    		enqueueThemeScript('drafts', 'scripts/drafts.js', true);
    		$context['have_drafts'] = true;
    	}
    	else*/
    $context['have_drafts'] = false;
    $context['auto_preview'] = isset($_REQUEST['autopreview']) && $_REQUEST['autopreview'] ? 1 : 0;
    $context['need_synhlt'] = true;
    $context['no_astream'] = isset($_REQUEST['noactivity']) && (int) $_REQUEST['noactivity'] == 1;
    $context['can_tag_users'] = allowedTo('tag_users');
    // Sneaking off, are we?
    if (empty($_POST) && empty($topic)) {
        redirectexit('action=post;board=' . $board . '.0');
    } elseif (empty($_POST) && !empty($topic)) {
        redirectexit('action=post;topic=' . $topic . '.0');
    }
    // No need!
    $context['robot_no_index'] = true;
    // If we came from WYSIWYG then turn it back into BBC regardless.
    if (!empty($_REQUEST['message_mode']) && isset($_REQUEST['message'])) {
        require_once $sourcedir . '/lib/Subs-Editor.php';
        $_REQUEST['message'] = html_to_bbc($_REQUEST['message']);
        // We need to unhtml it now as it gets done shortly.
        $_REQUEST['message'] = un_htmlspecialchars($_REQUEST['message']);
        // We need this for everything else.
        $_POST['message'] = $_REQUEST['message'];
    }
    // Previewing? Go back to start.
    if (isset($_REQUEST['preview'])) {
        return Post();
    }
    // Prevent double submission of this form.
    checkSubmitOnce('check');
    // No errors as yet.
    $post_errors = array();
    // If the session has timed out, let the user re-submit their form.
    if (checkSession('post', '', false) != '') {
        $post_errors[] = 'session_timeout';
    }
    // Wrong verification code?
    if (!$user_info['is_admin'] && !$user_info['is_mod'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1)) {
        require_once $sourcedir . '/lib/Subs-Editor.php';
        $verificationOptions = array('id' => 'post', 'skip_template' => true);
        $context['require_verification'] = create_control_verification($verificationOptions, true);
        if (is_array($context['require_verification'])) {
            $post_errors = array_merge($post_errors, $context['require_verification']);
        }
    }
    require_once $sourcedir . '/lib/Subs-Post.php';
    loadLanguage('Post');
    // If this isn't a new topic load the topic info that we need.
    if (!empty($topic)) {
        $request = smf_db_query('
			SELECT t.locked, t.is_sticky, t.id_poll, t.approved, t.id_first_msg, t.id_last_msg, t.id_member_started, t.id_member_updated,
				t.id_board, t.id_prefix, t.id_layout, t.num_replies, b.automerge, ba.id_topic AS banned_from_topic
			FROM {db_prefix}topics AS t
			LEFT JOIN {db_prefix}boards AS b on b.id_board = t.id_board 
			LEFT JOIN {db_prefix}topicbans AS ba ON (ba.id_topic = {int:current_topic} AND ba.id_member = {int:current_member})
			WHERE t.id_topic = {int:current_topic}
			LIMIT 1', array('current_topic' => $topic, 'current_member' => $user_info['id']));
        $topic_info = mysql_fetch_assoc($request);
        mysql_free_result($request);
        // Though the topic should be there, it might have vanished.
        if (!is_array($topic_info)) {
            fatal_lang_error('topic_doesnt_exist');
        }
        // Did this topic suddenly move? Just checking...
        if ($topic_info['id_board'] != $board) {
            fatal_lang_error('not_a_topic');
        }
        if ($topic_info['banned_from_topic'] != 0 && !$user_info['is_admin'] && !allowedTo('moderate_board') && !allowedTo('moderate_forum')) {
            fatal_lang_error('banned_from_topic');
        }
    }
    // Replying to a topic?
    if (!empty($topic) && !isset($_REQUEST['msg'])) {
        // Don't allow a post if it's locked.
        if ($topic_info['locked'] != 0 && !allowedTo('moderate_board')) {
            fatal_lang_error('topic_locked', false);
        }
        // Sorry, multiple polls aren't allowed... yet.  You should stop giving me ideas :P.
        if (isset($_REQUEST['poll']) && $topic_info['id_poll'] > 0) {
            unset($_REQUEST['poll']);
        }
        // Do the permissions and approval stuff...
        $becomesApproved = true;
        if ($topic_info['id_member_started'] != $user_info['id']) {
            if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                $becomesApproved = false;
            } else {
                isAllowedTo('post_reply_any');
            }
        } elseif (!allowedTo('post_reply_any')) {
            if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                $becomesApproved = false;
            } else {
                isAllowedTo('post_reply_own');
            }
        }
        if (isset($_POST['lock'])) {
            // Nothing is changed to the lock.
            if (empty($topic_info['locked']) && empty($_POST['lock']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You cannot override a moderator lock.
                if ($topic_info['locked'] == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // So you wanna (un)sticky this...let's see.
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || $_POST['sticky'] == $topic_info['is_sticky'] || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        // If the number of replies has changed, if the setting is enabled, go back to Post() - which handles the error.
        if (empty($options['no_new_reply_warning']) && isset($_POST['last_msg']) && $topic_info['id_last_msg'] > $_POST['last_msg']) {
            $_REQUEST['preview'] = true;
            return Post();
        }
        // drafts
        if (isset($_POST['lock'])) {
            $_POST['lock_draft'] = !empty($_POST['lock']) ? 1 : 0;
        } else {
            $_POST['lock_draft'] = !empty($topic_info['locked']) ? 1 : 0;
        }
        // it's not, grab from topic's current info
        if ($context['have_drafts']) {
            $draft = saveDraft();
            if (!empty($draft) && !in_array('session_timeout', $post_errors)) {
                if (isset($_REQUEST['xml'])) {
                    draftXmlReturn($draft);
                }
                EoS_Smarty::loadTemplate('post/draft_saved');
                $context['page_title'] = $txt['draft_saved_short'];
                return;
            }
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (empty($topic)) {
        // Now don't be silly, new topics will get their own id_msg soon enough.
        unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
        // Do like, the permissions, for safety and stuff...
        $becomesApproved = true;
        if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
            $becomesApproved = false;
        } else {
            isAllowedTo('post_new');
        }
        if (isset($_POST['lock'])) {
            // New topics are by default not locked.
            if (empty($_POST['lock'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own'))) {
                unset($_POST['lock']);
            } else {
                $_POST['lock'] = allowedTo('lock_any') ? 1 : 2;
            }
        }
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || empty($_POST['sticky']) || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        $posterIsGuest = $user_info['is_guest'];
        // Are we saving a draft? If so, hand over control to the draft code -- except, in the case of a session failure
        $_POST['lock_draft'] = !empty($_POST['lock']) ? 1 : 0;
        if ($context['have_drafts']) {
            $draft = saveDraft();
            if (!empty($draft) && !in_array('session_timeout', $post_errors)) {
                if (isset($_REQUEST['xml'])) {
                    draftXmlReturn($draft);
                }
                EoS_Smarty::loadTemplate('post/draft_saved');
                $context['page_title'] = $txt['draft_saved_short'];
                return;
            }
        }
    } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        $request = smf_db_query('
			SELECT id_member, poster_name, poster_email, poster_time, approved, locked
			FROM {db_prefix}messages
			WHERE id_msg = {int:id_msg}
			LIMIT 1', array('id_msg' => $_REQUEST['msg']));
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('cant_find_messages', false);
        }
        $row = mysql_fetch_assoc($request);
        $msg_owner = $row['id_member'];
        mysql_free_result($request);
        if (!empty($topic_info['locked']) && !allowedTo('moderate_board')) {
            fatal_lang_error('topic_locked', false);
        }
        if (isset($_POST['lock'])) {
            // Nothing changes to the lock status.
            if (empty($_POST['lock']) && empty($topic_info['locked']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You're not allowed to break a moderator's lock.
                if ($topic_info['locked'] == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // Change the sticky status of this topic?
        if (isset($_POST['sticky']) && (!allowedTo('make_sticky') || $_POST['sticky'] == $topic_info['is_sticky'])) {
            unset($_POST['sticky']);
        }
        if ($row['locked'] && !(allowedTo('moderate_board') || allowedTo('moderate_forum'))) {
            fatal_lang_error('modify_message_locked', false);
        }
        if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
            if ((!$modSettings['postmod_active'] || $row['approved']) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
            // If you're modifying a reply, I say it better be logged...
            $moderationAction = true;
        } else {
            isAllowedTo('modify_any');
            // Log it, assuming you're not modifying your own post.
            if ($row['id_member'] != $user_info['id']) {
                $moderationAction = true;
            }
        }
        $posterIsGuest = empty($row['id_member']);
        // Can they approve it?
        $can_approve = allowedTo('approve_posts');
        $becomesApproved = $modSettings['postmod_active'] ? $can_approve && !$row['approved'] ? !empty($_REQUEST['approve']) ? 1 : 0 : $row['approved'] : 1;
        $approve_has_changed = $row['approved'] != $becomesApproved;
        if (!allowedTo('moderate_forum') || !$posterIsGuest) {
            $_POST['guestname'] = $row['poster_name'];
            $_POST['email'] = $row['poster_email'];
        }
        if ($context['have_drafts']) {
            $draft = saveDraft();
            if (!empty($draft) && !in_array('session_timeout', $post_errors)) {
                if (isset($_REQUEST['xml'])) {
                    draftXmlReturn($draft);
                }
                EoS_Smarty::loadTemplate('post/draft_saved');
                $context['page_title'] = $txt['draft_saved_short'];
                return;
            }
        }
    }
    // If the poster is a guest evaluate the legality of name and email.
    if ($posterIsGuest) {
        $_POST['guestname'] = !isset($_POST['guestname']) ? '' : trim($_POST['guestname']);
        $_POST['email'] = !isset($_POST['email']) ? '' : trim($_POST['email']);
        if ($_POST['guestname'] == '' || $_POST['guestname'] == '_') {
            $post_errors[] = 'no_name';
        }
        if (commonAPI::strlen($_POST['guestname']) > 25) {
            $post_errors[] = 'long_name';
        }
        if (empty($modSettings['guest_post_no_email'])) {
            // Only check if they changed it!
            if (!isset($row) || $row['poster_email'] != $_POST['email']) {
                if (!allowedTo('moderate_forum') && (!isset($_POST['email']) || $_POST['email'] == '')) {
                    $post_errors[] = 'no_email';
                }
                if (!allowedTo('moderate_forum') && preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['email']) == 0) {
                    $post_errors[] = 'bad_email';
                }
            }
            // Now make sure this email address is not banned from posting.
            isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt['guest_title']));
        }
        // In case they are making multiple posts this visit, help them along by storing their name.
        if (empty($post_errors)) {
            $_SESSION['guest_name'] = $_POST['guestname'];
            $_SESSION['guest_email'] = $_POST['email'];
        }
    }
    // Check the subject and message.
    if (!isset($_POST['subject']) || commonAPI::htmltrim(commonAPI::htmlspecialchars($_POST['subject'])) === '') {
        $post_errors[] = 'no_subject';
    }
    if (!isset($_POST['message']) || commonAPI::htmltrim(commonAPI::htmlspecialchars($_POST['message']), ENT_QUOTES) === '') {
        $post_errors[] = 'no_message';
    } elseif (!empty($modSettings['max_messageLength']) && commonAPI::strlen($_POST['message']) > $modSettings['max_messageLength']) {
        $post_errors[] = 'long_message';
    } else {
        // Prepare the message a bit for some additional testing.
        $_POST['message'] = commonAPI::htmlspecialchars($_POST['message'], ENT_QUOTES);
        // Preparse code. (Zef)
        if ($user_info['is_guest']) {
            $user_info['name'] = $_POST['guestname'];
        }
        preparsecode($_POST['message']);
        // Let's see if there's still some content left without the tags.
        if (commonAPI::htmltrim(strip_tags(parse_bbc($_POST['message'], false), '<img>')) === '' && (!allowedTo('admin_forum') || strpos($_POST['message'], '[html]') === false)) {
            $post_errors[] = 'no_message';
        }
    }
    if (isset($_POST['calendar']) && !isset($_REQUEST['deleteevent']) && commonAPI::htmltrim($_POST['evtitle']) === '') {
        $post_errors[] = 'no_event';
    }
    // You are not!
    if (isset($_POST['message']) && strtolower($_POST['message']) == 'i am the administrator.' && !$user_info['is_admin']) {
        fatal_error('Knave! Masquerader! Charlatan!', false);
    }
    // Validate the poll...
    if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') {
        if (!empty($topic) && !isset($_REQUEST['msg'])) {
            fatal_lang_error('no_access', false);
        }
        // This is a new topic... so it's a new poll.
        if (empty($topic)) {
            isAllowedTo('poll_post');
        } elseif ($user_info['id'] == $topic_info['id_member_started'] && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        if (!isset($_POST['question']) || trim($_POST['question']) == '') {
            $post_errors[] = 'no_question';
        }
        $_POST['options'] = empty($_POST['options']) ? array() : htmltrim__recursive($_POST['options']);
        // Get rid of empty ones.
        foreach ($_POST['options'] as $k => $option) {
            if ($option == '') {
                unset($_POST['options'][$k], $_POST['options'][$k]);
            }
        }
        // What are you going to vote between with one choice?!?
        if (count($_POST['options']) < 2) {
            $post_errors[] = 'poll_few';
        }
    }
    if ($posterIsGuest) {
        // If user is a guest, make sure the chosen name isn't taken.
        require_once $sourcedir . '/lib/Subs-Members.php';
        if (isReservedName($_POST['guestname'], 0, true, false) && (!isset($row['poster_name']) || $_POST['guestname'] != $row['poster_name'])) {
            $post_errors[] = 'bad_name';
        }
    } elseif (!isset($_REQUEST['msg'])) {
        $_POST['guestname'] = $user_info['username'];
        $_POST['email'] = $user_info['email'];
    }
    // Any mistakes?
    if (!empty($post_errors)) {
        loadLanguage('Errors');
        // Previewing.
        $_REQUEST['preview'] = true;
        $context['post_error'] = array('messages' => array());
        foreach ($post_errors as $post_error) {
            $context['post_error'][$post_error] = true;
            if ($post_error == 'long_message') {
                $txt['error_' . $post_error] = sprintf($txt['error_' . $post_error], $modSettings['max_messageLength']);
            }
            $context['post_error']['messages'][] = $txt['error_' . $post_error];
        }
        return Post();
    }
    // Make sure the user isn't spamming the board.
    if (!isset($_REQUEST['msg'])) {
        spamProtection('post');
    }
    // At about this point, we're posting and that's that.
    ignore_user_abort(true);
    @set_time_limit(300);
    // Add special html entities to the subject, name, and email.
    $_POST['subject'] = strtr(commonAPI::htmlspecialchars($_POST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
    $_POST['guestname'] = htmlspecialchars($_POST['guestname']);
    $_POST['email'] = htmlspecialchars($_POST['email']);
    // At this point, we want to make sure the subject isn't too long.
    if (commonAPI::strlen($_POST['subject']) > 100) {
        $_POST['subject'] = commonAPI::substr($_POST['subject'], 0, 100);
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Make sure that the user has not entered a ridiculous number of options..
        if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
            $_POST['poll_max_votes'] = 1;
        } elseif ($_POST['poll_max_votes'] > count($_POST['options'])) {
            $_POST['poll_max_votes'] = count($_POST['options']);
        } else {
            $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
        }
        $_POST['poll_expire'] = (int) $_POST['poll_expire'];
        $_POST['poll_expire'] = $_POST['poll_expire'] > 9999 ? 9999 : ($_POST['poll_expire'] < 0 ? 0 : $_POST['poll_expire']);
        // Just set it to zero if it's not there..
        if (!isset($_POST['poll_hide'])) {
            $_POST['poll_hide'] = 0;
        } else {
            $_POST['poll_hide'] = (int) $_POST['poll_hide'];
        }
        $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0;
        $_POST['poll_guest_vote'] = isset($_POST['poll_guest_vote']) ? 1 : 0;
        // Make sure guests are actually allowed to vote generally.
        if ($_POST['poll_guest_vote']) {
            require_once $sourcedir . '/lib/Subs-Members.php';
            $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
            if (!in_array(-1, $allowedVoteGroups['allowed'])) {
                $_POST['poll_guest_vote'] = 0;
            }
        }
        // If the user tries to set the poll too far in advance, don't let them.
        if (!empty($_POST['poll_expire']) && $_POST['poll_expire'] < 1) {
            fatal_lang_error('poll_range_error', false);
        } elseif (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
            $_POST['poll_hide'] = 1;
        }
        // Clean up the question and answers.
        $_POST['question'] = htmlspecialchars($_POST['question']);
        $_POST['question'] = commonAPI::truncate($_POST['question'], 255);
        $_POST['question'] = preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', $_POST['question']);
        $_POST['options'] = htmlspecialchars__recursive($_POST['options']);
    }
    // Check if they are trying to delete any current attachments....
    if (isset($_REQUEST['msg'], $_POST['attach_del']) && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'))) {
        $del_temp = array();
        foreach ($_POST['attach_del'] as $i => $dummy) {
            $del_temp[$i] = (int) $dummy;
        }
        require_once $sourcedir . '/lib/Subs-ManageAttachments.php';
        $attachmentQuery = array('attachment_type' => 0, 'id_msg' => (int) $_REQUEST['msg'], 'not_id_attach' => $del_temp);
        removeAttachments($attachmentQuery);
    }
    // ...or attach a new file...
    if (isset($_FILES['attachment']['name']) || !empty($_SESSION['temp_attachments']) && empty($_POST['from_qr'])) {
        // Verify they can post them!
        if (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_attachments')) {
            isAllowedTo('post_attachment');
        }
        // Make sure we're uploading to the right place.
        if (!empty($modSettings['currentAttachmentUploadDir'])) {
            if (!is_array($modSettings['attachmentUploadDir'])) {
                $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
            }
            // The current directory, of course!
            $current_attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
        } else {
            $current_attach_dir = $modSettings['attachmentUploadDir'];
        }
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $request = smf_db_query('
				SELECT COUNT(*), SUM(size)
				FROM {db_prefix}attachments
				WHERE id_msg = {int:id_msg}
					AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0));
            list($quantity, $total_size) = mysql_fetch_row($request);
            mysql_free_result($request);
        } else {
            $quantity = 0;
            $total_size = 0;
        }
        if (!empty($_SESSION['temp_attachments'])) {
            foreach ($_SESSION['temp_attachments'] as $attachID => $name) {
                if (preg_match('~^post_tmp_' . $user_info['id'] . '_\\d+$~', $attachID) == 0) {
                    continue;
                }
                if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) {
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($current_attach_dir . '/' . $attachID);
                    continue;
                }
                $_FILES['attachment']['tmp_name'][] = $attachID;
                $_FILES['attachment']['name'][] = $name;
                $_FILES['attachment']['size'][] = filesize($current_attach_dir . '/' . $attachID);
                list($_FILES['attachment']['width'][], $_FILES['attachment']['height'][]) = @getimagesize($current_attach_dir . '/' . $attachID);
                unset($_SESSION['temp_attachments'][$attachID]);
            }
        }
        if (!isset($_FILES['attachment']['name'])) {
            $_FILES['attachment']['tmp_name'] = array();
        }
        $attachIDs = array();
        foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) {
            if ($_FILES['attachment']['name'][$n] == '') {
                continue;
            }
            // Have we reached the maximum number of files we are allowed?
            $quantity++;
            if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) {
                checkSubmitOnce('free');
                fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit']));
            }
            // Check the total upload size for this post...
            $total_size += $_FILES['attachment']['size'][$n];
            if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) {
                checkSubmitOnce('free');
                fatal_lang_error('file_too_big', false, array($modSettings['attachmentPostLimit']));
            }
            $attachmentOptions = array('post' => isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0, 'poster' => $user_info['id'], 'name' => $_FILES['attachment']['name'][$n], 'tmp_name' => $_FILES['attachment']['tmp_name'][$n], 'size' => $_FILES['attachment']['size'][$n], 'approved' => !$modSettings['postmod_active'] || allowedTo('post_attachment'));
            if (createAttachment($attachmentOptions)) {
                $attachIDs[] = $attachmentOptions['id'];
                if (!empty($attachmentOptions['thumb'])) {
                    $attachIDs[] = $attachmentOptions['thumb'];
                }
            } else {
                if (in_array('could_not_upload', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('attach_timeout', 'critical');
                }
                if (in_array('too_large', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('file_too_big', false, array($modSettings['attachmentSizeLimit']));
                }
                if (in_array('bad_extension', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_error($attachmentOptions['name'] . '.<br />' . $txt['cant_upload_type'] . ' ' . $modSettings['attachmentExtensions'] . '.', false);
                }
                if (in_array('directory_full', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('ran_out_of_space', 'critical');
                }
                if (in_array('bad_filename', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_error(basename($attachmentOptions['name']) . '.<br />' . $txt['restricted_filename'] . '.', 'critical');
                }
                if (in_array('taken_filename', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('filename_exists');
                }
                if (in_array('bad_attachment', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('bad_attachment');
                }
            }
        }
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Create the poll.
        smf_db_insert('', '{db_prefix}polls', array('question' => 'string-255', 'hide_results' => 'int', 'max_votes' => 'int', 'expire_time' => 'int', 'id_member' => 'int', 'poster_name' => 'string-255', 'change_vote' => 'int', 'guest_vote' => 'int'), array($_POST['question'], $_POST['poll_hide'], $_POST['poll_max_votes'], empty($_POST['poll_expire']) ? 0 : time() + $_POST['poll_expire'] * 3600 * 24, $user_info['id'], $_POST['guestname'], $_POST['poll_change_vote'], $_POST['poll_guest_vote']), array('id_poll'));
        $id_poll = smf_db_insert_id('{db_prefix}polls', 'id_poll');
        // Create each answer choice.
        $i = 0;
        $pollOptions = array();
        foreach ($_POST['options'] as $option) {
            $pollOptions[] = array($id_poll, $i, $option);
            $i++;
        }
        smf_db_insert('insert', '{db_prefix}poll_choices', array('id_poll' => 'int', 'id_choice' => 'int', 'label' => 'string-255'), $pollOptions, array('id_poll', 'id_choice'));
    } else {
        $id_poll = 0;
    }
    // Creating a new topic?
    $newTopic = empty($_REQUEST['msg']) && empty($topic);
    $_POST['icon'] = !empty($attachIDs) && $_POST['icon'] == 'xx' ? 'clip' : $_POST['icon'];
    if (empty($attachIDs) && $_POST['icon'] == 'clip') {
        $_POST['icon'] = 'xx';
    }
    // Collect all parameters for the creation or modification of a post.
    $msgOptions = array('id' => empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg'], 'subject' => $_POST['subject'], 'body' => $_POST['message'], 'icon' => preg_replace('~[\\./\\\\*:"\'<>]~', '', $_POST['icon']), 'smileys_enabled' => !isset($_POST['ns']), 'attachments' => empty($attachIDs) ? array() : $attachIDs, 'approved' => $becomesApproved, 'id_owner' => isset($msg_owner) ? $msg_owner : 0, 'locked' => !empty($_POST['lock_message']) && (allowedTo('moderate_board') || allowedTo('moderate_forum')));
    $topicOptions = array('id' => empty($topic) ? 0 : $topic, 'board' => $board, 'poll' => isset($_REQUEST['poll']) ? $id_poll : null, 'lock_mode' => isset($_POST['lock']) ? (int) $_POST['lock'] : null, 'sticky_mode' => isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics']) ? (int) $_POST['sticky'] : null, 'mark_as_read' => true, 'topic_prefix' => isset($_REQUEST['topic_prefix']) ? intval($_REQUEST['topic_prefix']) : null, 'topic_layout' => (isset($_REQUEST['stickfirst']) && $_REQUEST['stickfirst'] ? 0x80 : 0) | (isset($_REQUEST['firstlayout']) && $_REQUEST['firstlayout'] ? $_REQUEST['firstlayout'] : 0), 'automerge' => !empty($topic) ? $topic_info['automerge'] : 0, 'id_first_msg' => !empty($topic) ? $topic_info['id_first_msg'] : 0, 'id_last_msg' => !empty($topic) ? $topic_info['id_last_msg'] : 0, 'id_member_started' => !empty($topic) ? $topic_info['id_member_started'] : 0, 'id_member_updated' => !empty($topic) ? $topic_info['id_member_updated'] : 0, 'is_approved' => !$modSettings['postmod_active'] || empty($topic) || !empty($board_info['cur_topic_approved']), 'num_replies' => !empty($topic) ? $topic_info['num_replies'] : 0);
    $posterOptions = array('id' => $user_info['id'], 'name' => $_POST['guestname'], 'email' => $_POST['email'], 'update_post_count' => !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count']);
    // This is an already existing message. Edit it.
    if (!empty($_REQUEST['msg'])) {
        // Have admins allowed people to hide their screwups?
        if (time() - $row['poster_time'] > $modSettings['edit_wait_time'] || $user_info['id'] != $row['id_member']) {
            $msgOptions['modify_time'] = time();
            $msgOptions['modify_name'] = $user_info['name'];
        }
        // This will save some time...
        if (empty($approve_has_changed)) {
            unset($msgOptions['approved']);
        }
        modifyPost($msgOptions, $topicOptions, $posterOptions);
    } else {
        //handleUserTags($msgOptions['body']);
        createPost($msgOptions, $topicOptions, $posterOptions);
        if (isset($topicOptions['id'])) {
            $topic = $topicOptions['id'];
        }
        if (isset($_REQUEST['tags']) && !isset($_REQUEST['num_replies'])) {
            global $user_info;
            $result = smf_db_query('
              SELECT COUNT(*) as total
              FROM {db_prefix}tags_log
              WHERE ID_TOPIC = {int:id_topic}', array('id_topic' => $topic));
            $row = mysql_fetch_assoc($result);
            $nr_tags = $row['total'];
            mysql_free_result($result);
            // Check Tag restrictions
            $tags = explode(',', htmlspecialchars($_REQUEST['tags'], ENT_QUOTES));
            if ($nr_tags < $modSettings['smftags_set_maxtags']) {
                $count = 0;
                foreach ($tags as $tag) {
                    $tag = trim($tag);
                    if (empty($tag)) {
                        continue;
                    }
                    if ($count >= $modSettings['smftags_set_maxtags']) {
                        continue;
                    }
                    if (strlen($tag) < $modSettings['smftags_set_mintaglength']) {
                        continue;
                    }
                    if (strlen($tag) > $modSettings['smftags_set_maxtaglength']) {
                        continue;
                    }
                    $result = smf_db_query('
                      SELECT ID_TAG
                      FROM {db_prefix}tags
                      WHERE tag = {string:tag}', array('tag' => $tag));
                    if (0 == smf_db_affected_rows()) {
                        smf_db_query('INSERT INTO {db_prefix}tags
                          (tag, approved)
                          VALUES ({string:tag}, 1)', array('tag' => $tag));
                        $ID_TAG = smf_db_insert_id('{db_prefix}tags', 'ID_TAG');
                        smf_db_query('INSERT INTO {db_prefix}tags_log
                            (ID_TAG, ID_TOPIC, ID_MEMBER)
                            VALUES ({int:id_tag}, {int:topic}, {int:userid})', array('id_tag' => $ID_TAG, 'topic' => $topic, 'userid' => $user_info['id']));
                        $count++;
                    } else {
                        $row = mysql_fetch_assoc($result);
                        $ID_TAG = $row['ID_TAG'];
                        $result2 = smf_db_query('
                          SELECT ID FROM {db_prefix}tags_log
                          WHERE ID_TAG = {int:id_tag} AND ID_TOPIC = {int:topic}', array('id_tag' => $ID_TAG, 'topic' => $topic));
                        if (smf_db_affected_rows() != 0) {
                            continue;
                        }
                        mysql_free_result($result2);
                        smf_db_query('INSERT INTO {db_prefix}tags_log
                            (ID_TAG, ID_TOPIC, ID_MEMBER)
                            VALUES ({int:id_tag}, {int:topic}, {int:userid})', array('id_tag' => $ID_TAG, 'topic' => $topic, 'userid' => $user_info['id']));
                        $count++;
                    }
                    mysql_free_result($result);
                }
            }
        }
    }
    // Editing or posting an event?
    if (isset($_POST['calendar']) && (!isset($_REQUEST['eventid']) || $_REQUEST['eventid'] == -1)) {
        require_once $sourcedir . '/lib/Subs-Calendar.php';
        // Make sure they can link an event to this post.
        canLinkEvent();
        // Insert the event.
        $eventOptions = array('board' => $board, 'topic' => $topic, 'title' => $_POST['evtitle'], 'member' => $user_info['id'], 'start_date' => sprintf('%04d-%02d-%02d', $_POST['year'], $_POST['month'], $_POST['day']), 'span' => isset($_POST['span']) && $_POST['span'] > 0 ? min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1) : 0);
        insertEvent($eventOptions);
    } elseif (isset($_POST['calendar'])) {
        $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
        // Validate the post...
        require_once $sourcedir . '/lib/Subs-Calendar.php';
        validateEventPost();
        // If you're not allowed to edit any events, you have to be the poster.
        if (!allowedTo('calendar_edit_any')) {
            // Get the event's poster.
            $request = smf_db_query('
				SELECT id_member
				FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}', array('id_event' => $_REQUEST['eventid']));
            $row2 = mysql_fetch_assoc($request);
            mysql_free_result($request);
            // Silly hacker, Trix are for kids. ...probably trademarked somewhere, this is FAIR USE! (parody...)
            isAllowedTo('calendar_edit_' . ($row2['id_member'] == $user_info['id'] ? 'own' : 'any'));
        }
        // Delete it?
        if (isset($_REQUEST['deleteevent'])) {
            smf_db_query('
				DELETE FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}', array('id_event' => $_REQUEST['eventid']));
        } else {
            $span = !empty($modSettings['cal_allowspan']) && !empty($_REQUEST['span']) ? min((int) $modSettings['cal_maxspan'], (int) $_REQUEST['span'] - 1) : 0;
            $start_time = mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year']);
            smf_db_query('
				UPDATE {db_prefix}calendar
				SET end_date = {date:end_date},
					start_date = {date:start_date},
					title = {string:title}
				WHERE id_event = {int:id_event}', array('end_date' => strftime('%Y-%m-%d', $start_time + $span * 86400), 'start_date' => strftime('%Y-%m-%d', $start_time), 'id_event' => $_REQUEST['eventid'], 'title' => commonAPI::htmlspecialchars($_REQUEST['evtitle'], ENT_QUOTES)));
        }
        updateSettings(array('calendar_updated' => time()));
    }
    // Marking read should be done even for editing messages....
    // Mark all the parents read.  (since you just posted and they will be unread.)
    if (!$user_info['is_guest'] && !empty($board_info['parent_boards'])) {
        smf_db_query('
			UPDATE {db_prefix}log_boards
			SET id_msg = {int:id_msg}
			WHERE id_member = {int:current_member}
				AND id_board IN ({array_int:board_list})', array('current_member' => $user_info['id'], 'board_list' => array_keys($board_info['parent_boards']), 'id_msg' => $modSettings['maxMsgID']));
    }
    // Turn notification on or off.  (note this just blows smoke if it's already on or off.)
    if (!empty($_POST['notify']) && allowedTo('mark_any_notify')) {
        smf_db_insert('ignore', '{db_prefix}log_notify', array('id_member' => 'int', 'id_topic' => 'int', 'id_board' => 'int'), array($user_info['id'], $topic, 0), array('id_member', 'id_topic', 'id_board'));
    } elseif (!$newTopic) {
        smf_db_query('
			DELETE FROM {db_prefix}log_notify
			WHERE id_member = {int:current_member}
				AND id_topic = {int:current_topic}', array('current_member' => $user_info['id'], 'current_topic' => $topic));
    }
    // Log an act of moderation - modifying.
    if (!empty($moderationAction)) {
        logAction('modify', array('topic' => $topic, 'message' => (int) $_REQUEST['msg'], 'member' => $row['id_member'], 'board' => $board));
    }
    if (isset($_POST['lock']) && $_POST['lock'] != 2) {
        logAction('lock', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
    }
    if (isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics'])) {
        logAction('sticky', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
    }
    // Notify any members who have notification turned on for this topic - only do this if it's going to be approved(!)
    if ($becomesApproved) {
        if ($newTopic) {
            $notifyData = array('body' => $_POST['message'], 'subject' => $_POST['subject'], 'name' => $user_info['name'], 'poster' => $user_info['id'], 'msg' => $msgOptions['id'], 'board' => $board, 'topic' => $topic);
            notifyMembersBoard($notifyData);
        } elseif (empty($_REQUEST['msg'])) {
            // Only send it to everyone if the topic is approved, otherwise just to the topic starter if they want it.
            if ($topic_info['approved']) {
                sendNotifications($topic, 'reply');
            } else {
                sendNotifications($topic, 'reply', array(), $topic_info['id_member_started']);
            }
        }
    }
    // Returning to the topic?
    // Um, did this come from a draft?
    if (!empty($_POST['draft_id']) && !empty($user_info['id'])) {
        $_POST['draft_id'] = (int) $_POST['draft_id'];
        smf_db_query('
			DELETE FROM {db_prefix}drafts
			WHERE id_draft = {int:draft}
				AND id_member = {int:member}
			LIMIT 1', array('draft' => $_POST['draft_id'], 'member' => $user_info['id']));
    }
    if (!empty($_REQUEST['goback'])) {
        // Mark the board as read.... because it might get confusing otherwise.
        smf_db_query('
			UPDATE {db_prefix}log_boards
			SET id_msg = {int:maxMsgID}
			WHERE id_member = {int:current_member}
				AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id'], 'maxMsgID' => $modSettings['maxMsgID']));
    }
    if ($board_info['num_topics'] == 0) {
        CacheAPI::putCache('board-' . $board, null, 120);
    }
    if (!empty($_POST['announce_topic'])) {
        redirectexit('action=announce;sa=selectgroup;topic=' . $topic . (!empty($_POST['move']) && allowedTo('move_any') ? ';move' : '') . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    if (!empty($_POST['move']) && allowedTo('move_any')) {
        redirectexit('action=movetopic;topic=' . $topic . '.0' . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    // Return to post if the mod is on.
    if (isset($_REQUEST['msg']) && !empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg'], $context['browser']['is_ie']);
    } elseif (!empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.new#new', $context['browser']['is_ie']);
    } else {
        redirectexit('board=' . $board . '.0');
    }
}
Example #16
0
function issueWarning($memID)
{
    global $txt, $scripturl, $modSettings, $user_info, $mbname;
    global $context, $cur_profile, $memberContext, $smcFunc, $sourcedir;
    if (!isset($context['profile_template_support_context'])) {
        $context['profile_template_support_context'] = new ProfileContext();
    }
    // Get all the actual settings.
    list($modSettings['warning_enable'], $modSettings['user_limit']) = explode(',', $modSettings['warning_settings']);
    EoS_Smarty::loadTemplate('profile/profile_base');
    EoS_Smarty::getConfigInstance()->registerHookTemplate('profile_content_area', 'profile/issuewarning');
    // This stores any legitimate errors.
    $issueErrors = array();
    $context['replace_helper_array'] = array('"' => "'", "\n" => '\\n', "\r" => '');
    // Doesn't hurt to be overly cautious.
    if (empty($modSettings['warning_enable']) || $context['user']['is_owner'] && !$cur_profile['warning'] || !allowedTo('issue_warning')) {
        fatal_lang_error('no_access', false);
    }
    // Make sure things which are disabled stay disabled.
    $modSettings['warning_watch'] = !empty($modSettings['warning_watch']) ? $modSettings['warning_watch'] : 110;
    $modSettings['warning_moderate'] = !empty($modSettings['warning_moderate']) && !empty($modSettings['postmod_active']) ? $modSettings['warning_moderate'] : 110;
    $modSettings['warning_mute'] = !empty($modSettings['warning_mute']) ? $modSettings['warning_mute'] : 110;
    $context['warning_limit'] = allowedTo('admin_forum') ? 0 : $modSettings['user_limit'];
    $context['member']['warning'] = $cur_profile['warning'];
    $context['member']['name'] = $cur_profile['real_name'];
    // What are the limits we can apply?
    $context['min_allowed'] = 0;
    $context['max_allowed'] = 100;
    if ($context['warning_limit'] > 0) {
        // Make sure we cannot go outside of our limit for the day.
        $request = smf_db_query('
			SELECT SUM(counter)
			FROM {db_prefix}log_comments
			WHERE id_recipient = {int:selected_member}
				AND id_member = {int:current_member}
				AND comment_type = {string:warning}
				AND log_time > {int:day_time_period}', array('current_member' => $user_info['id'], 'selected_member' => $memID, 'day_time_period' => time() - 86400, 'warning' => 'warning'));
        list($current_applied) = mysql_fetch_row($request);
        mysql_free_result($request);
        $context['min_allowed'] = max(0, $cur_profile['warning'] - $current_applied - $context['warning_limit']);
        $context['max_allowed'] = min(100, $cur_profile['warning'] - $current_applied + $context['warning_limit']);
    }
    // Defaults.
    $context['warning_data'] = array('reason' => '', 'notify' => '', 'notify_subject' => '', 'notify_body' => '', 'topicban' => '', 'topicban_expire' => 0, 'topicban_id_topic' => 0);
    // Are we saving?
    if (isset($_POST['save'])) {
        // Security is good here.
        checkSession('post');
        // This cannot be empty!
        $_POST['warn_reason'] = isset($_POST['warn_reason']) ? trim($_POST['warn_reason']) : '';
        if ($_POST['warn_reason'] == '' && !$context['user']['is_owner']) {
            $issueErrors[] = 'warning_no_reason';
        }
        $_POST['warn_reason'] = commonAPI::htmlspecialchars($_POST['warn_reason']);
        // If the value hasn't changed it's either no JS or a real no change (Which this will pass)
        if ($_POST['warning_level'] == 'SAME') {
            $_POST['warning_level'] = $_POST['warning_level_nojs'];
        }
        $_POST['warning_level'] = (int) $_POST['warning_level'];
        $_POST['warning_level'] = max(0, min(100, $_POST['warning_level']));
        if ($_POST['warning_level'] < $context['min_allowed']) {
            $_POST['warning_level'] = $context['min_allowed'];
        } elseif ($_POST['warning_level'] > $context['max_allowed']) {
            $_POST['warning_level'] = $context['max_allowed'];
        }
        // Do we actually have to issue them with a PM?
        $id_notice = 0;
        if (!empty($_POST['warn_notify']) && empty($issueErrors)) {
            $_POST['warn_sub'] = trim($_POST['warn_sub']);
            $_POST['warn_body'] = trim($_POST['warn_body']);
            if (empty($_POST['warn_sub']) || empty($_POST['warn_body'])) {
                $issueErrors[] = 'warning_notify_blank';
            } else {
                require_once $sourcedir . '/lib/Subs-Post.php';
                $from = array('id' => 0, 'name' => $context['forum_name'], 'username' => $context['forum_name']);
                sendpm(array('to' => array($memID), 'bcc' => array()), $_POST['warn_sub'], $_POST['warn_body'], false, $from);
                // Log the notice!
                smf_db_insert('', '{db_prefix}log_member_notices', array('subject' => 'string-255', 'body' => 'string-65534'), array(commonAPI::htmlspecialchars($_POST['warn_sub']), commonAPI::htmlspecialchars($_POST['warn_body'])), array('id_notice'));
                $id_notice = smf_db_insert_id('{db_prefix}log_member_notices', 'id_notice');
            }
        }
        // Just in case - make sure notice is valid!
        $id_notice = (int) $id_notice;
        // What have we changed?
        $level_change = $_POST['warning_level'] - $cur_profile['warning'];
        // No errors? Proceed! Only log if you're not the owner.
        if (empty($issueErrors)) {
            // Log what we've done!
            if (!$context['user']['is_owner']) {
                smf_db_insert('', '{db_prefix}log_comments', array('id_member' => 'int', 'member_name' => 'string', 'comment_type' => 'string', 'id_recipient' => 'int', 'recipient_name' => 'string-255', 'log_time' => 'int', 'id_notice' => 'int', 'counter' => 'int', 'body' => 'string-65534'), array($user_info['id'], $user_info['name'], 'warning', $memID, $cur_profile['real_name'], time(), $id_notice, $level_change, $_POST['warn_reason']), array('id_comment'));
            }
            // Make the change.
            updateMemberData($memID, array('warning' => $_POST['warning_level']));
            // Leave a lovely message.
            $context['profile_updated'] = $context['user']['is_owner'] ? $txt['profile_updated_own'] : $txt['profile_warning_success'];
            // if we want to issue a topicban, do it now
            if (isset($_POST['warn_topicban']) && !empty($_POST['warn_topicban']) && isset($_POST['warn_topicban_id_topic']) && !empty($_POST['warn_topicban_id_topic'])) {
                $ban_reason = (isset($_REQUEST['warn_msg']) ? (int) $_REQUEST['warn_msg'] : 0) . '|' . $_POST['warn_reason'];
                $ban_expires = isset($_POST['warn_topicban_expire']) && !empty($_POST['warn_topicban_expire']) ? $context['time_now'] + 86400 * (int) $_POST['warn_topicban_expire'] : 0;
                smf_db_insert('', '{db_prefix}topicbans', array('id_topic' => 'int', 'id_member' => 'int', 'updated' => 'int', 'expires' => 'int', 'reason' => 'string'), array($_POST['warn_topicban_id_topic'], $memID, $context['time_now'], $ban_expires, $ban_reason), array('id'));
            }
        } else {
            // Get the base stuff done.
            loadLanguage('Errors');
            $context['custom_error_title'] = $txt['profile_warning_errors_occured'];
            // Fill in the suite of errors.
            $context['post_errors'] = array();
            foreach ($issueErrors as $error) {
                $context['post_errors'][] = $txt[$error];
            }
            // Try to remember some bits.
            $context['warning_data'] = array('reason' => $_POST['warn_reason'], 'notify' => !empty($_POST['warn_notify']), 'notify_subject' => isset($_POST['warn_sub']) ? $_POST['warn_sub'] : '', 'notify_body' => isset($_POST['warn_body']) ? $_POST['warn_body'] : '', 'topicban' => isset($_POST['warn_topicban']) && !empty($_POST['warn_topicban']) ? 1 : 0, 'topicban_expire' => isset($_POST['warn_topicban_expire']) && !empty($_POST['warn_topicban_expire']) ? (int) $_POST['warn_topicban_expire'] : 0, 'topicban_id_topic' => isset($_POST['warn_topicban_id_topic']) ? (int) $_POST['warn_topicban_id_topic'] : 0, 'msg' => isset($_POST['warn_msg']) && !empty($_POST['warn_msg']) ? (int) $_POST['warn_msg'] : 0);
        }
        // Show the new improved warning level.
        $context['member']['warning'] = $_POST['warning_level'];
    }
    $context['page_title'] = $txt['profile_issue_warning'];
    // Work our the various levels.
    $context['level_effects'] = array(0 => $txt['profile_warning_effect_none'], $modSettings['warning_watch'] => $txt['profile_warning_effect_watch'], $modSettings['warning_moderate'] => $txt['profile_warning_effect_moderation'], $modSettings['warning_mute'] => $txt['profile_warning_effect_mute']);
    $context['current_level'] = 0;
    foreach ($context['level_effects'] as $limit => $dummy) {
        if ($context['member']['warning'] >= $limit) {
            $context['current_level'] = $limit;
        }
    }
    // Load up all the old warnings - count first!
    $context['total_warnings'] = list_getUserWarningCount($memID);
    // Make the page index.
    $context['start'] = (int) $_REQUEST['start'];
    $perPage = (int) $modSettings['defaultMaxMessages'];
    $context['page_index'] = constructPageIndex($scripturl . '?action=profile;u=' . $memID . ';area=issuewarning', $context['start'], $context['total_warnings'], $perPage);
    // Now do the data itself.
    $context['previous_warnings'] = list_getUserWarnings($context['start'], $perPage, 'log_time DESC', $memID);
    // Are they warning because of a message?
    $context['warned_message_subject'] = '';
    if (isset($_REQUEST['msg']) && 0 < (int) $_REQUEST['msg']) {
        $request = smf_db_query('
			SELECT subject, id_topic
			FROM {db_prefix}messages AS m
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
			WHERE id_msg = {int:message}
				AND {query_see_board}
			LIMIT 1', array('message' => (int) $_REQUEST['msg']));
        if (mysql_num_rows($request) != 0) {
            $context['warning_for_message'] = (int) $_REQUEST['msg'];
            $context['warning_data']['msg'] = $context['warning_for_message'];
            list($context['warned_message_subject'], $context['warning_for_topic']) = mysql_fetch_row($request);
        }
        mysql_free_result($request);
    }
    if (isset($_POST['warn_topicban_id_topic'])) {
        $context['warning_for_message'] = (int) $_POST['warn_topicban_id_topic'];
    }
    // Didn't find the message?
    if (empty($context['warning_for_message'])) {
        $context['warning_for_message'] = $context['warning_for_topic'] = 0;
        $context['warned_message_subject'] = '';
    }
    // we can issue a topic ban, now check if the member doesn't have one already
    if (isset($context['warning_for_topic'])) {
        $context['can_issue_topicban'] = $context['warning_for_topic'];
        $request = smf_db_query('SELECT id_member FROM {db_prefix}topicbans WHERE id_topic = {int:topic} AND id_member = {int:member}', array('topic' => $context['warning_for_topic'], 'member' => $memID));
        if (mysql_num_rows($request) > 0) {
            $context['warning_for_topic'] = $context['can_issue_topicban'] = 0;
            $context['member_is_topic_banned'] = true;
        } else {
            $context['warning_data']['topicban_id_topic'] = $context['warning_for_topic'];
        }
        mysql_free_result($request);
    } else {
        $context['can_issue_topicban'] = 0;
    }
    // Any custom templates?
    $context['notification_templates'] = array();
    $request = smf_db_query('
		SELECT recipient_name AS template_title, body
		FROM {db_prefix}log_comments
		WHERE comment_type = {string:warntpl}
			AND (id_recipient = {int:generic} OR id_recipient = {int:current_member})', array('warntpl' => 'warntpl', 'generic' => 0, 'current_member' => $user_info['id']));
    while ($row = mysql_fetch_assoc($request)) {
        // If we're not warning for a message skip any that are.
        if (!$context['warning_for_message'] && strpos($row['body'], '{MESSAGE}') !== false) {
            continue;
        }
        $context['notification_templates'][] = array('title' => $row['template_title'], 'body' => $row['body']);
    }
    mysql_free_result($request);
    // Setup the "default" templates.
    foreach (array('spamming', 'offence', 'insulting') as $type) {
        $context['notification_templates'][] = array('title' => $txt['profile_warning_notify_title_' . $type], 'body' => sprintf($txt['profile_warning_notify_template_outline' . (!empty($context['warning_for_message']) ? '_post' : '')], $txt['profile_warning_notify_for_' . $type]));
    }
    // Replace all the common variables in the templates.
    foreach ($context['notification_templates'] as $k => $name) {
        $context['notification_templates'][$k]['body'] = strtr($name['body'], array('{MEMBER}' => un_htmlspecialchars($context['member']['name']), '{MESSAGE}' => '[url=' . $scripturl . '?msg=' . $context['warning_for_message'] . ']' . un_htmlspecialchars($context['warned_message_subject']) . '[/url]', '{SCRIPTURL}' => $scripturl, '{FORUMNAME}' => $mbname, '{REGARDS}' => $txt['regards_team']));
    }
}
Example #17
0
function splitTopic($split1_ID_TOPIC, $splitMessages, $new_subject)
{
    global $user_info, $topic, $board, $modSettings, $smcFunc, $txt;
    // Nothing to split?
    if (empty($splitMessages)) {
        fatal_lang_error('no_posts_selected', false);
    }
    // Get some board info.
    $request = smf_db_query('
		SELECT id_board, approved
		FROM {db_prefix}topics
		WHERE id_topic = {int:id_topic}
		LIMIT 1', array('id_topic' => $split1_ID_TOPIC));
    list($id_board, $split1_approved) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Find the new first and last not in the list. (old topic)
    $request = smf_db_query('
		SELECT
			MIN(m.id_msg) AS myid_first_msg, MAX(m.id_msg) AS myid_last_msg, COUNT(*) AS message_count, m.approved
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:id_topic})
		WHERE m.id_msg NOT IN ({array_int:no_msg_list})
			AND m.id_topic = {int:id_topic}
		GROUP BY m.approved
		ORDER BY m.approved DESC
		LIMIT 2', array('id_topic' => $split1_ID_TOPIC, 'no_msg_list' => $splitMessages));
    // You can't select ALL the messages!
    if (mysql_num_rows($request) == 0) {
        fatal_lang_error('selected_all_posts', false);
    }
    while ($row = mysql_fetch_assoc($request)) {
        // Get the right first and last message dependant on approved state...
        if (empty($split1_first_msg) || $row['myid_first_msg'] < $split1_first_msg) {
            $split1_first_msg = $row['myid_first_msg'];
        }
        if (empty($split1_last_msg) || $row['approved']) {
            $split1_last_msg = $row['myid_last_msg'];
        }
        // Get the counts correct...
        if ($row['approved']) {
            $split1_replies = $row['message_count'] - 1;
            $split1_unapprovedposts = 0;
        } else {
            if (!isset($split1_replies)) {
                $split1_replies = 0;
            } elseif (!$split1_approved) {
                $split1_replies++;
            }
            $split1_unapprovedposts = $row['message_count'];
        }
    }
    mysql_free_result($request);
    $split1_firstMem = getMsgMemberID($split1_first_msg);
    $split1_lastMem = getMsgMemberID($split1_last_msg);
    // Find the first and last in the list. (new topic)
    $request = smf_db_query('
		SELECT MIN(id_msg) AS myid_first_msg, MAX(id_msg) AS myid_last_msg, COUNT(*) AS message_count, approved
		FROM {db_prefix}messages
		WHERE id_msg IN ({array_int:msg_list})
			AND id_topic = {int:id_topic}
		GROUP BY id_topic, approved
		ORDER BY approved DESC
		LIMIT 2', array('msg_list' => $splitMessages, 'id_topic' => $split1_ID_TOPIC));
    while ($row = mysql_fetch_assoc($request)) {
        // As before get the right first and last message dependant on approved state...
        if (empty($split2_first_msg) || $row['myid_first_msg'] < $split2_first_msg) {
            $split2_first_msg = $row['myid_first_msg'];
        }
        if (empty($split2_last_msg) || $row['approved']) {
            $split2_last_msg = $row['myid_last_msg'];
        }
        // Then do the counts again...
        if ($row['approved']) {
            $split2_approved = true;
            $split2_replies = $row['message_count'] - 1;
            $split2_unapprovedposts = 0;
        } else {
            // Should this one be approved??
            if ($split2_first_msg == $row['myid_first_msg']) {
                $split2_approved = false;
            }
            if (!isset($split2_replies)) {
                $split2_replies = 0;
            } elseif (!$split2_approved) {
                $split2_replies++;
            }
            $split2_unapprovedposts = $row['message_count'];
        }
    }
    mysql_free_result($request);
    $split2_firstMem = getMsgMemberID($split2_first_msg);
    $split2_lastMem = getMsgMemberID($split2_last_msg);
    // No database changes yet, so let's double check to see if everything makes at least a little sense.
    if ($split1_first_msg <= 0 || $split1_last_msg <= 0 || $split2_first_msg <= 0 || $split2_last_msg <= 0 || $split1_replies < 0 || $split2_replies < 0 || $split1_unapprovedposts < 0 || $split2_unapprovedposts < 0 || !isset($split1_approved) || !isset($split2_approved)) {
        fatal_lang_error('cant_find_messages');
    }
    // You cannot split off the first message of a topic.
    if ($split1_first_msg > $split2_first_msg) {
        fatal_lang_error('split_first_post', false);
    }
    // We're off to insert the new topic!  Use 0 for now to avoid UNIQUE errors.
    smf_db_insert('', '{db_prefix}topics', array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'num_replies' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'is_sticky' => 'int'), array((int) $id_board, $split2_firstMem, $split2_lastMem, 0, 0, $split2_replies, $split2_unapprovedposts, (int) $split2_approved, 0), array('id_topic'));
    $split2_ID_TOPIC = smf_db_insert_id('{db_prefix}topics', 'id_topic');
    if ($split2_ID_TOPIC <= 0) {
        fatal_lang_error('cant_insert_topic');
    }
    // Move the messages over to the other topic.
    $new_subject = strtr(commonAPI::htmltrim(commonAPI::htmlspecialchars($new_subject)), array("\r" => '', "\n" => '', "\t" => ''));
    // Check the subject length.
    if (commonAPI::strlen($new_subject) > 100) {
        $new_subject = commonAPI::substr($new_subject, 0, 100);
    }
    // Valid subject?
    if ($new_subject != '') {
        smf_db_query('
			UPDATE {db_prefix}messages
			SET
				id_topic = {int:id_topic},
				subject = CASE WHEN id_msg = {int:split_first_msg} THEN {string:new_subject} ELSE {string:new_subject_replies} END
			WHERE id_msg IN ({array_int:split_msgs})', array('split_msgs' => $splitMessages, 'id_topic' => $split2_ID_TOPIC, 'new_subject' => $new_subject, 'split_first_msg' => $split2_first_msg, 'new_subject_replies' => $txt['response_prefix'] . $new_subject));
        // Cache the new topics subject... we can do it now as all the subjects are the same!
        updateStats('subject', $split2_ID_TOPIC, $new_subject);
    }
    // Any associated reported posts better follow...
    smf_db_query('
		UPDATE {db_prefix}log_reported
		SET id_topic = {int:id_topic}
		WHERE id_msg IN ({array_int:split_msgs})', array('split_msgs' => $splitMessages, 'id_topic' => $split2_ID_TOPIC));
    // Mess with the old topic's first, last, and number of messages.
    smf_db_query('
		UPDATE {db_prefix}topics
		SET
			num_replies = {int:num_replies},
			id_first_msg = {int:id_first_msg},
			id_last_msg = {int:id_last_msg},
			id_member_started = {int:id_member_started},
			id_member_updated = {int:id_member_updated},
			unapproved_posts = {int:unapproved_posts}
		WHERE id_topic = {int:id_topic}', array('num_replies' => $split1_replies, 'id_first_msg' => $split1_first_msg, 'id_last_msg' => $split1_last_msg, 'id_member_started' => $split1_firstMem, 'id_member_updated' => $split1_lastMem, 'unapproved_posts' => $split1_unapprovedposts, 'id_topic' => $split1_ID_TOPIC));
    // Now, put the first/last message back to what they should be.
    smf_db_query('
		UPDATE {db_prefix}topics
		SET
			id_first_msg = {int:id_first_msg},
			id_last_msg = {int:id_last_msg}
		WHERE id_topic = {int:id_topic}', array('id_first_msg' => $split2_first_msg, 'id_last_msg' => $split2_last_msg, 'id_topic' => $split2_ID_TOPIC));
    // If the new topic isn't approved ensure the first message flags this just in case.
    if (!$split2_approved) {
        smf_db_query('
			UPDATE {db_prefix}messages
			SET approved = {int:approved}
			WHERE id_msg = {int:id_msg}
				AND id_topic = {int:id_topic}', array('approved' => 0, 'id_msg' => $split2_first_msg, 'id_topic' => $split2_ID_TOPIC));
    }
    // The board has more topics now (Or more unapproved ones!).
    smf_db_query('
		UPDATE {db_prefix}boards
		SET ' . ($split2_approved ? '
			num_topics = num_topics + 1' : '
			unapproved_topics = unapproved_topics + 1') . '
		WHERE id_board = {int:id_board}', array('id_board' => $id_board));
    // Copy log topic entries.
    // !!! This should really be chunked.
    $request = smf_db_query('
		SELECT id_member, id_msg
		FROM {db_prefix}log_topics
		WHERE id_topic = {int:id_topic}', array('id_topic' => (int) $split1_ID_TOPIC));
    if (mysql_num_rows($request) > 0) {
        $replaceEntries = array();
        while ($row = mysql_fetch_assoc($request)) {
            $replaceEntries[] = array($row['id_member'], $split2_ID_TOPIC, $row['id_msg']);
        }
        smf_db_insert('ignore', '{db_prefix}log_topics', array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'), $replaceEntries, array('id_member', 'id_topic'));
        unset($replaceEntries);
    }
    mysql_free_result($request);
    // Housekeeping.
    updateStats('topic');
    updateLastMessages($id_board);
    logAction('split', array('topic' => $split1_ID_TOPIC, 'new_topic' => $split2_ID_TOPIC, 'board' => $id_board));
    // Notify people that this topic has been split?
    sendNotifications($split1_ID_TOPIC, 'split');
    // Return the ID of the newly created topic.
    return $split2_ID_TOPIC;
}
Example #18
0
function createCategory($catOptions)
{
    global $smcFunc;
    // Check required values.
    if (!isset($catOptions['cat_name']) || trim($catOptions['cat_name']) == '') {
        trigger_error('createCategory(): A category name is required', E_USER_ERROR);
    }
    // Set default values.
    if (!isset($catOptions['move_after'])) {
        $catOptions['move_after'] = 0;
    }
    if (!isset($catOptions['is_collapsible'])) {
        $catOptions['is_collapsible'] = true;
    }
    // Don't log an edit right after.
    $catOptions['dont_log'] = true;
    // Add the category to the database.
    smf_db_insert('', '{db_prefix}categories', array('name' => 'string-48', 'description' => 'string-200'), array($catOptions['cat_name'], $catOptions['cat_desc']), array('id_cat'));
    // Grab the new category ID.
    $category_id = smf_db_insert_id('{db_prefix}categories', 'id_cat');
    // Set the given properties to the newly created category.
    modifyCategory($category_id, $catOptions);
    logAction('add_cat', array('catname' => $catOptions['cat_name']), 'admin');
    // Return the database ID of the category.
    return $category_id;
}
Example #19
0
function profileSaveAvatarData(&$value)
{
    global $modSettings, $sourcedir, $backend_subdir, $profile_vars, $cur_profile, $context;
    $memID = $context['id_member'];
    if (empty($memID) && !empty($context['password_auth_failed'])) {
        return false;
    }
    require_once $sourcedir . '/lib/Subs-ManageAttachments.php';
    // We need to know where we're going to be putting it..
    if (!empty($modSettings['custom_avatar_enabled'])) {
        $uploadDir = $modSettings['custom_avatar_dir'];
        $id_folder = 1;
    } elseif (!empty($modSettings['currentAttachmentUploadDir'])) {
        if (!is_array($modSettings['attachmentUploadDir'])) {
            $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
        }
        // Just use the current path for temp files.
        $uploadDir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
        $id_folder = $modSettings['currentAttachmentUploadDir'];
    } else {
        $uploadDir = $modSettings['attachmentUploadDir'];
        $id_folder = 1;
    }
    $downloadedExternalAvatar = false;
    if ($value == 'external' && allowedTo('profile_remote_avatar') && strtolower(substr($_POST['userpicpersonal'], 0, 7)) == 'http://' && strlen($_POST['userpicpersonal']) > 7 && !empty($modSettings['avatar_download_external'])) {
        if (!is_writable($uploadDir)) {
            fatal_lang_error('attachments_no_write', 'critical');
        }
        require_once $sourcedir . '/lib/Subs-Package.php';
        $url = parse_url($_POST['userpicpersonal']);
        $contents = fetch_web_data('http://' . $url['host'] . (empty($url['port']) ? '' : ':' . $url['port']) . str_replace(' ', '%20', trim($url['path'])));
        if ($contents != false && ($tmpAvatar = fopen($uploadDir . '/avatar_tmp_' . $memID, 'wb'))) {
            fwrite($tmpAvatar, $contents);
            fclose($tmpAvatar);
            $downloadedExternalAvatar = true;
            $_FILES['attachment']['tmp_name'] = $uploadDir . '/avatar_tmp_' . $memID;
        }
    }
    if ($value == 'none') {
        $profile_vars['avatar'] = '';
        // Reset the attach ID.
        $cur_profile['id_attach'] = 0;
        $cur_profile['attachment_type'] = 0;
        $cur_profile['filename'] = '';
        removeAttachments(array('id_member' => $memID));
    } elseif ($value == 'server_stored' && allowedTo('profile_server_avatar')) {
        $profile_vars['avatar'] = strtr(empty($_POST['file']) ? empty($_POST['cat']) ? '' : $_POST['cat'] : $_POST['file'], array('&amp;' => '&'));
        $profile_vars['avatar'] = preg_match('~^([\\w _!@%*=\\-#()\\[\\]&.,]+/)?[\\w _!@%*=\\-#()\\[\\]&.,]+$~', $profile_vars['avatar']) != 0 && preg_match('/\\.\\./', $profile_vars['avatar']) == 0 && file_exists($modSettings['avatar_directory'] . '/' . $profile_vars['avatar']) ? $profile_vars['avatar'] == 'blank.gif' ? '' : $profile_vars['avatar'] : '';
        // Clear current profile...
        $cur_profile['id_attach'] = 0;
        $cur_profile['attachment_type'] = 0;
        $cur_profile['filename'] = '';
        // Get rid of their old avatar. (if uploaded.)
        removeAttachments(array('id_member' => $memID));
    } elseif ($value == 'external' && allowedTo('profile_remote_avatar') && strtolower(substr($_POST['userpicpersonal'], 0, 7)) == 'http://' && empty($modSettings['avatar_download_external'])) {
        // We need these clean...
        $cur_profile['id_attach'] = 0;
        $cur_profile['attachment_type'] = 0;
        $cur_profile['filename'] = '';
        // Remove any attached avatar...
        removeAttachments(array('id_member' => $memID));
        $profile_vars['avatar'] = str_replace('%20', '', preg_replace('~action(?:=|%3d)(?!dlattach)~i', 'action-', $_POST['userpicpersonal']));
        if ($profile_vars['avatar'] == 'http://' || $profile_vars['avatar'] == 'http:///') {
            $profile_vars['avatar'] = '';
        } elseif (substr($profile_vars['avatar'], 0, 7) != 'http://') {
            return 'bad_avatar';
        } elseif (!empty($modSettings['avatar_max_height_external']) || !empty($modSettings['avatar_max_width_external'])) {
            // Now let's validate the avatar.
            $sizes = url_image_size($profile_vars['avatar']);
            if (is_array($sizes) && ($sizes[0] > $modSettings['avatar_max_width_external'] && !empty($modSettings['avatar_max_width_external']) || $sizes[1] > $modSettings['avatar_max_height_external'] && !empty($modSettings['avatar_max_height_external']))) {
                // Houston, we have a problem. The avatar is too large!!
                if ($modSettings['avatar_action_too_large'] == 'option_refuse') {
                    return 'bad_avatar';
                } elseif ($modSettings['avatar_action_too_large'] == 'option_download_and_resize') {
                    require_once $sourcedir . '/lib/Subs-Graphics.php';
                    if (downloadAvatar($profile_vars['avatar'], $memID, $modSettings['avatar_max_width_external'], $modSettings['avatar_max_height_external'])) {
                        $profile_vars['avatar'] = '';
                        $cur_profile['id_attach'] = $modSettings['new_avatar_data']['id'];
                        $cur_profile['filename'] = $modSettings['new_avatar_data']['filename'];
                        $cur_profile['attachment_type'] = $modSettings['new_avatar_data']['type'];
                    } else {
                        return 'bad_avatar';
                    }
                }
            }
        }
    } elseif ($value == 'upload' && allowedTo('profile_upload_avatar') || $downloadedExternalAvatar) {
        if (isset($_FILES['attachment']['name']) && $_FILES['attachment']['name'] != '' || $downloadedExternalAvatar) {
            // Get the dimensions of the image.
            if (!$downloadedExternalAvatar) {
                if (!is_writable($uploadDir)) {
                    fatal_lang_error('attachments_no_write', 'critical');
                }
                if (!move_uploaded_file($_FILES['attachment']['tmp_name'], $uploadDir . '/avatar_tmp_' . $memID)) {
                    fatal_lang_error('attach_timeout', 'critical');
                }
                $_FILES['attachment']['tmp_name'] = $uploadDir . '/avatar_tmp_' . $memID;
            }
            $sizes = @getimagesize($_FILES['attachment']['tmp_name']);
            // No size, then it's probably not a valid pic.
            if ($sizes === false) {
                return 'bad_avatar';
            } elseif (!empty($modSettings['avatar_max_width_upload']) && $sizes[0] > $modSettings['avatar_max_width_upload'] || !empty($modSettings['avatar_max_height_upload']) && $sizes[1] > $modSettings['avatar_max_height_upload']) {
                if (!empty($modSettings['avatar_resize_upload'])) {
                    // Attempt to chmod it.
                    @chmod($uploadDir . '/avatar_tmp_' . $memID, 0644);
                    require_once $sourcedir . '/lib/Subs-Graphics.php';
                    if (!downloadAvatar($uploadDir . '/avatar_tmp_' . $memID, $memID, $modSettings['avatar_max_width_upload'], $modSettings['avatar_max_height_upload'])) {
                        return 'bad_avatar';
                    }
                    // Reset attachment avatar data.
                    $cur_profile['id_attach'] = $modSettings['new_avatar_data']['id'];
                    $cur_profile['filename'] = $modSettings['new_avatar_data']['filename'];
                    $cur_profile['attachment_type'] = $modSettings['new_avatar_data']['type'];
                } else {
                    return 'bad_avatar';
                }
            } elseif (is_array($sizes)) {
                // Now try to find an infection.
                require_once $sourcedir . '/lib/Subs-Graphics.php';
                if (!checkImageContents($_FILES['attachment']['tmp_name'], !empty($modSettings['avatar_paranoid']))) {
                    // It's bad. Try to re-encode the contents?
                    if (empty($modSettings['avatar_reencode']) || !reencodeImage($_FILES['attachment']['tmp_name'], $sizes[2])) {
                        return 'bad_avatar';
                    }
                    // We were successful. However, at what price?
                    $sizes = @getimagesize($_FILES['attachment']['tmp_name']);
                    // Hard to believe this would happen, but can you bet?
                    if ($sizes === false) {
                        return 'bad_avatar';
                    }
                }
                $extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png', '6' => 'bmp');
                $extension = isset($extensions[$sizes[2]]) ? $extensions[$sizes[2]] : 'bmp';
                $mime_type = 'image/' . ($extension === 'jpg' ? 'jpeg' : ($extension === 'bmp' ? 'x-ms-bmp' : $extension));
                $destName = 'avatar_' . $memID . '_' . time() . '.' . $extension;
                list($width, $height) = getimagesize($_FILES['attachment']['tmp_name']);
                $file_hash = empty($modSettings['custom_avatar_enabled']) ? getAttachmentFilename($destName, false, null, true) : '';
                // Remove previous attachments this member might have had.
                removeAttachments(array('id_member' => $memID));
                smf_db_insert('', '{db_prefix}attachments', array('id_member' => 'int', 'attachment_type' => 'int', 'filename' => 'string', 'file_hash' => 'string', 'fileext' => 'string', 'size' => 'int', 'width' => 'int', 'height' => 'int', 'mime_type' => 'string', 'id_folder' => 'int'), array($memID, empty($modSettings['custom_avatar_enabled']) ? 0 : 1, $destName, $file_hash, $extension, filesize($_FILES['attachment']['tmp_name']), (int) $width, (int) $height, $mime_type, $id_folder), array('id_attach'));
                $cur_profile['id_attach'] = smf_db_insert_id('{db_prefix}attachments', 'id_attach');
                $cur_profile['filename'] = $destName;
                $cur_profile['attachment_type'] = empty($modSettings['custom_avatar_enabled']) ? 0 : 1;
                $destinationPath = $uploadDir . '/' . (empty($file_hash) ? $destName : $cur_profile['id_attach'] . '_' . $file_hash);
                if (!rename($_FILES['attachment']['tmp_name'], $destinationPath)) {
                    // I guess a man can try.
                    removeAttachments(array('id_member' => $memID));
                    fatal_lang_error('attach_timeout', 'critical');
                }
                // Attempt to chmod it.
                @chmod($uploadDir . '/' . $destinationPath, 0644);
            }
            $profile_vars['avatar'] = '';
            // Delete any temporary file.
            if (file_exists($uploadDir . '/avatar_tmp_' . $memID)) {
                @unlink($uploadDir . '/avatar_tmp_' . $memID);
            }
        } else {
            $profile_vars['avatar'] = '';
        }
    } else {
        if ($value == 'gravatar') {
            $profile_vars['avatar'] = 'gravatar';
        } else {
            $profile_vars['avatar'] = '';
        }
    }
    // Setup the profile variables so it shows things right on display!
    $cur_profile['avatar'] = $profile_vars['avatar'];
    return false;
}
Example #20
0
function registerMember(&$regOptions, $return_errors = false)
{
    global $scripturl, $txt, $modSettings, $context, $sourcedir;
    global $user_info, $options, $settings, $smcFunc;
    loadLanguage('Login');
    // We'll need some external functions.
    require_once $sourcedir . '/lib/Subs-Auth.php';
    require_once $sourcedir . '/lib/Subs-Post.php';
    // Put any errors in here.
    $reg_errors = array();
    // Registration from the admin center, let them sweat a little more.
    if ($regOptions['interface'] == 'admin') {
        is_not_guest();
        isAllowedTo('moderate_forum');
    } elseif ($regOptions['interface'] == 'guest') {
        // You cannot register twice...
        if (empty($user_info['is_guest'])) {
            redirectexit();
        }
        // Make sure they didn't just register with this session.
        if (!empty($_SESSION['just_registered']) && empty($modSettings['disableRegisterCheck'])) {
            fatal_lang_error('register_only_once', false);
        }
    }
    // What method of authorization are we going to use?
    if (empty($regOptions['auth_method']) || !in_array($regOptions['auth_method'], array('password', 'openid'))) {
        if (!empty($regOptions['openid'])) {
            $regOptions['auth_method'] = 'openid';
        } else {
            $regOptions['auth_method'] = 'password';
        }
    }
    // No name?!  How can you register with no name?
    if (empty($regOptions['username'])) {
        $reg_errors[] = array('lang', 'need_username');
    }
    // Spaces and other odd characters are evil...
    $regOptions['username'] = preg_replace('~[\\t\\n\\r\\x0B\\0' . ($context['server']['complex_preg_chars'] ? '\\x{A0}' : " ") . ']+~u', ' ', $regOptions['username']);
    // Don't use too long a name.
    if (commonAPI::strlen($regOptions['username']) > 25) {
        $reg_errors[] = array('lang', 'error_long_name');
    }
    // Only these characters are permitted.
    if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $regOptions['username'])) != 0 || $regOptions['username'] == '_' || $regOptions['username'] == '|' || strpos($regOptions['username'], '[code') !== false || strpos($regOptions['username'], '[/code') !== false) {
        $reg_errors[] = array('lang', 'error_invalid_characters_username');
    }
    if (commonAPI::strtolower($regOptions['username']) === commonAPI::strtolower($txt['guest_title'])) {
        $reg_errors[] = array('lang', 'username_reserved', 'general', array($txt['guest_title']));
    }
    // !!! Separate the sprintf?
    if (empty($regOptions['email']) || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $regOptions['email']) === 0 || strlen($regOptions['email']) > 255) {
        $reg_errors[] = array('done', sprintf($txt['valid_email_needed'], commonAPI::htmlspecialchars($regOptions['username'])));
    }
    if (!empty($regOptions['check_reserved_name']) && isReservedName($regOptions['username'], 0, false)) {
        if ($regOptions['password'] == 'chocolate cake') {
            $reg_errors[] = array('done', 'Sorry, I don\'t take bribes... you\'ll need to come up with a different name.');
        }
        $reg_errors[] = array('done', '(' . htmlspecialchars($regOptions['username']) . ') ' . $txt['name_in_use']);
    }
    // Generate a validation code if it's supposed to be emailed.
    $validation_code = '';
    if ($regOptions['require'] == 'activation') {
        $validation_code = generateValidationCode();
    }
    // If you haven't put in a password generate one.
    if ($regOptions['interface'] == 'admin' && $regOptions['password'] == '' && $regOptions['auth_method'] == 'password') {
        mt_srand(time() + 1277);
        $regOptions['password'] = generateValidationCode();
        $regOptions['password_check'] = $regOptions['password'];
    } elseif ($regOptions['password'] != $regOptions['password_check'] && $regOptions['auth_method'] == 'password') {
        $reg_errors[] = array('lang', 'passwords_dont_match');
    }
    // That's kind of easy to guess...
    if ($regOptions['password'] == '') {
        if ($regOptions['auth_method'] == 'password') {
            $reg_errors[] = array('lang', 'no_password');
        } else {
            $regOptions['password'] = sha1(mt_rand());
        }
    }
    // Now perform hard password validation as required.
    if (!empty($regOptions['check_password_strength'])) {
        $passwordError = validatePassword($regOptions['password'], $regOptions['username'], array($regOptions['email']));
        // Password isn't legal?
        if ($passwordError != null) {
            $reg_errors[] = array('lang', 'profile_error_password_' . $passwordError);
        }
    }
    // If they are using an OpenID that hasn't been verified yet error out.
    // !!! Change this so they can register without having to attempt a login first
    if ($regOptions['auth_method'] == 'openid' && (empty($_SESSION['openid']['verified']) || $_SESSION['openid']['openid_uri'] != $regOptions['openid'])) {
        $reg_errors[] = array('lang', 'openid_not_verified');
    }
    // You may not be allowed to register this email.
    if (!empty($regOptions['check_email_ban'])) {
        isBannedEmail($regOptions['email'], 'cannot_register', $txt['ban_register_prohibited']);
    }
    // Check if the email address is in use.
    $request = smf_db_query('
		SELECT id_member
		FROM {db_prefix}members
		WHERE email_address = {string:email_address}
			OR email_address = {string:username}
		LIMIT 1', array('email_address' => $regOptions['email'], 'username' => $regOptions['username']));
    // !!! Separate the sprintf?
    if (mysql_num_rows($request) != 0) {
        $reg_errors[] = array('lang', 'email_in_use', false, array(htmlspecialchars($regOptions['email'])));
    }
    mysql_free_result($request);
    // If we found any errors we need to do something about it right away!
    foreach ($reg_errors as $key => $error) {
        /* Note for each error:
        			0 = 'lang' if it's an index, 'done' if it's clear text.
        			1 = The text/index.
        			2 = Whether to log.
        			3 = sprintf data if necessary. */
        if ($error[0] == 'lang') {
            loadLanguage('Errors');
        }
        $message = $error[0] == 'lang' ? empty($error[3]) ? $txt[$error[1]] : vsprintf($txt[$error[1]], $error[3]) : $error[1];
        // What to do, what to do, what to do.
        if ($return_errors) {
            if (!empty($error[2])) {
                log_error($message, $error[2]);
            }
            $reg_errors[$key] = $message;
        } else {
            fatal_error($message, empty($error[2]) ? false : $error[2]);
        }
    }
    // If there's any errors left return them at once!
    if (!empty($reg_errors)) {
        return $reg_errors;
    }
    $reservedVars = array('actual_theme_url', 'actual_images_url', 'base_theme_dir', 'base_theme_url', 'default_images_url', 'default_theme_dir', 'default_theme_url', 'default_template', 'images_url', 'number_recent_posts', 'smiley_sets_default', 'theme_dir', 'theme_id', 'theme_layers', 'theme_templates', 'theme_url');
    // Can't change reserved vars.
    if (isset($regOptions['theme_vars']) && array_intersect($regOptions['theme_vars'], $reservedVars) != array()) {
        fatal_lang_error('no_theme');
    }
    // Some of these might be overwritten. (the lower ones that are in the arrays below.)
    $regOptions['register_vars'] = array('member_name' => $regOptions['username'], 'email_address' => $regOptions['email'], 'passwd' => sha1(strtolower($regOptions['username']) . $regOptions['password']), 'password_salt' => substr(md5(mt_rand()), 0, 4), 'posts' => 0, 'date_registered' => time(), 'member_ip' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $user_info['ip'], 'member_ip2' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $_SERVER['BAN_CHECK_IP'], 'validation_code' => $validation_code, 'real_name' => $regOptions['username'], 'personal_text' => $modSettings['default_personal_text'], 'pm_email_notify' => 1, 'id_theme' => 0, 'id_post_group' => 4, 'lngfile' => '', 'buddy_list' => '', 'pm_ignore_list' => '', 'message_labels' => '', 'location' => '', 'time_format' => '', 'signature' => '', 'avatar' => '', 'usertitle' => '', 'secret_question' => '', 'secret_answer' => '', 'additional_groups' => '', 'ignore_boards' => '', 'smiley_set' => '', 'openid_uri' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
    // Setup the activation status on this new account so it is correct - firstly is it an under age account?
    if ($regOptions['require'] == 'coppa') {
        $regOptions['register_vars']['is_activated'] = 5;
        // !!! This should be changed.  To what should be it be changed??
        $regOptions['register_vars']['validation_code'] = '';
    } elseif ($regOptions['require'] == 'nothing') {
        $regOptions['register_vars']['is_activated'] = 1;
    } elseif ($regOptions['require'] == 'activation') {
        $regOptions['register_vars']['is_activated'] = 0;
    } else {
        $regOptions['register_vars']['is_activated'] = 3;
    }
    if (isset($regOptions['memberGroup'])) {
        // Make sure the id_group will be valid, if this is an administator.
        $regOptions['register_vars']['id_group'] = $regOptions['memberGroup'] == 1 && !allowedTo('admin_forum') ? 0 : $regOptions['memberGroup'];
        // Check if this group is assignable.
        $unassignableGroups = array(-1, 3);
        $request = smf_db_query('
			SELECT id_group
			FROM {db_prefix}membergroups
			WHERE min_posts != {int:min_posts}' . (allowedTo('admin_forum') ? '' : '
				OR group_type = {int:is_protected}'), array('min_posts' => -1, 'is_protected' => 1));
        while ($row = mysql_fetch_assoc($request)) {
            $unassignableGroups[] = $row['id_group'];
        }
        mysql_free_result($request);
        if (in_array($regOptions['register_vars']['id_group'], $unassignableGroups)) {
            $regOptions['register_vars']['id_group'] = 0;
        }
    }
    // Integrate optional member settings to be set.
    if (!empty($regOptions['extra_register_vars'])) {
        foreach ($regOptions['extra_register_vars'] as $var => $value) {
            $regOptions['register_vars'][$var] = $value;
        }
    }
    // Integrate optional user theme options to be set.
    $theme_vars = array();
    if (!empty($regOptions['theme_vars'])) {
        foreach ($regOptions['theme_vars'] as $var => $value) {
            $theme_vars[$var] = $value;
        }
    }
    // Call an optional function to validate the users' input.
    HookAPI::callHook('integrate_register', array(&$regOptions, &$theme_vars));
    // Right, now let's prepare for insertion.
    $knownInts = array('date_registered', 'posts', 'id_group', 'last_login', 'instant_messages', 'unread_messages', 'new_pm', 'pm_prefs', 'gender', 'hide_email', 'show_online', 'pm_email_notify', 'karma_good', 'karma_bad', 'notify_announcements', 'notify_send_body', 'notify_regularity', 'notify_types', 'id_theme', 'is_activated', 'id_msg_last_visit', 'id_post_group', 'total_time_logged_in', 'warning');
    $knownFloats = array('time_offset');
    $column_names = array();
    $values = array();
    foreach ($regOptions['register_vars'] as $var => $val) {
        $type = 'string';
        if (in_array($var, $knownInts)) {
            $type = 'int';
        } elseif (in_array($var, $knownFloats)) {
            $type = 'float';
        } elseif ($var == 'birthdate') {
            $type = 'date';
        }
        $column_names[$var] = $type;
        $values[$var] = $val;
    }
    // Register them into the database.
    smf_db_insert('', '{db_prefix}members', $column_names, $values, array('id_member'));
    $memberID = smf_db_insert_id('{db_prefix}members', 'id_member');
    // Update the number of members and latest member's info - and pass the name, but remove the 's.
    if ($regOptions['register_vars']['is_activated'] == 1) {
        updateStats('member', $memberID, $regOptions['register_vars']['real_name']);
    } else {
        updateStats('member');
    }
    // Theme variables too?
    if (!empty($theme_vars)) {
        $inserts = array();
        foreach ($theme_vars as $var => $val) {
            $inserts[] = array($memberID, $var, $val);
        }
        smf_db_insert('insert', '{db_prefix}themes', array('id_member' => 'int', 'variable' => 'string-255', 'value' => 'string-65534'), $inserts, array('id_member', 'variable'));
    }
    // If it's enabled, increase the registrations for today.
    trackStats(array('registers' => '+'));
    // Administrative registrations are a bit different...
    if ($regOptions['interface'] == 'admin') {
        if ($regOptions['require'] == 'activation') {
            $email_message = 'admin_register_activate';
        } elseif (!empty($regOptions['send_welcome_email'])) {
            $email_message = 'admin_register_immediate';
        }
        if (isset($email_message)) {
            $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code);
            $emaildata = loadEmailTemplate($email_message, $replacements);
            sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
        }
        // All admins are finished here.
        return $memberID;
    }
    // Can post straight away - welcome them to your fantastic community...
    if ($regOptions['require'] == 'nothing') {
        if (!empty($regOptions['send_welcome_email'])) {
            $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
            $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'immediate', $replacements);
            sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
        }
        // Send admin their notification.
        adminNotify('standard', $memberID, $regOptions['username']);
    } elseif ($regOptions['require'] == 'activation' || $regOptions['require'] == 'coppa') {
        $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
        if ($regOptions['require'] == 'activation') {
            $replacements += array('ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code);
        } else {
            $replacements += array('COPPALINK' => $scripturl . '?action=coppa;u=' . $memberID);
        }
        $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . ($regOptions['require'] == 'activation' ? 'activate' : 'coppa'), $replacements);
        sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
    } else {
        $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
        $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'pending', $replacements);
        sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
        // Admin gets informed here...
        adminNotify('approval', $memberID, $regOptions['username']);
    }
    // Okay, they're for sure registered... make sure the session is aware of this for security. (Just married :P!)
    $_SESSION['just_registered'] = 1;
    return $memberID;
}
Example #21
0
function TaggingSystem_Submit()
{
    global $txt, $modSettings, $smcFunc, $user_info;
    $isajax = $_REQUEST['action'] == 'xmlhttp' ? true : false;
    if (!$isajax) {
        isAllowedTo('smftags_add');
    } else {
        if (!allowedTo('smftags_add')) {
            TagErrorMsg($txt['cannot_smftags_add']);
        }
    }
    $topic = (int) $_REQUEST['topic'];
    if (empty($topic)) {
        TagErrorMsg($txt['smftags_err_notopic']);
    }
    $edit = allowedTo('smftags_manage');
    $result = smf_db_query('
		SELECT t.id_member_started FROM {db_prefix}topics AS t
		WHERE t.id_topic = {int:topic}', array('topic' => $topic));
    $row = mysql_fetch_assoc($result);
    mysql_free_result($result);
    if ($user_info['id'] != $row['id_member_started'] && $edit == false) {
        TagErrorMsg($txt['smftags_err_permaddtags']);
    }
    $result = smf_db_query('
		SELECT COUNT(*) as total FROM {db_prefix}tags_log WHERE ID_TOPIC = {int:topic}', array('topic' => $topic));
    $row = mysql_fetch_assoc($result);
    $totaltags = $row['total'];
    mysql_free_result($result);
    if ($totaltags >= $modSettings['smftags_set_maxtags']) {
        TagErrorMsg($txt['smftags_err_toomaxtag']);
    }
    // Check Tag restrictions
    $tag = htmlspecialchars(trim($_REQUEST['tag']), ENT_QUOTES);
    $tag = strtolower($tag);
    if (empty($tag)) {
        TagErrorMsg($txt['smftags_err_notag']);
    }
    $tags = explode(',', htmlspecialchars($tag, ENT_QUOTES));
    foreach ($tags as $tag) {
        $tag = trim($tag);
        if (strlen($tag) < $modSettings['smftags_set_mintaglength']) {
            continue;
        }
        if (strlen($tag) > $modSettings['smftags_set_maxtaglength']) {
            continue;
        }
        $dbresult = smf_db_query('SELECT id_tag FROM {db_prefix}tags 
			WHERE tag = {string:tag} LIMIT 1', array('tag' => $tag));
        if (smf_db_affected_rows() == 0) {
            smf_db_query('INSERT INTO {db_prefix}tags
				(tag, approved)	VALUES ({string:tag},1)', array('tag' => $tag));
            $ID_TAG = smf_db_insert_id("{db_prefix}tags", 'id_tag');
            smf_db_query('INSERT INTO {db_prefix}tags_log (id_tag, id_topic, id_member)
			VALUES ({int:id_tag}, {int:topic}, {int:id_user})', array('id_tag' => $ID_TAG, 'topic' => $topic, 'id_user' => $user_info['id']));
        } else {
            $row = mysql_fetch_assoc($dbresult);
            $ID_TAG = $row['id_tag'];
            $dbresult2 = smf_db_query('SELECT id	FROM {db_prefix}tags_log WHERE id_tag = {int:id_tag}
			 	AND id_topic = {int:topic}', array('id_tag' => $ID_TAG, 'topic' => $topic));
            if (smf_db_affected_rows() != 0) {
                continue;
            }
            mysql_free_result($dbresult2);
            smf_db_query('INSERT INTO {db_prefix}tags_log (id_tag, id_topic, id_member)
			VALUES ({int:id_tag}, {int:id_topic}, {int:id_user})', array('id_tag' => $ID_TAG, 'id_topic' => $topic, 'id_user' => $user_info['id']));
        }
        mysql_free_result($dbresult);
    }
    if ($isajax) {
        $output = RegenerateTagList($topic);
        echo $output;
        die;
    }
    redirectexit('topic=' . $topic);
}
Example #22
0
function AdminAccount()
{
    global $txt, $db_type, $db_connection, $incontext, $db_prefix, $db_passwd, $sourcedir;
    $incontext['sub_template'] = 'admin_account';
    $incontext['page_title'] = $txt['user_settings'];
    $incontext['continue'] = 1;
    // Skipping?
    if (!empty($_POST['skip'])) {
        return true;
    }
    // Need this to check whether we need the database password.
    require dirname(__FILE__) . '/Settings.php';
    load_database();
    if (!isset($_POST['username'])) {
        $_POST['username'] = '';
    }
    if (!isset($_POST['email'])) {
        $_POST['email'] = '';
    }
    $incontext['username'] = htmlspecialchars(stripslashes($_POST['username']));
    $incontext['email'] = htmlspecialchars(stripslashes($_POST['email']));
    $incontext['require_db_confirm'] = empty($db_type) || $db_type != 'sqlite';
    // Only allow skipping if we think they already have an account setup.
    $request = smf_db_query('
		SELECT id_member
		FROM {db_prefix}members
		WHERE id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0
		LIMIT 1', array('db_error_skip' => true, 'admin_group' => 1));
    if (mysql_num_rows($request) != 0) {
        $incontext['skip'] = 1;
    }
    mysql_free_result($request);
    // Trying to create an account?
    if (isset($_POST['password1']) && !empty($_POST['contbutt'])) {
        // Wrong password?
        if ($incontext['require_db_confirm'] && $_POST['password3'] != $db_passwd) {
            $incontext['error'] = $txt['error_db_connect'];
            return false;
        }
        // Not matching passwords?
        if ($_POST['password1'] != $_POST['password2']) {
            $incontext['error'] = $txt['error_user_settings_again_match'];
            return false;
        }
        // No password?
        if (strlen($_POST['password1']) < 4) {
            $incontext['error'] = $txt['error_user_settings_no_password'];
            return false;
        }
        if (!file_exists($sourcedir . '/lib/Subs.php')) {
            $incontext['error'] = $txt['error_subs_missing'];
            return false;
        }
        // Update the main contact email?
        if (!empty($_POST['email']) && (empty($webmaster_email) || $webmaster_email == '*****@*****.**')) {
            updateSettingsFile(array('webmaster_email' => $_POST['email']));
        }
        // Work out whether we're going to have dodgy characters and remove them.
        $invalid_characters = preg_match('~[<>&"\'=\\\\]~', $_POST['username']) != 0;
        $_POST['username'] = preg_replace('~[<>&"\'=\\\\]~', '', $_POST['username']);
        $result = smf_db_query('
			SELECT id_member, password_salt
			FROM {db_prefix}members
			WHERE member_name = {string:username} OR email_address = {string:email}
			LIMIT 1', array('username' => stripslashes($_POST['username']), 'email' => stripslashes($_POST['email']), 'db_error_skip' => true));
        if (mysql_num_rows($result) != 0) {
            list($incontext['member_id'], $incontext['member_salt']) = mysql_fetch_row($result);
            mysql_free_result($result);
            $incontext['account_existed'] = $txt['error_user_settings_taken'];
        } elseif ($_POST['username'] == '' || strlen($_POST['username']) > 25) {
            // Try the previous step again.
            $incontext['error'] = $_POST['username'] == '' ? $txt['error_username_left_empty'] : $txt['error_username_too_long'];
            return false;
        } elseif ($invalid_characters || $_POST['username'] == '_' || $_POST['username'] == '|' || strpos($_POST['username'], '[code') !== false || strpos($_POST['username'], '[/code') !== false) {
            // Try the previous step again.
            $incontext['error'] = $txt['error_invalid_characters_username'];
            return false;
        } elseif (empty($_POST['email']) || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($_POST['email'])) === 0 || strlen(stripslashes($_POST['email'])) > 255) {
            // One step back, this time fill out a proper email address.
            $incontext['error'] = sprintf($txt['error_valid_email_needed'], $_POST['username']);
            return false;
        } elseif ($_POST['username'] != '') {
            $incontext['member_salt'] = substr(md5(mt_rand()), 0, 4);
            // Format the username properly.
            $_POST['username'] = preg_replace('~[\\t\\n\\r\\x0B\\0\\xA0]+~', ' ', $_POST['username']);
            $ip = isset($_SERVER['REMOTE_ADDR']) ? substr($_SERVER['REMOTE_ADDR'], 0, 255) : '';
            $request = smf_db_insert('insert', $db_prefix . 'members', array('member_name' => 'string-25', 'real_name' => 'string-25', 'passwd' => 'string', 'email_address' => 'string', 'id_group' => 'int', 'posts' => 'int', 'date_registered' => 'int', 'hide_email' => 'int', 'password_salt' => 'string', 'lngfile' => 'string', 'personal_text' => 'string', 'avatar' => 'string', 'member_ip' => 'string', 'member_ip2' => 'string', 'buddy_list' => 'string', 'pm_ignore_list' => 'string', 'message_labels' => 'string', 'location' => 'string', 'signature' => 'string', 'usertitle' => 'string', 'secret_question' => 'string', 'additional_groups' => 'string', 'ignore_boards' => 'string', 'openid_uri' => 'string'), array(stripslashes($_POST['username']), stripslashes($_POST['username']), sha1(strtolower(stripslashes($_POST['username'])) . stripslashes($_POST['password1'])), stripslashes($_POST['email']), 1, 0, time(), 0, $incontext['member_salt'], '', '', '', $ip, $ip, '', '', '', '', '', '', '', '', '', ''), array('id_member'));
            // Awww, crud!
            if ($request === false) {
                $incontext['error'] = $txt['error_user_settings_query'] . '<br />
				<div style="margin: 2ex;">' . nl2br(htmlspecialchars(mysql_error($db_connection))) . '</div>';
                return false;
            }
            $incontext['member_id'] = smf_db_insert_id("{$db_prefix}members", 'id_member');
        }
        // If we're here we're good.
        return true;
    }
    return false;
}
Example #23
0
function downloadAvatar($url, $memID, $max_width, $max_height)
{
    global $modSettings, $sourcedir, $backend_subdir;
    $ext = !empty($modSettings['avatar_download_png']) ? 'png' : 'jpeg';
    $destName = 'avatar_' . $memID . '_' . time() . '.' . $ext;
    // Just making sure there is a non-zero member.
    if (empty($memID)) {
        return false;
    }
    require_once $sourcedir . '/lib/Subs-ManageAttachments.php';
    removeAttachments(array('id_member' => $memID));
    $id_folder = !empty($modSettings['currentAttachmentUploadDir']) ? $modSettings['currentAttachmentUploadDir'] : 1;
    $avatar_hash = empty($modSettings['custom_avatar_enabled']) ? getAttachmentFilename($destName, false, null, true) : '';
    smf_db_insert('', '{db_prefix}attachments', array('id_member' => 'int', 'attachment_type' => 'int', 'filename' => 'string-255', 'file_hash' => 'string-255', 'fileext' => 'string-8', 'size' => 'int', 'id_folder' => 'int'), array($memID, empty($modSettings['custom_avatar_enabled']) ? 0 : 1, $destName, $avatar_hash, $ext, 1, $id_folder), array('id_attach'));
    $attachID = smf_db_insert_id('{db_prefix}attachments', 'id_attach');
    // Retain this globally in case the script wants it.
    $modSettings['new_avatar_data'] = array('id' => $attachID, 'filename' => $destName, 'type' => empty($modSettings['custom_avatar_enabled']) ? 0 : 1);
    $destName = (empty($modSettings['custom_avatar_enabled']) ? is_array($modSettings['attachmentUploadDir']) ? $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']] : $modSettings['attachmentUploadDir'] : $modSettings['custom_avatar_dir']) . '/' . $destName . '.tmp';
    // Resize it.
    if (!empty($modSettings['avatar_download_png'])) {
        $success = resizeImageFile($url, $destName, $max_width, $max_height, 3);
    } else {
        $success = resizeImageFile($url, $destName, $max_width, $max_height);
    }
    // Remove the .tmp extension.
    $destName = substr($destName, 0, -4);
    if ($success) {
        // Walk the right path.
        if (!empty($modSettings['currentAttachmentUploadDir'])) {
            if (!is_array($modSettings['attachmentUploadDir'])) {
                $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
            }
            $path = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
        } else {
            $path = $modSettings['attachmentUploadDir'];
        }
        // Remove the .tmp extension from the attachment.
        if (rename($destName . '.tmp', empty($avatar_hash) ? $destName : $path . '/' . $attachID . '_' . $avatar_hash)) {
            $destName = empty($avatar_hash) ? $destName : $path . '/' . $attachID . '_' . $avatar_hash;
            list($width, $height) = getimagesize($destName);
            $mime_type = 'image/' . $ext;
            // Write filesize in the database.
            smf_db_query('
				UPDATE {db_prefix}attachments
				SET size = {int:filesize}, width = {int:width}, height = {int:height},
					mime_type = {string:mime_type}
				WHERE id_attach = {int:current_attachment}', array('filesize' => filesize($destName), 'width' => (int) $width, 'height' => (int) $height, 'current_attachment' => $attachID, 'mime_type' => $mime_type));
            return true;
        } else {
            return false;
        }
    } else {
        smf_db_query('
			DELETE FROM {db_prefix}attachments
			WHERE id_attach = {int:current_attachment}', array('current_attachment' => $attachID));
        @unlink($destName . '.tmp');
        return false;
    }
}