Exemplo n.º 1
0
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()));
}
Exemplo n.º 2
0
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');
}