00001 <?php
00002 # This file is part of the Savane project
00003 # <http://gna.org/projects/savane/>
00004 #
00005 # $Id: browse.php 5441 2006-02-19 13:53:40Z toddy $
00006 #
00007 # Copyright 1999-2000 (c) The SourceForge Crew
00008 # Copyright 2001-2002 (c) Laurent Julliard, CodeX Team, Xerox
00009 #
00010 # Copyright 2003-2005 (c) Mathieu Roy <yeupou--gnu.org>
00011 # Yves Perrin <yves.perrin--cern.ch>
00012 #
00013 # The Savane project is free software; you can redistribute it and/or
00014 # modify it under the terms of the GNU General Public License
00015 # as published by the Free Software Foundation; either version 2
00016 # of the License, or (at your option) any later version.
00017 #
00018 # The Savane project is distributed in the hope that it will be useful,
00019 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00021 # GNU General Public License for more details.
00022 #
00023 # You should have received a copy of the GNU General Public License
00024 # along with the Savane project; if not, write to the Free Software
00025 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00026
00027 # There are parameters that defined before, in the pages that include browse.
00028 # For instance, $sober is defined by the cookbook/index.php page
00029
00030
00031 $preference_prefix = ARTIFACT;
00032 if ($sober)
00033 {
00034 $preference_prefix .= "-sober";
00035 }
00036
00037
00038 # Number of search criteria (boxes) displayed in one row
00039 $fields_per_line=5;
00040
00041 # Avoid undesired user input
00042 unset($browse_preamble);
00043
00044 # Number of bugs displayed on screen in one chunk.
00045 # Default 50
00046 $chunksz = sane_get("chunksz");
00047 if (!$chunksz)
00048 { $chunksz = 50; }
00049
00050 # Digest mode? Set the digest variable to one
00051 $func = sane_get("func");
00052 if ($func == "digest")
00053 { $digest = 1; }
00054 else
00055 {
00056 $digest = 0;
00057 $func = "browse";
00058 }
00059
00060
00061 # Make sure offset is defined and has a correct value
00062 $offset = sane_get("offset");
00063 if (!$offset || $offset < 0)
00064 { $offset=0; }
00065
00066
00067 # ==================================================
00068 # Get the list of bug fields used in the form (they are in the URL - GET method)
00069 # and then build the preferences array accordingly
00070 # Exclude the group_id parameter# Extract the list of bug fields
00071 #
00072 # NB: Note that trackers_extract_field_list function does build and
00073 # return date arguments (using _dayfd|monthfd|yearfd boxes) whether
00074 # or not they are tracker fields used by the project.
00075 # ==================================================
00076
00077 # $prefs renamed $url_params to avoid confusion with $pref_arr and $pref_stg
00078 # used further down
00079 $url_params = trackers_extract_field_list(false);
00080 unset($url_params['group_id']);
00081
00082 # Get rid of url_params['history_date'] which has been included
00083 # by trackers_extract_field_list
00084 unset($url_params['history_date']);
00085
00086
00087 # ==================================================
00088 # Make sure all URL arguments are captured as array. For simple
00089 # search they'll be arrays with only one element at index 0 (this
00090 # will avoid to deal with scalar in simple search and array in
00091 # advanced which would greatly complexifies the code)
00092 # ================================================== */
00093 $advsrch = sane_get("advsrch");
00094 while (list($field,$value_id) = each($url_params))
00095 {
00096 if (!is_array($value_id))
00097 {
00098 unset($url_params[$field]);
00099 $url_params[$field][] = $value_id;
00100 #print '<br /> DBG Setting $url_params['.$field.'] [] = '.$value_id;
00101 }
00102 else
00103 {
00104 #print '<br /> DBG $url_params['.$field.'] = ('.implode(',',$value_id).')';
00105 }
00106
00107 if (trackers_data_is_date_field($field))
00108 {
00109 if ($advsrch)
00110 {
00111 $field_end = $field.'_end';
00112 $url_params[$field_end] = $$field_end;
00113 #print '<br /> DBG Setting $url_params['.$field.'_end]= '.$prefs[$field.'_end'];
00114 }
00115 else
00116 {
00117 $field_op = $field.'_op';
00118 $url_params[$field_op] = $$field_op;
00119 if (!$url_params[$field_op])
00120 { $url_params[$field_op] = '='; }
00121 #print '<br /> DBG Setting $url_params['.$field.'_op]= '.$url_params[$field.'_op'];
00122 }
00123 }
00124 }
00125
00126 # If history event additional constraint is used, add it
00127 $history_search = sane_get("history_search");
00128 $history_date_yearfd = sane_get("history_date_yearfd");
00129 $history_date_monthfd = sane_get("history_date_monthfd");
00130 $history_date_dayfd = sane_get("history_date_dayfd");
00131 if ($history_search)
00132 {
00133 # Dates must numeric date, even can be only modified or unmodified
00134 # If there is crap in there, ignore silently
00135 if (ctype_digit($history_date_yearfd) &&
00136 ctype_digit($history_date_monthfd) &&
00137 ctype_digit($history_date_dayfd))
00138 {
00139 $history_date = "$history_date_yearfd-$history_date_monthfd-$history_date_dayfd";
00140 $url_params['history'][] = addslashes($history_search).'>'.addslashes($history_field).'>'.addslashes($history_event).'>'.$history_date;
00141 }
00142 }
00143
00144 # ==================================================
00145 # Memorize order by field as a user preference if explicitly specified.
00146 #
00147 # $morder = comma separated list of sort criteria followed by - for
00148 # DESC and + for ASC order
00149 # $order = last sort criteria selected in the UI
00150 # $msort = 1 if multicolumn sort activated.
00151 # ==================================================
00152
00153 #print "<br />DBG \$morder at top: [$morder ]";
00154 $morder = sane_get("morder");
00155 $order = sane_get("order");
00156
00157 # if morder not defined then reuse the one in preferences
00158 if (user_isloggedin() && !isset($morder))
00159 {
00160 $morder = user_get_preference($preference_prefix.'_browse_order'.$group_id);
00161 }
00162
00163 if (isset($order))
00164 {
00165 if (($order != '') && ($order != 'digest'))
00166 {
00167 # Add the criteria to the list of existing ones
00168 $morder = trackers_add_sort_criteria($morder, $order, $msort);
00169 }
00170 else
00171 {
00172 # Reset list of sort criteria
00173 $morder = '';
00174 }
00175 }
00176
00177 if ($morder != '')
00178 {
00179 # If the user is logged in, save the wanted order if different from the
00180 # current
00181 if (user_isloggedin())
00182 {
00183 if ($morder != user_get_preference($preference_prefix.'_browse_order'.$group_id))
00184 {
00185 user_set_preference($preference_prefix.'_browse_order'.$group_id, $morder);
00186 }
00187 }
00188 }
00189
00190 # Fill the relevant sql bit to be used later
00191 # Sensible default case: order by item_id from the recent to the older
00192 if ($morder == '')
00193 { $morder = "bug_id<"; }
00194 $order_by = ' ORDER BY '.trackers_criteria_list_to_query($morder);
00195
00196 #print "<BR>>DBG Order by = $order_by";
00197
00198
00199 # ==================================================
00200 # If the report type is not defined then get it from the user preferences.
00201 # If it is set then update the user preference. Also initialize the
00202 # bug report structures.
00203 # ==================================================
00204 $report_id = sane_get("report_id");
00205 if (user_isloggedin())
00206 {
00207 if (!isset($report_id))
00208 {
00209 $report_id = user_get_preference($preference_prefix.'_browse_report'.$group_id);
00210 }
00211 else
00212 {
00213 if ($report_id != user_get_preference($preference_prefix.'_browse_report'.$group_id))
00214 user_set_preference($preference_prefix.'_browse_report'.$group_id, $report_id);
00215 }
00216 }
00217
00218 # If still not defined then force it to system 'Basic' report
00219 # of to 'Sober Basic' in sober mode, 103. This is hardcoded, if at some point
00220 # we need to put the sober output of existing trackers where 103 may already
00221 # be used, we will have to think of an other way to put it.
00222 if (!$report_id)
00223 {
00224 if (!$sober)
00225 { $report_id = 100; }
00226 else
00227 { $report_id = 103; }
00228 }
00229
00230 trackers_report_init($group_id, $report_id);
00231
00232
00233 # ==================================================
00234 # Now see what type of bug set is requested (set is one of none,
00235 # 'my', 'open', 'custom').
00236 # - if no set is passed in, see if a preference was set ('custom' set).
00237 # - if no preference and logged in then use 'my' set
00238 # - if no preference and not logged in the use 'open' set
00239 # (Prefs is a string of the form
00240 # &field1[]=value_id1&field2[]=value_id2&.... )
00241 # ==================================================
00242 $set = sane_get("set");
00243 if (!$set)
00244 {
00245
00246 if (user_isloggedin())
00247 {
00248
00249 $custom_pref=user_get_preference($preference_prefix.'_brow_cust'.$group_id);
00250
00251 if ($custom_pref)
00252 {
00253 $pref_arr = explode('&', substr($custom_pref, 5));
00254 while (list(,$expr) = each($pref_arr))
00255 {
00256 # Extract left and right parts of the assignment
00257 # and remove the '[]' array symbol from the left part
00258 list($field,$value_id) = explode('=',$expr);
00259 $field = str_replace('[]','',$field);
00260 if ($field == 'advsrch')
00261 { $advsrch = $value_id; }
00262 else if ($field == 'msort')
00263 { $msort = $value_id; }
00264 else if ($field == 'chunksz')
00265 { $chunksz = $value_id; }
00266 else if ($field == 'report_id')
00267 { $report_id = $value_id; }
00268 else if ($field == 'sumORdet')
00269 { $sumORdet = $value_id; }
00270 else if ($field == 'history')
00271 {
00272 $history = $value_id;
00273 $hist_pref = explode('>', $history);
00274 $history_search = $hist_pref[0];
00275 $history_field = $hist_pref[1];
00276 $history_event = $hist_pref[2];
00277 $history_date = $hist_pref[3];
00278
00279 # if not args in url (means not after post) ...
00280 # set $url_params['history'] explicitly since 'history'
00281 # is not a tracker field and thus wont have been set
00282 $url_params['history'][] = $history_search.'>'.$history_field.'>'.$history_event.'>'.$history_date;
00283
00284 }
00285 else
00286 {
00287 $url_params[$field][] = $value_id;
00288 }
00289
00290 #print '<br />DBG restoring prefs : $url_params['.$field.'] []='.$value_id;
00291 }
00292 $set='custom';
00293
00294 }
00295 else
00296 {
00297 $set='open';
00298 }
00299
00300 }
00301 else
00302 {
00303 $set='open';
00304 }
00305 }
00306
00307
00308 if ($set=='my')
00309 {
00310 # My bugs - backwards compat can be removed 9/10
00311 $url_params['status_id'][]=1;
00312 $url_params['assigned_to'][]=user_getid();
00313
00314 }
00315 else if ($set=='custom')
00316 {
00317 # Use the list of fields built from the arguments and used by the project
00318 # (the group_id parameter has been excluded)
00319 # NB: Note that trackers_extract_field_list function did build and
00320 # return date arguments (using _dayfd|monthfd|yearfd boxes) whether
00321 # or not they were tracker fields used by the project.
00322
00323 reset($url_params);
00324 while (list($field,$arr_val) = each($url_params))
00325 {
00326 while (list(,$value_id) = each($arr_val))
00327 {
00328 $pref_stg .= '&'.$field.'[]='.$value_id;
00329 }
00330
00331 # build part of the HTML title of this page for more friendly bookmarking
00332 # Do not add the criteria in the header if value is "Any"
00333 if ($value_id != 0)
00334 {
00335 $hdr .= _(" By ").trackers_data_get_label($field).': '.
00336 trackers_data_get_value($field,$group_id,$value_id);
00337 }
00338 }
00339 $pref_stg .= '&advsrch='.$advsrch;
00340 $pref_stg .= '&msort='.$msort;
00341 $pref_stg .= '&chunksz='.$chunksz;
00342 $pref_stg .= '&report_id='.$report_id;
00343 $pref_stg .= '&sumORdet='.$sumORdet;
00344
00345 if ($pref_stg != user_get_preference($preference_prefix.'_brow_cust'.$group_id))
00346 {
00347 #print "<br /> DBG setting pref = $pref_stg";
00348 user_set_preference($preference_prefix.'_brow_cust'.$group_id,$pref_stg);
00349 }
00350
00351 }
00352 else
00353 {
00354 # Open bugs - backwards compat can be removed 9/10
00355 $url_params['status_id'][]=1;
00356 }
00357
00358 # ==================================================
00359 # At this point make sure that all paramaters are defined
00360 # as well as all the arguments that serves as selection criteria
00361 # If not defined then defaults to ANY (0)
00362 # ==================================================
00363 if (!isset($advsrch))
00364 { $advsrch = 0; }
00365 if (!isset($msort))
00366 { $msort = 0; }
00367
00368 # Will be used later to find out if it make sense to look for items of the
00369 # system group (meaningful on the cookbook)
00370 $not_group_specific = 1;
00371
00372 while ($field = trackers_list_all_fields())
00373 {
00374 # the select boxes for the bug DB search first
00375 if (trackers_data_is_showed_on_query($field) &&
00376 trackers_data_is_select_box($field) )
00377 {
00378 if (!isset($url_params[$field]))
00379 { $url_params[$field][] = 0; }
00380
00381 # If we are about to generate the sober output, find out if we can
00382 # look for items of the site admin project or not.
00383 # All fields that have preconfigured values that can be changed by
00384 # projects could end up in flawed results, because the value id and the
00385 # actual value label (and so, meaning) are likely to be out of sync.
00386 # The most obvious case if the category field case.
00387 if (ARTIFACT == 'cookbook' && $sober)
00388 {
00389 if (trackers_data_is_project_scope($field) &&
00390 $url_params[$field][0] != '0' &&
00391 $url_params[$field][0] != '100')
00392 {
00393 $not_group_specific = 0;
00394 }
00395 }
00396 }
00397 }
00398
00399 # ==================================================
00400 # Start building the SQL query (select and where clauses)
00401 # ==================================================
00402
00403 # Force the selection of priority because it is always shown as color code
00404 # Force the selection of privacy, we always want to be sure that no private
00405 # item title is provided to everybody.
00406 $full_field_list = $col_list = $lbl_list = array();
00407 $select_count = 'SELECT count(DISTINCT '.ARTIFACT.'.bug_id) AS count ';
00408 $select = 'SELECT DISTINCT '.ARTIFACT.'.group_id,'.ARTIFACT.'.priority,'.ARTIFACT.'.privacy,'.ARTIFACT.'.status_id';
00409 $from = 'FROM '.ARTIFACT.' ';
00410
00411 # On the cookbook in sober mode, we want the system wide recipes,
00412 # as long as there is no field that comes as select boxes with values
00413 # configurable per project set.
00414 if (ARTIFACT == 'cookbook' && $sober && $not_group_specific)
00415 {
00416 $where = 'WHERE ('.ARTIFACT.'.group_id='.$group_id.' OR '.ARTIFACT.'.group_id='.$sys_group_id.') ';
00417 }
00418 else
00419 {
00420 $where = 'WHERE '.ARTIFACT.'.group_id='.$group_id.' ';
00421 }
00422 # No limit on sober output, we want all recipes
00423 unset($limit);
00424 if (!$sober)
00425 { $limit = " LIMIT $offset,$chunksz"; }
00426
00427
00428 # prepare the where clause with the selection criteria given by the user
00429 reset($url_params);
00430
00431 # prepare for summary and original submission as 'special' criteria
00432 unset($summary_search, $details_search);
00433
00434 while (list($field,$value_id) = each($url_params))
00435 {
00436
00437 # If the criteria is not in the field showed on query screen then
00438 # skip it. This is a sanity check to make sure that the SQL
00439 # query we run actually matches the displayed search criteria
00440 if (!trackers_data_is_showed_on_query($field))
00441 { continue; }
00442
00443 if (trackers_data_is_select_box($field) && !trackers_isvarany($url_params[$field]) )
00444 {
00445
00446 # Only select box criteria to where clause if argument is not ANY
00447 $where .= ' AND '.ARTIFACT.'.'.$field.' IN ('.implode(',',$url_params[$field]).') ';
00448
00449 }
00450 else if (trackers_data_is_date_field($field) && $url_params[$field][0])
00451 {
00452
00453 # Transform a date field into a unix time and use <, > or =
00454 list($time,$ok) = utils_date_to_unixtime($url_params[$field][0]);
00455 preg_match("/\s*(\d+)-(\d+)-(\d+)/", $url_params[$field][0],$match);
00456 list(,$year,$month,$day) = $match;
00457
00458 if ($advsrch)
00459 {
00460 list($time_end,$ok_end) = utils_date_to_unixtime($url_params[$field.'_end'][0]);
00461 if ($ok)
00462 {
00463 $where .= ' AND '.ARTIFACT.'.'.$field.' >= '. $time; }
00464
00465 if ($ok_end)
00466 { $where .= ' AND '.ARTIFACT.'.'.$field.' <= '. $time_end; }
00467
00468 }
00469 else
00470 {
00471
00472 $operator = $url_params[$field.'_op'][0];
00473 # '=' means that day between 00:00 and 23:59
00474 if ($operator == '=')
00475 {
00476 $time_end = mktime(23, 59, 59, $month, $day, $year);
00477 $where .= ' AND '.ARTIFACT.'.'.$field." >= $time ".'AND '.ARTIFACT.'.'.$field." <= $time_end ";
00478 }
00479 else
00480 {
00481 $time = mktime(0,0,0, $month, ($day+1), $year);
00482 $where .= ' AND '.ARTIFACT.'.'.$field." $operator= $time ";
00483 }
00484 }
00485
00486 # Always exclude undefined dates (0)
00487 $where .= ' AND '.ARTIFACT.'.'.$field." <> 0 ";
00488
00489 }
00490 elseif ((trackers_data_is_text_field($field) ||
00491 trackers_data_is_text_area($field)) &&
00492 $url_params[$field][0])
00493 {
00494 # Buffer summary and original submission (details) to handle them later
00495 # in case we have an OR to do between the two, instead of the usual
00496 # AND
00497 if ($sumORdet == 1 &&
00498 ($field == 'summary' || $field == 'details'))
00499 {
00500 if ($field == 'summary')
00501 { $summary_search = 1; }
00502 if ($field == 'details')
00503 { $details_search = 1; }
00504 }
00505 else
00506 {
00507 # It s a text field accept. Process INT or TEXT,VARCHAR fields differently
00508 $where .= ' AND '.trackers_build_match_expression($field, $url_params[$field][0]);
00509 }
00510 }
00511 }
00512
00513
00514 # Handle summary and/or original submission now, if a AND is required
00515 if ($sumORdet == 1)
00516 {
00517 # We will process the usual normal AND case: there was something for both
00518 # fields.
00519 if ($details_search == 1 && $summary_search == 1)
00520 {
00521 $where .= ' AND ';
00522 $where .= '( ( ';
00523 $where .= trackers_build_match_expression('details', $url_params['details'][0]);
00524 $where .= ' ) OR ( ';
00525 $where .= trackers_build_match_expression('summary', $url_params['summary'][0]);
00526 $where .= ') ) ';
00527 }
00528 else
00529 {
00530 # Now we take care of the unusual, possible though, case where and
00531 # AND was asked but not both fields set.
00532 # Since the AND was asked, the fields havent been taken care of before
00533 # and we need to do it now.
00534 # We do that in two IF, in case something went very wrong. In such case
00535 # we will proceed with a usual AND.
00536 if ($details_search == 1 && $url_params['details'][0])
00537 {
00538 $where .= ' AND ';
00539 $where .= trackers_build_match_expression('details', $url_params['details'][0]);
00540 }
00541 if ($summary_search == 1 && $url_params['summary'][0])
00542 {
00543 $where .= ' AND ';
00544 $where .= trackers_build_match_expression('summary', $url_params['summary'][0]);
00545 }
00546 }
00547 }
00548
00549 # ==================================================
00550 # Loop through the list of used fields to define label and fields/boxes
00551 # used as search criteria
00552 # ==================================================
00553
00554 $ib=0;
00555 $is=0;
00556 $load_cal=false;
00557
00558 # Check if summary and original submission are criteria
00559 $summary_search = 0;
00560 $details_search = 0;
00561
00562 while ($field = trackers_list_all_fields(cmp_place_query))
00563 {
00564 # Skip unused field
00565 if (!trackers_data_is_used($field))
00566 { continue; }
00567
00568 # Skip fields not part of this query form
00569 if (!trackers_data_is_showed_on_query($field))
00570 { continue; }
00571
00572 # beginning of a new row
00573 if ($ib % $fields_per_line == 0)
00574 {
00575 $align = ($printer ? "left" : "center");
00576 $labels .= "\n".'<tr align="'.$align.'" valign="top">';
00577 $boxes .= "\n".'<tr align="'.$align.'" valign="top">';
00578 }
00579
00580 $labels .= '<td>'.trackers_field_label_display($field,$group_id,false,false).'</td>';
00581 $boxes .= '<td><span class="smaller">';
00582
00583 if (trackers_data_is_select_box($field))
00584 {
00585 $boxes .=
00586 trackers_field_display($field,$group_id,
00587 ($advsrch ? $url_params[$field] : $url_params[$field][0]),
00588 false,false,($printer?true:false),false,true,'None', true,'Any');
00589
00590 }
00591 elseif (trackers_data_is_date_field($field))
00592 {
00593
00594 if ($advsrch)
00595 {
00596 $boxes .= trackers_multiple_field_date($field,$url_params[$field][0],
00597 $url_params[$field.'_end'][0],0,0,$printer);
00598 }
00599 else
00600 {
00601 $boxes .= trackers_field_date_operator($field,$url_params[$field.'_op'][0],$printer).
00602 trackers_field_date($field,$url_params[$field][0],0,0,$printer);
00603 }
00604
00605 }
00606 elseif (trackers_data_is_text_field($field) ||trackers_data_is_text_area($field))
00607 {
00608 if ($field == 'summary')
00609 { $summary_search = 1; }
00610 if ($field == 'details')
00611 { $details_search = 1; }
00612
00613 $boxes .=
00614 ($printer ? $url_params[$field][0] : trackers_field_text($field,$url_params[$field][0],15,80)) ;
00615 }
00616
00617 $boxes .= "</span></td>\n";
00618
00619 $ib++;
00620
00621 # end of this row
00622 if ($ib % $fields_per_line == 0)
00623 {
00624 $html_select .= $labels.'</tr>'.$boxes.'</tr>';
00625 $labels = $boxes = '';
00626 }
00627
00628 }
00629
00630 # Make sure the last few cells are in the table
00631 if ($labels)
00632 {
00633 $html_select .= $labels.'</tr>'.$boxes.'</tr>';
00634 }
00635
00636 # ==================================================
00637 # Loop through the list of used fields to see what fields are in the
00638 # result table and complement the SQL query accordingly.
00639 # ==================================================
00640
00641 # Add extra digest column, if necessary
00642 if ($digest)
00643 {
00644 $col_list[] = "digest";
00645 $width_list[] = "";
00646 $lbl_list[] = _("Digest");
00647 }
00648
00649 unset($morder_icon_is_set);
00650 while ($field = trackers_list_all_fields(cmp_place_result))
00651 {
00652 # Need the full list of used fields
00653 $full_field_list[] = $field;
00654
00655 if (!trackers_data_is_used($field) ||
00656 !trackers_data_is_showed_on_result($field))
00657 { continue; }
00658
00659 $col_list[] = $field;
00660 $width_list[] = trackers_data_get_col_width($field);
00661
00662 # If we have the field that defines the order, add an icon.
00663 # Quite simple in monolcolumn
00664 if (!$msort)
00665 {
00666 if (!$morder_icon_is_set)
00667 {
00668 if ($morder == "$field<" ||
00669 $morder == "$field>")
00670 {
00671 $lbl_list[] = trackers_data_get_label($field).' '.
00672 '<img class="icon" src="'.$GLOBALS['sys_home'].'images/'.SV_THEME.'.theme/'.((substr($morder, -1) == '>') ? 'down' : 'up').
00673 '.png" border="0" />';
00674 $morder_icon_is_set = 1;
00675 }
00676 else
00677 {
00678 $lbl_list[] = trackers_data_get_label($field);
00679 }
00680 }
00681 else
00682 {
00683 $lbl_list[] = trackers_data_get_label($field);
00684 }
00685 }
00686 else
00687 {
00688 # Less simple in multicolumn, indeed
00689 unset($morder_icon_is_set);
00690 $morder_arr = explode(',',$morder);
00691 while (list(,$crit) = each($morder_arr))
00692 {
00693 if ($crit == "$field<" ||
00694 $crit == "$field>")
00695 {
00696 $lbl_list[] = trackers_data_get_label($field).' '.
00697 '<img class="icon" src="'.$GLOBALS['sys_home'].'images/'.SV_THEME.'.theme/'.((substr($crit, -1) == '>') ? 'down' : 'up').
00698 '.png" border="0" />';
00699
00700 # If we found a criteria, go deal with the next column
00701 $morder_icon_is_set = 1;
00702 continue;
00703 }
00704 }
00705
00706 # If this field is not a sort criteria, we still have to create
00707 # the column
00708 if (!$morder_icon_is_set)
00709 {
00710 $lbl_list[] = trackers_data_get_label($field);
00711 }
00712 }
00713
00714 if (trackers_data_is_username_field($field))
00715 {
00716 # user names requires some special processing to display the username
00717 # instead of the user_id
00718 $select .= ",user_$field.user_name AS $field";
00719 $from .= ",user user_$field";
00720 $where .= " AND user_$field.user_id=".ARTIFACT.".$field ";
00721 #dbg("ICI $field ");
00722 }
00723 else
00724 {
00725 # otherwise just select this column as is
00726 $select .= ",".ARTIFACT.".$field";
00727 }
00728
00729 }
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 $sql_count = "$select_count $from $where";
00740 $result_count = db_query($sql_count);
00741 $totalrows = db_result($result_count,0,'count');
00742
00743 $sql = "$select $from $where $order_by $limit";
00744
00745 # If additional constraint history_event is modified, this result will be
00746 # replaced, and so we dont have to run this sql
00747 if (!$history_search || $history_event != "modified")
00748 {
00749 $result = db_query($sql);
00750 }
00751
00752 # Additional constraint
00753 if ($history_search)
00754 {
00755 list($unix_history_date,$ok) = utils_date_to_unixtime($history_date);
00756
00757 # Do 2nd sql query (on history) as long as MINUS is not supported by mysql
00758 $select_hist = $select;
00759 $from_hist = $from.', '.ARTIFACT.'_history ';
00760 $where_hist = $where.'AND '.ARTIFACT.'_history.bug_id = '.ARTIFACT.'.bug_id ';
00761 $where_hist .= ' AND '.ARTIFACT.'_history.date >= '.$unix_history_date.' ';
00762 if ($history_field != '0')
00763 {
00764 $where_hist .= 'AND '.ARTIFACT."_history.field_name = '".$history_field."' ";
00765 }
00766 $sql_history = "$select_hist $from_hist $where_hist $order_by $limit";
00767 $result_history = db_query($sql_history);
00768
00769 # If the even is "modified", we replace the original sql results.
00770 # Otherwise, we build up a list of result to substract
00771 if ($history_event == "modified")
00772 {
00773 $result = $result_history;
00774 $totalrows = db_numrows($result);
00775 }
00776 else
00777 {
00778 $rows_history = db_numrows($result_history);
00779 $history_arr = array();
00780
00781 for ($i=0; $i < $rows_history; $i++)
00782 {
00783 # Store the entry to be removed later
00784 $hist_bug_id = db_result($result_history, $i, 'bug_id');
00785 $history_arr[$hist_bug_id] = 1;
00786 }
00787 }
00788 }
00789
00790 # Build the array that will be given to the function that make the item
00791 # list. We cannot simply return the SQL results, since we have to remove
00792 # some entries from the list first:
00793 # - private items if necessary
00794 # - items depending on the additional constraint
00795 #
00796 # $totalrows must be set accordingly
00797 $result_array = array();
00798 while ($thisarray = db_fetch_array($result))
00799 {
00800 # Get the id
00801 $thisitem_id = $thisarray['bug_id'];
00802
00803 # Check if we must ignore it due to history additional constraint
00804 if ($history_arr[$thisitem_id])
00805 {
00806 $totalrows--;
00807 continue;
00808 }
00809
00810 # Do not show private item, apart to technician level members
00811 # and submitter
00812 if ($thisarray["privacy"] == "2" &&
00813 !member_check_private(0,$group_id) &&
00814 $thisarray["submitted_by"] != user_getname())
00815 {
00816 $totalrows--;
00817 continue;
00818 }
00819
00820 # Build a specific array for each item
00821 $result_array[$thisitem_id] = array();
00822
00823 # Always store the group, it may be necessary later, in case we actually
00824 # look for items from different projects
00825 $result_array[$thisitem_id]["group_id"] = $thisarray["group_id"];
00826
00827 # Store each field that will be necessary later
00828 $nb_of_fields = count($full_field_list);
00829 for ($k=0; $k<$nb_of_fields; $k++)
00830 {
00831 $result_array[$thisitem_id][$full_field_list[$k]] = $thisarray[$full_field_list[$k]];
00832 }
00833 }
00834
00835 # DBG
00836 #while (list(,$thisitem) = each($result_array))
00837 #{
00838 # $thisitem_id = $thisitem['bug_id'];
00839 # print "TEST ".$thisitem_id.", ".$result_array[$thisitem_id]["summary"].", ".$result_array[$thisitem_id]["resolution_id"].", ".$result_array[$thisitem_id]["group_id"]." -- ";
00840 #}
00841
00842
00843
00844
00845
00846
00847 if ($printer)
00848 {
00849 trackers_header(array('title'=>_("Browse Items").' - '.format_date($sys_datefmt,time())));
00850 }
00851 else
00852 {
00853 trackers_header(array('title'=>_("Browse Items").' '.$hdr));
00854 }
00855
00856 if ($browse_preamble)
00857 { print $browse_preamble; }
00858
00859
00860 $form_opening = '<form action="'.$PHP_SELF.'#options" method="get" name="bug_form">';
00861 $form = '
00862 <input type="hidden" name="group" value="'.$group_name.'" />
00863 <input type="hidden" name="func" value="'.$func.'" />
00864 <input type="hidden" name="set" value="custom" />
00865 <input type="hidden" name="msort" value="'.$msort.'" />
00866 '._("Browse").' ';
00867
00868 # Show the list of available bug reports kind
00869 $res_report = trackers_data_get_reports($group_id,user_getid(),$sober);
00870 if (!$printer)
00871 {
00872 # In sober mode, there is no relevant query form that have reportid = 100
00873 $show_100 = true;
00874 if ($sober)
00875 { $show_100 = false; }
00876
00877 $form .= sprintf(_("with the %s query form"),
00878 html_build_select_box($res_report,
00879 'report_id',
00880 $report_id,
00881 $show_100,
00882 'Basic')); # basic == 100
00883 }
00884 else
00885 {
00886 while (list($f,$v) = db_fetch_array($res_report))
00887 {
00888 if ($f != $report_id)
00889 { continue; }
00890 else
00891 {
00892 $report_name = $v;
00893 break;
00894 }
00895
00896 }
00897 $form .= sprintf(_("with the %s query form"), $report_name);
00898 }
00899
00900 # Start building the URL that we use to for hyperlink in the form
00901 $url = $GLOBALS['sys_home'].ARTIFACT."/?group=$group_name&func=".$func."&set=$set&msort=$msort";
00902 if ($set == 'custom')
00903 $url .= $pref_stg;
00904 else
00905 $url .= '&advsrch='.$advsrch;
00906
00907 $url_nomorder = $url;
00908 # the htmlspecialchars() is necessary, because $morder
00909 # contains < and > for the sorting order.
00910 $url .= '&morder='.htmlspecialchars($morder);
00911
00912 # Build the URL for alternate Search
00913 if ($advsrch)
00914 {
00915 $url_alternate_search = str_replace('advsrch=1','advsrch=0',$url);
00916 $text = _("Simple Search");
00917 }
00918 else
00919 {
00920 $url_alternate_search = str_replace('advsrch=0','advsrch=1',$url);
00921 $text = _("Advanced Search");
00922 }
00923
00924 # Select 'list form' or 'select' form
00925 if (!$printer)
00926 {
00927 if ($advsrch)
00928 {
00929 $advsrch_1 = ' selected="selected"';
00930 }
00931 else
00932 {
00933 $advsrch_0 = ' selected="selected"';
00934 }
00935 $form .= sprintf(' '._("and %s selection."), '<select name="advsrch"><option value="0"'.$advsrch_0.'>'._("Simple").'</option><option value="1"'.$advsrch_1.'>'._("Multiple").'</option></select>');
00936 $form_submit = '<input class="bold" value="'._("Apply").'" name="go_report" type="submit" />';
00937 }
00938 else
00939 {
00940 if ($advsrch)
00941 { $advsrch_x = _("Multiple"); }
00942 else
00943 { $advsrch_x = _("Simple"); }
00944
00945 $form .= sprintf(' '._("and %s selection."), $advsrch_x);
00946 }
00947
00948 $form .= '<table cellpadding="0" cellspacing="5">
00949 <tr><td colspan="'.$fields_per_line.'" nowrap="nowrap">';
00950 $form .= $html_select;
00951
00952 $form .= '</table>';
00953
00954
00955 # If both summary and org subm are searched, propose an OR instead of AND
00956 if (($details_search == 1) && ($summary_search == 1))
00957 {
00958 if (!$printer)
00959 {
00960 $form .= '<p class="smaller">'.
00961 sprintf(_("Use logical %s between '%s' and '%s' searches."),
00962 '<select name="sumORdet"><option value="0" '.(!$sumORdet ? 'selected="selected"':'').'>'._("AND").'</option><option value="1" '.($sumORdet ? 'selected="selected"':'').'>'._("OR").'</option></select>',
00963 rtrim(trackers_field_label_display("summary", $group_id, false,true), ': '),
00964 rtrim(trackers_field_label_display("details", $group_id, false,true), ': ')).
00965 '</p>';
00966 }
00967 else
00968 {
00969 $form .= '<p class="smaller">'.
00970 sprintf(_("Use logical %s between '%s' and '%s' searches."),
00971 ($sumORdet ? _("OR"):_("AND")),
00972 rtrim(trackers_field_label_display("summary", $group_id, false,true), ': '),
00973 rtrim(trackers_field_label_display("details", $group_id, false,true), ': ')).
00974 '</p>';
00975 }
00976
00977 # Update the url
00978 $url .= "&sumOrdet=$sumORdet";
00979 }
00980
00981
01134 if ($digest)
01135 {
01136 print '<form action="'.$PHP_SELF.'" method="get">
01137 <input type="hidden" name="group" value="'.$group_name.'" />
01138 <input type="hidden" name="func" value="digestselectfield" />
01139 ';
01140
01141 }
01142
01143 if ($totalrows > 0)
01144 {
01145 if (!$sober)
01146 {
01147
01148 show_item_list($result_array,$offset,$totalrows,$col_list,$lbl_list,$width_list,$url,false);
01149
01150 if ($digest)
01151 {
01152 print form_footer(_("Proceed to Digest next step"));
01153 }
01154
01155 show_priority_colors_key();
01156 }
01157 else
01158 {
01159 # Sober got it is own list design
01160 show_item_list_sober($result_array,$totalrows,$width_list,$url,false);
01161 }
01162
01163 }
01164 else
01165 {
01166
01167 print '<h2>'._("No matching items found. The display criteria may be too restrictive.").'</h2>';
01168 print db_error();
01169
01170 }
01171
01172 trackers_footer(array());
01173
01174 ?>