5 * Copyright 1999-2001 (c) VA Linux Systems
6 * Copyright 2010 Roland Mas
7 * Copyright (C) 2011-2012 Alain Peyrat - Alcatel-Lucent
8 * Copyright 2011, Iñigo Martinez
9 * Copyright 2012, Thorsten “mirabilos” Glaser <t.glaser@tarent.de>
10 * Copyright 2012-2017,2022, Franck Villaume - TrivialDev
11 * Copyright 2014, Stéphane-Eymeric Bredthauer
12 * Copyright 2016-2017, Stéphane-Eymeric Bredthauer - TrivialDev
13 * http://fusionforge.org
15 * This file is part of FusionForge. FusionForge is free software;
16 * you can redistribute it and/or modify it under the terms of the
17 * GNU General Public License as published by the Free Software
18 * Foundation; either version 2 of the Licence, or (at your option)
21 * FusionForge is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License along
27 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 require_once $gfcommon.'tracker/ArtifactFactory.class.php';
32 require_once $gfcommon.'tracker/ArtifactQuery.class.php';
33 require_once $gfcommon.'include/utils_crossref.php';
42 // make sure this person has permission to view artifacts
44 session_require_perm('tracker', $ath->getID(), 'read');
46 $query_id = getIntFromRequest('query_id');
47 $start = getIntFromRequest('start');
50 // The browse page can be powered by a pre-saved query
51 // or by select boxes chosen by the user
53 // If there is a $query_id coming from the request OR the pref
54 // was already saved, use the artifact factory that way.
56 // If the query_id = -1, unset the pref and use regular browse boxes
58 if (session_loggedin()) {
59 if (getStringFromRequest('setpaging')) {
60 /* store paging preferences */
61 $paging = getIntFromRequest('nres');
65 $LUSER->setPreference("paging", $paging);
67 /* logged in users get configurable paging */
68 $paging = $LUSER->getPreference("paging");
71 if ($query_id == '-1') {
72 $LUSER->setPreference('art_query'.$ath->getID(), '');
74 $aq = new ArtifactQuery($ath,$query_id);
75 if (!$aq || !is_object($aq)) {
76 exit_error($aq->getErrorMessage(),'tracker');
81 $query_id = $LUSER->getPreference('art_query'.$ath->getID(), '');
83 } elseif ($query_id) {
84 // If user is not logged, then use a cookie to store the current query.
85 if (isset($_COOKIE["FFTrackerQuery"])) {
86 $gf_tracker = unserialize($_COOKIE["FFTrackerQuery"]);
88 $gf_tracker = array();
90 $gf_tracker[$ath->getID()] = $query_id;
91 // Send the query_id as a cookie to save it.
92 setcookie("FFTrackerQuery", serialize($gf_tracker));
93 $_COOKIE["FFTrackerQuery"] = serialize($gf_tracker);
94 } elseif (isset($_COOKIE["FFTrackerQuery"])) {
95 $gf_tracker = unserialize($_COOKIE["FFTrackerQuery"]);
96 if (isset($gf_tracker[$ath->getID()])) {
97 $query_id = (int)$gf_tracker[$ath->getID()];
101 if(!isset($paging) || !$paging) {
104 $af = new ArtifactFactory($ath);
106 if (!$af || !is_object($af)) {
107 exit_error(_('Could Not Get Factory'),'tracker');
108 } elseif ($af->isError()) {
109 exit_error($af->getErrorMessage(),'tracker');
112 if (!isset($_sort_col)) {
113 /* default sort order: highest priority first */
114 $_sort_col = 'priority';
118 if (!isset($_changed)) {
119 $_changed = 0x7fffffff;
122 $_sort_col = getStringFromRequest('_sort_col',$_sort_col);
123 $_sort_ord = getStringFromRequest('_sort_ord',$_sort_ord);
124 $_changed = getStringFromRequest('_changed', $_changed);
125 $_last_modified_by = getIntFromRequest('_last_modified_by');
126 $_priority = getIntFromRequest('_priority');
127 $set = getStringFromRequest('set');
128 $_assigned_to = getIntFromRequest('_assigned_to');
129 $_status = getIntFromRequest('_status');
130 $_extra_fields = array() ;
131 $aux_extra_fields = array() ;
133 if ($set == 'custom') {
134 /* may be past in next/prev url */
135 $i = $ath->getCustomStatusField();
136 $tmp_extra_fields = getArrayFromRequest('extra_fields');
137 if (isset($tmp_extra_fields[$i])) {
138 $_extra_fields[$i] = $tmp_extra_fields[$i];
142 if (isset($_extra_fields) && is_array($_extra_fields)) {
143 $keys=array_keys($_extra_fields);
144 foreach ($keys as $key) {
145 if ($_extra_fields[$key] != 'Array') {
146 $aux_extra_fields[$key] = $_extra_fields[$key];
150 if (isset($_extra_fields)) {
151 $aux_extra_fields = $_extra_fields;
153 $aux_extra_fields = '';
157 $af->setup($start, $_sort_col, $_sort_ord, $paging, $set, $_assigned_to, $_status, $aux_extra_fields, time() - $_changed, $_last_modified_by, $_priority);
159 // These vals are sanitized and/or retrieved from ArtifactFactory stored settings
161 $_sort_col=$af->order_col;
162 $_sort_ord=$af->sort;
163 $_status=$af->status;
164 $_assigned_to=$af->assigned_to;
165 $_extra_fields=$af->extra_fields;
167 $art_arr = $af->getArtifacts();
169 if (!$art_arr && $af->isError()) {
170 exit_error($af->getErrorMessage(),'tracker');
173 //build page title to make bookmarking easier
174 //if a user was selected, add the user_name to the title
177 html_use_coolfieldset();
179 $ath->header(array('atid'=>$ath->getID(), 'title'=>$ath->getName()));
182 * Build the powerful browsing options pop-up boxes
186 // creating a custom technician box which includes "any" and "unassigned"
188 if (is_array($_assigned_to)) {
191 $tech_box = $ath->technicianBox('_assigned_to', $_assigned_to, true, _('Unassigned'), '0', _('Any'));
194 // custom order by arrays to build a pop-up box
196 $order_name_arr=array();
197 $order_name_arr[]=_('Id');
198 $order_name_arr[]=_('Priority');
199 $order_name_arr[]=_('Summary');
200 $order_name_arr[]=_('Open Date');
201 $order_name_arr[]=_('Last Modified Date');
202 $order_name_arr[]=_('Last Modifier');
203 $order_name_arr[]=_('Close Date');
204 $order_name_arr[]=_('Submitter');
205 $order_name_arr[]=_('Assignee');
206 $order_name_arr[]=_('# Votes');
207 $order_name_arr[]=_('# Voters');
208 $order_name_arr[]=_('% Votes');
211 $order_arr[]='artifact_id';
212 $order_arr[]='priority';
213 $order_arr[]='summary';
214 $order_arr[]='open_date';
215 $order_arr[]='last_modified_date';
216 $order_arr[]='last_modified_by';
217 $order_arr[]='close_date';
218 $order_arr[]='submitted_by';
219 $order_arr[]='assigned_to';
220 $order_arr[]='_votes';
221 $order_arr[]='_voters';
222 $order_arr[]='_votage';
225 // custom sort arrays to build pop-up box
227 $sort_name_arr=array();
228 $sort_name_arr[]=_('Ascending');
229 $sort_name_arr[]=_('Descending');
236 // custom changed arrays to build pop-up box
238 $changed_name_arr=array();
239 $changed_name_arr[]=_('Any');
240 $changed_name_arr[]=_('Last 24 h');
241 $changed_name_arr[]=_('Last 7 days');
242 $changed_name_arr[]=_('Last 2 weeks');
243 $changed_name_arr[]=_('Last month');
245 $changed_arr=array();
246 $changed_arr[]= 0x7fffffff; // Any
247 $changed_arr[]= 3600 * 24; // 24 hour
248 $changed_arr[]= 3600 * 24 * 7; // 1 week
249 $changed_arr[]= 3600 * 24 * 14;// 2 week
250 $changed_arr[]= 3600 * 24 * 30;// 1 month
252 if ($art_arr && ($art_cnt = count($art_arr)) > 0) {
253 $focus = getIntFromRequest('focus');
262 for ($i = 0; $i < $art_cnt; ++$i) {
263 if ($art_arr[$i]->getID() == $focus) {
269 $max = ($art_cnt > ($start + $paging)) ? ($start + $paging) : $art_cnt;
274 echo $HTML->paging_top($start, $paging, $art_cnt, $max, '/tracker/?group_id='.$group_id.'&atid='.$ath->getID());
278 * Show the free-form text submitted by the project admin
280 echo $ath->renderBrowseInstructions();
282 if ($ath->usesCustomStatuses()) {
283 $aux_extra_fields = array();
284 if (is_array($_extra_fields)) {
285 $keys=array_keys($_extra_fields);
286 foreach ($keys as $key) {
287 if (!is_array($_extra_fields[$key])) {
288 $aux_extra_fields[$key] = $_extra_fields[$key];
292 $aux_extra_fields = $_extra_fields;
294 $checked_status = isset($aux_extra_fields[$ath->getCustomStatusField()]) ? $aux_extra_fields[$ath->getCustomStatusField()] : '';
295 $status_box = $ath->renderSelect ($ath->getCustomStatusField(), $checked_status, false, '', true, _('Any'));
297 if (is_array($_status)) {
300 $status_box = $ath->statusBox('_status', $_status, true, _('Any'));
304 $proj_name = $group->getUnixName();
305 $proj_url = util_make_url_g($group->getUnixName());
306 // the tracker's URIs are constructed in order to support addition of an OSLC-CM REST server
307 // inside /tracker/cm/. There each tracker has a URL in the form .../project/PROJ_NAME/atid/ATID
308 $tracker_stdzd_uri = util_make_url('/tracker/cm/project/'. $proj_name .'/atid/'. $ath->getID());
309 print '<div about="'. $tracker_stdzd_uri
310 .'" typeof="sioc:Container">'."\n";
311 print '<span rel="http://www.w3.org/2002/07/owl#sameAs" resource="" ></span>'."\n";
312 print '<span rev="doap:bug-database sioc:space_of" resource="'. $proj_url .'" ></span>'."\n";
313 print "</div>\n"; // end of about
315 if ($af->query_type == 'custom') {
316 $javascript = 'jQuery(document).ready(function() {jQuery("#tabber").tabs({active: 1});});';
317 echo html_e('script', array( 'type'=>'text/javascript'), '//<![CDATA['."\n".$javascript."\n".'//]]>');
319 echo '<div id="tabber" class="tabber">';
320 $elementLi[] = array('content' => util_make_link('#tabber-advancedquery', _('Advanced queries'), array('title' => _('Use project queries or build and use your own queries.')), true));
321 $elementLi[] = array('content' => util_make_link('#tabber-simplefiltering', _('Simple Filtering and Sorting'), array('title' => _('Filtering by assignee, state, priority.')), true));
322 echo $HTML->html_list($elementLi);
323 echo '<div id="tabber-advancedquery">';
325 if (session_loggedin()) {
326 $res = db_query_params ('SELECT artifact_query_id,query_name, CASE WHEN query_type>0 THEN 1 ELSE 0 END as type
328 WHERE group_artifact_id=$1 AND (user_id=$2 OR query_type>0)
329 ORDER BY type ASC, query_name ASC',
330 array ($ath->getID(),
333 $res = db_query_params ('SELECT artifact_query_id,query_name, CASE WHEN query_type>0 THEN 1 ELSE 0 END as type
335 WHERE group_artifact_id=$1 AND query_type>0
336 ORDER BY type ASC, query_name ASC',
337 array ($ath->getID()));
340 if (db_numrows($res)>0) {
341 echo $HTML->openForm(array('action' => '/tracker/', 'method' => 'get'));
342 echo '<input type="hidden" name="group_id" value="'.$group_id.'" />';
343 echo '<input type="hidden" name="atid" value="'.$ath->getID().'" />';
344 echo '<input type="hidden" name="power_query" value="1" />';
345 echo $HTML->listTableTop().
347 $selected = $af->getDefaultQuery();
348 $value_arr = array();
350 $opt_group_arr = array();
351 while ($row = db_fetch_array($res)) {
352 $value_arr[] = $row['artifact_query_id'];
353 $text_arr[] = $row['query_name'];
354 $opt_group_arr[] = ($row['type'] ? _('Project') : _('Private'));
356 echo html_build_select_box_from_arrays($value_arr, $text_arr, 'query_id', $af->getDefaultQuery(), true, _('Select One'), false, '', false, array('id' => 'query_id'), array(), array(), $opt_group_arr);
357 echo '<noscript><input type="submit" name="run" value="'._('Power Query').'" /></noscript>
358 '.util_make_link('/tracker/?atid='. $ath->getID().'&group_id='.$group_id.'&func=query', _('Build Query')).'
359 </td></tr>'.$HTML->listTableBottom();
360 echo $HTML->closeForm();
361 $javascript = 'jQuery("#query_id").change(function() {location.href = "'.util_make_url('/tracker/?group_id='.$group_id.'&atid='.$ath->getID().'&power_query=1&query_id=').'"+jQuery("#query_id").val();});';
362 echo html_e('script', array( 'type'=>'text/javascript'), '//<![CDATA['."\n".$javascript."\n".'//]]>');
365 echo util_make_link('/tracker/?atid='.$ath->getID().'&group_id='.$group_id.'&func=query','<strong>'._('Build Query').'</strong>');
368 <div id="tabber-simplefiltering">';
369 $sort_fields = explode(',', $ath->getBrowseList());
370 // Get the list of fields which can be sorted.
371 $efarr = $ath->getExtraFields(array(ARTIFACT_EXTRAFIELDTYPE_TEXT,
372 ARTIFACT_EXTRAFIELDTYPE_TEXTAREA,
373 ARTIFACT_EXTRAFIELDTYPE_INTEGER,
374 ARTIFACT_EXTRAFIELDTYPE_SELECT,
375 ARTIFACT_EXTRAFIELDTYPE_RADIO,
376 ARTIFACT_EXTRAFIELDTYPE_STATUS,
377 ARTIFACT_EXTRAFIELDTYPE_DATE,
378 ARTIFACT_EXTRAFIELDTYPE_DATETIME,
379 ARTIFACT_EXTRAFIELDTYPE_EFFORT));
380 echo $HTML->openForm(array('action' => '/tracker/?group_id='.$group_id.'&atid='.$ath->getID(), 'method' => 'post'));
382 <input type="hidden" name="query_id" value="-1" />
383 <input type="hidden" name="set" value="custom" />
386 foreach ($sort_fields as $sort_field) {
387 switch ($sort_field) {
389 echo '<td>'._('Assignee')._(':').html_e('br').$tech_box.'</td>';
391 case 'last_modified_by':
392 echo '<td>'._('Modified by')._(':').html_e('br').$ath->lastModifierBox('_last_modified_by', $_last_modified_by, false, false, '0', _('Any')).'</td>';
394 case 'last_modified_date':
395 echo '<td>'._('Changed')._(':').html_e('br').html_build_select_box_from_arrays($changed_arr, $changed_name_arr, '_changed', $_changed, false).'<td>';
398 echo '<td>'._('State')._(':').'<br>'. $status_box.'</td>';
409 //no ordering on these columns yet.
411 if (intval($sort_field) > 0 && isset($efarr[$sort_field])) {
412 if ($efarr[$sort_field]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
413 echo '<td>'.$ath->getExtraFieldName($sort_field)._(':').'<br>'.$status_box.'</td>';
416 //build a box for extrafield ?
422 $keys=array_keys($efarr);
423 for ($k=0; $k<count($keys); $k++) {
425 $order_name_arr[] = $efarr[$i]['field_name'];
426 $order_arr[] = $efarr[$i]['extra_field_id'];
428 echo '<td>'._('Priority')._(':').html_e('br').
429 html_build_priority_select_box('_priority', $_priority, false, array(), true).'</td>';
430 echo '<td>'._('Order by')._(':').'<br>'.
431 html_build_select_box_from_arrays($order_arr,$order_name_arr,'_sort_col',$_sort_col,false) .
432 html_build_select_box_from_arrays($sort_arr,$sort_name_arr,'_sort_ord',$_sort_ord,false) .
434 <td><br><input type="submit" name="submit" value="'._('Quick Browse').'" /></td>';
439 echo $HTML->closeForm();
441 if ($af->query_type == 'default') {
442 echo '<div class="tabbertab tabbertabdefault" >';
444 echo sprintf(_('Viewing only opened records by default, use “%1$s” or “%2$s” to change.'),
445 _('Advanced queries'),
446 _('Simple Filtering and Sorting'));
448 echo '</div>' . "\n";
450 echo '</div>' . "\n";
452 $art_cnt = count($art_arr);
453 if ($art_arr && $art_cnt > 0) {
456 $aq = new ArtifactQuery($ath,$query_id);
457 $has_bargraph = (in_array('bargraph', $aq->getQueryOptions()));
459 $has_bargraph = false;
463 // Display the roadmap block based on the values of the Status field.
464 $colors = array('#a71d16', '#ffa0a0', '#f5f5b5', '#bae0ba', '#16a716');
467 foreach($art_arr as $art) {
468 if ($ath->usesCustomStatuses()) {
469 $custom_id = $ath->getCustomStatusField();
470 $extra_data = $art->getExtraFieldDataText();
471 @$count[ $extra_data[$custom_id]['value'] ]++;
473 @$count[ $art->getStatusName()]++;
476 foreach($count as $n => $c) {
477 $percent[$n] = round(100*$c/$art_cnt);
479 if ($ath->getCustomStatusField()) {
480 $efarr = $ath->getExtraFields(array(ARTIFACT_EXTRAFIELDTYPE_STATUS));
481 $keys=array_keys($efarr);
482 $field_id = $keys[0];
483 $custom_states = $ath->getExtraFieldElements($field_id);
485 if (is_array($custom_states)) {
486 foreach($custom_states as $state) {
487 $states[] = $state['element_name'];
491 $colors = array('#ffa0a0', '#bae0ba');
492 $res = $ath->getStatuses();
493 while ($row = db_fetch_array($res)) {
494 $states[] = $row['status_name'];
501 if (is_array($states)) {
502 foreach($states as $name) {
503 if (isset($count[$name]) && $count[$name]) {
504 $graph .= '<td style="background: '.$colors[$i].'; width: '.$percent[$name].'%;"> </td>';
505 $legend .= '<td style="white-space: nowrap; width: '.$percent[$name].'%;">'.html_e('em', array(), $name.': '.$count[$name].' ('.$percent[$name].'%)').'</td>';
513 <table class="progress">
515 <tr><?php echo $graph; ?></tr>
518 <table class="progress_legend">
519 <tr><?php echo $legend ?></tr>
525 if ($set=='custom') {
526 $set .= '&_assigned_to='.$_assigned_to.'&_status='.$_status.'&_sort_col='.$_sort_col.'&_sort_ord='.$_sort_ord;
527 if (array_key_exists($ath->getCustomStatusField(),$_extra_fields)) {
528 $set .= '&extra_fields['.$ath->getCustomStatusField().']='.$_extra_fields[$ath->getCustomStatusField()];
533 $IS_ADMIN = forge_check_perm ('tracker', $ath->getID(), 'manager') ;
536 echo $HTML->openForm(array('name' => 'artifactList', 'action' => '/tracker/?group_id='.$group_id.'&atid='.$ath->getID(), 'method' => 'post'));
537 echo '<input type="hidden" name="form_key" value="'.form_generate_key().'" />
538 <input type="hidden" name="func" value="massupdate" />';
544 <a href="javascript:checkAllArtifacts(1)">'._('Check all').'</a>
546 <a href="javascript:checkAllArtifacts(0)">'._('Clear all').'</a>';
550 $browse_fields = explode(',', "id,".$ath->getBrowseList());
551 if (!in_array($_sort_col,$browse_fields) && $_sort_col!='artifact_id') {
552 $browse_fields[] = $_sort_col;
556 foreach ($browse_fields as $f) {
566 $title=_('Description');
569 $title=_('Open Date');
572 $title=_('Close Date');
578 $title=_('Priority');
581 $title=_('Assigned to');
584 $title=_('Submitted by');
586 case 'related_tasks':
587 $title=_('Related Tasks');
589 case 'last_modified_date':
590 $title=_('Last Modified Date');
592 case 'last_modified_by':
593 $title=_('Last Modifier');
596 $title = _('# Votes');
599 $title = _('# Voters');
602 $title = _('% Voted');
605 if (intval($f) > 0) {
606 $title = $ath->getExtraFieldName($f);
609 $title_arr[] = $title;
613 echo $HTML->listTableTop($title_arr, array(), 'full');
616 $then=(time()-$ath->getDuePeriod());
617 $voters = count($ath->getVoters());
619 for ($i=$start; $i<$max; $i++) {
620 $extra_data = $art_arr[$i]->getExtraFieldDataText();
622 <tr class=priority'. $art_arr[$i]->getPriority().'>';
623 foreach ($browse_fields as $f) {
626 echo '<td style="white-space: nowrap;">'.
627 ($IS_ADMIN?'<input type="checkbox" name="artifact_id_list[]" value="'.
628 $art_arr[$i]->getID() .'" /> ':'').
629 util_make_link('/tracker/?func=detail&aid='.
630 $art_arr[$i]->getID().
631 '&group_id='. $group_id .'&atid='.
633 $art_arr[$i]->getID()).
638 util_make_link('/tracker/?func=detail&aid='.
639 $art_arr[$i]->getID() .
640 '&group_id='. $group_id .'&atid='.
642 $art_arr[$i]->getSummary()).
646 echo '<td>'. (($set != 'closed' && $art_arr[$i]->getOpenDate() < $then)?'* ':' ') .
647 date(_('Y-m-d H:i'),$art_arr[$i]->getOpenDate()) .'</td>';
650 echo '<td>'. $art_arr[$i]->getStatusName() .'</td>';
653 echo '<td class="priority'.$art_arr[$i]->getPriority() .'">'. $art_arr[$i]->getPriority() .'</td>';
656 if($art_arr[$i]->getAssignedTo() != 100) {
657 echo '<td>'.util_display_user($art_arr[$i]->getAssignedUnixName(), $art_arr[$i]->getAssignedTo(), $art_arr[$i]->getAssignedRealName()).'</td>';
659 echo '<td>'. $art_arr[$i]->getAssignedRealName() .'</td>';
663 if($art_arr[$i]->getSubmittedBy() != 100) {
664 echo '<td>'.util_display_user($art_arr[$i]->getSubmittedUnixName(), $art_arr[$i]->getSubmittedBy(), $art_arr[$i]->getSubmittedRealName()).'</td>';
666 echo '<td>'.$art_arr[$i]->getSubmittedRealName().'</td>';
669 case 'last_modified_by':
670 if($art_arr[$i]->getLastModifiedRealName() != 100) {
671 echo '<td>'.util_display_user($art_arr[$i]->getLastModifiedUnixName(), $art_arr[$i]->getLastModifiedBy(), $art_arr[$i]->getLastModifiedRealName()).'</td>';
673 echo '<td>'.$art_arr[$i]->getLastModifiedRealName().'</td>';
677 echo '<td>'. ($art_arr[$i]->getCloseDate() ?
678 date(_('Y-m-d H:i'),$art_arr[$i]->getCloseDate()) :' ') .'</td>';
681 echo '<td>'. $art_arr[$i]->getDetails() .'</td>';
683 case 'related_tasks':
685 $tasks_res = $art_arr[$i]->getRelatedTasks();
687 while ($rest = db_fetch_array($tasks_res)) {
688 $link = '/pm/task.php?func=detailtask&project_task_id='.$rest['project_task_id'].
689 '&group_id='.$group_id.'&group_project_id='.$rest['group_project_id'];
690 $title = '[T'.$rest['project_task_id'].']';
691 if ($rest['status_id'] == 2) {
692 $title = '<span class="strike">'.$title.'</span>';
694 echo $s.util_make_link($link, $title, array( 'title' => util_html_secure($rest['summary'])));
699 case 'last_modified_date':
700 echo '<td>'. ($art_arr[$i]->getLastModifiedDate() ?
701 date(_('Y-m-d H:i'),$art_arr[$i]->getLastModifiedDate()) :' ') .'</td>';
704 $v = $art_arr[$i]->getVotes();
705 echo html_e('td', array(), $v[0], false);
708 echo html_e('td', array(), $voters, false);
711 $v = $art_arr[$i]->getVotes();
712 echo html_e('td', array(), $v[2], false);
715 if (intval($f) > 0) {
716 // Now display extra-fields (fields are numbers).
717 $value = $extra_data[$f]['value'];
718 if ($extra_data[$f]['type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
719 $value = preg_replace_callback('/\b(\d+)b\]/', function($matches) {return _artifactid2url($matches[1]);}, $value);
720 } elseif ($extra_data[$f]['type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
721 if ($art_arr[$i]->getStatusID() == 2) {
722 $value = '<span class="strike">'.$value.'</span>';
724 } elseif ($extra_data[$f]['type'] == ARTIFACT_EXTRAFIELDTYPE_EFFORT) {
725 if (!isset($effortUnitSet)) {
726 $effortUnitSet = new EffortUnitSet($ath, $ath->getEffortUnitSet());
727 $effortUnitFactory = new EffortUnitFactory($effortUnitSet);
729 $value = $effortUnitFactory->encodedToString($value);
731 echo '<td>' . $value .'</td>';
733 // Display ? for unknown values.
742 echo $HTML->listTableBottom();
744 echo $HTML->paging_bottom($start, $paging, $art_cnt, '/tracker/?func=browse&group_id='.$group_id.'&atid='.$ath->getID().'&set='. $set);
746 echo '<div style="display:table;width:100%">';
747 echo '<div style="display:table-row">';
749 echo '<div style="display:table-cell">';
750 printf(_('* Denotes requests > %s Days Old'), ($ath->getDuePeriod()/86400));
753 if (in_array('priority', $browse_fields)) {
754 echo '<div style="display:table-cell;text-align:right">';
755 echo $HTML->show_priority_colors_key();
760 echo '<div style="display:table-row">';
762 echo '<div style="display:table-cell">'.$check_all.'</div>';
763 echo '<div style="display:table-cell;text-align:right">'.$pager.'</div>'."\n";
772 echo '<fieldset id="fieldset1_closed" class="coolfieldset">
773 <legend>'._('Mass Update').'</legend>
775 echo $HTML->listTableTop(array(), array(), 'fullwidth', 'admin_mass_update');
776 echo ' <tr><td colspan="2">';
777 echo $HTML->information(_('If you wish to apply changes to all items selected above, use these controls to change their properties and click once on “Mass Update”.')).'
781 // build custom fields
783 $ef = $ath->getExtraFields(array(ARTIFACT_EXTRAFIELD_FILTER_INT));
784 $keys=array_keys($ef);
787 for ($i=0; $i<count($keys); $i++) {
788 if (($ef[$keys[$i]]['field_type']==ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) || ($ef[$keys[$i]]['field_type']==ARTIFACT_EXTRAFIELDTYPE_MULTISELECT)) {
789 $sel[$keys[$i]]=array('100');
791 $sel[$keys[$i]]='100';
794 $ath->renderExtraFields($sel,true,_('No Change'),false,'', array(ARTIFACT_EXTRAFIELD_FILTER_INT),true,'UPDATE');
796 echo '<td><strong>'._('Priority')._(':').'</strong><br />';
797 echo build_priority_select_box ('priority', '100', true);
800 if (forge_check_perm ('tracker', $ath->getID(), 'manager')) {
801 echo '<strong>'._('Submitted by')._(':').'</strong><br />';
802 echo $ath->technicianBox ('submitted_by', '100.1', true, _('Nobody'), '100.1', _('No Change'));
808 echo '<td><strong>'._('Assigned to')._(':').'</strong><br />';
809 echo $ath->technicianBox ('assigned_to','100.1',true,_('Nobody'),'100.1',_('No Change'));
812 if (!$ath->usesCustomStatuses()) {
813 echo '<strong>'._('State')._(': ').'</strong>
814 <br />'. $ath->statusBox ('status_id','xzxz',true,_('No Change'));
820 echo '<td colspan="2"><strong>'._('Canned Response')._(':').'</strong><br />';
821 echo $ath->cannedResponseBox ('canned_response') .'</td></tr>
823 <tr><td colspan="2" class="align-center"><input type="submit" name="submit" value="'._('Mass Update').'" /></td></tr>';
824 echo $HTML->listTableBottom();
825 echo '</div></fieldset>';
826 echo $HTML->closeForm();
830 echo $HTML->information(_('No items found'));
838 // c-file-style: "bsd"