From 752c73193e04f7eb22b3b90ad746a6b277e59272 Mon Sep 17 00:00:00 2001
From: Marc Alexander <admin@m-a-styles.de>
Date: Sun, 10 Aug 2014 16:49:01 +0200
Subject: [PATCH 1/2] [ticket/12966] Sort posts by post_id in addition to
 sorting by post_time

This should make sure that posts with the same post time are properly sorted
on database backends like postgres.

PHPBB3-12966
---
 phpBB/viewtopic.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index 50481302e6..dfee8fd2f7 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -388,7 +388,7 @@ if (!isset($topic_tracking_info))
 $limit_days = array(0 => $user->lang['ALL_POSTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
 
 $sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 's' => $user->lang['SUBJECT']);
-$sort_by_sql = array('a' => array('u.username_clean', 'p.post_id'), 't' => 'p.post_time', 's' => array('p.post_subject', 'p.post_id'));
+$sort_by_sql = array('a' => array('u.username_clean', 'p.post_id'), 't' => array('p.post_time', 'p.post_id'), 's' => array('p.post_subject', 'p.post_id'));
 $join_user_sql = array('a' => true, 't' => false, 's' => false);
 
 $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';

From e5e45f860b798c955f1817001f07aabcbccbabcf Mon Sep 17 00:00:00 2001
From: Marc Alexander <admin@m-a-styles.de>
Date: Sat, 23 Aug 2014 16:36:39 +0200
Subject: [PATCH 2/2] [ticket/12966] Sort by post_time and post_id where
 applicable

This change was not applied to the search as this would require a larger
rewrite of the search methods.

PHPBB3-12966
---
 phpBB/includes/functions.php         |  2 +-
 phpBB/includes/functions_mcp.php     | 17 +++++++++++++----
 phpBB/includes/functions_posting.php | 10 +++++-----
 phpBB/includes/mcp/mcp_front.php     |  6 +++---
 phpBB/includes/mcp/mcp_main.php      |  2 +-
 phpBB/includes/ucp/ucp_main.php      |  6 +++---
 phpBB/includes/ucp/ucp_prefs.php     |  2 +-
 phpBB/phpbb/feed/forum.php           |  4 ++--
 phpBB/phpbb/feed/news.php            |  2 +-
 phpBB/phpbb/feed/overall.php         |  4 ++--
 phpBB/phpbb/feed/topic.php           |  2 +-
 phpBB/phpbb/feed/topics.php          |  2 +-
 phpBB/phpbb/feed/topics_active.php   |  4 ++--
 phpBB/viewforum.php                  | 15 ++++++++++++---
 phpBB/viewtopic.php                  |  4 ++--
 15 files changed, 50 insertions(+), 32 deletions(-)

diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 4318b20b97..3fe13ae1e1 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -1638,7 +1638,7 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
 
 	if (empty($sql_sort))
 	{
-		$sql_sort = 'ORDER BY t.topic_last_post_time DESC';
+		$sql_sort = 'ORDER BY t.topic_last_post_time DESC, t.topic_last_post_id DESC';
 	}
 
 	if ($config['load_db_lastread'] && $user->data['is_registered'])
diff --git a/phpBB/includes/functions_mcp.php b/phpBB/includes/functions_mcp.php
index 7593f08f4d..811d49f1de 100644
--- a/phpBB/includes/functions_mcp.php
+++ b/phpBB/includes/functions_mcp.php
@@ -521,21 +521,21 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
 			$limit_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
 			$sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'tt' => $user->lang['TOPIC_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']);
 
