/** * 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'); }
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; }
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('~&#(\\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; }
/** * 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; }
/** * 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'; }
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']); }
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; }
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']); }
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())); }
/** * 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('~&#(\\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 />', ' '), $_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('~&#(\\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'); }
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; }
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'); }
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; } }
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'); }
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('~&#(\\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'); } }
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'])); } }
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; }
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; }
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('&' => '&')); $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; }
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; }
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); }
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; }
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; } }