diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index dc187f6ed1..876e42f474 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -323,6 +323,8 @@ class acp_forums break; + case 'sync_topic': + case 'sync_topic': @set_time_limit(0); @@ -336,7 +338,14 @@ class acp_forums if ($row['forum_topics_real']) { - $start = request_var('start', 0); + $sql = 'SELECT MIN(topic_id) as min_topic_id, MAX(topic_id) as max_topic_id + FROM ' . TOPICS_TABLE . ' + WHERE forum_id = ' . $forum_id; + $result = $db->sql_query($sql); + $row2 = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $start = request_var('start', $row2['min_topic_id']); $batch_size = 3000; $end = $start + $batch_size; @@ -345,11 +354,20 @@ class acp_forums sync('topic_approved', 'range', 'topic_id BETWEEN ' . $start . ' AND ' . $end, true, false); sync('topic', 'range', 'topic_id BETWEEN ' . $start . ' AND ' . $end, true, true); - if ($end < $row['forum_topics_real']) + if ($end < $row2['max_topic_id']) { + // We really need to find a way of showing statistics... no progress here + $sql = 'SELECT COUNT(topic_id) as num_topics + FROM ' . TOPICS_TABLE . ' + WHERE forum_id = ' . $forum_id . ' + AND topic_id BETWEEN ' . $start . ' AND ' . $end; + $result = $db->sql_query($sql); + $topics_done = request_var('topics_done', 0) + (int) $db->sql_fetchfield('num_topics'); + $db->sql_freeresult($result); + $start += $batch_size; - $url = $this->u_action . "&parent_id={$this->parent_id}&f=$forum_id&action=sync_topic&start=$start&total={$row['forum_topics_real']}"; + $url = $this->u_action . "&parent_id={$this->parent_id}&f=$forum_id&action=sync_topic&start=$start&topics_done=$topics_done&total={$row['forum_topics_real']}"; meta_refresh(0, $url); @@ -357,7 +375,7 @@ class acp_forums 'U_PROGRESS_BAR' => $this->u_action . "&action=progress_bar&start=$start&total={$row['forum_topics_real']}", 'UA_PROGRESS_BAR' => str_replace('&', '&', $this->u_action) . "&action=progress_bar&start=$start&total={$row['forum_topics_real']}", 'S_CONTINUE_SYNC' => true, - 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $start, $row['forum_topics_real'])) + 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $topics_done, $row['forum_topics_real'])) ); return; diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index f2964a2f39..62a025da97 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -1691,31 +1691,6 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, unset($delete_topics, $delete_topic_ids); } - // Make sure shadow topics do link to existing topics - if (sizeof($moved_topics)) - { - $delete_topics = array(); - - $sql = 'SELECT t1.topic_id, t1.topic_moved_id - FROM ' . TOPICS_TABLE . ' t1 - LEFT JOIN ' . TOPICS_TABLE . ' t2 ON (t2.topic_id = t1.topic_moved_id) - WHERE ' . $db->sql_in_set('t1.topic_id', $moved_topics) . ' - AND t2.topic_id IS NULL'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $delete_topics[] = $row['topic_id']; - } - $db->sql_freeresult($result); - - if (sizeof($delete_topics)) - { - delete_topics('topic_id', $delete_topics, false); - } - unset($delete_topics); - } - $sql = 'SELECT p.post_id, p.topic_id, p.post_approved, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . ' @@ -1750,6 +1725,111 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, } $db->sql_freeresult($result); + // Make sure shadow topics do link to existing topics + if (sizeof($moved_topics)) + { + $delete_topics = array(); + + $sql = 'SELECT t1.topic_id, t1.topic_moved_id + FROM ' . TOPICS_TABLE . ' t1 + LEFT JOIN ' . TOPICS_TABLE . ' t2 ON (t2.topic_id = t1.topic_moved_id) + WHERE ' . $db->sql_in_set('t1.topic_id', $moved_topics) . ' + AND t2.topic_id IS NULL'; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $delete_topics[] = $row['topic_id']; + } + $db->sql_freeresult($result); + + if (sizeof($delete_topics)) + { + delete_topics('topic_id', $delete_topics, false); + } + unset($delete_topics); + + // Make sure shadow topics having no last post data being updated (this only rarely happens...) + $sql = 'SELECT topic_id, topic_moved_id, topic_last_post_id, topic_first_post_id + FROM ' . TOPICS_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $moved_topics) . ' + AND topic_last_post_time = 0'; + $result = $db->sql_query($sql); + + $shadow_topic_data = $post_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $shadow_topic_data[$row['topic_moved_id']] = $row; + $post_ids[] = $row['topic_last_post_id']; + $post_ids[] = $row['topic_first_post_id']; + } + $db->sql_freeresult($result); + + $sync_shadow_topics = array(); + if (sizeof($post_ids)) + { + $sql = 'SELECT p.post_id, p.topic_id, p.post_approved, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour + FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u + WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . ' + AND u.user_id = p.poster_id'; + $result = $db->sql_query($sql); + + $post_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $topic_id = (int) $row['topic_id']; + + if ($row['post_id'] == $shadow_topic_data[$topic_id]['topic_first_post_id']) + { + $orig_topic_id = $shadow_topic_data[$topic_id]['topic_id']; + + if (!isset($sync_shadow_topics[$orig_topic_id])) + { + $sync_shadow_topics[$orig_topic_id] = array(); + } + + $sync_shadow_topics[$orig_topic_id]['topic_time'] = $row['post_time']; + $sync_shadow_topics[$orig_topic_id]['topic_poster'] = $row['poster_id']; + $sync_shadow_topics[$orig_topic_id]['topic_first_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']; + $sync_shadow_topics[$orig_topic_id]['topic_first_poster_colour'] = $row['user_colour']; + } + + if ($row['post_id'] == $shadow_topic_data[$topic_id]['topic_last_post_id']) + { + $orig_topic_id = $shadow_topic_data[$topic_id]['topic_id']; + + if (!isset($sync_shadow_topics[$orig_topic_id])) + { + $sync_shadow_topics[$orig_topic_id] = array(); + } + + $sync_shadow_topics[$orig_topic_id]['topic_last_poster_id'] = $row['poster_id']; + $sync_shadow_topics[$orig_topic_id]['topic_last_post_subject'] = $row['post_subject']; + $sync_shadow_topics[$orig_topic_id]['topic_last_post_time'] = $row['post_time']; + $sync_shadow_topics[$orig_topic_id]['topic_last_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']; + $sync_shadow_topics[$orig_topic_id]['topic_last_poster_colour'] = $row['user_colour']; + } + } + $db->sql_freeresult($result); + + $shadow_topic_data = array(); + + // Update the information we collected + if (sizeof($sync_shadow_topics)) + { + foreach ($sync_shadow_topics as $sync_topic_id => $sql_ary) + { + $sql = 'UPDATE ' . TOPICS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE topic_id = ' . $sync_topic_id; + $db->sql_query($sql); + } + } + } + + unset($sync_shadow_topics, $shadow_topic_data); + } + // approved becomes unapproved, and vice-versa if (sizeof($approved_unapproved_ids)) {