-			$sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'tt' => 't.topic_time', 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 't.topic_title', 'v' => 't.topic_views');
+			$sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => array('t.topic_last_post_time', 't.topic_last_post_id'), 'tt' => 't.topic_time', 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 't.topic_title', 'v' => 't.topic_views');
 			$limit_time_sql = ($min_time) ? "AND t.topic_last_post_time >= $min_time" : '';
 			break;
 
 		case 'posts':
 			$limit_days = array(0 => $user->lang['ALL_POSTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
 			$sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 's' => $user->lang['SUBJECT']);
-			$sort_by_sql = array('a' => 'u.username_clean', 't' => 'p.post_time', 's' => 'p.post_subject');
+			$sort_by_sql = array('a' => 'u.username_clean', 't' => array('p.post_time', 'p.post_id'), 's' => 'p.post_subject');
 			$limit_time_sql = ($min_time) ? "AND p.post_time >= $min_time" : '';
 			break;
 
 		case 'reports':
 			$limit_days = array(0 => $user->lang['ALL_REPORTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
 			$sort_by_text = array('a' => $user->lang['AUTHOR'], 'r' => $user->lang['REPORTER'], 'p' => $user->lang['POST_TIME'], 't' => $user->lang['REPORT_TIME'], 's' => $user->lang['SUBJECT']);
-			$sort_by_sql = array('a' => 'u.username_clean', 'r' => 'ru.username', 'p' => 'p.post_time', 't' => 'r.report_time', 's' => 'p.post_subject');
+			$sort_by_sql = array('a' => 'u.username_clean', 'r' => 'ru.username', 'p' => array('p.post_time', 'p.post_id'), 't' => 'r.report_time', 's' => 'p.post_subject');
 			break;
 
 		case 'pm_reports':
@@ -558,7 +558,16 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
 		$sort_key = $default_key;
 	}
 
-	$sort_order_sql = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
+	$direction = ($sort_dir == 'd') ? 'DESC' : 'ASC';
+
+	if (is_array($sort_by_sql[$sort_key]))
+	{
+		$sort_order_sql = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
+	}
+	else
+	{
+		$sort_order_sql = $sort_by_sql[$sort_key] . ' ' . $direction;
+	}
 
 	$s_limit_days = $s_sort_key = $s_sort_dir = $sort_url = '';
 	gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $sort_url);
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 624ce187b9..bc35f4e76b 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -1040,6 +1040,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
 	global $config, $phpbb_root_path, $phpEx, $phpbb_container;
 
 	$phpbb_content_visibility = $phpbb_container->get('content.visibility');
+	$sql_sort = ($mode == 'post_review') ? 'ASC' : 'DESC';
 
 	// Go ahead and pull all data for this topic
 	$sql = 'SELECT p.post_id
@@ -1048,8 +1049,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
 			AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.') . '
 			' . (($mode == 'post_review') ? " AND p.post_id > $cur_post_id" : '') . '
 			' . (($mode == 'post_review_edit') ? " AND p.post_id = $cur_post_id" : '') . '
-		ORDER BY p.post_time ';
-	$sql .= ($mode == 'post_review') ? 'ASC' : 'DESC';
+		ORDER BY p.post_time ' . $sql_sort . ', p.post_id ' . $sql_sort;
 	$result = $db->sql_query_limit($sql, $config['posts_per_page']);
 
 	$post_list = array();
@@ -1342,7 +1342,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
 				WHERE p.topic_id = $topic_id
 					AND p.poster_id = u.user_id
 					AND p.post_visibility = " . ITEM_APPROVED . '
-				ORDER BY p.post_time ASC';
+				ORDER BY p.post_time ASC, p.post_id ASC';
 			$result = $db->sql_query_limit($sql, 1);
 			$row = $db->sql_fetchrow($result);
 			$db->sql_freeresult($result);
@@ -1354,7 +1354,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
 					FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u
 					WHERE p.topic_id = $topic_id
 						AND p.poster_id = u.user_id
-					ORDER BY p.post_time ASC";
+					ORDER BY p.post_time ASC, p.post_id ASC";
 				$result = $db->sql_query_limit($sql, 1);
 				$row = $db->sql_fetchrow($result);
 				$db->sql_freeresult($result);
@@ -1409,7 +1409,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
 				WHERE topic_id = $topic_id
 					AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id) . '
 					AND post_time > ' . $data['post_time'] . '
-				ORDER BY post_time ASC';
+				ORDER BY post_time ASC, post_id ASC';
 			$result = $db->sql_query_limit($sql, 1);
 			$next_post_id = (int) $db->sql_fetchfield('post_id');
 			$db->sql_freeresult($result);
diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php
index b4ec0092e7..ebcf7ce643 100644
--- a/phpBB/includes/mcp/mcp_front.php
+++ b/phpBB/includes/mcp/mcp_front.php
@@ -66,7 +66,7 @@ function mcp_front_view($id, $mode, $action)
 					FROM ' . POSTS_TABLE . '
 					WHERE ' . $db->sql_in_set('forum_id', $forum_list) . '
 						AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . '
-					ORDER BY post_time DESC';
+					ORDER BY post_time DESC, post_id DESC';
 				$result = $db->sql_query_limit($sql, 5);
 
 				while ($row = $db->sql_fetchrow($result))
@@ -101,7 +101,7 @@ function mcp_front_view($id, $mode, $action)
 					WHERE ' . $db->sql_in_set('p.post_id', $post_list) . '
 						AND t.topic_id = p.topic_id
 						AND p.poster_id = u.user_id
-					ORDER BY p.post_time DESC';
+					ORDER BY p.post_time DESC, p.post_id DESC';
 				$result = $db->sql_query($sql);
 
 				while ($row = $db->sql_fetchrow($result))
@@ -190,7 +190,7 @@ function mcp_front_view($id, $mode, $action)
 						AND p.poster_id = u2.user_id
 						AND ' . $db->sql_in_set('p.forum_id', $forum_list),
 
