1<?php
2// This file is part of BOINC.
3// http://boinc.berkeley.edu
4// Copyright (C) 2008 University of California
5//
6// BOINC is free software; you can redistribute it and/or modify it
7// under the terms of the GNU Lesser General Public License
8// as published by the Free Software Foundation,
9// either version 3 of the License, or (at your option) any later version.
10//
11// BOINC is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14// See the GNU Lesser General Public License for more details.
15//
16// You should have received a copy of the GNU Lesser General Public License
17// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
18
19// search for posts or a thread.
20// Takes input from forum_search.php
21
22require_once('../inc/time.inc');
23require_once('../inc/text_transform.inc');
24require_once('../inc/forum.inc');
25
26if (DISABLE_FORUMS) error_page("Forums are disabled");
27
28check_get_args(array());
29
30// Searches for the keywords in the $keyword_list array in thread titles.
31// Optionally filters by forum, user, time, or hidden if specified.
32//
33function search_thread_titles(
34    $keyword_list, $forum="", $user="", $time="", $limit=200,
35    $sort_style=CREATE_TIME_NEW, $show_hidden = false
36){
37    $search_string="%";
38    foreach ($keyword_list as $key => $word) {
39        $search_string .= BoincDb::escape_string($word)."%";
40    }
41    $query = "title like '".$search_string."'";
42    if ($forum && $forum != "all") {
43        $query .= " and forum = $forum->id";
44    }
45    if ($user && $user != "all") {
46        $query .= " and owner = $user->id";
47    }
48    if ($time && $user != "all") {
49        $query .= " and timestamp > $time";
50    }
51    if (!$show_hidden) {
52        $query .= " and thread.hidden = 0";
53    }
54    switch($sort_style) {
55    case MODIFIED_NEW:
56        $query .= ' ORDER BY timestamp DESC';
57        break;
58    case VIEWS_MOST:
59        $query .= ' ORDER BY views DESC';
60        break;
61    case REPLIES_MOST:
62        $query .= ' ORDER BY replies DESC';
63        break;
64    case CREATE_TIME_NEW:
65        $query .= ' ORDER by create_time desc';
66        break;
67    case CREATE_TIME_OLD:
68        $query .= ' ORDER by create_time asc';
69        break;
70    case 'score':
71        $query .= ' ORDER by score desc';
72        break;
73    default:
74        $query .= ' ORDER BY timestamp DESC';
75        break;
76    }
77
78    $query .= " limit $limit";
79    return BoincThread::enum($query);
80}
81
82// Searches for the keywords in the $keyword_list array in post bodies.
83// optionally filters by forum, time, hidden, or user if specified.
84//
85function search_post_content(
86    $keyword_list, $forum, $user, $time, $limit, $sort_style, $show_hidden
87){
88    $db = BoincDb::get();
89
90    $search_string="%";
91    foreach ($keyword_list as $key => $word){
92        $search_string .= BoincDb::escape_string($word)."%";
93    }
94    $optional_join = "";
95    // if looking in a single forum, need to join w/ thread table
96    // because that's where the link to forum is
97    //
98    if ($forum) {
99        $optional_join = " LEFT JOIN ".$db->db_name.".thread ON post.thread = thread.id";
100    }
101    $query = "select post.* from ".$db->db_name.".post".$optional_join." where content like '".$search_string."'";
102    if ($forum) {
103        $query.=" and forum = $forum->id";
104    }
105    if ($user) {
106        $query.=" and post.user = $user->id ";
107    }
108    if ($time) {
109        $query.=" and post.timestamp > $time";
110    }
111    if (!$show_hidden) {
112        $query .= " AND post.hidden = 0";
113    }
114    switch($sort_style) {
115    case VIEWS_MOST:
116        $query.= ' ORDER BY views DESC';
117        break;
118    case CREATE_TIME_NEW:
119        $query .= ' ORDER by post.timestamp desc';
120        break;
121    case CREATE_TIME_OLD:
122        $query .= ' ORDER by post.timestamp asc';
123        break;
124    case POST_SCORE:
125        $query .= ' ORDER by post.score desc';
126        break;
127    default:
128        $query .= ' ORDER BY post.timestamp DESC';
129        break;
130    }
131    $query.= " limit $limit";
132    return BoincPost::enum_general($query);
133}
134
135$logged_in_user = get_logged_in_user(false);
136BoincForumPrefs::lookup($logged_in_user);
137if ($logged_in_user && $logged_in_user->prefs->privilege(S_MODERATOR)){
138    $show_hidden_posts = true;
139} else {
140    $show_hidden_posts = false;
141}
142
143page_head(tra("Forum search results"));
144
145$search_keywords = post_str("search_keywords", true);
146$search_author = post_int("search_author", true);
147$search_max_time = post_int("search_max_time");
148$search_forum = post_int("search_forum");
149$search_sort = post_int("search_sort");
150$search_list = explode(" ",$search_keywords);
151if ($search_max_time) {
152    $min_timestamp = time() - ($search_max_time*3600*24);
153} else {
154    $min_timestamp = 0;
155}
156
157$limit = 100;
158
159if ($search_forum==-1){
160    $forum = null;
161} else if ($search_forum) {
162    $forum = BoincForum::lookup_id($search_forum);
163}
164
165$user = null;
166if ($search_author) {
167    $user = BoincUser::lookup_id($search_author);
168}
169
170// First search thread titles; if we get a hit there it's probably relevant
171//
172$threads = search_thread_titles($search_list, $forum, $user, $min_timestamp, round($limit/7), $search_sort, $show_hidden_posts);
173
174// Display the threads while we search for posts
175//
176if (count($threads)){
177    echo "<h3>" . tra("Thread titles matching your query:") . "</h3>";
178    show_thread_and_context_header();
179    foreach ($threads as $thread){
180        if ($thread->hidden) continue;
181        show_thread_and_context($thread, $logged_in_user);
182    }
183    end_table();
184    echo "<br /><br />";
185}
186
187
188// Look in a post content as well
189//
190$posts = search_post_content(
191    $search_list, $forum, $user, $min_timestamp, $limit, $search_sort,
192    $show_hidden_posts
193);
194
195if (count($posts)){
196    echo "<h3>" . tra("Messages matching your query:") . "</h3>";
197    start_table();
198    $n = 1;
199    $options = get_output_options($logged_in_user);
200    $options->setHighlightTerms($search_list);
201    foreach ($posts as $post) {
202        $thread = BoincThread::lookup_id($post->thread);
203        if (!$thread) continue;
204        $forum = BoincForum::lookup_id($thread->forum);
205        if (!$forum) continue;
206        if (!is_forum_visible_to_user($forum, $logged_in_user)) continue;
207
208        if (!$show_hidden_posts) {
209            if ($thread->hidden) continue;
210            if ($post->hidden) continue;
211        }
212        show_post_and_context($post, $thread, $forum, $options, $n);
213        $n++;
214    }
215    end_table();
216}
217
218if (!count($threads) && !count($posts)){
219    echo "<p>".tra("Sorry, couldn't find anything matching your search query. You can try to broaden your search by using less words (or less specific words).")."</p>
220    <p>"
221    .tra("You can also %1try the same search on Google.%2",
222         "<a href=\"https://www.google.com/search?domains=".url_base()."&sitesearch=".url_base()."forum_thread.php&q=".htmlentities($search_keywords)."\">",
223         "</a>")
224    ."</p>";
225}
226echo "<p><a href=\"forum_search.php\">".tra("Perform another search")."</a></p>";
227page_tail();
228
229$cvs_version_tracker[]="\$Id$";  //Generated automatically - do not edit
230?>
231