00001 <?php
00002 # This file is part of the Savane project
00003 # <http://gna.org/projects/savane/>
00004 #
00005 # $Id: general.php 5441 2006-02-19 13:53:40Z toddy $
00006 #
00007 # Copyright 2003-2006 (c) Stéphane Urbanovski <s.urbanovski--ac-nancy-metz.fr>
00008 # Mathieu Roy <yeupou--gnu.org>
00009 #
00010 # The Savane project is free software; you can redistribute it and/or
00011 # modify it under the terms of the GNU General Public License
00012 # as published by the Free Software Foundation; either version 2
00013 # of the License, or (at your option) any later version.
00014 #
00015 # The Savane project is distributed in the hope that it will be useful,
00016 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 # GNU General Public License for more details.
00019 #
00020 # You should have received a copy of the GNU General Public License
00021 # along with the Savane project; if not, write to the Free Software
00022 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00023
00024 # only_artifact is quite important here:
00025 # - if it is not set, it will allow to select all trackers
00026 # - if it is set to menu, it will make sure the search is not restricted
00027 # to a given group, since it means it is in the left menu
00028 function search_box ($searched_words='', $only_artifact=0, $size=15, $class="")
00029 {
00030 global $words,$forum_id,$group_id,$exact,$type_of_search,$type,$max_rows,$only_group_id,$project;
00031
00032 if ($only_group_id)
00033 {
00034 $group_id = $only_group_id;
00035 }
00036
00037 if ($size > 15)
00038 { $is_small = 0; }
00039 else
00040 { $is_small = 1; }
00041
00042
00043 # If it is the left menu, small box, then make sure any group_id info
00044 # is ignored, because we want to keep the left menu site-wide.
00045 if ($only_artifact == "menu")
00046 { unset($group_id, $only_group_id, $only_artifact); }
00047
00048 # if there is no search currently, set the default
00049 if (!isset($type_of_search))
00050 { $exact = 1; }
00051 if (!isset($max_rows))
00052 { $max_rows = "25"; }
00053
00054
00055 # if the wildcard '%%%' is searched, replace it with the more usual '*'
00056 if ($words == "%%%")
00057 { $words = "*"; }
00058
00059 if ($class)
00060 { $class = ' class="'.$class.'"'; }
00061
00062 $ret = ' <form action="'.$GLOBALS['sys_home'].'search/#options" method="get" '.$class.'>';
00063
00064 if (!$is_small)
00065 {
00066 # If it's a big form, we want the submit button on the right
00067 $ret .= '<span class="boxoptionssubmit"><input type="submit" name="Search" value="'._("Search").'" /></span>';
00068 }
00069
00070 $ret .= '<input type="text" size="'.$size.'" name="words" value="'.$searched_words.'" />';
00071
00072 if ($is_small)
00073 { $ret .= '<br />'; }
00074
00075 if ($only_artifact)
00076 {
00077 $ret .= '<input type="hidden" name="type_of_search" value="'.$only_artifact.'" />';
00078 }
00079 else
00080 {
00081 # I18N
00082 # This word is used in the phrase "Search [phrase] in
00083 # [projects, bugs, tasks, ...]" in the main menu on the left side.
00084 # Please try to find a translation which is as short as possible,
00085 # so the layout of the menu wont be destroyed.
00086 $ret .= ' '._("<em>in</em>").' <select name="type_of_search">';
00087
00088 # If the search is restricted to a given group, remove the possibility
00089 # to search another group, unless we're showing the left box
00090 if (!$group_id)
00091 {
00092 $ret .= '<option value="soft"'.(($type_of_search == "soft")||($type_of_search == "") ? ' selected="selected"' : "").'>'._("Projects")."</option>\n";
00093
00094 $ret .= '<option value="people"'.(($type_of_search == "people") ? ' selected="selected"' : "").'>'._("People")."</option>\n";
00095 }
00096
00097 $group_realname = substr(group_getname($group_id), 0, 10)."...";
00098
00099 if (!$project && $group_id)
00100 {
00101 $project = project_get_object($group_id);
00102 }
00103
00104 unset($text);
00105 if (!$group_id ||
00106 ($is_small && $group_id))
00107 { $text = _("Cookbook"); }
00108 else
00109 {
00110 $text = sprintf(_("%s Cookbook"), $group_realname);
00111 }
00112 if ($text)
00113 {
00114 $ret .= '<option value="cookbook"'.(($type_of_search == "cookbook") ? ' selected="selected"' : "").'>'.$text."</option>\n";
00115 }
00116
00117 unset($text);
00118 if (!$group_id ||
00119 ($is_small && $group_id && $project->Uses("support")))
00120 { $text = _("Support"); }
00121 else
00122 {
00123 if ($project->Uses("support"))
00124 {
00125 $text = sprintf(_("%s Support"), $group_realname);
00126 }
00127 }
00128
00129 if ($text)
00130 {
00131 $ret .= '<option value="support"'.(($type_of_search == "support") ? ' selected="selected"' : "").'>'.$text."</option>\n";
00132 }
00133
00134 unset($text);
00135 if (!$group_id ||
00136 ($is_small && $group_id && $project->Uses("bugs")))
00137 { $text = _("Bugs"); }
00138 else
00139 {
00140 if ($project->Uses("bugs"))
00141 {
00142 $text = sprintf(_("%s Bugs"), $group_realname);
00143 }
00144 }
00145 if ($text)
00146 {
00147 $ret .= '<option value="bugs"'.(($type_of_search == "bugs") ? ' selected="selected"' : "").'>'.$text."</option>\n";
00148 }
00149
00150 unset($text);
00151 if (!$group_id ||
00152 ($is_small && $group_id && $project->Uses("task")))
00153 { $text = _("Tasks"); }
00154 else
00155 {
00156 if ($project->Uses("task"))
00157 {
00158 $text = sprintf(_("%s Tasks"), $group_realname);
00159 }
00160 }
00161 if ($text)
00162 {
00163 $ret .= '<option value="task"'.(($type_of_search == "task") ? ' selected="selected"' : "").'>'.$text."</option>\n";
00164 }
00165
00166 unset($text);
00167 if (!$group_id ||
00168 ($is_small && $group_id && $project->Uses("patch")))
00169 { $text = _("Patchs"); }
00170 else
00171 {
00172 if ($project->Uses("patch"))
00173 {
00174 $text = sprintf(_("%s Patchs"), $group_realname);
00175 }
00176
00177 }
00178 if ($text)
00179 {
00180 $ret .= '<option value="patch"'.(($type_of_search == "patch") ? ' selected="selected"' : "").'>'.$text."</option>\n";
00181 }
00182
00183 if ($GLOBALS['sys_use_google'])
00184 {
00185 $ret .= '<option value="google"'.(($type_of_search == "google") ? ' selected="selected"' : "").'><em>'._("via Google")."</em></option>\n";
00186 }
00187
00188 $ret .= '</select>';
00189
00190 }
00191 if ($size < 16)
00192 { $ret .= '<br />'; }
00193
00194 if (isset($group_id))
00195 {
00196 $ret .="<input type=\"hidden\" value=\"$group_id\" name=\"only_group_id\" />\n";
00197 }
00198
00199 if ($size < 16)
00200 {
00201 # If it's a small form, the submit button has not already been inserted
00202 $ret .= ' <input type="submit" name="Search" value="'._("Search").'" />';
00203 }
00204
00205 if ($size > 15)
00206 {
00207 $ret .= '<br /> <input type="radio" name="exact" value="0"'.( $exact ? " " : " checked").' />'._("with at least one of the words")."\n";
00208 $ret .= '<br /> <input type="radio" name="exact" value="1"'.( $exact ? " checked" : " " ).' />'._("with all of the words")."\n";
00209 $ret .= '<br /> '.sprintf(_("%s results per page"), '<input type="text" name="max_rows" value="'.$max_rows.'" size="4" />')."\n";
00210
00211
00212 if (!isset($group_id))
00213 {
00214 # add the functionality to restrict the search to a project type
00215 $ret .="<br /> ";
00216
00217 $select = '<select name="type" size="1"><option value="">'._("any").'</option>'."\n";
00218 $result = db_query("SELECT type_id,name FROM group_type ORDER BY type_id");
00219 while ($eachtype = db_fetch_array($result))
00220 {
00221 $select .= '<option value="'.$eachtype['type_id'].'"'.($type == $eachtype['type_id'] ? ' selected="selected"' : '').'>'.$eachtype['name'].'</option>'."\n";
00222 }
00223 $select .= '</select>'."\n";
00224
00225 $ret .=sprintf(_("Search in %s group type, when searching for a \"Project/Group\"."), $select);
00226 }
00227
00228 $ret .= '<p>'._("Notes: You can use the wildcard *, standing for everything. You can also search items by number.").'</p>';
00229 }
00230 else
00231 {
00232 $ret .= '<input type="hidden" name="exact" value="1" />';
00233 }
00234
00235 if (!$dontclose)
00236 { $ret .= ' </form>'; }
00237
00238 return $ret;
00239 }
00240
00241 function search_send_header ()
00242 {
00243 global $HTML,$words,$type_of_search,$only_group_id;
00244
00245 if ($type_of_search == "soft" || $type_of_search == "people")
00246 {
00247 # there cannot be a group id specific if we are looking for a group
00248 # group id is meaningless when looking for someone
00249 $group_id = 0;
00250 }
00251
00252 site_header(array('title'=>_("Search"),'context'=>'search'));
00253
00254
00255 # Print the form
00256
00257 if (!$only_group_id)
00258 { $title = _("Search Criteria:"); }
00259 else
00260 { $title = sprintf(_("New search criteria for the Group %s:"), group_getname($only_group_id)); }
00261
00262 print html_show_boxoptions($title, search_box($words, '', 45));
00263
00264 # Print the result
00265 print '<h3>';
00266 if ($words && $type_of_search)
00267 {
00268 # Print real words describing the type of search
00269 if ($type_of_search == "soft")
00270 { $type_of_search_real = _("Project/Group"); }
00271 else if ($type_of_search == "support")
00272 { $type_of_search_real = _("Support"); }
00273 else if ($type_of_search == "bugs")
00274 { $type_of_search_real = _("Bugs"); }
00275 else if ($type_of_search == "task")
00276 { $type_of_search_real = _("Task"); }
00277 else if ($type_of_search == "patch")
00278 { $type_of_search_real = _("Patch"); }
00279 else if ($type_of_search == "cookbook")
00280 { $type_of_search_real = _("Cookbook"); }
00281 else if ($type_of_search == "people")
00282 { $type_of_search_real = _("People"); }
00283
00284 if (!$only_group_id)
00285 {
00286 printf(_("Search results for %s (in %s):"), '<strong>'.$words.'</strong>', $type_of_search_real);
00287 }
00288 else
00289 {
00290 printf(_("Search results for %s (in %s, for the Group %s):"), '<strong>'.$words.'</strong>', $type_of_search_real, group_getname($only_group_id));
00291 }
00292 }
00293 else
00294 { print _("Search results:"); }
00295
00296 print '</h3><a name="results"></a>';
00297
00298 }
00299
00300
00301 function result_no_match ()
00302 {
00303 return search_failed();
00304 }
00305
00306 function search_failed ()
00307 {
00308 global $no_rows,$words;
00309 $no_rows = 1 ;
00310 search_send_header();
00311 print '<span class="warn">';
00312 print _("None found. Please note that only search words of more than three characters are valid.");
00313 print '</span>';
00314 print db_error();
00315 }
00316
00317 # Run a search in the database, by default on softwares
00318 function search_run ($words, $type_of_search="soft", $return_error_messages=1)
00319 {
00320 global $type, $exact, $crit, $offset, $only_group_id, $max_rows;
00321
00322 # Remove useless blank spaces, escape nasty characters
00323 $words = trim($words);
00324 $words = addslashes($words);
00325
00326 # Convert the wildcard * to the similar SQL one, when it is alone
00327 if ($words == "*")
00328 { $words = "%%%"; }
00329
00330 # Replace the wildcard * to the similar SQL one, when included in a
00331 # word
00332 $words = strtr($words, "*", "%");
00333
00334 # Convert the crit form value to the SQL equiv.
00335 if ($exact)
00336 { $crit='AND'; }
00337 else
00338 { $crit='OR'; }
00339
00340 # No offset defined? Start the search in the db at 0
00341 if (!$offset || $offset < 0)
00342 { $GLOBALS['offset'] = 0; }
00343
00344 # No how many rows to print? Print 25 rows by default
00345 if (!$max_rows)
00346 { $GLOBALS['max_rows'] = 25; }
00347
00348 # Accept only to do a search for more than 2 characters.
00349 # Exit only if we were not told to avoid returning error messages.
00350 # Note: we tell user we want more than 3 characters, to incitate to
00351 # do clever searchs. But it will be ok for only 2 characters (limit
00352 # that conveniently allow us to search by items numbers)
00353 if ($words && (strlen($words) < 3) && $return_error_messages)
00354 {
00355 search_failed();
00356 exit;
00357 }
00358
00359 # Build arrays
00360 $array = explode(" ", $words);
00361 if ($type_of_search == "soft")
00362 {
00363 $words1 = implode($array,"%' $crit group_name LIKE '%");
00364 $words2 = implode($array,"%' $crit short_description LIKE '%");
00365 $words3 = implode($array,"%' $crit unix_group_name LIKE '%");
00366 $words4=implode($array,"%' $crit group_id LIKE '%");
00367 # remove # from words4
00368 $words4=ereg_replace("#","",$words4);
00369 }
00370 else if ($type_of_search == "people")
00371 {
00372 $words1=implode($array,"%' $crit user_name LIKE '%");
00373 $words2=implode($array,"%' $crit realname LIKE '%");
00374 $words3=implode($array,"%' $crit user_id LIKE '%");
00375 # remove # from words3
00376 $words3=ereg_replace("#","",$words3);
00377 }
00378 else if ($type_of_search == 'bugs' ||
00379 $type_of_search == 'support' ||
00380 $type_of_search == 'patch' ||
00381 $type_of_search == 'cookbook' ||
00382 $type_of_search == 'task')
00383 {
00384 $words1=implode($array,"%' $crit ".$type_of_search.".details LIKE '%");
00385 $words2=implode($array,"%' $crit ".$type_of_search.".summary LIKE '%");
00386 $words3=implode($array,"%' $crit ".$type_of_search.".bug_id LIKE '%");
00387 # remove # from words3
00388 $words3=ereg_replace("#","",$words3);
00389 }
00390
00391 # Build SQL command
00392 if ($type_of_search == "soft")
00393 {
00394 if (!$type)
00395 {
00396 $sql = "SELECT group_name,unix_group_name,type,group_id,short_description ".
00397 "FROM groups ".
00398 "WHERE status='A' AND is_public='1' ".
00399 "AND ((group_name LIKE '%$words1%') OR (short_description LIKE '%$words2%') OR (unix_group_name LIKE '%$words3%') OR (group_id LIKE '$words4')) ORDER BY unix_group_name,group_name LIMIT $offset,".($max_rows+1);
00400 }
00401 else
00402 {
00403 $sql = "SELECT group_name,unix_group_name,type,group_id,short_description ".
00404 "FROM groups ".
00405 "WHERE status='A' AND type='$type' AND is_public='1' ".
00406 "AND ((group_name LIKE '%$words1%') OR (short_description LIKE '%$words2%') OR (unix_group_name LIKE '%$words3%') OR (group_id LIKE '$words4')) ORDER BY unix_group_name,group_name LIMIT $offset,".($max_rows+1);
00407 }
00408 }
00409 else if ($type_of_search == "people")
00410 {
00411 $sql = "SELECT user_name,user_id,realname "
00412 . "FROM user "
00413 . "WHERE ((user_name LIKE '%$words1%') OR (realname LIKE '%$words2%') OR (user_id LIKE '$words3')) AND (status='A') ORDER BY user_name LIMIT $offset,".($max_rows+1);
00414 }
00415 else if ($type_of_search == 'bugs' ||
00416 $type_of_search == 'support' ||
00417 $type_of_search == 'patch' ||
00418 $type_of_search == 'cookbook' ||
00419 $type_of_search == 'task')
00420 {
00421
00422 if ($only_group_id)
00423 {
00424 # $search_without_group_id can be set to avoid restricting search
00425 # to a group even if group_id is set
00426 $sql_with_group_id = "AND ".$type_of_search.".group_id='".addslashes($only_group_id)."' ";
00427 }
00428
00429 $sql = "SELECT ".$type_of_search.".bug_id,".
00430 $type_of_search.".summary,".
00431 $type_of_search.".date,".
00432 $type_of_search.".privacy,".
00433 $type_of_search.".submitted_by,".
00434 "user.user_name,".
00435 $type_of_search.".group_id "
00436 . "FROM ".$type_of_search.",user "
00437 . "WHERE user.user_id=".$type_of_search.".submitted_by AND ((".$type_of_search.".details LIKE '%$words1%') "
00438 . "OR (".$type_of_search.".summary LIKE '%$words2%') "
00439 . "OR (".$type_of_search.".bug_id = '$words3')) "
00440 . $sql_with_group_id
00441 . "GROUP BY bug_id,summary,date,user_name "
00442 . "ORDER BY ".$type_of_search.".date DESC "
00443 . "LIMIT $offset,".($max_rows+1);
00444 }
00445 return db_query($sql);
00446 }
00447
00448 ?>