-					'ORDER_BY'	=> 'p.post_time DESC',
+					'ORDER_BY'	=> 'p.post_time DESC, p.post_id DESC',
 				);
 
 				/**
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 92000c6ceb..f03bc034e4 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -1265,7 +1265,7 @@ function mcp_fork_topic($topic_ids)
 			$sql = 'SELECT *
 				FROM ' . POSTS_TABLE . "
 				WHERE topic_id = $topic_id
-				ORDER BY post_time ASC";
+				ORDER BY post_time ASC, post_id ASC";
 			$result = $db->sql_query($sql);
 
 			$post_rows = array();
diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php
index 304c04eb3d..a1624e78ec 100644
--- a/phpBB/includes/ucp/ucp_main.php
+++ b/phpBB/includes/ucp/ucp_main.php
@@ -81,7 +81,7 @@ class ucp_main
 						FROM $sql_from
 						WHERE t.topic_type = " . POST_GLOBAL . '
 							AND ' . $db->sql_in_set('t.forum_id', $forum_ary) . '
-						ORDER BY t.topic_last_post_time DESC';
+						ORDER BY t.topic_last_post_time DESC, t.topic_last_post_id DESC';
 					$result = $db->sql_query($sql);
 
 					while ($row = $db->sql_fetchrow($result))
@@ -693,7 +693,7 @@ class ucp_main
 					AND t.topic_id = tw.topic_id
 					AND ' . $db->sql_in_set('t.forum_id', $forbidden_forum_ary, true, true),
 
-				'ORDER_BY'	=> 't.topic_last_post_time DESC'
+				'ORDER_BY'	=> 't.topic_last_post_time DESC, t.topic_last_post_id DESC'
 			);
 
 			$sql_array['LEFT_JOIN'] = array();
@@ -710,7 +710,7 @@ class ucp_main
 				'WHERE'		=> 'b.user_id = ' . $user->data['user_id'] . '
 					AND ' . $db->sql_in_set('f.forum_id', $forbidden_forum_ary, true, true),
 
-				'ORDER_BY'	=> 't.topic_last_post_time DESC'
+				'ORDER_BY'	=> 't.topic_last_post_time DESC, t.topic_last_post_id DESC'
 			);
 
 			$sql_array['LEFT_JOIN'] = array();
diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php
index a8c8920a7d..b0a8e8d374 100644
--- a/phpBB/includes/ucp/ucp_prefs.php
+++ b/phpBB/includes/ucp/ucp_prefs.php
@@ -320,7 +320,7 @@ class ucp_prefs
 				$limit_topic_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
 
 				$sort_by_topic_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']);
-				$sort_by_topic_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'r' => 't.topic_posts_approved', 's' => 't.topic_title', 'v' => 't.topic_views');
+				$sort_by_topic_sql = array('a' => 't.topic_first_poster_name', 't' => array('t.topic_last_post_time', 't.topic_last_post_id'), 'r' => 't.topic_posts_approved', 's' => 't.topic_title', 'v' => 't.topic_views');
 
 				// Post ordering options
 				$limit_post_days = array(0 => $user->lang['ALL_POSTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php
index 610b755af3..7a2087c1cd 100644
--- a/phpBB/phpbb/feed/forum.php
+++ b/phpBB/phpbb/feed/forum.php
@@ -94,7 +94,7 @@ class forum extends \phpbb\feed\post_base
 			WHERE forum_id = ' . $this->forum_id . '
 				AND topic_moved_id = 0
 				AND ' . $this->content_visibility->get_visibility_sql('topic', $this->forum_id) . '
-			ORDER BY topic_last_post_time DESC';
+			ORDER BY topic_last_post_time DESC, topic_last_post_id DESC';
 		$result = $this->db->sql_query_limit($sql, $this->num_items);
 
 		$topic_ids = array();
@@ -123,7 +123,7 @@ class forum extends \phpbb\feed\post_base
 							AND ' . $this->content_visibility->get_visibility_sql('post', $this->forum_id, 'p.') . '
 							AND p.post_time >= ' . $min_post_time . '
 							AND p.poster_id = u.user_id',
-			'ORDER_BY'	=> 'p.post_time DESC',
+			'ORDER_BY'	=> 'p.post_time DESC, p.post_id DESC',
 		);
 
 		return true;
diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php
index ea5f4febf5..a02c199d85 100644
--- a/phpBB/phpbb/feed/news.php
+++ b/phpBB/phpbb/feed/news.php
@@ -99,7 +99,7 @@ class news extends \phpbb\feed\topic_base
 			),
 			'WHERE'		=> 'p.topic_id = t.topic_id
 							AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
-			'ORDER_BY'	=> 'p.post_time DESC',
+			'ORDER_BY'	=> 'p.post_time DESC, p.post_id DESC',
 		);
 
 		return true;
diff --git a/phpBB/phpbb/feed/overall.php b/phpBB/phpbb/feed/overall.php
index f6847c041e..ab452f5386 100644
--- a/phpBB/phpbb/feed/overall.php
+++ b/phpBB/phpbb/feed/overall.php
@@ -34,7 +34,7 @@ class overall extends \phpbb\feed\post_base
 			FROM ' . TOPICS_TABLE . '
 			WHERE topic_moved_id = 0
 				AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $forum_ids) . '
-			ORDER BY topic_last_post_time DESC';
+			ORDER BY topic_last_post_time DESC, topic_last_post_id DESC';
 		$result = $this->db->sql_query_limit($sql, $this->num_items);
 
 		$topic_ids = array();
@@ -71,7 +71,7 @@ class overall extends \phpbb\feed\post_base
 							AND ' . $this->content_visibility->get_forums_visibility_sql('post', $forum_ids, 'p.') . '
 							AND p.post_time >= ' . $min_post_time . '
 							AND u.user_id = p.poster_id',
-			'ORDER_BY'	=> 'p.post_time DESC',
+			'ORDER_BY'	=> 'p.post_time DESC, p.post_id DESC',
 		);
 
 		return true;
diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php
index 78e0b4b8ab..66c49e55cf 100644
--- a/phpBB/phpbb/feed/topic.php
+++ b/phpBB/phpbb/feed/topic.php
@@ -101,7 +101,7 @@ class topic extends \phpbb\feed\post_base
 			'WHERE'		=> 'p.topic_id = ' . $this->topic_id . '
 								AND ' . $this->content_visibility->get_visibility_sql('post', $this->forum_id, 'p.') . '
 								AND p.poster_id = u.user_id',
-			'ORDER_BY'	=> 'p.post_time DESC',
+			'ORDER_BY'	=> 'p.post_time DESC, p.post_id DESC',
 		);
 
 		return true;
diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php
index 88ca7c33f3..2b9cb3501a 100644
--- a/phpBB/phpbb/feed/topics.php
+++ b/phpBB/phpbb/feed/topics.php
@@ -71,7 +71,7 @@ class topics extends \phpbb\feed\topic_base
 			),
 			'WHERE'		=> 'p.topic_id = t.topic_id
 							AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
-			'ORDER_BY'	=> 'p.post_time DESC',
+			'ORDER_BY'	=> 'p.post_time DESC, p.post_id DESC',
 		);
 
 		return true;
diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php
index cde6d36f45..6d5eddfc16 100644
--- a/phpBB/phpbb/feed/topics_active.php
+++ b/phpBB/phpbb/feed/topics_active.php
@@ -56,7 +56,7 @@ class topics_active extends \phpbb\feed\topic_base
 			WHERE topic_moved_id = 0
 				AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $in_fid_ary) . '
 				' . $last_post_time_sql . '
-			ORDER BY topic_last_post_time DESC';
+			ORDER BY topic_last_post_time DESC, topic_last_post_id DESC';
 		$result = $this->db->sql_query_limit($sql, $this->num_items);
 
 		$post_ids = array();
@@ -88,7 +88,7 @@ class topics_active extends \phpbb\feed\topic_base
 			),
 			'WHERE'		=> 'p.topic_id = t.topic_id
 							AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
-			'ORDER_BY'	=> 'p.post_time DESC',
+			'ORDER_BY'	=> 'p.post_time DESC, p.post_id DESC',
 		);
 
 		return true;
diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php
index 9086feb390..9ecbdea77a 100644
--- a/phpBB/viewforum.php
+++ b/phpBB/viewforum.php
@@ -264,7 +264,7 @@ gen_forum_auth_level('forum', $forum_id, $forum_data['forum_status']);
 $limit_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
 
 $sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']);
-$sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 't.topic_title', 'v' => 't.topic_views');
+$sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => array('t.topic_last_post_time', 't.topic_last_post_id'), 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 't.topic_title', 'v' => 't.topic_views');
 
 $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
 gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param, $default_sort_days, $default_sort_key, $default_sort_dir);
@@ -497,7 +497,7 @@ if ($start > $topics_count / 2)
 	$store_reverse = true;
 
 	// Select the sort order
-	$sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'ASC' : 'DESC');
+	$direction = (($sort_dir == 'd') ? 'ASC' : 'DESC');
 
 	$sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count);
 	$sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count);
@@ -505,10 +505,19 @@ if ($start > $topics_count / 2)
 else
 {
 	// Select the sort order
-	$sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
+	$direction = (($sort_dir == 'd') ? 'DESC' : 'ASC');
 	$sql_start = $start;
 }
 
+if (is_array($sort_by_sql[$sort_key]))
+{
+	$sql_sort_order = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
+}
+else
+{
+	$sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction;
+}
+
 if ($forum_data['forum_type'] == FORUM_POST || !sizeof($active_forum_ary))
 {
 	$sql_where = 't.forum_id = ' . $forum_id;
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index dfee8fd2f7..3d1bce1ccc 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -94,7 +94,7 @@ if ($view && !$post_id)
 				AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id) . "
 				AND post_time > $topic_last_read
 				AND forum_id = $forum_id
-			ORDER BY post_time ASC";
+			ORDER BY post_time ASC, post_id ASC";
 		$result = $db->sql_query_limit($sql, 1);
 		$row = $db->sql_fetchrow($result);
 		$db->sql_freeresult($result);
@@ -146,7 +146,7 @@ if ($view && !$post_id)
 					AND topic_moved_id = 0
 					AND topic_last_post_time $sql_condition {$row['topic_last_post_time']}
 					AND " . $phpbb_content_visibility->get_visibility_sql('topic', $row['forum_id']) . "
-				ORDER BY topic_last_post_time $sql_ordering";
+				ORDER BY topic_last_post_time $sql_ordering, topic_last_post_id $sql_ordering";
 			$result = $db->sql_query_limit($sql, 1);
 			$row = $db->sql_fetchrow($result);
 			$db->sql_freeresult($result);