function CopyTopics($original_topic_id, $board_id, $count_posts) { global $txt, $scripturl, $sourcedir, $modSettings, $context, $user_info, $smcFunc; // Try to buy some time... @set_time_limit(0); // Check Topic Exists and get some info for now and later $request = $smcFunc['db_query']('', ' SELECT id_board, id_poll, num_replies FROM {db_prefix}topics WHERE id_topic = {int:original_topic_id} LIMIT 1', array('original_topic_id' => $original_topic_id)); if ($smcFunc['db_num_rows']($request) == 0) { fatal_lang_error('no_topic_id'); } list($original_board_id, $original_poll_id, $num_posts) = $smcFunc['db_fetch_row']($request); // Its topic so it has 1 more reply that it states $num_posts++; $smcFunc['db_free_result']($request); // --- Copy Topic Entry --- // Query to Copy the Topic // The Columns for the table with our new topic and board ids. // id_topic is not listed because it is Auto-Incremented // id_board is set to our destination board // id_first_msg and id_last_msg are set to 0 for now(to prevent key errors if copying into same forum) $smcFunc['db_query']('', ' INSERT INTO {db_prefix}topics (id_board, id_first_msg, id_last_msg, id_member_started, id_member_updated, is_sticky, id_poll, num_replies, num_views, locked) SELECT {int:board_id}, 0, 0, id_member_started, id_member_updated, is_sticky, id_poll, num_replies, num_views, locked FROM {db_prefix}topics WHERE id_topic = {int:original_topic_id} LIMIT 1', array('original_topic_id' => $original_topic_id, 'board_id' => $board_id)); $topic_id = $smcFunc['db_insert_id']('{db_prefix}topics', 'id_topic'); // --- Copy Messages Entries --- // Query to Copy EVERY post in the topic (Potentially could be a beast of a query) // The Columns for the table with our new topic and board ids. // id_msg is not listed because it is Auto-Incremented // id_msg_modified is made to the old msg id temporarily. $smcFunc['db_query']('', ' INSERT INTO {db_prefix}messages (id_topic, id_board, id_msg_modified, id_member, poster_time, subject, poster_name, poster_email, poster_ip, modified_name, body, icon, approved) SELECT {int:topic_id}, {int:board_id}, id_msg, id_member, poster_time, subject, poster_name, poster_email, poster_ip, modified_name, body, icon, approved FROM {db_prefix}messages WHERE id_topic = {int:original_topic_id} ORDER BY id_msg ASC', array('original_topic_id' => $original_topic_id, 'topic_id' => $topic_id, 'board_id' => $board_id)); // --- Log Search Subject Cache (for searching) --- // Standard // Query to Copy EVERY matching row // The Columns for the table with our new topic id instead $smcFunc['db_query']('', ' INSERT INTO {db_prefix}log_search_subjects (word, id_topic) SELECT word, {int:topic_id} FROM {db_prefix}log_search_subjects WHERE id_topic = {int:original_topic_id}', array('original_topic_id' => $original_topic_id, 'topic_id' => $topic_id)); // Custom Search Index? if (!empty($modSettings['search_custom_index_config'])) { // Query to Copy EVERY matching row // The Columns for the table with our new msg id instead $smcFunc['db_query']('', ' INSERT INTO {db_prefix}log_search_words (id_word, id_msg) SELECT w.id_word, m.id_msg FROM {db_prefix}log_search_words as w LEFT JOIN {db_prefix}messages as m ON (w.id_msg = m.id_msg_modified) WHERE m.id_topic = {int:topic_id}', array('topic_id' => $topic_id)); } /* Disabled v1.2 - Causing duplicate key issues // --- Log_Search_Results --- // Query to Copy EVERY matching row // Include this new topic in existing search results // The Columns for the table with our new msg id and topic id instead $smcFunc['db_query']('', ' INSERT INTO {db_prefix}log_search_results (id_search, id_topic, id_msg, relevance, num_matches) SELECT r.id_search, {int:topic_id}, m.id_msg, r.relevance, r.num_matches FROM {db_prefix}log_search_results as r LEFT JOIN {db_prefix}messages as m ON (r.id_msg = m.id_msg_modified) WHERE m.id_topic = {int:topic_id}', array( 'topic_id' => $topic_id, ) ); */ // --- Copy Attachments --- // * Only those less than 1mb in size, larger files may crash your server // 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; } $doattachments = 1; // First make sure the attachment dir is writable. if (!is_writable($attach_dir)) { // Try to fix it. @chmod($attach_dir, 0777); // Guess that didn't work :/? if (!is_writable($attach_dir)) { $doattachments = 0; } } // Check how we are on directory filesize? if ($doattachments && !empty($modSettings['attachmentDirSizeLimit'])) { $doattachments = attachmentDirectorySizeCheck($attach_dir); } // Right try to go ahead with the attachments. if (!empty($doattachments)) { // id_attach is not listed because it is Auto-Incremented // Matching the id_msg_modified and switching it for the new id_msg // id_folder is new in 2.0 (for multiple attachment directory support), will be changed later once its been copied $smcFunc['db_query']('', ' INSERT INTO {db_prefix}attachments (fileext, mime_type, approved, id_folder, id_thumb, id_msg, id_member, attachment_type, filename, size, downloads, width, height) SELECT fileext, a.mime_type, a.approved, a.id_folder, a.id_attach, m.id_msg, a.id_member, a.attachment_type, a.filename, a.size, a.downloads, a.width, a.height FROM {db_prefix}attachments as a LEFT JOIN {db_prefix}messages as m ON (a.id_msg = m.id_msg_modified) WHERE m.id_topic = {int:topic_id} AND size < 1048600 ORDER BY id_attach ASC', array('topic_id' => $topic_id)); // Grab and store the new vs old attachment ids in a array (we temporarily stored the old ID in the id_thumb column) $request = $smcFunc['db_query']('', ' SELECT a.id_attach, a.id_thumb FROM {db_prefix}attachments as a LEFT JOIN {db_prefix}messages as m ON (a.id_msg = m.id_msg) WHERE m.id_topic = {int:topic_id} ORDER BY id_attach ASC', array('topic_id' => $topic_id)); // Did it copy any attachment entries in the db? if ($smcFunc['db_num_rows']($request) != 0) { $ids = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $ids[$row['id_attach']] = $row['id_thumb']; } // Tidy up $smcFunc['db_free_result']($request); unset($row); // Re-Associate Thumbs with our new attachment and thumb ids // Grab all the information about the attachments so we can re-associate them to the correct $request = $smcFunc['db_query']('', ' SELECT a.id_attach as attach_id, IFNULL(a3.id_attach, 0) as thumb_id FROM {db_prefix}attachments as a LEFT JOIN {db_prefix}messages as m ON (a.id_msg = m.id_msg) LEFT JOIN {db_prefix}attachments as a2 ON (a.id_thumb = a2.id_attach) LEFT JOIN {db_prefix}attachments as a3 ON (a2.id_thumb = a3.id_thumb AND m.id_msg = a3.id_msg) WHERE m.id_topic = {int:topic_id} AND a2.id_attach != 0 ', array('topic_id' => $topic_id)); $change = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $change[$row['attach_id']] = $row['thumb_id']; } foreach ($change as $a => $b) { $smcFunc['db_query']('', ' UPDATE {db_prefix}attachments SET id_thumb = {int:thumb_id} WHERE id_attach = {int:attach_id} AND id_attach != 0', array('attach_id' => $a, 'thumb_id' => (int) $b)); } unset($a, $b, $change, $row); // Grab all the information about the attachments (including thumbs) attached to this topic $request = $smcFunc['db_query']('', ' SELECT a.id_attach as file_id, a.filename as filename, a.size as filesize, a.id_thumb as thumb_id, a2.filename as thumbname, a2.size as thumbsize, a.id_folder as folder, a2.id_folder as thumbfolder FROM {db_prefix}attachments as a LEFT JOIN {db_prefix}messages as m ON (a.id_msg = m.id_msg) LEFT JOIN {db_prefix}attachments as a2 ON (a.id_thumb = a2.id_attach) WHERE m.id_topic = {int:topic_id} AND a.attachment_type != 3 ORDER BY a.id_attach ASC', array('topic_id' => $topic_id)); // Attachments found if ($smcFunc['db_num_rows']($request) != 0) { $attachments = array(); // For each attachment, we will try to copy the file while ($row = $smcFunc['db_fetch_assoc']($request)) { $row['original_id'] = $ids[$row['file_id']]; $row['original_thumb_id'] = empty($row['thumb_id']) ? 0 : $ids[$row['thumb_id']]; $attachments[] = $row; } // Tidy up $smcFunc['db_free_result']($request); unset($ids, $row); foreach ($attachments as $row) { // Is there enough space for the copied attachment + thumb if (empty($modSettings['attachmentDirSizeLimit']) || $doattachments + (int) $row['filesize'] + (int) $row['thumbsize'] < $modSettings['attachmentDirSizeLimit'] * 1024) { // Copy the attachment if ($filename = copyAttachment($row, $attach_dir)) { // Successly copied the attachment // Update the attachment db entry with the new filename (only if new filename was generated); $smcFunc['db_query']('', ' UPDATE {db_prefix}attachments SET filename = {string:filename}, id_folder = {int:id_folder} WHERE id_attach = {int:file_id} ', array('file_id' => $row['file_id'], 'filename' => $filename, 'id_folder' => $id_folder)); // Increase the size $doattachments = $doattachments + (int) $row['filesize'] + (int) $row['thumbsize']; // If theres a thumb, rename that aswell if (!empty($row['thumb_id'])) { $smcFunc['db_query']('', ' UPDATE {db_prefix}attachments SET filename = {string:thumbname}, id_folder = {int:id_folder} WHERE id_attach = {int:thumb_id} ', array('thumb_id' => $row['thumb_id'], 'thumbname' => $filename . '_thumb', 'id_folder' => $id_folder)); } } else { // Copying the attachment failed, so delete the db entries $smcFunc['db_query']('', ' DELETE FROM {db_prefix}attachments WHERE id_attach = {int:file_id} OR id_attach = {int:thumb_id} ', array('file_id' => $row['file_id'], 'thumb_id' => $row['thumb_id'])); } } else { // Ran out of space or error, so delete the db entries $smcFunc['db_query']('', ' DELETE FROM {db_prefix}attachments WHERE id_attach = {int:file_id} OR id_attach = {int:thumb_id} ', array('file_id' => $row['file_id'], 'thumb_id' => $row['thumb_id'])); } // Tidy up unset($row); } // Tidy up unset($attachments, $ids, $row); } } } // Fix Attachment Icon, if icon is set to clip and no attachments were copied. $request = $smcFunc['db_query']('', ' SELECT count(a.id_attach) as attachments, m.icon, m.id_msg FROM {db_prefix}messages as m LEFT JOIN {db_prefix}attachments as a ON (m.id_msg = a.id_msg) WHERE m.id_topic = {int:topic_id} GROUP BY a.id_attach ', array('topic_id' => $topic_id)); $fix = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($row['attachments'] == 0 && $row['icon'] == 'clip') { $fix[] = $row['id_msg']; } } if (!empty($fix)) { // So change it back to default $smcFunc['db_query']('', ' UPDATE {db_prefix}messages SET icon = {string:default_icon} WHERE id_topic = {int:topic_id} AND id_msg IN ({array_int:id_msgs}) AND icon = {string:clip} ', array('topic_id' => $topic_id, 'id_msgs' => $fix, 'default_icon' => 'xx', 'clip' => 'clip')); } // Tidy up unset($fix, $row); // --- Fix some stats and logs --- // Fix id_msg_modified to the New id_msg $smcFunc['db_query']('', ' UPDATE {db_prefix}messages SET id_msg_modified = id_msg WHERE id_topic = {int:topic_id}', array('topic_id' => $topic_id)); // Grab First & Last Message Id $request = $smcFunc['db_query']('', ' SELECT max(id_msg) as last, min(id_msg) as first FROM {db_prefix}messages WHERE id_topic = {int:topic_id}', array('topic_id' => $topic_id)); $row = $smcFunc['db_fetch_assoc']($request); // Update the topic info with that info $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET id_first_msg = {int:first}, id_last_msg = {int:last} WHERE id_topic = {int:topic_id}', array('topic_id' => $topic_id, 'first' => $row['first'], 'last' => $row['last'])); // Update log topics (for this user only) $smcFunc['db_query']('', ' REPLACE INTO {db_prefix}log_topics (id_topic, id_member, id_msg) VALUES ({int:topic_id}, {int:user_id}, {int:last}) ', array('topic_id' => $topic_id, 'last' => $row['last'], 'user_id' => $context['user']['id'])); // Update log boards (for this user only) $smcFunc['db_query']('', ' REPLACE INTO {db_prefix}log_boards (id_board, id_member, id_msg) VALUES ({int:board_id}, {int:user_id}, {int:last}) ', array('board_id' => $board_id, 'last' => $row['last'], 'user_id' => $context['user']['id'])); require_once $sourcedir . '/Subs-Post.php'; updateLastMessages($board_id, $row['last']); // --- Fix Post Counts --- // Posts in the board we're copying the topic to count, so we need to get the figures for each if ($count_posts) { // Increase the stats for the board $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET num_posts = num_posts + {int:num_posts}, num_topics = num_topics + 1 WHERE id_board = {int:board_id} ', array('board_id' => $board_id, 'num_posts' => $num_posts)); // How many posts have been made by each user in the copied topic? $request = $smcFunc['db_query']('', ' SELECT count(*) as increase, id_member FROM {db_prefix}messages WHERE id_topic = {int:topic_id} AND id_member > 0 GROUP BY id_member ', array('topic_id' => $topic_id)); // Any members to update (non-guests); if ($smcFunc['db_num_rows']($request) != 0) { $members = $increase = array(); // Prepare the information in arrays for easy update while ($row = $smcFunc['db_fetch_assoc']($request)) { $increase[$row['id_member']] = $row['increase']; // Store the member ids, as we will need to Update PostGroups if (!in_array($row['id_member'], $members)) { $members[] = $row['id_member']; } } // Update each users postcount accordingly. Could add significant number of queries for large topics. foreach ($increase as $a => $b) { $smcFunc['db_query']('', ' UPDATE {db_prefix}members SET posts = posts + {int:posts} WHERE id_member = {int:id_member} ', array('id_member' => $a, 'posts' => $b)); } unset($increase, $a, $b); // Update PostGroups for member who's postcounts have been altered. updateStats('postgroups', $members); } } $_SESSION['last_read_topic'] = $original_topic_id; // --- Copy Poll --- // Is it a poll? if ($original_poll_id > 0) { // Copy the poll // id_poll is not listed because it is Auto-Incremented // The rest are the same $smcFunc['db_query']('', ' INSERT INTO {db_prefix}polls (question, voting_locked, max_votes, expire_time, hide_results, change_vote, id_member, poster_name) SELECT question, voting_locked, max_votes, expire_time, hide_results, change_vote, id_member, poster_name FROM {db_prefix}polls WHERE id_poll = {int:original_poll_id} ', array('original_poll_id' => $original_poll_id)); // Save the new poll id $poll_id = $smcFunc['db_insert_id']('{db_prefix}polls', 'id_poll'); // Update the topic info with the poll id $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET id_poll = {int:poll_id} WHERE id_topic = {int:topic_id} ', array('poll_id' => $poll_id, 'topic_id' => $topic_id)); // --- Copy Poll Choices --- // Query to Select & Copy ALL the poll choices in one query. // id_poll is set to our new poll id $smcFunc['db_query']('', ' INSERT INTO {db_prefix}poll_choices (id_poll, id_choice, label, votes) SELECT {int:poll_id}, id_choice, label, votes FROM {db_prefix}poll_choices WHERE id_poll = {int:original_poll_id} ORDER BY id_choice ASC ', array('poll_id' => $poll_id, 'original_poll_id' => $original_poll_id)); // --- Copy Log Polls --- // Query to Select & Copy the log polls in one query. (depending on the no. of voters, it could be heavy) // id_poll is set to our new poll id $smcFunc['db_query']('', ' INSERT INTO {db_prefix}log_polls(id_poll, id_member, id_choice) SELECT {int:poll_id}, id_member, id_choice FROM {db_prefix}log_polls WHERE id_poll = {int:original_poll_id} ', array('poll_id' => $poll_id, 'original_poll_id' => $original_poll_id)); } // --- Calender Events --- // Query to Copy each calendar entry related to this topic // id_event is not listed as its auto-incremented // id_topic and id_board are set to our new poll id $smcFunc['db_query']('', ' INSERT INTO {db_prefix}calendar (start_date, end_date, id_board, id_topic, title, id_member) SELECT start_date, end_date, {int:board_id}, {int:topic_id}, title, id_member FROM {db_prefix}calendar WHERE id_topic = {int:original_topic_id} ORDER BY id_event ASC ', array('topic_id' => $topic_id, 'board_id' => $board_id, 'original_topic_id' => $original_topic_id)); updateStats('topic'); updateStats('message'); updateSettings(array('calendar_updated' => time())); }
function CopyTopics($original_topic_id, $board_id, $countPosts) { global $db_prefix, $txt, $scripturl, $sourcedir, $modSettings, $context, $user_info; // Try to buy some time... @set_time_limit(0); // Check Topic Exists and get some info for now and later $request = db_query("\n\t\tSELECT ID_BOARD, ID_POLL, numReplies\n\t\tFROM {$db_prefix}topics\n\t\tWHERE ID_TOPIC = {$original_topic_id}\n\t\tLIMIT 1\n\t\t", __FILE__, __LINE__); if (mysql_num_rows($request) == 0) { fatal_lang_error('smf263'); } list($original_board_id, $original_poll_id, $numPosts) = mysql_fetch_row($request); // Its topic so it has 1 more reply that it states $numPosts++; mysql_free_result($request); // --- Copy Topic Entry --- // The Columns for the table with our new topic and board ids. // ID_TOPIC is not listed because it is Auto-Incremented // ID_BOARD is set to our destination board // ID_FIRST_MSG and ID_LAST_MSG are set to 0 for now(to prevent key errors if copying into same forum) $insert = "ID_BOARD, ID_FIRST_MSG, ID_LAST_MSG, ID_MEMBER_STARTED, ID_MEMBER_UPDATED, isSticky, ID_POLL, numReplies, numViews, locked"; $select = "'{$board_id}', 0, 0, ID_MEMBER_STARTED, ID_MEMBER_UPDATED, isSticky, ID_POLL, numReplies, numViews, locked"; // Query to Copy the Topic db_query("\n\t\tINSERT INTO {$db_prefix}topics (" . $insert . ")\n\t\tSELECT " . $select . "\n\t\tFROM {$db_prefix}topics\n\t\tWHERE ID_TOPIC = '" . $original_topic_id . "'\n\t\tLIMIT 1\n\t", __FILE__, __LINE__); $topic_id = db_insert_id(); // Tidy up unset($insert, $select); // --- Copy Messages Entries --- // The Columns for the table with our new topic and board ids. // ID_MSG is not listed because it is Auto-Incremented // ID_MSG_MODIFIED is made to the old msg id temporarily. $insert = "ID_TOPIC, ID_BOARD, ID_MSG_MODIFIED, ID_MEMBER, posterTime, subject, posterName, posterEmail, posterIP, modifiedName, body, icon"; $select = "'{$topic_id}', '{$board_id}', ID_MSG, ID_MEMBER, posterTime, subject, posterName, posterEmail, posterIP, modifiedName, body, icon"; // Query to Copy EVERY post in the topic (Potentially could be a beast of a query) db_query("\n\t\tINSERT INTO {$db_prefix}messages (" . $insert . ")\n\t\tSELECT " . $select . "\n\t\tFROM {$db_prefix}messages\n\t\tWHERE ID_TOPIC = " . $original_topic_id . "\n\t\tORDER BY ID_MSG ASC\n\t", __FILE__, __LINE__); // Tidy up unset($insert, $select); // --- Log Search Subject Cache (for searching) --- // Standard // The Columns for the table with our new topic id instead $insert = "word, ID_TOPIC"; $select = "word, '{$topic_id}'"; // Query to Copy EVERY matching row db_query("\n\t\tINSERT INTO {$db_prefix}log_search_subjects (" . $insert . ")\n\t\tSELECT " . $select . "\n\t\tFROM {$db_prefix}log_search_subjects\n\t\tWHERE ID_TOPIC = " . $original_topic_id . "\n\t", __FILE__, __LINE__); // Tidy up unset($insert, $select); // Custom Search Index? if (!empty($modSettings['search_custom_index_config'])) { // The Columns for the table with our new msg id instead $insert = "ID_WORD, ID_MSG"; $select = "w.ID_WORD, m.ID_MSG"; // Query to Copy EVERY matching row db_query("\n\t\t\tINSERT INTO {$db_prefix}log_search_words (" . $insert . ")\n\t\t\tSELECT " . $select . "\n\t\t\tFROM {$db_prefix}log_search_words as w\n\t\t\t\tLEFT JOIN {$db_prefix}messages as m ON (w.ID_MSG = m.ID_MSG_MODIFIED)\n\t\t\tWHERE m.ID_TOPIC = " . $topic_id . "\n\t\t", __FILE__, __LINE__); // Tidy up unset($insert, $select); } /* Disabled v1.2 - Causing duplicate key issues // --- Log_Search_Results --- // Include this new topic in existing search results // The Columns for the table with our new msg id and topic id instead $insert = "ID_SEARCH, ID_TOPIC, ID_MSG, relevance, num_matches"; $select = "r.ID_SEARCH, '$topic_id', m.ID_MSG, r.relevance, r.num_matches"; // Query to Copy EVERY matching row db_query(" INSERT INTO {$db_prefix}log_search_results (". $insert .") SELECT ". $select ." FROM {$db_prefix}log_search_results as r LEFT JOIN {$db_prefix}messages as m ON (r.ID_MSG = m.ID_MSG_MODIFIED) WHERE m.ID_TOPIC = ".$topic_id." ", __FILE__, __LINE__); // Tidy up unset($insert,$select); */ // --- Copy Attachments --- // * Only those less than 1mb in size, larger files may crash your server $doattachments = 1; // First make sure the attachment dir is writable. if (!is_writable($modSettings['attachmentUploadDir'])) { // Try to fix it. @chmod($modSettings['attachmentUploadDir'], 0777); // Guess that didn't work :/? if (!is_writable($modSettings['attachmentUploadDir'])) { $doattachments = 0; } } // Check how we are on directory filesize? if ($doattachments && !empty($modSettings['attachmentDirSizeLimit'])) { $doattachments = attachmentDirectorySizeCheck(); } // Right try to go ahead with the attachments. if (!empty($doattachments)) { // The Columns for the table // ID_ATTACH is not listed because it is Auto-Incremented // Matching the ID_MSG_MODIFIED and switching it for the new ID_MSG $insert = "ID_THUMB, ID_MSG, ID_MEMBER, attachmentType, filename, size, downloads, width, height"; $select = "a.ID_ATTACH, m.ID_MSG, a.ID_MEMBER, a.attachmentType, a.filename, a.size, a.downloads, a.width, a.height"; db_query("\n\t\t\tINSERT INTO {$db_prefix}attachments (" . $insert . ")\n\t\t\tSELECT " . $select . "\n\t\t\tFROM {$db_prefix}attachments as a\n\t\t\t\tLEFT JOIN {$db_prefix}messages as m ON (a.ID_MSG = m.ID_MSG_MODIFIED)\n\t\t\tWHERE m.ID_TOPIC = " . $topic_id . "\n\t\t\t\tAND size < 1048600\n\t\t\tORDER BY ID_ATTACH ASC\n\t\t", __FILE__, __LINE__); // Tidy up unset($insert, $select); // Grab and store the new vs old attachment ids in a array (we temporarily stored the old ID in the ID_THUMB column) $request = db_query("\n\t\t\tSELECT a.ID_ATTACH, a.ID_THUMB\n\t\t\tFROM {$db_prefix}attachments as a\n\t\t\t\tLEFT JOIN {$db_prefix}messages as m ON (a.ID_MSG = m.ID_MSG)\n\t\t\tWHERE m.ID_TOPIC = " . $topic_id . "\n\t\t\tORDER BY ID_ATTACH ASC\n\t\t", __FILE__, __LINE__); // Did it copy any attachment entries in the db? if (mysql_num_rows($request) != 0) { $ids = array(); while ($row = mysql_fetch_assoc($request)) { $ids[$row['ID_ATTACH']] = $row['ID_THUMB']; } // Tidy up mysql_free_result($request); unset($row); // Re-Associate Thumbs with our new attachment and thumb ids db_query("\n\t\t\t\tUPDATE {$db_prefix}attachments as a\n\t\t\t\t\tLEFT JOIN {$db_prefix}messages as m ON (a.ID_MSG = m.ID_MSG)\n\t\t\t\t\tLEFT JOIN {$db_prefix}attachments as a2 ON (a.ID_THUMB = a2.ID_ATTACH)\n\t\t\t\t\tLEFT JOIN {$db_prefix}attachments as a3 ON (a2.ID_THUMB = a3.ID_THUMB AND m.ID_MSG = a3.ID_MSG)\n\t\t\t\tSET a.ID_THUMB = a3.ID_ATTACH\n\t\t\t\tWHERE m.ID_TOPIC = " . $topic_id . "\n\t\t\t\t\tAND a2.ID_ATTACH != 0\n\t\t\t", __FILE__, __LINE__); // Grab all the information about the attachments (including thumbs) attached to this topic $request = db_query("\n\t\t\t\tSELECT \ta.ID_ATTACH as file_id, a.filename as filename, a.size as filesize,\n\t\t\t\t\t\ta.ID_THUMB as thumb_id, a2.filename as thumbname, a2.size as thumbsize\n\t\t\t\tFROM {$db_prefix}attachments as a\n\t\t\t\t\tLEFT JOIN {$db_prefix}messages as m ON (a.ID_MSG = m.ID_MSG)\n\t\t\t\t\tLEFT JOIN {$db_prefix}attachments as a2 ON (a.ID_THUMB = a2.ID_ATTACH)\n\t\t\t\tWHERE m.ID_TOPIC = " . $topic_id . "\n\t\t\t\t\tAND\ta.attachmentType != 3\n\t\t\t\tORDER BY a.ID_ATTACH ASC\n\t\t\t", __FILE__, __LINE__); // Attachments found if (mysql_num_rows($request) != 0) { $attachments = array(); // For each attachment, we will try to copy the file while ($row = mysql_fetch_assoc($request)) { $row['original_id'] = $ids[$row['file_id']]; $row['original_thumb_id'] = empty($row['thumb_id']) ? 0 : $ids[$row['thumb_id']]; $attachments[] = $row; } // Tidy up mysql_free_result($request); unset($ids, $row); foreach ($attachments as $row) { // Is there enough space for the copied attachment + thumb if (empty($modSettings['attachmentDirSizeLimit']) || $doattachments + (int) $row['filesize'] + (int) $row['thumbsize'] < $modSettings['attachmentDirSizeLimit'] * 1024) { // Copy the attachment if ($filename = copyAttachment($row)) { // Successly copied the attachment // Update the attachment db entry with the new filename (only if new filename was generated); db_query("\n\t\t\t\t\t\t\t\tUPDATE {$db_prefix}attachments\n\t\t\t\t\t\t\t\tSET filename = '{$filename}'\n\t\t\t\t\t\t\t\tWHERE ID_ATTACH = " . (int) $row['file_id'] . "\n\t\t\t\t\t\t\t", __FILE__, __LINE__); // Increase the size $doattachments = $doattachments + (int) $row['filesize'] + (int) $row['thumbsize']; // If theres a thumb, rename that aswell if (!empty($row['thumb_id'])) { db_query("\n\t\t\t\t\t\t\t\t\tUPDATE {$db_prefix}attachments\n\t\t\t\t\t\t\t\t\tSET filename = '" . $filename . "_thumb'\n\t\t\t\t\t\t\t\t\tWHERE ID_ATTACH = " . (int) $row['thumb_id'] . "\n\t\t\t\t\t\t\t\t", __FILE__, __LINE__); } } else { // Copying the attachment failed, so delete the db entries db_query("\n\t\t\t\t\t\t\t\tDELETE FROM {$db_prefix}attachments\n\t\t\t\t\t\t\t\tWHERE ID_ATTACH = " . (int) $row['file_id'] . "\n\t\t\t\t\t\t\t\t\tOR ID_ATTACH = " . (int) $row['thumb_id'] . "\n\t\t\t\t\t\t\t", __FILE__, __LINE__); } } else { // Ran out of space or error, so delete the db entries db_query("\n\t\t\t\t\t\t\tDELETE FROM {$db_prefix}attachments\n\t\t\t\t\t\t\tWHERE ID_ATTACH = " . (int) $row['file_id'] . "\n\t\t\t\t\t\t\t\tOR ID_ATTACH = " . (int) $row['thumb_id'] . "\n\t\t\t\t\t\t", __FILE__, __LINE__); } // Tidy up unset($row); } // Tidy up unset($attachments, $ids, $row); } } } // --- Fix some stats and logs --- // Fix ID_MSG_MODIFIED to the New ID_MSG db_query("\n\t\tUPDATE {$db_prefix}messages\n\t\tSET ID_MSG_MODIFIED = ID_MSG\n\t\tWHERE ID_TOPIC = " . $topic_id . "\n\t", __FILE__, __LINE__); // Grab First & Last Message Id $request = db_query("\n\t\tSELECT max(ID_MSG) as last, min(ID_MSG) as first\n\t\tFROM {$db_prefix}messages\n\t\tWHERE ID_TOPIC = " . $topic_id . "\n\t", __FILE__, __LINE__); $row = mysql_fetch_assoc($request); // Update the topic info with that info db_query("\n\t\tUPDATE {$db_prefix}topics\n\t\tSET ID_FIRST_MSG = " . $row['first'] . ", ID_LAST_MSG = " . $row['last'] . "\n\t\tWHERE ID_TOPIC = " . $topic_id . "\n\t", __FILE__, __LINE__); // Update log topics (for this user only) db_query("\n\t\tREPLACE\n\t\tINTO {$db_prefix}log_topics\n\t\t\t(ID_TOPIC, ID_MEMBER, ID_MSG)\n\t\tVALUES (" . $topic_id . ", " . $context['user']['id'] . ", " . $row['last'] . ")\n\t\t", __FILE__, __LINE__); // Update log boards (for this user only) db_query("\n\t\tREPLACE\n\t\tINTO {$db_prefix}log_boards\n\t\t\t(ID_BOARD, ID_MEMBER, ID_MSG)\n\t\tVALUES (" . $board_id . ", " . $context['user']['id'] . ", " . $row['last'] . ")\n\t\t", __FILE__, __LINE__); require_once $sourcedir . '/Subs-Post.php'; updateLastMessages($board_id, $row['last']); // --- Fix Post Counts --- // Posts in the board we're copying the topic to count, so we need to get the figures for each if ($countPosts) { // Increase the stats for the board db_query("\n\t\t\tUPDATE {$db_prefix}boards\n\t\t\tSET numPosts = numPosts + " . $numPosts . ", numTopics = numTopics + 1\n\t\t\tWHERE ID_BOARD = " . $board_id . "\n\t\t", __FILE__, __LINE__); // How many posts have been made by each user in the copied topic? $request = db_query("\n\t\t\tSELECT count(*) as increase, ID_MEMBER\n\t\t\tFROM {$db_prefix}messages\n\t\t\tWHERE ID_TOPIC = " . $topic_id . "\n\t\t\t\tAND ID_MEMBER > 0\n\t\t\tGROUP BY ID_MEMBER\n\t\t", __FILE__, __LINE__); // Any members to update (non-guests); if (mysql_num_rows($request) != 0) { $members = $increase = array(); // Prepare the information in arrays for easy update while ($row = mysql_fetch_assoc($request)) { $increase[$row['ID_MEMBER']] = $row['increase']; // Store the member ids, as we will need to Update PostGroups if (!in_array($row['ID_MEMBER'], $members)) { $members[] = $row['ID_MEMBER']; } } // Update each users postcount accordingly. Could add significant number of queries for large topics. foreach ($increase as $a => $b) { db_query("\n\t\t\t\t\tUPDATE {$db_prefix}members\n\t\t\t\t\tSET posts = posts + " . $b . "\n\t\t\t\t\tWHERE ID_MEMBER = " . $a . "\n\t\t\t\t", __FILE__, __LINE__); } unset($increase, $a, $b); // Update PostGroups for member who's postcounts have been altered. updateStats('postgroups', 'ID_MEMBER IN (' . implode(', ', $members) . ')'); } } $_SESSION['last_read_topic'] = $original_topic_id; // --- Copy Poll --- // Is it a poll? if ($original_poll_id > 0) { // The Columns for the table // ID_POLL is not listed because it is Auto-Incremented // The rest are the same $select = $insert = "question, votingLocked, maxVotes, expireTime, hideResults, changeVote, ID_MEMBER, posterName"; // Copy the poll db_query("\n\t\t\tINSERT INTO {$db_prefix}polls (" . $insert . ")\n\t\t\tSELECT " . $select . "\n\t\t\tFROM {$db_prefix}polls\n\t\t\tWHERE ID_POLL = '" . $original_poll_id . "'\n\t\t", __FILE__, __LINE__); // Save the new poll id $poll_id = db_insert_id(); // Update the topic info with the poll id db_query("\n\t\t\tUPDATE {$db_prefix}topics\n\t\t\tSET ID_POLL = " . $poll_id . "\n\t\t\tWHERE ID_TOPIC = " . $topic_id . "\n\t\t", __FILE__, __LINE__); // Tidy up unset($insert, $select); // --- Copy Poll Choices --- // The Columns for the table // ID_POLL is set to our new poll id $insert = "ID_POLL, ID_CHOICE, label, votes"; $select = "'{$poll_id}', ID_CHOICE, label, votes"; // Query to Select & Copy ALL the poll choices in one query. db_query("\n\t\t\tINSERT INTO {$db_prefix}poll_choices (" . $insert . ")\n\t\t\tSELECT " . $select . "\n\t\t\tFROM {$db_prefix}poll_choices\n\t\t\tWHERE ID_POLL = " . $original_poll_id . "\n\t\t\tORDER BY ID_CHOICE ASC\n\t\t", __FILE__, __LINE__); // Tidy up unset($insert, $select); // --- Copy Log Polls --- // The Columns for the table // ID_POLL is set to our new poll id $insert = "ID_POLL, ID_MEMBER, ID_CHOICE"; $select = "'{$poll_id}', ID_MEMBER, ID_CHOICE"; // Query to Select & Copy the log polls in one query. (depending on the no. of voters, it could be heavy) db_query("\n\t\t\tINSERT INTO {$db_prefix}log_polls(" . $insert . ")\n\t\t\tSELECT " . $select . "\n\t\t\tFROM {$db_prefix}log_polls\n\t\t\tWHERE ID_POLL = " . $original_poll_id . "\n\t\t", __FILE__, __LINE__); // Tidy up unset($insert, $select); } // --- Calender Events --- // The Columns for the table // ID_EVENT is not listed as its auto-incremented // ID_TOPIC and ID_BOARD are set to our new poll id $insert = "startDate, endDate, ID_BOARD, ID_TOPIC, title, ID_MEMBER"; $select = "startDate, endDate, '{$board_id}', '{$topic_id}', title, ID_MEMBER"; // Query to Copy each calendar entry related to this topic db_query("\n\t\tINSERT INTO {$db_prefix}calendar (" . $insert . ")\n\t\tSELECT " . $select . "\n\t\tFROM {$db_prefix}calendar\n\t\tWHERE ID_TOPIC = " . $original_topic_id . "\n\t\tORDER BY ID_EVENT ASC\n\t", __FILE__, __LINE__); updateStats('topic'); updateStats('message'); updateStats('calendar'); }