diff options
Diffstat (limited to 'phpBB')
-rw-r--r-- | phpBB/develop/posting-api.php | 544 |
1 files changed, 384 insertions, 160 deletions
diff --git a/phpBB/develop/posting-api.php b/phpBB/develop/posting-api.php index 494cb9773d..e57fc4b140 100644 --- a/phpBB/develop/posting-api.php +++ b/phpBB/develop/posting-api.php @@ -8,7 +8,6 @@ include(PHPBB_ROOT_PATH . 'common.' . PHP_EXT); class posting_api { - // ideas on global topics? I am stuck here :'-( /* topic table: topic_id @@ -381,234 +380,449 @@ class posting_api static function delete_topic($data) { + // just call the more powerful variant with just one topic :) + self::delete_topics(array('topic_ids' => array($data['topic_id']))); + } + + static function delete_topics($data) + { global $db; // lets get this party started $db->sql_transaction('begin'); - $topic_id = (int) $data['topic_id']; + $topic_ids = array_map('intval', $data['topic_ids']); // what kind of topic is this? lets find out how much we must tamper with the forum table... - $sql = 'SELECT topic_posts, topic_shadow_posts, topic_deleted_posts, topic_unapproved_posts, topic_shadow_id, forum_id + // TODO: investigate how aggregate functions can speed this up/reduce the number of results returned/misc. other benefits + $sql = 'SELECT topic_posts, topic_shadow_posts, topic_deleted_posts, topic_unapproved_posts, topic_shadow_id, forum_id, topic_status FROM ' . TOPICS_TABLE . ' - WHERE topic_id = ' . $topic_id; + WHERE ' . $db->sql_in_set('topic_id', $topic_ids); $result = $db->sql_query($sql); - $topic_row = $db->sql_fetchrow($result); + // the following in an array, key'd by forum id that refers to topic rows + $forum_lookup = array(); + while ($topic_row = $db->sql_fetchrow($result)) + { + $forum_id = (int) $topic_row['forum_id']; + + // deal with posts + $forum_lookup[$forum_id]['forum_posts'] += $topic_row['topic_posts']; + $forum_lookup[$forum_id]['forum_shadow_posts'] += $topic_row['topic_shadow_posts']; + $forum_lookup[$forum_id]['forum_deleted_posts'] += $topic_row['topic_deleted_posts']; + $forum_lookup[$forum_id]['forum_unapproved_posts'] += $topic_row['topic_unapproved_posts']; + + // deal with topics + $topic_status = (int) $topic_row['topic_status']; + $forum_lookup[$forum_id]['forum_topics']++; // a topic is a topic + $forum_lookup[$forum_id]['forum_shadow_topics'] += ($topic_row['topic_shadow_id'] != 0); + $forum_lookup[$forum_id]['forum_deleted_topics'] += ($topic_status & self::DELETED); + $forum_lookup[$forum_id]['forum_unapproved_topics'] += ($topic_status & self::UNAPPROVED); + } $db->sql_freeresult($result); - // goodnight topic - $db->sql_query('DELETE FROM ' . TOPICS_TABLE . ' WHERE topic_id = ' . $topic_id); + // goodnight, topics + $db->sql_query('DELETE FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); - // goodnight post - $db->sql_query('DELETE FROM ' . POSTS_TABLE . ' WHERE topic_id = ' . $topic_id); + // goodnight, posts + $db->sql_query('DELETE FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); - $forum_id = (int) $topic_row['forum_id']; + $forum_ids = array_keys($forum_lookup); // what kind of topic is this? lets find out how much we must tamper with the forum table... - $sql = 'SELECT forum_posts, forum_shadow_posts, forum_deleted_posts, forum_unapproved_posts + $sql = 'SELECT forum_posts, forum_shadow_posts, forum_deleted_posts, forum_unapproved_posts, forum_id FROM ' . FORUMS_TABLE . ' - WHERE forum_id = ' . $forum_id; + WHERE ' . $db->sql_in_set('forum_id', $forum_ids); $result = $db->sql_query($sql); - $forum_row = $db->sql_fetchrow($result); - - $forum_array = array( - 'forum_posts' => max($forum_row['forum_posts'] - $topic_id['forum_posts'], 0), - 'forum_shadow_posts' => max($forum_row['forum_shadow_posts'] - $topic_id['forum_shadow_posts'], 0), - 'forum_deleted_posts' => max($forum_row['forum_deleted_posts'] - $topic_id['forum_deleted_posts'], 0), - 'forum_unapproved_posts' => max($forum_row['forum_unapproved_posts'] - $topic_id['forum_unapproved_posts'], 0), - - 'forum_topics' => max($forum_row['forum_topics'] - 1, 0), - 'forum_shadow_topics' => max($forum_row['forum_shadow_topics'] - (($topic_type == self::SHADOW) ? 1 : 0), 0), - 'forum_deleted_topics' => max($forum_row['forum_deleted_topics'] - (($topic_status == self::DELETED) ? 1 : 0), 0), - 'forum_unapproved_topics' => max($forum_row['forum_unapproved_topics'] - (($topic_row['topic_shadow_id'] != 0) ? 1 : 0), 0), - ); - - // get the last "normal" post in the forum, we _must_ update it - $sql = 'SELECT MAX(post_id) as max_post_id - FROM ' . POSTS_TABLE . ' - WHERE post_status = ' . self::NORMAL . ' - AND forum_id = ' . $forum_id; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); + $forum_rows = array(); + while ($forum_row = $db->sql_fetchrow($result)) + { + $forum_id = (int) $forum_row['forum_id']; + $forum_rows[$forum_id] = $forum_row; + } $db->sql_freeresult($result); - // anything left? - if ($row) + $shadow_topic_ids = array(); + foreach ($forum_rows as $forum_id => $forum_row) { - // OK, lets go do some magick - $sql = 'SELECT post_username, poster_id, post_subject, post_time - FROM '. POSTS_TABLE . ' - WHERE post_id = ' . (int) $row['max_post_id']; + $topic_row = $forum_lookup[$forum_id]; + $forum_array = array( + 'forum_posts' => max($forum_row['forum_posts'] - $topic_row['forum_posts'], 0), + 'forum_shadow_posts' => max($forum_row['forum_shadow_posts'] - $topic_row['forum_shadow_posts'], 0), + 'forum_deleted_posts' => max($forum_row['forum_deleted_posts'] - $topic_row['forum_deleted_posts'], 0), + 'forum_unapproved_posts' => max($forum_row['forum_unapproved_posts'] - $topic_row['forum_unapproved_posts'], 0), + + 'forum_topics' => max($forum_row['forum_topics'] - $topic_row['forum_topics'], 0), + 'forum_shadow_topics' => max($forum_row['forum_shadow_topics'] - $topic_row['forum_shadow_topics'], 0), + 'forum_deleted_topics' => max($forum_row['forum_deleted_topics'] - $topic_row['forum_deleted_topics'], 0), + 'forum_unapproved_topics' => max($forum_row['forum_unapproved_topics'] - $topic_row['forum_unapproved_topics'], 0), + ); + + // get the last "normal" post in the forum, we _must_ update it + $sql = 'SELECT MAX(post_id) as max_post_id + FROM ' . POSTS_TABLE . ' + WHERE post_status = ' . self::NORMAL . ' + AND forum_id = ' . $forum_id; $result = $db->sql_query($sql); - $last_post = $db->sql_fetchrow($result); + $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - - $forum_array['forum_last_user_id'] = (int) $last_post['poster_id']; - $forum_array['forum_last_poster_name'] = $last_post['post_username']; - $forum_array['forum_last_post_title'] = $last_post['post_subject']; - $forum_array['forum_last_post_time'] = (int) $last_post['post_time']; - } - else - { - // reset forum state - $forum_array['forum_last_user_id'] = 0; - $forum_array['forum_last_poster_name'] = ''; - $forum_array['forum_last_post_title'] = ''; - $forum_array['forum_last_post_time'] = 0; + + // anything left? + if ($row) + { + // OK, lets go do some magick + $sql = 'SELECT post_username, poster_id, post_subject, post_time + FROM '. POSTS_TABLE . ' + WHERE post_id = ' . (int) $row['max_post_id']; + $result = $db->sql_query($sql); + $last_post = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $forum_array['forum_last_user_id'] = (int) $last_post['poster_id']; + $forum_array['forum_last_poster_name'] = $last_post['post_username']; + $forum_array['forum_last_post_title'] = $last_post['post_subject']; + $forum_array['forum_last_post_time'] = (int) $last_post['post_time']; + } + else + { + // reset forum state + $forum_array['forum_last_user_id'] = 0; + $forum_array['forum_last_poster_name'] = ''; + $forum_array['forum_last_post_title'] = ''; + $forum_array['forum_last_post_time'] = 0; + } + + $db->sql_handle_data('UPDATE', FORUMS_TABLE, $forum_data, "forum_id = $forum_id"); } - $db->sql_handle_data('UPDATE', FORUMS_TABLE, $forum_data, "forum_id = $forum_id"); - - // lastly, kill off all the unbelievers... erm, I mean shadow topics... - $sql = 'SELECT topic_id, forum_id + // let's not get too hasty, we can kill off the shadows later, + // instead we compose a list of all shadows and then efficiently kill them off :) + $sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . ' - WHERE topic_shadow_id = ' . $topic_id; + WHERE ' . $db->sql_in_set('topic_shadow_id', $topic_ids); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - $data['topic_id'] = (int) $topic_id; - self::delete_topic($data); + $shadow_topic_ids[] = $row['topic_id']; + } + + $db->sql_freeresult($result); + + // recursion, the other white meat. + if (sizeof($shadow_topic_ids)) + { + self::delete_topics(array('topic_ids' => $shadow_topic_ids)); } // goodnight, moon - $db->transaction('COMMIT'); + $db->transaction('commit'); } - static function move_topic($data) + static function delete_post($data) + { + // just call the more powerful variant with just one post :) + self::delete_posts(array('post_ids' => array($data['post_id']))); + } + + static function delete_posts($data) { global $db; // lets get this party started - $db->transaction('BEGIN'); + $db->sql_transaction('begin'); - $topic_id = (int) $data['topic_id']; - $to_forum_id = (int) $data['forum_id']; - $make_shadow = (bool) $data['make_shadow']; + $post_ids = array_map('intval', $data['post_ids']); - // let us first determine how many items we are removing from the pool - $sql = 'SELECT topic_posts, topic_shadow_posts, topic_deleted_posts, topic_unapproved_posts, forum_id as from_forum_id, topic_status, topic_type, topic_shadow_id + $sql = 'SELECT topic_id, post_status, post_id, post_shadow_id, forum_id + FROM ' . POSTS_TABLE . ' + WHERE ' . $db->sql_in_set('post_id', $post_ids); + $result = $db->sql_query($sql); + + // the following arrays are designed to allow for much faster updates + $topic_lookup = array(); + $forum_lookup = array(); + + while ($post_row = $db->sql_fetchrow($result)) + { + $topic_id = (int) $post_row['topic_id']; + $forum_id = (int) $post_row['forum_id']; + $post_status = (int) $post_row['post_status']; + + $topic_lookup[$topic_id]['topic_posts']++; // we remove a post, go figure + $topic_lookup[$topic_id]['topic_shadow_posts'] += ($post_row['post_shadow_id'] != 0); // did we just try to kill a shadow post?! + $topic_lookup[$topic_id]['topic_deleted_posts'] += ($post_status & self::DELETED); + $topic_lookup[$topic_id]['topic_unapproved_posts'] += ($post_status & self::UNAPPROVED); + + $forum_lookup[$forum_id]['forum_posts']++; + $forum_lookup[$topic_id]['forum_shadow_posts'] += ($post_row['post_shadow_id'] != 0); // did we just try to kill a shadow post?! + $forum_lookup[$topic_id]['forum_deleted_posts'] += ($post_status & self::DELETED); + $forum_lookup[$topic_id]['forum_unapproved_posts'] += ($post_status & self::UNAPPROVED); + } + $db->sql_freeresult($result); + + // goodnight, posts + $db->sql_query('DELETE FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids)); + + // mangle the forums table + $sql = 'SELECT forum_posts, forum_shadow_posts, forum_deleted_posts, forum_unapproved_posts, forum_id + FROM ' . FORUMS_TABLE . ' + WHERE forum_id = ' . $forum_id; + $result = $db->sql_query($sql); + $forum_rows = array(); + while ($forum_row = $db->sql_fetchrow($result)) + { + $forum_id = (int) $forum_row['forum_id']; + $forum_rows[$forum_id] = $forum_row; + } + $db->sql_freeresult($result); + + $shadow_topic_ids = array(); + foreach ($forum_rows as $forum_id => $forum_row) + { + $topic_row = $forum_lookup[$forum_id]; + $forum_array = array( + 'forum_posts' => max($forum_row['forum_posts'] - $topic_row['forum_posts'], 0), + 'forum_shadow_posts' => max($forum_row['forum_shadow_posts'] - $topic_row['forum_shadow_posts'], 0), + 'forum_deleted_posts' => max($forum_row['forum_deleted_posts'] - $topic_row['forum_deleted_posts'], 0), + 'forum_unapproved_posts' => max($forum_row['forum_unapproved_posts'] - $topic_row['forum_unapproved_posts'], 0), + ); + + // get the last "normal" post in the forum, we _must_ update it + $sql = 'SELECT MAX(post_id) as max_post_id + FROM ' . POSTS_TABLE . ' + WHERE post_status = ' . self::NORMAL . ' + AND forum_id = ' . $forum_id; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + // anything left? + if ($row) + { + // OK, lets go do some magick + $sql = 'SELECT post_username, poster_id, post_subject, post_time + FROM '. POSTS_TABLE . ' + WHERE post_id = ' . (int) $row['max_post_id']; + $result = $db->sql_query($sql); + $last_post = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $forum_array['forum_last_user_id'] = (int) $last_post['poster_id']; + $forum_array['forum_last_poster_name'] = $last_post['post_username']; + $forum_array['forum_last_post_title'] = $last_post['post_subject']; + $forum_array['forum_last_post_time'] = (int) $last_post['post_time']; + } + else + { + // reset forum state + $forum_array['forum_last_user_id'] = 0; + $forum_array['forum_last_poster_name'] = ''; + $forum_array['forum_last_post_title'] = ''; + $forum_array['forum_last_post_time'] = 0; + } + + $db->sql_handle_data('UPDATE', FORUMS_TABLE, $forum_data, "forum_id = $forum_id"); + } + + // mangle the topics table now :) + $sql = 'SELECT topic_posts, topic_shadow_posts, topic_deleted_posts, topic_unapproved_posts, topic_id FROM ' . TOPICS_TABLE . ' - WHERE topic_id = ' . $topic_id; + WHERE forum_id = ' . $forum_id; $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); + $topic_rows = array(); + while ($topic_row = $db->sql_fetchrow($result)) + { + $topic_id = (int) $topic_row['topic_id']; + $topic_rows[$topic_id] = $topic_row; + } $db->sql_freeresult($result); - $topic_status = (int) $row['topic_status']; - $topic_type = (int) $row['topic_type']; - $from_forum_id = (int) $row['from_forum_id']; + $empty_topic_ids = array(); + + foreach ($topic_rows as $topic_id => $topic_row) + { + $post_row = $topic_lookup[$topic_id]; + $topic_array = array( + 'topic_posts' => max($topic_row['topic_posts'] - $post_row['topic_posts'], 0), + 'topic_shadow_posts' => max($topic_row['topic_shadow_posts'] - $post_row['topic_shadow_posts'], 0), + 'topic_deleted_posts' => max($topic_row['topic_deleted_posts'] - $post_row['topic_deleted_posts'], 0), + 'topic_unapproved_posts' => max($topic_row['topic_unapproved_posts'] - $post_row['topic_unapproved_posts'], 0), + ); + + // get the last "normal" post in the topic, we _must_ update it + $sql = 'SELECT MAX(post_id) as max_post_id + FROM ' . POSTS_TABLE . ' + WHERE post_status = ' . self::NORMAL . ' + AND topic_id = ' . $topic_id; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + // anything left? + if ($row) + { + // OK, lets go do some magick + $sql = 'SELECT post_username, poster_id, post_subject, post_time + FROM '. POSTS_TABLE . ' + WHERE post_id = ' . (int) $row['max_post_id']; + $result = $db->sql_query($sql); + $last_post = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $topic_array['topic_last_user_id'] = (int) $last_post['poster_id']; + $topic_array['topic_last_poster_name'] = $last_post['post_username']; + $topic_array['topic_last_post_title'] = $last_post['post_subject']; + $topic_array['topic_last_post_time'] = (int) $last_post['post_time']; + } + else + { + // mark this post for execution! + $empty_topic_ids[] = $topic_id; + } + + $db->sql_handle_data('UPDATE', TOPICS_TABLE, $topic_array, "topic_id = $topic_id"); + } - $topic_row['topic_posts'] = (int) $row['topic_posts']; - $topic_row['topic_shadow_posts'] = (int) $row['topic_shadow_posts']; - $topic_row['topic_deleted_posts'] = (int) $row['topic_deleted_posts']; - $topic_row['topic_unapproved_posts'] = (int) $row['topic_unapproved_posts']; + $shadow_post_ids = array(); - // let us first determine how many items we are removing from the pool - $sql = 'SELECT forum_posts, forum_shadow_posts, forum_deleted_posts, forum_unapproved_posts, forum_id, forum_topics, forum_deleted_topics, forum_unapproved_topics - FROM ' . FORUMS_TABLE . ' - WHERE ' . $db->sql_in_set('forum_id', array($to_forum_id, $from_forum_id)); + // let's not get too hasty, we can kill off the shadows later, + // instead we compose a list of all shadows and then efficiently kill them off :) + $sql = 'SELECT post_id + FROM ' . POSTS_TABLE . ' + WHERE ' . $db->sql_in_set('post_shadow_id', $topic_ids); $result = $db->sql_query($sql); - $forum_row = array(); while ($row = $db->sql_fetchrow($result)) { - $forum_id = (int) $row['forum_id']; + $shadow_post_ids[] = $row['post_id']; + } - $forum_row[$forum_id]['forum_posts'] = (int) $row['forum_posts']; - $forum_row[$forum_id]['forum_shadow_posts'] = (int) $row['forum_shadow_posts']; - $forum_row[$forum_id]['forum_deleted_posts'] = (int) $row['forum_deleted_posts']; - $forum_row[$forum_id]['forum_unapproved_posts'] = (int) $row['forum_unapproved_posts']; + $db->sql_freeresult($result); - $forum_row[$forum_id]['forum_topics'] = (int) $row['forum_topics']; - $forum_row[$forum_id]['forum_shadow_topics'] = (int) $row['forum_shadow_topics']; - $forum_row[$forum_id]['forum_deleted_topics'] = (int) $row['forum_deleted_topics']; - $forum_row[$forum_id]['forum_unapproved_topics'] = (int) $row['forum_unapproved_topics']; + // recursion, the other white meat. + if (sizeof($shadow_topic_ids)) + { + self::delete_posts(array('post_ids' => $shadow_post_ids)); } - $db->sql_freeresult($result); + // we killed all the posts in a topic, time to kill the topics! + if (sizeof($empty_topics)) + { + self::delete_topics(array('topic_ids' => $empty_topic_ids)); + } - // update the topic itself - $db->sql_handle_data('UPDATE', TOPICS_TABLE, array('forum_id' => $to_forum_id), "topic_id = $topic_id"); + // goodnight, moon + $db->transaction('commit'); + } - // update the posts now - $db->sql_handle_data('UPDATE', POSTS_TABLE, array('forum_id' => $to_forum_id), "topic_id = $topic_id"); + static function move_topic($data) + { + self::move_topics(array('topic_forum_mapping' => array(array('topic_id' => $data['topic_id'], 'forum_id' => $data['forum_id'], 'make_shadow' => $data['make_shadow'])))); + } - // remove the numbers from the old forum row - $from_forum_array = array( - 'forum_posts' => max($forum_row[$from_forum_id]['forum_posts'] - $topic_row['forum_posts'], 0), - 'forum_shadow_posts' => max($forum_row[$from_forum_id]['forum_shadow_posts'] - $topic_row['forum_shadow_posts'], 0), - 'forum_deleted_posts' => max($forum_row[$from_forum_id]['forum_deleted_posts'] - $topic_row['forum_deleted_posts'], 0), - 'forum_unapproved_posts' => max($forum_row[$from_forum_id]['forum_unapproved_posts'] - $topic_row['forum_unapproved_posts'], 0), + static function move_topics($data) + { + global $db; - 'forum_topics' => max($forum_row[$from_forum_id]['forum_topics'] - 1, 0), - 'forum_shadow_topics' => max($forum_row[$from_forum_id]['forum_shadow_topics'] - (($topic_row['topic_shadow_id'] != 0) ? 1 : 0), 0), - 'forum_deleted_topics' => max($forum_row[$from_forum_id]['forum_deleted_topics'] - (($topic_status == self::DELETED) ? 1 : 0), 0), - 'forum_unapproved_topics' => max($forum_row[$from_forum_id]['forum_unapproved_topics'] - (($topic_status == self::UNAPPROVED) ? 1 : 0), 0), - ); + // lets get this party started + $db->transaction('begin'); - // get the last "normal" post in the old forum, we _must_ update it - $sql = 'SELECT MAX(post_id) as max_post_id - FROM ' . POSTS_TABLE . ' - WHERE post_status = ' . self::NORMAL . ' - AND forum_id = ' . $from_forum_id; + // all of each are indexed by topic id + $to_forum_ids = $shadow_topic_ids = array(); + + foreach ($data['topic_forum_mapping'] as $mapping) + { + $topic_id = (int) $mapping['topic_id']; + $to_forum_ids[$topic_id] = (int) $mapping['forum_id']; + if ($mapping['make_shadow']) + { + $shadow_topic_ids[] = $topic_id; + } + } + + $forum_columns = array('forum_posts', 'forum_shadow_posts', 'forum_deleted_posts', 'forum_unapproved_posts', 'forum_topics', 'forum_shadow_topics', 'forum_deleted_topics', 'forum_unapproved_topics'); + + $topic_ids = array_keys($to_forum_ids); + + // let us first determine how many items we are removing from the pool + $sql = 'SELECT topic_posts, topic_shadow_posts, topic_deleted_posts, topic_unapproved_posts, forum_id, topic_status, topic_type, topic_shadow_id, topic_id + FROM ' . TOPICS_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $topic_ids); $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); + $forum_lookup = array(); + while ($topic_row = $db->sql_fetchrow($result)) + { + $topic_id = $topic_row['topic_id']; + $from_forum_id = (int) $topic_row['forum_id']; + $topic_status = (int) $topic_row['topic_status']; + + $from_forum_ids[$topic_id] = $from_forum_id; + + $to_forum_id = $to_forum_ids[$topic_id]; + + // we are iterating one topic at a time... + $forum_lookup[$from_forum_id]['forum_topics'] = $forum_lookup[$to_forum_id]['forum_topics'] = 1; + + foreach ($forum_columns as $column) + { + $forum_lookup[$from_forum_id][$column] -= $topic_row['topic_posts']; + $forum_lookup[$to_forum_id][$column] += $topic_row['topic_posts']; + } + } $db->sql_freeresult($result); - // anything left? - if ($row) + // determine the totals + $sql = 'SELECT forum_posts, forum_shadow_posts, forum_deleted_posts, forum_unapproved_posts, forum_id, forum_topics, forum_deleted_topics, forum_unapproved_topics + FROM ' . FORUMS_TABLE . ' + WHERE ' . $db->sql_in_set('forum_id', array_keys($forum_lookup)); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) { - // OK, lets go do some magick - $sql = 'SELECT post_username, poster_id, post_subject, post_time - FROM '. POSTS_TABLE . ' - WHERE post_id = ' . (int) $row['max_post_id']; - $result = $db->sql_query($sql); - $last_post = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $forum_id = (int) $row['forum_id']; - $from_forum_array['forum_last_user_id'] = (int) $last_post['poster_id']; - $from_forum_array['forum_last_poster_name'] = $last_post['post_username']; - $from_forum_array['forum_last_post_title'] = $last_post['post_subject']; - $from_forum_array['forum_last_post_time'] = (int) $last_post['post_time']; + foreach ($forum_columns as $column) + { + $forum_lookup[$forum_id][$column] += (int) $row[$column]; + } } - else + + // create a listing of which topics are going in which forums + $update_list = array(); + + foreach ($to_forum_ids as $topic_id => $forum_id) { - // reset forum state - $from_forum_array['forum_last_user_id'] = 0; - $from_forum_array['forum_last_poster_name'] = ''; - $from_forum_array['forum_last_post_title'] = ''; - $from_forum_array['forum_last_post_time'] = 0; + $update_list[$forum_id][] = $topic_id; } - // update the old forum - $db->sql_handle_data('UPDATE', FORUMS_TABLE, $from_forum_array, "forum_id = $from_forum_id"); - - // add the numbers to the new forum row - $to_forum_array = array( - 'forum_posts' => $forum_row[$to_forum_id]['forum_posts'] + $topic_row['forum_posts'], - 'forum_shadow_posts' => $forum_row[$to_forum_id]['forum_shadow_posts'] + $topic_row['forum_shadow_posts'], - 'forum_deleted_posts' => $forum_row[$to_forum_id]['forum_deleted_posts'] + $topic_row['forum_deleted_posts'], - 'forum_unapproved_posts'=> $forum_row[$to_forum_id]['forum_unapproved_posts'] + $topic_row['forum_unapproved_posts'], + // we save as many queries as we can by updating all similar topics at once + foreach ($update_list as $forum_id => $topic_ids) + { + // update the topic itself + $db->sql_handle_data('UPDATE', TOPICS_TABLE, array('forum_id' => $to_forum_id), $db->sql_in_set('topic_id', $topic_ids)); - 'forum_topics' => $forum_row[$from_forum_id]['forum_topics'] + 1, - 'forum_shadow_topics' => $forum_row[$from_forum_id]['forum_shadow_topics'] + (($topic_row['topic_shadow_id'] != 0) ? 1 : 0), - 'forum_deleted_topics' => $forum_row[$from_forum_id]['forum_deleted_topics'] + (($topic_status === self::DELETED) ? 1 : 0), - 'forum_unapproved_topics' => $forum_row[$from_forum_id]['forum_unapproved_topics'] + (($topic_status === self::UNAPPROVED) ? 1 : 0), - ); + // update the posts now + $db->sql_handle_data('UPDATE', POSTS_TABLE, array('forum_id' => $to_forum_id), $db->sql_in_set('topic_id', $topic_ids)); + } - // the new topic is approved and is not soft deleted and is not unapproved, go and sync some status - if ($topic_status === self::NORMAL) + // start building the needed arrays for updating the forum data + foreach ($forum_lookup as $forum_id => $forum_data) { - // get the lastest "normal" post in the new forum, we _must_ update it + foreach ($forum_columns as $column) + { + $forum_data[$column] = max($forum_data[$column], 0); // ensure the result is unsigned + } + + // get the last "normal" post in the old forum, we _must_ update it $sql = 'SELECT MAX(post_id) as max_post_id FROM ' . POSTS_TABLE . ' WHERE post_status = ' . self::NORMAL . ' - AND forum_id = ' . $to_forum_id; + AND forum_id = ' . $forum_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - - // we better find something... after all, we just moved a topic here! + + // anything left? if ($row) { // OK, lets go do some magick @@ -619,17 +833,26 @@ class posting_api $last_post = $db->sql_fetchrow($result); $db->sql_freeresult($result); - $from_forum_array['forum_last_user_id'] = (int) $last_post['poster_id']; - $from_forum_array['forum_last_poster_name'] = $last_post['post_username']; - $from_forum_array['forum_last_post_title'] = $last_post['post_subject']; - $from_forum_array['forum_last_post_time'] = (int) $last_post['post_time']; + $forum_data['forum_last_user_id'] = (int) $last_post['poster_id']; + $forum_data['forum_last_poster_name'] = $last_post['post_username']; + $forum_data['forum_last_post_title'] = $last_post['post_subject']; + $forum_data['forum_last_post_time'] = (int) $last_post['post_time']; + } + else + { + // reset forum state + $forum_data['forum_last_user_id'] = 0; + $forum_data['forum_last_poster_name'] = ''; + $forum_data['forum_last_post_title'] = ''; + $forum_data['forum_last_post_time'] = 0; } + + // update the old forum + $db->sql_handle_data('UPDATE', FORUMS_TABLE, $forum_data, "forum_id = $forum_id"); } - // update the new forum - $db->sql_handle_data('UPDATE', FORUMS_TABLE, $to_forum_array, "forum_id = $to_forum_id"); - - if ($make_shadow === true) + // hooray for code reuse! + foreach ($shadow_topic_ids as $topic_id) { $data['shadow_topic_id'] = $topic_id; $data['forum_id'] = $from_forum_id; @@ -637,6 +860,7 @@ class posting_api } $db->sql_transaction('commit'); + } } |