3 * SourceForge Generic Tracker facility
5 * SourceForge: Breaking Down the Barriers to Open Source Development
6 * Copyright 1999-2001 (c) VA Linux Systems
7 * http://sourceforge.net
10 require_once $gfcommon.'tracker/ArtifactFactory.class.php';
11 require_once $gfcommon.'tracker/ArtifactQuery.class.php';
13 // make sure this person has permission to view artifacts
15 if (!$ath->userCanView()) {
16 exit_permission_denied();
19 $query_id = getIntFromRequest('query_id');
22 // The browse page can be powered by a pre-saved query
23 // or by select boxes chosen by the user
25 // If there is a $query_id coming from the request OR the pref
26 // was already saved, use the artifact factory that way.
28 // If the query_id = -1, unset the pref and use regular browse boxes
30 if (session_loggedin()) {
32 if ($query_id == '-1') {
33 $u =& session_get_user();
34 $u->setPreference('art_query'.$ath->getID(),'');
36 $aq = new ArtifactQuery($ath,$query_id);
37 if (!$aq || !is_object($aq)) {
38 exit_error('Error',$aq->getErrorMessage());
43 $u =& session_get_user();
44 $query_id=$u->getPreference('art_query'.$ath->getID(),'');
46 } elseif ($query_id) {
47 // If user is not logged, then use a cookie to store the current query.
48 if (isset($_COOKIE["GFTrackerQuery"])) {
49 $gf_tracker = unserialize($_COOKIE["GFTrackerQuery"]);
51 $gf_tracker = array();
53 $gf_tracker[$ath->getID()] = $query_id;
54 // Send the query_id as a cookie to save it.
55 setcookie("GFTrackerQuery", serialize($gf_tracker));
56 $_COOKIE["GFTrackerQuery"] = serialize($gf_tracker);
57 } elseif (isset($_COOKIE["GFTrackerQuery"])) {
58 $gf_tracker = unserialize($_COOKIE["GFTrackerQuery"]);
59 $query_id = (int)$gf_tracker[$ath->getID()];
62 $af = new ArtifactFactory($ath);
64 if (!$af || !is_object($af)) {
65 exit_error('Error','Could Not Get Factory');
66 } elseif ($af->isError()) {
67 exit_error('Error',$af->getErrorMessage());
70 $offset = getStringFromRequest('offset',$offset);
71 $_sort_col = getStringFromRequest('_sort_col',$_sort_col);
72 $_sort_ord = getStringFromRequest('_sort_ord',$_sort_ord);
73 $max_rows = getStringFromRequest('max_rows',$max_rows);
74 $set = getStringFromRequest('set',$set);
75 $_assigned_to = getIntFromRequest('_assigned_to',$_assigned_to);
76 $_status = getIntFromRequest('_status',$_status);
77 $_extra_fields = array() ;
78 $aux_extra_fields = array() ;
79 if ($set == 'custom') {
81 //may be past in next/prev url
83 if (isset($_GET['extra_fields'][$ath->getCustomStatusField()])) {
84 $_extra_fields[$ath->getCustomStatusField()] = $_GET['extra_fields'][$ath->getCustomStatusField()];
85 } elseif (isset($_POST['extra_fields'][$ath->getCustomStatusField()])) {
86 $_extra_fields[$ath->getCustomStatusField()] = $_POST['extra_fields'][$ath->getCustomStatusField()];
90 if (is_array($_extra_fields)){
91 $keys=array_keys($_extra_fields);
92 foreach ($keys as $key) {
93 if ($_extra_fields[$key] != 'Array') {
94 $aux_extra_fields[$key] = $_extra_fields[$key];
98 if (isset($_extra_fields)){
99 $aux_extra_fields = $_extra_fields;
101 $aux_extra_fields = '';
105 $af->setup($offset,$_sort_col,$_sort_ord,null,$set,$_assigned_to,$_status,$aux_extra_fields);
107 // These vals are sanitized and/or retrieved from ArtifactFactory stored settings
109 $_sort_col=$af->order_col;
110 $_sort_ord=$af->sort;
111 $_status=$af->status;
112 $_assigned_to=$af->assigned_to;
113 $_extra_fields=$af->extra_fields;
115 $art_arr =& $af->getArtifacts();
117 if (!$art_arr && $af->isError()) {
118 exit_error('Error',$af->getErrorMessage());
121 //build page title to make bookmarking easier
122 //if a user was selected, add the user_name to the title
124 $ath->header(array('atid'=>$ath->getID()));
128 * Build the powerful browsing options pop-up boxes
133 // creating a custom technician box which includes "any" and "unassigned"
135 $res_tech= $ath->getTechnicians();
137 $tech_id_arr=util_result_column_to_array($res_tech,0);
138 $tech_id_arr[]='0'; //this will be the 'any' row
140 $tech_name_arr=util_result_column_to_array($res_tech,1);
141 $tech_name_arr[]=_('Any');
143 if (is_array($_assigned_to)) {
146 $tech_box=html_build_select_box_from_arrays ($tech_id_arr,$tech_name_arr,'_assigned_to',$_assigned_to,true,_('Unassigned'));
150 // custom order by arrays to build a pop-up box
152 $order_name_arr=array();
153 $order_name_arr[]=_('ID');
154 $order_name_arr[]=_('Priority');
155 $order_name_arr[]=_('Summary');
156 $order_name_arr[]=_('Open Date');
157 $order_name_arr[]=_('Close Date');
158 $order_name_arr[]=_('Submitter');
159 $order_name_arr[]=_('Assignee');
163 $order_arr[]='artifact_id';
164 $order_arr[]='priority';
165 $order_arr[]='summary';
166 $order_arr[]='open_date';
167 $order_arr[]='close_date';
168 $order_arr[]='submitted_by';
169 $order_arr[]='assigned_to';
172 // custom sort arrays to build pop-up box
174 $sort_name_arr=array();
175 $sort_name_arr[]=_('Ascending');
176 $sort_name_arr[]=_('Descending');
183 // custom changed arrays to build pop-up box
185 $changed_name_arr=array();
186 $changed_name_arr[]=_('Any changes');
187 $changed_name_arr[]=_('Last 24H');
188 $changed_name_arr[]=_('Last 7days');
189 $changed_name_arr[]=_('Last 2weeks');
190 $changed_name_arr[]=_('Last 1month');
192 $changed_arr=array();
193 $changed_arr[]= 0x7fffffff; // Any
194 $changed_arr[]= 3600 * 24; // 24 hour
195 $changed_arr[]= 3600 * 24 * 7; // 1 week
196 $changed_arr[]= 3600 * 24 * 14;// 2 week
197 $changed_arr[]= 3600 * 24 * 30;// 1 month
201 * Show the free-form text submitted by the project admin
203 echo $ath->renderBrowseInstructions();
206 // statuses can be custom in GForge 4.5+
208 if ($ath->usesCustomStatuses()) {
209 $aux_extra_fields = array();
210 if (is_array($_extra_fields)){
211 $keys=array_keys($_extra_fields);
212 foreach ($keys as $key) {
213 if (!is_array($_extra_fields[$key])) {
214 $aux_extra_fields[$key] = $_extra_fields[$key];
218 $aux_extra_fields = $_extra_fields;
220 $status_box=$ath->renderSelect ($ath->getCustomStatusField(),$aux_extra_fields[$ath->getCustomStatusField()],false,'',true,_('Any'));
222 if (is_array($_status)) {
225 $status_box = $ath->statusBox('_status',$_status,true,_('Any'));
227 echo '<script type="text/javascript" src="/tabber/tabber.js"></script>'."\n";
229 <div id="tabber" class="tabber">
230 <div class="tabbertab" title="'._('Advanced queries').'">';
232 if (session_loggedin()) {
233 $res = db_query_params ('SELECT artifact_query_id,query_name, CASE WHEN query_type>0 THEN 1 ELSE 0 END as type
235 WHERE group_artifact_id=$1 AND (user_id=$2 OR query_type>0)
236 ORDER BY type ASC, query_name ASC',
237 array ($ath->getID(),
240 $res = db_query_params ('SELECT artifact_query_id,query_name, CASE WHEN query_type>0 THEN 1 ELSE 0 END as type
242 WHERE group_artifact_id=$1 AND query_type>0
243 ORDER BY type ASC, query_name ASC',
244 array ($ath->getID()));
248 if (db_numrows($res)>0) {
249 echo '<form action="'. getStringFromServer('PHP_SELF') .'" method="get">';
250 echo '<input type="hidden" name="group_id" value="'.$group_id.'" />';
251 echo '<input type="hidden" name="atid" value="'.$ath->getID().'" />';
252 echo '<input type="hidden" name="power_query" value="1" />';
253 echo ' <table width="100%" cellspacing="0">
257 $optgroup['key'] = 'type';
258 $optgroup['values'][0] = 'Private queries';
259 $optgroup['values'][1] = 'Project queries';
260 echo '<span style="font-size:smaller">';
261 echo '<select name="query_id">';
262 echo '<option value="100">Select One</option>';
264 $selected = $af->getDefaultQuery();
265 while ($row = db_fetch_array($res)) {
266 if ($current != $row['type']) {
269 $label = $row['type'] ? 'Project' : 'Private';
270 echo '<optgroup label="'.$label.'">';
271 $current = $row['type'];
273 echo '<option value="'.$row['artifact_query_id'].'"';
274 if ($row['artifact_query_id'] == $selected)
275 echo ' selected="selected"';
276 echo '>'. $row['query_name'] .'</option>'."\n";
282 <input type="submit" name="run" value="'._('Power Query').'" />
283 <a href="/tracker/?atid='. $ath->getID().'&group_id='.$group_id.'&func=query">'.
284 _('Build Query').'</a>
289 <a href="/tracker/?atid='. $ath->getID().'&group_id='.$group_id.'&func=query">'._('Build Query').'</a></strong>';
293 <div class="tabbertab'.($af->query_type == 'custom' ? ' tabbertabdefault' : '').'" title="'._('Simple Filtering and Sorting').'">
294 <form action="'. getStringFromServer('PHP_SELF') .'?group_id='.$group_id.'&atid='.$ath->getID().'" method="post">
295 <input type="hidden" name="query_id" value="-1" />
296 <input type="hidden" name="set" value="custom" />
297 <table width="100%" cellspacing="0">
300 '._('Assignee').': '. $tech_box .'
303 '._('State').': '. $status_box .'
308 ': <a href="javascript:help_window(\'/help/tracker.php?helpname=sort_by\')">' .
309 '<strong>(?)</strong></a>'.
310 html_build_select_box_from_arrays($order_arr,$order_name_arr,'_sort_col',$_sort_col,false) .
311 html_build_select_box_from_arrays($sort_arr,$sort_name_arr,'_sort_ord',$_sort_ord,false) .
312 '<input type="submit" name="submit" value="'._('Quick Browse').'" />';
320 if ($af->query_type == 'default') {
321 echo '<div class="tabbertab tabbertabdefault" title="'._('Default').'">';
322 echo '<strong>'._('Viewing only opened records by default, use \'Advanced queries\' or \'Simple Filtering and Sorting\' to change.').'</strong>';
328 if ($art_arr && count($art_arr) > 0) {
330 if ($set=='custom') {
331 $set .= '&_assigned_to='.$_assigned_to.'&_status='.$_status.'&_sort_col='.$_sort_col.'&_sort_ord='.$_sort_ord;
332 if (array_key_exists($ath->getCustomStatusField(),$_extra_fields)) {
333 $set .= '&extra_fields['.$ath->getCustomStatusField().']='.$_extra_fields[$ath->getCustomStatusField()];
338 $IS_ADMIN=$ath->userIsAdmin();
342 <form name="artifactList" action="'. getStringFromServer('PHP_SELF') .'?group_id='.$group_id.'&atid='.$ath->getID().'" method="post">
343 <input type="hidden" name="form_key" value="'.form_generate_key().'" />
344 <input type="hidden" name="func" value="massupdate" />';
347 $browse_fields = explode(',', "id,".$ath->getBrowseList());
349 foreach ($browse_fields as $f) {
350 if (intval($f) > 0) {
351 $title = $ath->getExtraFieldName($f);
358 $title=_('Description');
359 if ($f == 'open_date')
360 $title=_('Open Date');
361 if ($f == 'close_date')
362 $title=_('Close Date');
363 if ($f == 'status_id')
365 if ($f == 'priority')
366 $title=_('Priority');
367 if ($f == 'assigned_to')
368 $title=_('Assigned to');
369 if ($f == 'submitted_by')
370 $title=_('Submitted by');
372 $title_arr[] = $title;
375 echo $GLOBALS['HTML']->listTableTop ($title_arr);
377 $then=(time()-$ath->getDuePeriod());
379 if (!isset($_GET['start'])) {
382 $start=$_GET['start'];
384 $max = ((count($art_arr) > ($start + 25)) ? ($start+25) : count($art_arr) );
386 for ($i=$start; $i<$max; $i++) {
387 $extra_data = $art_arr[$i]->getExtraFieldDataText();
389 <tr '. $HTML->boxGetAltRowStyle($i) . '>';
390 foreach ($browse_fields as $f) {
392 echo '<td style="white-space: nowrap;">'.
393 ($IS_ADMIN?'<input type="checkbox" name="artifact_id_list[]" value="'.
394 $art_arr[$i]->getID() .'" /> ':'').
395 '<a href="'.getStringFromServer('PHP_SELF').'?func=detail&aid='.
396 $art_arr[$i]->getID() .
397 '&group_id='. $group_id .'&atid='.
398 $ath->getID().'">'.$art_arr[$i]->getID() .
400 } else if ($f == 'summary') {
401 echo '<td><a href="'.getStringFromServer('PHP_SELF').'?func=detail&aid='.
402 $art_arr[$i]->getID() .
403 '&group_id='. $group_id .'&atid='.
405 $art_arr[$i]->getSummary().
407 } else if ($f == 'open_date') {
408 echo '<td>'. (($set != 'closed' && $art_arr[$i]->getOpenDate() < $then)?'* ':' ') .
409 date(_('Y-m-d H:i'),$art_arr[$i]->getOpenDate()) .'</td>';
410 } else if ($f == 'status_id') {
411 echo '<td>'. $art_arr[$i]->getStatusName() .'</td>';
412 } else if ($f == 'priority') {
413 echo '<td class="priority'.$art_arr[$i]->getPriority() .'">'. $art_arr[$i]->getPriority() .'</td>';
414 } else if ($f == 'assigned_to') {
415 echo '<td>'. $art_arr[$i]->getAssignedRealName() .'</td>';
416 } else if ($f == 'submitted_by') {
417 echo '<td>'. $art_arr[$i]->getSubmittedRealName() .'</td>';
418 } else if ($f == 'close_date') {
419 echo '<td>'. ($art_arr[$i]->getCloseDate() ?
420 date(_('Y-m-d H:i'),$art_arr[$i]->getCloseDate()) :' ') .'</td>';
421 } else if ($f == 'details') {
422 echo '<td>'. $art_arr[$i]->getDetails() .'</td>';
423 } else if (intval($f) > 0) {
424 // Now display extra-fields (fields are numbers).
425 $value = $extra_data[$f]['value'];
426 if ($extra_data[$f]['type'] == 9) {
427 $value = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1')", $value);
429 echo '<td>' . $value .'</td>';
431 // Display ? for unknown values.
439 Show extra rows for <-- Prev / Next -->
441 //only show this if we're not using a power query
442 if ($af->max_rows > 0) {
443 if (($offset > 0) || ($rows >= 50)) {
445 <tr><td colspan="2">';
447 echo '<a href="'.getStringFromServer('PHP_SELF').'?func=browse&group_id='.$group_id.'&atid='.$ath->getID().'&set='.
448 $set.'&offset='.($offset-50).'"><strong><-- '._('Previous 50').'</strong></a>';
452 echo '</td><td> </td><td colspan="2">';
454 echo '<a href="'.getStringFromServer('PHP_SELF').'?func=browse&group_id='.$group_id.'&atid='.$ath->getID().'&set='.
455 $set.'&offset='.($offset+50).'"><strong>'._('Next 50').' --></strong></a>';
463 echo $GLOBALS['HTML']->listTableBottom();
464 $pages = count($art_arr) / 25;
465 $currentpage = intval($start / 25);
466 //echo "Item Count: ".count($arr)."Pages: $pages";
468 $skipped_pages=false;
469 for ($j=0; $j<$pages; $j++) {
471 if ((($j > 4) && ($j < ($currentpage-5))) || (($j > ($currentpage+5)) && ($j < ($pages-5)))) {
472 if (!$skipped_pages) {
478 $skipped_pages=false;
481 if ($j == $currentpage) {
482 echo '<strong>'.($j+1).'</strong> ';
484 echo '<a href="'.getStringFromServer('PHP_SELF')."?func=browse&group_id=".$group_id.'&atid='.$ath->getID().'&set='. $set.'&start='.($j*25).'"><strong>'.($j+1).'</strong></a> ';
493 echo '<script type="text/javascript">
495 function checkAll(val) {
496 al=document.artifactList;
497 len = al.elements.length;
499 for( i=0 ; i<len ; i++) {
500 if (al.elements[i].name==\'artifact_id_list[]\') {
501 al.elements[i].checked=val;
508 <table width="100%" border="0" id="admin_mass_update">
511 <a href="javascript:checkAll(1)">'._('Check all').'</a>
513 <a href="javascript:checkAll(0)">'._('Clear all').'</a>
516 <span class="important">'._('<strong>Admin:</strong> If you wish to apply changes to all items selected above, use these controls to change their properties and click once on "Mass Update".').'</span></p>
521 // build custom fields
523 $ef =& $ath->getExtraFields(ARTIFACT_EXTRAFIELD_FILTER_INT);
524 $keys=array_keys($ef);
527 for ($i=0; $i<count($keys); $i++) {
528 if (($ef[$keys[$i]]['field_type']==ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) || ($ef[$keys[$i]]['field_type']==ARTIFACT_EXTRAFIELDTYPE_MULTISELECT)) {
529 $sel[$keys[$i]]=array('100');
531 $sel[$keys[$i]]='100';
534 $ath->renderExtraFields($sel,true,_('No Change'),false,'',ARTIFACT_EXTRAFIELD_FILTER_INT,true);
536 <td><strong>'._('Priority').': <a href="javascript:help_window(\'/help/tracker.php?helpname=priority\')"><strong>(?)</strong></a>
538 echo build_priority_select_box ('priority', '100', true);
545 <td><strong>'._('Assigned to').': <a href="javascript:help_window(\'/help/tracker.php?helpname=assignee\')"><strong>(?)</strong></a>
546 </strong><br />'. $ath->technicianBox ('assigned_to','100.1',true,_('Nobody'),'100.1',_('No Change')) .'</td>
548 if (!$ath->usesCustomStatuses()) {
549 echo '<strong>'._('State').': <a href="javascript:help_window(\'/help/tracker.php?helpname=status\')"><strong>(?)</strong></a></strong>
550 <br />'. $ath->statusBox ('status_id','xzxz',true,_('No Change'));
555 <tr><td colspan="2"><strong>'._('Canned Response').':
556 <a href="javascript:help_window(\'/help/tracker.php?helpname=canned_response\')"><strong>(?)</strong></a>
557 </strong><br />'. $ath->cannedResponseBox ('canned_response') .'</td></tr>
559 <tr><td colspan="3" align="center"><input type="submit" name="submit" value="'._('Mass update').'" /></td></tr>
564 printf(_('* Denotes requests > %1$s Days Old'), ($ath->getDuePeriod()/86400));
565 show_priority_colors_key();
570 <h1>'._('No items found').'</h1>';
572 //echo "<!-- $sql -->";
576 $ath->footer(array());
580 // c-file-style: "bsd"