3 * FusionForge Generic Tracker facility
5 * Copyright 1999-2001 (c) VA Linux Systems - Sourceforge
6 * Copyright 2010 (c) Fusionforge Team
7 * Copyright 2011, Franck Villaume - Capgemini
8 * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
9 * http://fusionforge.org
11 * This file is part of FusionForge. FusionForge is free software;
12 * you can redistribute it and/or modify it under the terms of the
13 * GNU General Public License as published by the Free Software
14 * Foundation; either version 2 of the Licence, or (at your option)
17 * FusionForge is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 require_once $gfcommon.'tracker/ArtifactType.class.php';
28 require_once $gfcommon.'tracker/ArtifactExtraField.class.php';
29 require_once $gfcommon.'tracker/ArtifactExtraFieldElement.class.php';
30 require_once $gfcommon.'tracker/ArtifactWorkflow.class.php';
31 require_once $gfcommon.'include/utils_crossref.php';
33 class ArtifactTypeHtml extends ArtifactType {
35 function header($params) {
37 if (!forge_get_config('use_tracker')) {
40 $group_id= $this->Group->getID();
42 //required by new site_project_header
43 $params['group']=$group_id;
44 $params['toptab']='tracker';
45 $params['tabtext']=$this->getName();
51 $labels[] = _("View Trackers");
52 $links[] = '/tracker/?group_id='.$group_id;
53 $attr[] = array('title' => _('Get the list of available trackers'), 'class' => 'tabtitle-nw');
54 $labels[] = $this->getName();
55 $links[] = '/tracker/?func=browse&group_id='.$group_id.'&atid='. $this->getID();
56 $attr[] = array('title' => _('Browse this tracker.'), 'class' => 'tabtitle');
57 $labels[] = _('Export CSV');
58 $links[] = '/tracker/?func=csv&group_id='.$group_id.'&atid='. $this->getID();
59 $attr[] = array('title' => _('Download data from this tracker as csv file.'), 'class' => 'tabtitle');
60 if ($this->allowsAnon() || session_loggedin()) {
61 $labels[] = _('Submit New');
62 $links[] = '/tracker/?func=add&group_id='.$group_id.'&atid='. $this->getID();
63 $attr[] = array('title' => _('Add a new issue.'), 'class' => 'tabtitle');
66 if (session_loggedin()) {
67 $labels[] = _('Reporting');
68 $links[] = '/tracker/reporting/?group_id='.$group_id.'&atid='. $this->getID();
69 $attr[] = array('title' => _('Various graph about statistics.'), 'class' => 'tabtitle');
70 if ($this->isMonitoring()) {
71 $labels[] = _('Stop Monitor');
72 $links[] = '/tracker/?group_id='.$group_id.'&atid='. $this->getID().'&func=monitor&stop=1';
73 $attr[] = array('title' => _('Remove this tracker from your monitoring.'), 'class' => 'tabtitle');
75 $labels[] = _('Monitor');
76 $links[] = '/tracker/?group_id='.$group_id.'&atid='. $this->getID().'&func=monitor&start=1';
77 $attr[] = array('title' => _('Add this tracker from your monitoring.'), 'class' => 'tabtitle');
80 if (forge_check_perm ('tracker', $this->getID(), 'manager')) {
81 $labels[] = _('Administration');
82 $links[] = '/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID();
83 $attr[] = array('title' => _('Global administration for trackers. Create, clone, workflow, fields ...'), 'class' => 'tabtitle');
86 $labels[] = _('Monitor');
87 $links[] = '/tracker/?group_id='.$group_id.'&atid='. $this->getID().'&func=monitor&start=1';
88 $attr[] = array('title' => _('Add this tracker from your monitoring.'), 'class' => 'tabtitle');
91 $params['submenu'] = $HTML->subMenu($labels, $links, $attr);
92 site_project_header($params);
95 plugin_hook("blocks", "tracker_".$this->getName());
99 function footer($params) {
100 site_project_footer($params);
103 function adminHeader($params) {
105 $this->header($params);
106 $group_id= $this->Group->getID();
108 $links_arr[]='/tracker/admin/?group_id='.$group_id;
109 $title_arr[]=_('New Tracker');
111 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&update_type=1';
112 $title_arr[]=_('Update Settings');
114 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&add_extrafield=1';
115 $title_arr[]=_('Manage Custom Fields');
117 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&workflow=1';
118 $title_arr[]=_('Manage Workflow');
120 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&customize_list=1';
121 $title_arr[]=_('Customize List');
123 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&add_canned=1';
124 $title_arr[]=_('Add/Update Canned Responses');
126 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&clone_tracker=1';
127 $title_arr[]=_('Clone Tracker');
129 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&delete=1';
130 $title_arr[]=_('Delete');
132 echo $HTML->printSubMenu($title_arr, $links_arr, false);
135 function adminFooter($params) {
136 echo $this->footer($params);
139 function renderSubmitInstructions() {
140 $msg = $this->getSubmitInstructions();
141 return str_replace("\n","<br />", $msg);
144 function renderBrowseInstructions() {
145 $msg = $this->getBrowseInstructions();
146 return str_replace("\n","<br />", $msg);
149 function renderExtraFields($selected=array(),$show_100=false,$text_100='none',$show_any=false,$text_any='Any',$types=array(),$status_show_100=false,$mode='') {
150 $efarr = $this->getExtraFields($types);
151 //each two columns, we'll reset this and start a new row
153 $template = $this->getRenderHTML($types, $mode);
155 if ($mode=='QUERY') {
156 $keys=array_keys($efarr);
157 for ($k=0; $k<count($keys); $k++) {
159 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT ||
160 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX ||
161 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO ||
162 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS ||
163 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
164 $efarr[$i]['field_type'] = ARTIFACT_EXTRAFIELDTYPE_MULTISELECT;
166 $efarr[$i]['field_type'] = ARTIFACT_EXTRAFIELDTYPE_TEXT;
171 // 'DISPLAY' mode is for renderding in 'read-only' mode (for detail view).
172 if ($mode === 'DISPLAY') {
173 $keys=array_keys($efarr);
174 for ($k=0; $k<count($keys); $k++) {
177 if (!isset($selected[$efarr[$i]['extra_field_id']]))
178 $selected[$efarr[$i]['extra_field_id']] = '';
180 $value = @$selected[$efarr[$i]['extra_field_id']];
182 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT ||
183 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX ||
184 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO ||
185 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS ||
186 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
190 $arr = $this->getExtraFieldElements($efarr[$i]['extra_field_id']);
192 // Convert the values (ids) to names in the ids order.
194 for ($j=0; $j<count($arr); $j++) {
195 if (is_array($value)) {
196 if (in_array($arr[$j]['element_id'],$value))
197 $new[]= $arr[$j]['element_name'];
198 } elseif ($arr[$j]['element_id'] === $value) {
199 $new[] = $arr[$j]['element_name'];
202 $value = join('<br />', $new);
204 } else if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
205 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
206 $value = preg_replace('/((http|https|ftp):\/\/\S+)/',
207 "<a href=\"\\1\" target=\"_blank\">\\1</a>", $value);
208 } else if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
209 // Convert artifact id to links.
210 $value = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1')", $value);
212 $template = str_replace('{$PostName:'.$efarr[$i]['field_name'].'}',$post_name,$template);
213 $template = str_replace('{$'.$efarr[$i]['field_name'].'}',$value,$template);
219 $keys=array_keys($efarr);
220 for ($k=0; $k<count($keys); $k++) {
224 if (!isset($selected[$efarr[$i]['extra_field_id']]))
225 $selected[$efarr[$i]['extra_field_id']] = '';
227 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT) {
228 $str = $this->renderSelect($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100,$show_any,$text_any);
230 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) {
232 $str = $this->renderCheckbox($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100);
234 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO) {
236 $str = $this->renderRadio($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100,$show_any,$text_any);
238 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
239 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
241 $str = $this->renderTextField($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
242 if ($mode == 'QUERY') {
243 $post_name = ' <i>'._('(%% for wildcards)').'</i> ';
246 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
248 $str = $this->renderTextArea($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
249 if ($mode == 'QUERY') {
250 $post_name = ' <i>'._('(%% for wildcards)').'</i> ';
253 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
255 $str = $this->renderMultiSelectBox ($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100);
257 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
259 // Get the allowed values from the workflow.
260 $atw = new ArtifactWorkflow($this, $efarr[$i]['extra_field_id']);
262 // Special treatement for the initial step (Submit).
263 // In this case, the initial value is the first value.
264 if ($selected === true) {
265 $selected_node = 100;
266 } elseif (isset($selected[$efarr[$i]['extra_field_id']]) && $selected[$efarr[$i]['extra_field_id']]) {
267 $selected_node = $selected[$efarr[$i]['extra_field_id']];
269 $selected_node = 100;
272 $allowed = $atw->getNextNodes($selected_node);
273 $allowed[] = $selected_node;
274 $str = $this->renderSelect($efarr[$i]['extra_field_id'],$selected_node,$status_show_100,$text_100,$show_any,$text_any, $allowed);
276 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
278 $str = $this->renderRelationField($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
279 if ($mode == 'UPDATE') {
280 $post_name = html_image('ic/forum_edit.gif','37','15',array('title'=>"Click to edit", 'alt'=>"Click to edit", 'onclick'=>"switch2edit(this, 'show$i', 'edit$i')"));
283 $template = str_replace('{$PostName:'.$efarr[$i]['field_name'].'}',$post_name,$template);
284 $template = str_replace('{$'.$efarr[$i]['field_name'].'}',$str,$template);
286 if($template != NULL){
291 function renderRelatedTasks($group, $ah) {
293 if (!$group->usesPM()) {
297 $taskcount = db_numrows($ah->getRelatedTasks());
298 db_result_reset($ah->getRelatedTasks());
300 if (forge_check_perm ('tracker_admin', $ah->ArtifactType->Group->getID())) {
306 $totalPercentage = 0;
308 if ($taskcount > 0) {
309 echo '<tr><td colspan="2">';
310 echo '<b>'._("Related Tasks").':</b>'.'<br/>';
311 $title_arr = array();
312 $title_arr[] = _('Task Id and Summary');
313 $title_arr[] = _('Start Date');
314 $title_arr[] = _('End Date');
315 $title_arr[] = _('Status');
316 (($is_admin) ? $title_arr[]=_('Remove Relation') : '');
317 echo $GLOBALS['HTML']->listTableTop($title_arr);
319 for ($i = 0; $i < $taskcount; $i++) {
320 $taskinfo = db_fetch_array($ah->relatedtasks, $i);
321 $totalPercentage += $taskinfo['percent_complete'];
322 $taskid = $taskinfo['project_task_id'];
323 $projectid = $taskinfo['group_project_id'];
324 $groupid = $taskinfo['group_id'];
325 $summary = util_unconvert_htmlspecialchars($taskinfo['summary']);
326 $startdate = date(_('Y-m-d H:i'), $taskinfo['start_date']);
327 $enddate = date(_('Y-m-d H:i'), $taskinfo['end_date']);
328 $status = $taskinfo['status_name'];
330 <td><a href="/pm/task.php?func=detailtask&project_task_id='.$taskid.'&group_id='.$groupid.'&group_project_id='.$projectid.'">[T'.$taskid.'] '.$summary.'</a></td>
331 <td>'.$startdate.'</td>
332 <td>'.$enddate.'</td>
333 <td>'.$status.' ('.$taskinfo['percent_complete'].'%)</td>'.
334 (($is_admin) ? '<td><input type="checkbox" name="remlink[]" value="'.$taskid.'" /></td>' : '').
337 echo $GLOBALS['HTML']->listTableBottom();
339 echo "\n<hr /><p style=\"text-align:right;\">";
340 printf(_('Average completion rate: %d%%'), (int)($totalPercentage/$taskcount));
341 echo "</p>\n"; echo '</td></tr>';
345 function renderFiles($group_id, $ah) {
347 $file_list =& $ah->getFiles();
348 $count=count($file_list);
351 echo '<tr><td colspan="2">';
352 echo '<b>'._("Attachments").':</b>'.'<br/>';
354 $title_arr[] = _('Size');
355 $title_arr[] = _('Name');
356 $title_arr[] = _('Date');
357 $title_arr[] = _('By');
358 $title_arr[] = _('Download');
359 echo $GLOBALS['HTML']->listTableTop($title_arr);
361 foreach ($file_list as $file) {
363 echo '<td>'.human_readable_bytes($file->getSize()).'</td>';
364 echo '<td>'.htmlspecialchars($file->getName()).'</td>';
365 echo '<td>'.date(_('Y-m-d H:i'), $file->getDate()).'</td>';
366 echo '<td>'.$file->getSubmittedUnixName().'</td>';
367 echo '<td><a href="/tracker/download.php/'.$group_id.'/'. $this->getID().'/'. $ah->getID() .'/'.$file->getID().'/'.$file->getName() .'">'. htmlspecialchars($file->getName()) .'</a></td>';
368 // <td><input type="checkbox" name="delete_file[]" value="'. $file->getID() .'">'._("Delete").' </td>
372 echo $GLOBALS['HTML']->listTableBottom();
380 * @return string HTML template.
382 function getRenderHTML($types=array(), $mode='') {
383 // Use template only for the browse (not for query or mass update)
384 if (($mode === 'DISPLAY' || $mode === 'DETAIL' || $mode === 'UPDATE')
385 && $this->data_array['custom_renderer']) {
386 return preg_replace('/<!--(\S+.*?)-->/','{$\\1}',$this->data_array['custom_renderer']);
388 return $this->generateRenderHTML($types, $mode);
395 * @return string HTML template.
397 function generateRenderHTML($types=array(), $mode) {
398 $efarr = $this->getExtraFields($types);
399 //each two columns, we'll reset this and start a new row
402 <!-- Start Extra Fields Rendering -->
406 $keys=array_keys($efarr);
408 if ($count == 0) return '';
410 for ($k=0; $k<$count; $k++) {
413 // Do not show the required star in query mode (creating/updating a query).
414 $is_required = ($mode == 'QUERY' || $mode == 'DISPLAY') ? 0 : $efarr[$i]['is_required'];
415 $name = $efarr[$i]['field_name'].($is_required ? utils_requiredField() : '').': ';
416 $name = '<strong>'.$name.'</strong>';
418 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT) {
421 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
423 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) {
426 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
428 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO) {
431 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
433 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
434 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
436 //text fields might be really wide, so need a row to themselves.
437 if (($col_count == 1) && ($efarr[$i]['attribute1'] > 30)) {
447 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
449 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
451 //text areas might be really wide, so need a row to themselves.
452 if (($col_count == 1) && ($efarr[$i]['attribute2'] > 30)) {
462 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
464 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
467 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
469 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
472 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
474 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
476 //text fields might be really wide, so need a row to themselves.
477 if (($col_count == 1) && ($efarr[$i]['attribute1'] > 30)) {
487 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
491 //we've done two columns - if there are more to do, start a new row
492 if (($col_count == 2) && ($k != $count-1)) {
499 if ($col_count == 1) {
505 <!-- End Extra Fields Rendering -->';
510 * renderSelect - this function builds pop up
513 * @param int The ID of this field.
514 * @param string The item that should be checked
515 * @param string Whether to show the '100 row'
516 * @param string What to call the '100 row'
517 * @return box and choices
519 function renderSelect ($extra_field_id,$checked='xzxz',$show_100=false,$text_100='none',$show_any=false,$text_any='Any', $allowed=false) {
520 if ($text_100 == 'none'){
523 $arr = $this->getExtraFieldElements($extra_field_id);
526 for ($i=0; $i<count($arr); $i++) {
527 $keys[$i]=$arr[$i]['element_id'];
528 $vals[$i]=$arr[$i]['element_name'];
530 return html_build_select_box_from_arrays ($keys,$vals,'extra_fields['.$extra_field_id.']',$checked,$show_100,$text_100,$show_any,$text_any, $allowed);
534 * renderRadio - this function builds radio buttons.
536 * @param int The ID of this field.
537 * @param string The item that should be checked
538 * @param string Whether to show the '100 row'
539 * @param string What to call the '100 row'
540 * @return radio buttons
542 function renderRadio ($extra_field_id,$checked='xzxz',$show_100=false,$text_100='none',$show_any=false,$text_any='Any') {
543 $arr = $this->getExtraFieldElements($extra_field_id);
546 for ($i=0; $i<count($arr); $i++) {
547 $keys[$i]=$arr[$i]['element_id'];
548 $vals[$i]=$arr[$i]['element_name'];
550 return html_build_radio_buttons_from_arrays ($keys,$vals,'extra_fields['.$extra_field_id.']',$checked,$show_100,$text_100,$show_any,$text_any);
554 * renderCheckbox - this function builds checkboxes.
556 * @param int The ID of this field.
557 * @param array The items that should be checked
558 * @param string Whether to show the '100 row'
559 * @param string What to call the '100 row'
560 * @return radio buttons
562 function renderCheckbox ($extra_field_id,$checked=array(),$show_100=false,$text_100='none') {
563 if ($text_100 == 'none'){
566 if (!$checked || !is_array($checked)) {
569 $arr = $this->getExtraFieldElements($extra_field_id);
573 <input type="checkbox" name="extra_fields['.$extra_field_id.'][]" value="100" '.
574 ((in_array(100,$checked)) ? 'checked="checked"' : '').'/> '.$text_100.'<br />';
576 for ($i=0; $i<count($arr); $i++) {
578 <input type="checkbox" name="extra_fields['.$extra_field_id.'][]" value="'.$arr[$i]['element_id'].'" '.
579 ((in_array($arr[$i]['element_id'],$checked)) ? 'checked="checked"' : '').'/> '.$arr[$i]['element_name'].'<br />';
585 * renderMultiSelectBox - this function builds checkboxes.
587 * @param int The ID of this field.
588 * @param array The items that should be checked
589 * @param string Whether to show the '100 row'
590 * @param string What to call the '100 row'
591 * @return radio multiselectbox
593 function renderMultiSelectBox ($extra_field_id,$checked=array(),$show_100=false,$text_100='none') {
594 $arr = $this->getExtraFieldElements($extra_field_id);
598 if (!is_array($checked)) {
599 $checked = explode(',',$checked);
603 $arr = $this->getExtraFieldElements($extra_field_id);
604 for ($i=0; $i<count($arr); $i++) {
605 $keys[]=$arr[$i]['element_id'];
606 $vals[]=$arr[$i]['element_name'];
608 $size = min( count($arr)+1, 15);
609 return html_build_multiple_select_box_from_arrays($keys,$vals,"extra_fields[$extra_field_id][]",$checked,$size,$show_100,$text_100);
613 * renderTextField - this function builds a text field.
615 * @param int The ID of this field.
616 * @param string The data for this field.
617 * @return text area and data.
619 function renderTextField ($extra_field_id,$contents,$size,$maxlength) {
621 <input type="text" name="extra_fields['.$extra_field_id.']" value="'.$contents.'" size="'.$size.'" maxlength="'.$maxlength.'"/>';
625 * renderRelationField - this function builds a relation field.
627 * @param int The ID of this field.
628 * @param string The data for this field.
629 * @return text area and data.
631 function renderRelationField ($extra_field_id,$contents,$size,$maxlength) {
632 $arr = $this->getExtraFieldElements($extra_field_id);
633 for ($i=0; $i<count($arr); $i++) {
634 $keys[$i]=$arr[$i]['element_id'];
635 $vals[$i]=$arr[$i]['element_name'];
637 // Convert artifact id to links.
638 $html_contents = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1','title')", $contents);
639 $edit_contents = $this->renderTextField ($extra_field_id,$contents,$size,$maxlength);
640 $edit_tips = '<br/><span class="tips">'._('Tip: Enter a space-separated list of artifact ids ([#NNN] also accepted)').'</span>';
642 <div id="edit'.$extra_field_id.'" style="display: none;">'.$edit_contents.$edit_tips.'</div>
643 <div id="show'.$extra_field_id.'" style="display: block;">'.$html_contents.'</div>';
647 * renderTextArea - this function builds a text area.
649 * @param int The ID of this field.
650 * @param string The data for this field.
651 * @return text area and data.
653 function renderTextArea ($extra_field_id,$contents,$rows,$cols) {
655 <textarea name="extra_fields['.$extra_field_id.']" rows="'.$rows.'" cols="'.$cols.'">'.$contents.'</textarea>';
658 function technicianBox ($name='assigned_to[]',$checked='xzxz',$show_100=true,$text_100='none',$extra_id='-1',$extra_name='',$multiple=false) {
659 if ($text_100=='none'){
660 $text_100=_('Nobody');
663 $engine = RBACEngine::getInstance () ;
664 $techs = $engine->getUsersByAllowedAction ('tracker', $this->getID(), 'tech') ;
669 sortUserList($techs);
671 foreach ($techs as $tech) {
672 $ids[] = $tech->getID() ;
673 $names[] = $tech->getRealName() ;
676 if ($extra_id != '-1') {
678 $names[]=$extra_name;
682 if (!is_array($checked)) {
683 $checked = explode(',',$checked);
685 $size = min( count($ids)+1, 15);
686 return html_build_multiple_select_box_from_arrays ($ids,$names,$name,$checked,$size,$show_100,$text_100);
688 return html_build_select_box_from_arrays ($ids,$names,$name,$checked,$show_100,$text_100);
692 function submitterBox ($name='submitted_by[]',$checked='xzxz',$show_100=true,$text_100='none',$extra_id='-1',$extra_name='',$multiple=false) {
693 if ($text_100=='none'){
694 $text_100=_('Nobody');
696 $result = $this->getSubmitters();
697 $ids =& util_result_column_to_array($result,0);
698 $names =& util_result_column_to_array($result,1);
699 if ($extra_id != '-1') {
701 $names[]=$extra_name;
705 if (!is_array($checked)) {
706 $checked = explode(',',$checked);
708 $size = min( count($ids)+1, 15);
709 return html_build_multiple_select_box_from_arrays ($ids,$names,$name,$checked,$size,$show_100,$text_100);
711 return html_build_select_box_from_arrays ($ids,$names,$name,$checked,$show_100,$text_100);
715 function cannedResponseBox ($name='canned_response',$checked='xzxz') {
716 return html_build_select_box ($this->getCannedResponses(),$name,$checked);
720 * statusBox - show the statuses - automatically shows the "custom statuses" if they exist
724 function statusBox ($name='status_id',$checked='xzxz',$show_100=false,$text_100='none') {
725 if ($text_100=='none'){
728 return html_build_select_box($this->getStatuses(),$name,$checked,$show_100,$text_100);
735 // c-file-style: "bsd"