diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 8334214de2..30d624c08f 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -196,6 +196,7 @@
[Feature] Store signature configuration options in database (Bug #45115 - Patch by rxu)
[Feature] Add bare-bones quick-reply editor to viewtopic.
[Feature] Detect when a post has been altered by someone else while editing. (Patch by bantu)
+ [Feature] Add unread posts quick search option (Bug #46765 - Patch by rxu)
1.ii. Changes since 3.0.4
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 84bbb964de..74f7e31bee 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -3896,6 +3896,7 @@ function page_header($page_title = '', $display_online_list = true)
'U_SEARCH_SELF' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=egosearch'),
'U_SEARCH_NEW' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=newposts'),
'U_SEARCH_UNANSWERED' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=unanswered'),
+ 'U_SEARCH_UNREAD' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=unreadposts'),
'U_SEARCH_ACTIVE_TOPICS'=> append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=active_topics'),
'U_DELETE_COOKIES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=delete_cookies'),
'U_TEAM' => ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=leaders'),
@@ -4119,4 +4120,94 @@ function phpbb_user_session_handler()
return;
}
+/*
+* Get list of unread topics
+* only for registered users and non-cookie tracking this function is used
+*/
+function get_unread_topics_list($user_id = false, $sql_extra = '')
+{
+ global $config, $db, $user;
+
+ if($user_id === false)
+ {
+ $user_id = $user->data['user_id'];
+ }
+
+ $tracked_topics_list = $unread_topics_list = $read_topics_list = array();
+ $tracked_forums_list = array();
+
+ if ($config['load_db_lastread'] && $user->data['is_registered'])
+ {
+ // List of the tracked forums (not ideal, hope the better way will be found)
+ // This list is to fetch later the forums user never read (fully) before
+ $sql = 'SELECT forum_id FROM ' . FORUMS_TRACK_TABLE . "
+ WHERE user_id = {$user_id}";
+ $result = $db->sql_query($sql);
+ while($row = $db->sql_fetchrow($result))
+ {
+ $tracked_forums_list[] = $row['forum_id'];
+ }
+ $db->sql_freeresult($result);
+
+ // Get list of the unread topics - on topics tracking as the first step
+ $sql = 'SELECT t.topic_id, t.topic_last_post_time, tt.mark_time FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TRACK_TABLE . " tt
+ WHERE t.topic_id = tt.topic_id
+ AND t.topic_last_post_time >= tt.mark_time
+ AND tt.user_id = {$user_id}
+ $sql_extra";
+ $result = $db->sql_query($sql);
+ while($row = $db->sql_fetchrow($result))
+ {
+ if($row['topic_last_post_time'] == $row['mark_time'])
+ {
+ // Check if there're read topics for the forums having unread ones
+ $read_topics_list[$row['topic_id']] = $row['mark_time'];
+ }
+ else
+ {
+ $unread_topics_list[$row['topic_id']] = $row['mark_time'];
+ }
+ }
+ $db->sql_freeresult($result);
+
+ // Get the full list of the tracked topics
+ $tracked_topics_list = array_merge(array_keys($unread_topics_list), array_keys($read_topics_list));
+
+ // Get list of the unread topics - on forums tracking as the second step
+ // We don't take in account topics tracked before
+ $sql = 'SELECT t.topic_id, ft.mark_time FROM ' . TOPICS_TABLE . ' t, ' . FORUMS_TRACK_TABLE . ' ft
+ WHERE t.forum_id = ft.forum_id
+ AND t.topic_last_post_time > ft.mark_time
+ AND ' . $db->sql_in_set('t.topic_id', $tracked_topics_list, true, true) . "
+ AND ft.user_id = {$user_id}
+ $sql_extra";
+ $result = $db->sql_query($sql);
+ while($row = $db->sql_fetchrow($result))
+ {
+ $unread_topics_list[$row['topic_id']] = $row['mark_time'];
+ }
+ $db->sql_freeresult($result);
+
+ // And the last step - find unread topics were not found before (that can mean a user has never read some forums)
+ $sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . "
+ WHERE topic_last_post_time > {$user->data['user_lastmark']}
+ AND " . $db->sql_in_set('topic_id', array_keys($unread_topics_list), true, true) . '
+ AND ' . $db->sql_in_set('forum_id', $tracked_forums_list, true, true) . "
+ $sql_extra";
+ $result = $db->sql_query_limit($sql, 1000);
+ while($row = $db->sql_fetchrow($result))
+ {
+ $unread_topics_list[$row['topic_id']] = $user->data['user_lastmark'];
+ }
+ $db->sql_freeresult($result);
+ }
+ else if ($config['load_anon_lastread'] || $user->data['is_registered'])
+ {
+ // We do not implement unread topics list for cookie based tracking
+ // because it would require expensive database queries
+ }
+
+ return $unread_topics_list;
+}
+
?>
\ No newline at end of file
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index 6f3433892a..a2b8eafd52 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -522,6 +522,7 @@ $lang = array_merge($lang, array(
'SEARCH_SELF' => 'View your posts',
'SEARCH_TOPIC' => 'Search this topic…',
'SEARCH_UNANSWERED' => 'View unanswered posts',
+ 'SEARCH_UNREAD' => 'View unread posts',
'SECONDS' => 'Seconds',
'SELECT' => 'Select',
'SELECT_ALL_CODE' => 'Select all',
diff --git a/phpBB/search.php b/phpBB/search.php
index 48c0290d87..61aa16a6fb 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -364,6 +364,39 @@ if ($keywords || $author || $author_id || $search_id || $submit)
}
break;
+ case 'unreadposts':
+ if ($config['load_db_lastread'] && $user->data['is_registered'])
+ {
+ $l_search_title = $user->lang['SEARCH_UNREAD'];
+ // force sorting
+ $show_results = 'topics';
+ $sort_key = 't';
+ $sort_dir = 'd';
+ $sort_by_sql['t'] = 't.topic_last_post_time';
+ $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
+
+ 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);
+ $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = '';
+
+ $unread_list = array();
+ $unread_list = get_unread_topics_list();
+
+ if(!empty($unread_list))
+ {
+ $sql = 'SELECT t.topic_id
+ FROM ' . TOPICS_TABLE . ' t
+ WHERE ' . $db->sql_in_set('t.topic_id', array_keys($unread_list)) . '
+ AND t.topic_moved_id = 0
+ ' . str_replace(array('p.', 'post_'), array('t.', 'topic_'), $m_approve_fid_sql) . '
+ ' . ((sizeof($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . "
+ $sql_sort";
+ $field = 'topic_id';
+ }
+ break;
+ }
+ // Do nothing if it's cookie based read tracking
+ // Just do not break and let user to see newposts
+
case 'newposts':
$l_search_title = $user->lang['SEARCH_NEW'];
// force sorting
diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html
index 43d8ad0309..9cb4d2067d 100644
--- a/phpBB/styles/prosilver/template/index_body.html
+++ b/phpBB/styles/prosilver/template/index_body.html
@@ -6,7 +6,7 @@
diff --git a/phpBB/styles/subsilver2/template/overall_header.html b/phpBB/styles/subsilver2/template/overall_header.html
index 3dd8740832..a45e51b467 100644
--- a/phpBB/styles/subsilver2/template/overall_header.html
+++ b/phpBB/styles/subsilver2/template/overall_header.html
@@ -201,7 +201,7 @@ function marklist(id, name, state)
{L_SEARCH_UNANSWERED} | {L_SEARCH_ACTIVE_TOPICS}
- {L_SEARCH_NEW} | {L_SEARCH_SELF}
+ {L_SEARCH_UNREAD} | {L_SEARCH_NEW} | {L_SEARCH_SELF}