function SubmitPost() { global $CFG, $dbConn, $aPostIcons, $iThreadID, $iForumID; // Get the values from the user. $strSubject = $_REQUEST['subject']; $iPostIcon = (int) $_REQUEST['icon']; $strMessage = $_REQUEST['message']; $bParseEMails = (int) (bool) $_REQUEST['parseemails']; $bDisableSmilies = (int) (bool) $_REQUEST['dsmilies']; // Floodcheck if (!$_SESSION['permissions']['cbypassflood'] && $_SESSION['lastpost'] + $CFG['floodcheck'] > $CFG['globaltime']) { Msg("Sorry! The administrator has specified that users can only post one message every {$CFG['floodcheck']} seconds.", '', 'justify'); } // Subject if (strlen($strSubject) > $CFG['maxlen']['subject']) { // The subject they specified is too long. $aError[] = "The subject you specified is longer than {$CFG['maxlen']['subject']} characters."; } $strCleanSubject = $dbConn->sanitize($strSubject); // Icon if ($iPostIcon < 0 || $iPostIcon > count($aPostIcons) - 1) { // They don't know what icon they want. We'll give them none. $iPostIcon = 0; } // Message if (trim($strMessage) == '') { // They either put in only whitespace or nothing at all. $aError[] = 'You must specify a message.'; } else { if (strlen($strMessage) > $CFG['maxlen']['messagebody']) { // The message they specified is too long. $aError[] = "The message you specified is longer than {$CFG['maxlen']['messagebody']} characters."; } } if ($bParseEMails) { $strMessage = ParseEMails($strMessage); } $strCleanMessage = $dbConn->sanitize($strMessage); // Attachment if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] != UPLOAD_ERR_NO_FILE) { // What is the problem? switch ($_FILES['attachment']['error']) { // Upload was successful? case UPLOAD_ERR_OK: // Is it bigger than 100KB? if ($_FILES['attachment']['size'] > $CFG['uploads']['maxsize']) { $aError[] = "The attachment you uploaded is too large. The maximum allowable filesize is {$CFG['uploads']['maxsize']} bytes."; } // Is it an invalid filetype? if (!isset($CFG['uploads']['oktypes'][strtolower(substr(strrchr($_FILES['attachment']['name'], '.'), 1))])) { $aError[] = 'The file you uploaded is an invalid type of attachment. Valid types are: ' . htmlsanitize(implode(', ', array_keys($CFG['uploads']['oktypes']))) . '.'; } // If there are no errors, grab the data from the temporary file. if (!is_array($aError)) { $strAttachmentName = $dbConn->sanitize($_FILES['attachment']['name']); if ($fileUploaded = fopen($_FILES['attachment']['tmp_name'], 'rb')) { $blobAttachment = $dbConn->sanitize(fread($fileUploaded, 65536), TRUE); } else { $aError[] = 'There was a problem while reading the attachment. If this problem persists, please contact the Webmaster.'; } } break; // File is too big? // File is too big? case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $aError[] = "The attachment you uploaded is too large. The maximum allowable filesize is {$CFG['uploads']['maxsize']} bytes."; break; // File was partially uploaded? // File was partially uploaded? case UPLOAD_ERR_PARTIAL: $aError[] = 'The attachment was only partially uploaded.'; break; // WTF happened? // WTF happened? default: $aError[] = 'There was an error while uploading the attachment.'; break; } } // If there was an error, let's return it. if (is_array($aError)) { return $aError; } // First we obviously need the post in the post table. $dbConn->query("INSERT INTO post(author, datetime_posted, title, body, parent, ipaddress, icon, dsmilies) VALUES({$_SESSION['userid']}, {$CFG['globaltime']}, '{$strCleanSubject}', '{$strCleanMessage}', {$iThreadID}, {$_SESSION['userip']}, {$iPostIcon}, {$bDisableSmilies})"); // Before we continue, get the ID of the post we just created. $iPostID = $dbConn->getinsertid('post'); // Second, we need to update record of the thread we are posting to. $dbConn->query("UPDATE thread SET lpost={$CFG['globaltime']}, lposter={$_SESSION['userid']}, postcount=postcount+1 WHERE id={$iThreadID}"); // Get the post count of the thread we replied to, so we can figure the last page. $dbConn->query("SELECT postcount FROM thread WHERE id={$iThreadID}"); list($iPostCount) = $dbConn->getresult(); // Third, we need to update the record of the forum that contains the thread we are posting to. $dbConn->query("UPDATE board SET postcount=postcount+1, lpost={$CFG['globaltime']}, lposter={$_SESSION['userid']}, lthread={$iThreadID}, lthreadpcount={$iPostCount} WHERE id={$iForumID}"); // Fourth, we need to update the poster's postcount. $dbConn->query("UPDATE citizen SET postcount=postcount+1 WHERE id={$_SESSION['userid']}"); // And finally, we need to store the attachment, if there is one. if ($fileUploaded) { // Insert the first chunk of the file. $dbConn->query("INSERT INTO attachment(filename, filedata, viewcount, parent) VALUES('{$strAttachmentName}', '{$blobAttachment}', 0, {$iPostID})"); // Get the ID of the attachment we just created. $iAttachmentID = $dbConn->getinsertid('attachment'); // Insert the rest of the file, if any, into the database. while (!feof($fileUploaded)) { $blobAttachment = $dbConn->sanitize(fread($fileUploaded, 65536), TRUE); $dbConn->squery(CONCAT_ATTACHMENT, $blobAttachment, $iAttachmentID); } // Close the temporary file. fclose($fileUploaded); // Update the attachment count for the thread. $dbConn->query("UPDATE thread SET attachcount=attachcount+1 WHERE id={$iThreadID}"); } // Now let's add the message into the search engine index. AddSearchIndex($iPostID, $strSubject, $strMessage); // Update the forum stats. $dbConn->query("UPDATE stats SET content=content+1 WHERE name='postcount'"); // Set user's last post time. $_SESSION['lastpost'] = $CFG['globaltime']; // What page is this new post on (so we can redirect them)? $iPage = ceil($iPostCount / $_SESSION['postsperpage']); // Render the page. Msg("<b>Thank you for posting.</b><br /><br /><span class=\"smaller\">You should be redirected to your post momentarily. Click <a href=\"thread.php?threadid={$iThreadID}&page={$iPage}#post{$iPostID}\">here</a> if you do not want to wait any longer or if you are not redirected.</span>", "thread.php?threadid={$iThreadID}&page={$iPage}#post{$iPostID}"); }
function SavePost($aPostInfo) { global $CFG, $dbConn, $iRootID, $aAttachments, $aPostIcons; $iPostID = $aPostInfo['id']; $iThreadID = $aPostInfo['parent']; // Initiate some variables. $aToDelete = array(); $iAddedAttachments = 0; $iRemovedAttachments = 0; // Grab the info. specified by the user. $strSubject = $_REQUEST['subject']; $strThreadDesc = $_REQUEST['description']; $iPostIcon = (int) $_REQUEST['icon']; $strBody = $_REQUEST['message']; $bParseURLs = (bool) $_REQUEST['parseurls']; $bParseEMails = (bool) $_REQUEST['parseemails']; $bDisableSmilies = (int) (bool) $_REQUEST['dsmilies']; $aDeleteAttachments = $_REQUEST['deleteattach']; // Subject if (trim($strSubject) == '' && $iPostID == $iRootID) { // This post is the thread root, and they either put in only whitespace or nothing at all. $aError[] = 'You must specify a subject.'; } else { if (strlen($strSubject) > $CFG['maxlen']['subject']) { // The subject they specified is too long. $aError[] = "The subject you specified is longer than {$CFG['maxlen']['subject']} characters."; } } $strCleanSubject = $dbConn->sanitize($strSubject); // Description if (strlen($strThreadDesc) > $CFG['maxlen']['desc']) { // The description they specified is too long. $aError[] = "The description you specified is longer than {$CFG['maxlen']['desc']} characters."; } $strThreadDesc = $dbConn->sanitize($strThreadDesc); // Icon if ($iPostIcon < 0 || $iPostIcon > count($aPostIcons) - 1) { // They don't know what icon they want. We'll give them none. $iPostIcon = 0; } // Body if (trim($strBody) == '') { // They either put in only whitespace or nothing at all. $aError[] = 'You must specify a message.'; } else { if (strlen($strBody) > $CFG['maxlen']['messagebody']) { // The body they specified is too long. $aError[] = "The message you specified is longer than {$CFG['maxlen']['messagebody']} characters."; } } $strCleanBody = $dbConn->sanitize($strBody); // Attachment if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] != UPLOAD_ERR_NO_FILE) { // What is the problem? switch ($_FILES['attachment']['error']) { // Upload was successful? case UPLOAD_ERR_OK: // Is it bigger than the allowable maximum? if ($_FILES['attachment']['size'] > $CFG['uploads']['maxsize']) { $aError[] = "The attachment you uploaded is too large. The maximum allowable filesize is {$CFG['uploads']['maxsize']} bytes."; } // Is it an invalid filetype? if (!isset($CFG['uploads']['oktypes'][strtolower(substr(strrchr($_FILES['attachment']['name'], '.'), 1))])) { $aError[] = 'The file you uploaded is an invalid type of attachment. Valid types are: ' . htmlsanitize(implode(', ', array_keys($CFG['uploads']['oktypes']))) . '.'; } // If there are no errors, grab the data from the temporary file. if (!is_array($aError)) { $strAttachmentName = $dbConn->sanitize($_FILES['attachment']['name']); if ($fileUploaded = fopen($_FILES['attachment']['tmp_name'], 'rb')) { $blobAttachment = $dbConn->sanitize(fread($fileUploaded, 65536), TRUE); } else { $aError[] = 'There was a problem while reading the attachment. If this problem persists, please contact the Webmaster.'; } } break; // File is too big? // File is too big? case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $aError[] = "The attachment you uploaded is too large. The maximum allowable filesize is {$CFG['uploads']['maxsize']} bytes."; break; // File was partially uploaded? // File was partially uploaded? case UPLOAD_ERR_PARTIAL: $aError[] = 'The attachment was only partially uploaded.'; break; // WTF happened? // WTF happened? default: $aError[] = 'There was an error while uploading the attachment.'; break; } } // If there was an error, let's return it. if ($aError) { return $aError; } // Update the post's record. $dbConn->query("UPDATE post SET datetime_edited={$CFG['globaltime']}, title='{$strCleanSubject}', body='{$strCleanBody}', icon={$iPostIcon}, dsmilies={$bDisableSmilies} WHERE id={$iPostID}"); // Was this post the thread root? if ($iPostID == $iRootID) { // Yes, update the thread description. $dbConn->query("UPDATE thread SET title='{$strCleanSubject}', icon={$iPostIcon}, description='{$strThreadDesc}' WHERE id={$iThreadID}"); } // Store the attachment, if there is one. if ($fileUploaded) { // Insert the first chunk of the file. $dbConn->query("INSERT INTO attachment(filename, filedata, viewcount, parent) VALUES('{$strAttachmentName}', '{$blobAttachment}', 0, {$iPostID})"); // Get the ID of the attachment we just created. $iAttachmentID = $dbConn->getinsertid('attachment'); // Insert the rest of the file, if any, into the database. while (!feof($fileUploaded)) { $blobAttachment = $dbConn->sanitize(fread($fileUploaded, 65536), TRUE); $dbConn->squery(CONCAT_ATTACHMENT, $blobAttachment, $iAttachmentID); } // Close the temporary file. fclose($fileUploaded); // Increment the added attachment count. $iAddedAttachments++; } // Are there any attachments to delete? if (is_array($aDeleteAttachments) && is_array($aAttachments)) { // Yes, so remove the ones that don't belong to this post. foreach ($aDeleteAttachments as $iAttachmentID => $null) { // Is the attachment in this post? if (array_key_exists($iAttachmentID, $aAttachments) && !array_search($iAttachmentID, $aToDelete)) { // Yes, so add the attachment to the list to delete. $aToDelete[] = $iAttachmentID; } } // Are there still attachments to delete? if (is_array($aToDelete)) { // Yes, so delete them. $strToDelete = implode(', ', $aToDelete); $dbConn->query("DELETE FROM attachment WHERE id IN ({$strToDelete})"); // Set the removed attachments counter. $iRemovedAttachments = count($aToDelete); } } // Are there any changes to the number of attachments in this post (and therefore the parent thread)? $iAttachmentCount = $iAddedAttachments - $iRemovedAttachments; if ($iAttachmentCount != 0) { // Yes, so update the thread's record. $dbConn->query("UPDATE thread SET attachcount=attachcount+({$iAttachmentCount}) WHERE id={$iThreadID}"); } // Remove all searchindexes for this post. $dbConn->query("DELETE FROM searchindex WHERE postid={$iPostID}"); // Now let's re-add the message into the search engine index. AddSearchIndex($iPostID, $strSubject, $strBody); // Update the user. Msg("<b>Your changes have been successfully saved.</b><br /><br /><span class=\"smaller\">You should be redirected to your post momentarily. Click <a href=\"thread.php?threadid={$iThreadID}&postid={$iPostID}#post{$iPostID}\">here</a> if you do not want to wait any longer or if you are not redirected.</span>", "thread.php?threadid={$iThreadID}&postid={$iPostID}#post{$iPostID}"); }
function CopyThreadNow($iThreadID) { global $CFG, $dbConn; // What forum do they want to copy it to? $iDestinationID = (int) $_REQUEST['forumid']; // Get the thread's information. $dbConn->query("SELECT * FROM thread WHERE thread.id={$iThreadID}"); if (!($aThreadInfo = $dbConn->getresult(TRUE))) { Msg("Invalid thread specified.{$CFG['msg']['invalidlink']}"); } // Make sure the destination isn't the same as the parent. if ($aThreadInfo['parent'] == $iDestinationID) { Msg("You cannot copy a thread to a forum it's already in."); } // Make sure the destination is valid (exists and isn't a category). $dbConn->query("SELECT displaydepth FROM board WHERE id={$iDestinationID}"); if (!(list($iLevel) = $dbConn->getresult())) { Msg('The destination forum you specified does not exist.'); } else { if ($iLevel == 0) { Msg('The destination forum you specified cannot contain posts. Please select a different forum.'); } } // Get a list of the posts in the thread. $dbConn->query("SELECT id, author FROM post WHERE parent={$iThreadID}"); while (list($iPostID, $iAuthorID) = $dbConn->getresult()) { // Save the post to the list. $aPosts[] = $iPostID; // Increment the author's postcount of this thread. $aPostCounts[$iAuthorID]++; } $strPosts = implode(', ', $aPosts); // Sanitize some thread fields. $aThreadInfo['title'] = $dbConn->sanitize($aThreadInfo['title']); $aThreadInfo['description'] = $dbConn->sanitize($aThreadInfo['description']); $aThreadInfo['notes'] = $dbConn->sanitize($aThreadInfo['notes']); $aThreadInfo['poll'] = (int) (bool) $aThreadInfo['poll']; // Copy the thread record (but keep it closed and invisible until we're done). $dbConn->query("INSERT INTO thread(title, description, parent, viewcount, postcount, attachcount, lpost, lposter, icon, author, notes, poll, closed, visible, sticky) VALUES('{$aThreadInfo['title']}', '{$aThreadInfo['description']}', {$iDestinationID}, {$aThreadInfo['viewcount']}, {$aThreadInfo['postcount']}, {$aThreadInfo['attachcount']}, {$aThreadInfo['lpost']}, {$aThreadInfo['lposter']}, {$aThreadInfo['icon']}, {$aThreadInfo['author']}, '{$aThreadInfo['notes']}', {$aThreadInfo['poll']}, 1, 0, {$aThreadInfo['sticky']})"); // What is the ID of the thread we just created? $iNewThreadID = $dbConn->getinsertid('thread'); // Get a list of the attachments in this thread. $dbConn->query("SELECT id, parent FROM attachment WHERE parent IN ({$strPosts})"); while (list($iAttachmentID, $iParentID) = $dbConn->getresult()) { $aAttachments[$iAttachmentID] = $iParentID; } // Copy all of the post records. $dbConn->query("SELECT * FROM post WHERE parent={$iThreadID}"); $aSQLAllResults = $dbConn->getall(TRUE); while (list($key, $aPostInfo) = each($aSQLAllResults)) { // Convert data types, if necessary. if ($aPostInfo['datetime_edited'] === NULL) { $aPostInfo['datetime_edited'] = 'NULL'; } if ($aPostInfo['ipaddress'] === NULL) { $aPostInfo['ipaddress'] = 'NULL'; } // Sanitize some post fields. $strTitle = $aPostInfo['title']; $strBody = $aPostInfo['body']; $aPostInfo['title'] = $dbConn->sanitize($aPostInfo['title']); $aPostInfo['body'] = $dbConn->sanitize($aPostInfo['body']); // Insert the copy of the post. $dbConn->query("INSERT INTO post(author, datetime_posted, datetime_edited, title, body, parent, ipaddress, icon, dsmilies) VALUES({$aPostInfo['author']}, {$aPostInfo['datetime_posted']}, {$aPostInfo['datetime_edited']}, '{$aPostInfo['title']}', '{$aPostInfo['body']}', {$iNewThreadID}, {$aPostInfo['ipaddress']}, {$aPostInfo['icon']}, {$aPostInfo['dsmilies']})"); // Get the ID of the post we just created. $iPostID = $dbConn->getinsertid('post'); // Now let's add the message into the search engine index. AddSearchIndex($iPostID, $strTitle, $strBody); // Store the attachments the post has (if any). if (is_array($aAttachments)) { // Did the original post contain any attachments? $temp = array_keys($aAttachments, $aPostInfo['id']); if (is_array($temp)) { // Yes, so save them. foreach ($temp as $iAttachmentID) { $aAttachments[$iAttachmentID] = $iPostID; } } } } // Copy all of the attachment records. if (is_array($aAttachments)) { $dbConn->query("SELECT * FROM attachment WHERE parent IN ({$strPosts})"); $aSQLAllResults = $dbConn->getall(TRUE); while (list($key, $aAttachmentInfo) = each($aSQLAllResults)) { // What is the new post ID that will be the parent of this new attachment? $iParentID = $aAttachments[$aAttachmentInfo['id']]; // Break the file data into an array of 64KB strings. $aData = sqlsplit($aAttachmentInfo['filedata'], 65536); // Sanitize the filename. $aAttachmentInfo['filename'] = $dbConn->sanitize($aAttachmentInfo['filename']); // Insert the duplicate attachment's record. $dbConn->query("INSERT INTO attachment(filename, filedata, viewcount, parent) VALUES('{$aAttachmentInfo['filename']}', '{$aData[0]}', {$aAttachmentInfo['viewcount']}, {$iParentID})"); $iAttachmentID = $dbConn->getinsertid('attachment'); unset($aData[0]); // Insert the rest of the attachment's data. foreach ($aData as $strData) { $dbConn->squery(CONCAT_ATTACHMENT, $strData, $iAttachmentID); } // Reset the data array for the next attachment. unset($aData); } } // Copy the poll, if there is one. if ($aThreadInfo['poll']) { CopyPoll($iThreadID, $iNewThreadID); } // Add to the users' postcounts the number of posts they had in the original thread. foreach ($aPostCounts as $iAuthorID => $iPostCount) { $dbConn->query("UPDATE citizen SET postcount=postcount+{$iPostCount} WHERE id={$iAuthorID}"); } // Give the new thread life. $dbConn->query("UPDATE thread SET closed={$aThreadInfo['closed']}, visible={$aThreadInfo['visible']} WHERE id={$iNewThreadID}"); // Get the total number of posts we've copied/added. $iPostCount = count($aPosts); // Update the destination forum's post and thread counts. $dbConn->query("UPDATE board SET postcount=postcount+{$iPostCount}, threadcount=threadcount+1 WHERE id={$iDestinationID}"); // Update the forum stats. $dbConn->query("UPDATE stats SET content=content+{$iPostCount} WHERE name='postcount'"); $dbConn->query("UPDATE stats SET content=content+1 WHERE name='threadcount'"); // Update the destination forum's stats. UpdateForumStats($iDestinationID); // Render page. Msg("<b>The thread has been copied successfully.</b><br /><br /><span class=\"smaller\">You should be redirected momentarily. Click <a href=\"thread.php?threadid={$iNewThreadID}\">here</a> if you do not want to wait any longer or if you are not redirected.</span>", "thread.php?threadid={$iNewThreadID}"); }