aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB')
-rw-r--r--phpBB/develop/posting-api.php544
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');
+
}
}