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');
87 $params['submenu'] = $HTML->subMenu($labels, $links, $attr);
88 site_project_header($params);
91 plugin_hook("blocks", "tracker_".$this->getName());
95 function footer($params) {
96 site_project_footer($params);
99 function adminHeader($params) {
101 $this->header($params);
102 $group_id= $this->Group->getID();
104 $links_arr[]='/tracker/admin/?group_id='.$group_id;
105 $title_arr[]=_('New Tracker');
107 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&update_type=1';
108 $title_arr[]=_('Update Settings');
110 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&add_extrafield=1';
111 $title_arr[]=_('Manage Custom Fields');
113 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&workflow=1';
114 $title_arr[]=_('Manage Workflow');
116 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&customize_list=1';
117 $title_arr[]=_('Customize List');
119 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&add_canned=1';
120 $title_arr[]=_('Add/Update Canned Responses');
122 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&clone_tracker=1';
123 $title_arr[]=_('Clone Tracker');
125 $links_arr[]='/tracker/admin/?group_id='.$group_id.'&atid='.$this->getID().'&delete=1';
126 $title_arr[]=_('Delete');
128 echo $HTML->printSubMenu($title_arr, $links_arr, false);
131 function adminFooter($params) {
132 echo $this->footer($params);
135 function renderSubmitInstructions() {
136 $msg = $this->getSubmitInstructions();
137 return str_replace("\n","<br />", $msg);
140 function renderBrowseInstructions() {
141 $msg = $this->getBrowseInstructions();
142 return str_replace("\n","<br />", $msg);
145 function renderExtraFields($selected=array(),$show_100=false,$text_100='none',$show_any=false,$text_any='Any',$types=array(),$status_show_100=false,$mode='') {
146 $efarr = $this->getExtraFields($types);
147 //each two columns, we'll reset this and start a new row
149 $template = $this->getRenderHTML($types, $mode);
151 if ($mode=='QUERY') {
152 $keys=array_keys($efarr);
153 for ($k=0; $k<count($keys); $k++) {
155 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT ||
156 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX ||
157 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO ||
158 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS ||
159 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
160 $efarr[$i]['field_type'] = ARTIFACT_EXTRAFIELDTYPE_MULTISELECT;
162 $efarr[$i]['field_type'] = ARTIFACT_EXTRAFIELDTYPE_TEXT;
167 // 'DISPLAY' mode is for renderding in 'read-only' mode (for detail view).
168 if ($mode === 'DISPLAY') {
169 $keys=array_keys($efarr);
170 for ($k=0; $k<count($keys); $k++) {
173 if (!isset($selected[$efarr[$i]['extra_field_id']]))
174 $selected[$efarr[$i]['extra_field_id']] = '';
176 $value = @$selected[$efarr[$i]['extra_field_id']];
178 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT ||
179 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX ||
180 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO ||
181 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS ||
182 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
186 $arr = $this->getExtraFieldElements($efarr[$i]['extra_field_id']);
188 // Convert the values (ids) to names in the ids order.
190 for ($j=0; $j<count($arr); $j++) {
191 if (is_array($value)) {
192 if (in_array($arr[$j]['element_id'],$value))
193 $new[]= $arr[$j]['element_name'];
194 } elseif ($arr[$j]['element_id'] === $value) {
195 $new[] = $arr[$j]['element_name'];
198 $value = join('<br />', $new);
200 } else if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
201 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
202 $value = preg_replace('/((http|https|ftp):\/\/\S+)/',
203 "<a href=\"\\1\" target=\"_blank\">\\1</a>", $value);
204 } else if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
205 // Convert artifact id to links.
206 $value = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1')", $value);
208 $template = str_replace('{$PostName:'.$efarr[$i]['field_name'].'}',$post_name,$template);
209 $template = str_replace('{$'.$efarr[$i]['field_name'].'}',$value,$template);
215 $keys=array_keys($efarr);
216 for ($k=0; $k<count($keys); $k++) {
220 if (!isset($selected[$efarr[$i]['extra_field_id']]))
221 $selected[$efarr[$i]['extra_field_id']] = '';
223 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT) {
224 $str = $this->renderSelect($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100,$show_any,$text_any);
226 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) {
228 $str = $this->renderCheckbox($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100);
230 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO) {
232 $str = $this->renderRadio($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100,$show_any,$text_any);
234 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
235 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
237 $str = $this->renderTextField($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
238 if ($mode == 'QUERY') {
239 $post_name = ' <i>'._('(%% for wildcards)').'</i> ';
242 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
244 $str = $this->renderTextArea($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
245 if ($mode == 'QUERY') {
246 $post_name = ' <i>'._('(%% for wildcards)').'</i> ';
249 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
251 $str = $this->renderMultiSelectBox ($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100);
253 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
255 // Get the allowed values from the workflow.
256 $atw = new ArtifactWorkflow($this, $efarr[$i]['extra_field_id']);
258 // Special treatement for the initial step (Submit).
259 // In this case, the initial value is the first value.
260 if ($selected === true) {
261 $selected_node = 100;
262 } elseif (isset($selected[$efarr[$i]['extra_field_id']]) && $selected[$efarr[$i]['extra_field_id']]) {
263 $selected_node = $selected[$efarr[$i]['extra_field_id']];
265 $selected_node = 100;
268 $allowed = $atw->getNextNodes($selected_node);
269 $allowed[] = $selected_node;
270 $str = $this->renderSelect($efarr[$i]['extra_field_id'],$selected_node,$status_show_100,$text_100,$show_any,$text_any, $allowed);
272 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
274 $str = $this->renderRelationField($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
275 if ($mode == 'UPDATE') {
276 $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')"));
279 $template = str_replace('{$PostName:'.$efarr[$i]['field_name'].'}',$post_name,$template);
280 $template = str_replace('{$'.$efarr[$i]['field_name'].'}',$str,$template);
282 if($template != NULL){
287 function renderRelatedTasks($group, $ah) {
289 if (!$group->usesPM()) {
293 $taskcount = db_numrows($ah->getRelatedTasks());
294 db_result_reset($ah->getRelatedTasks());
296 if (forge_check_perm ('tracker_admin', $ah->ArtifactType->Group->getID())) {
302 $totalPercentage = 0;
304 if ($taskcount > 0) {
305 echo '<tr><td colspan="2">';
306 echo '<b>'._("Related Tasks").':</b>'.'<br/>';
307 $title_arr = array();
308 $title_arr[] = _('Task Id and Summary');
309 $title_arr[] = _('Start Date');
310 $title_arr[] = _('End Date');
311 $title_arr[] = _('Status');
312 (($is_admin) ? $title_arr[]=_('Remove Relation') : '');
313 echo $GLOBALS['HTML']->listTableTop($title_arr);
315 for ($i = 0; $i < $taskcount; $i++) {
316 $taskinfo = db_fetch_array($ah->relatedtasks, $i);
317 $totalPercentage += $taskinfo['percent_complete'];
318 $taskid = $taskinfo['project_task_id'];
319 $projectid = $taskinfo['group_project_id'];
320 $groupid = $taskinfo['group_id'];
321 $summary = util_unconvert_htmlspecialchars($taskinfo['summary']);
322 $startdate = date(_('Y-m-d H:i'), $taskinfo['start_date']);
323 $enddate = date(_('Y-m-d H:i'), $taskinfo['end_date']);
324 $status = $taskinfo['status_name'];
326 <td><a href="/pm/task.php?func=detailtask&project_task_id='.$taskid.'&group_id='.$groupid.'&group_project_id='.$projectid.'">[T'.$taskid.'] '.$summary.'</a></td>
327 <td>'.$startdate.'</td>
328 <td>'.$enddate.'</td>
329 <td>'.$status.' ('.$taskinfo['percent_complete'].'%)</td>'.
330 (($is_admin) ? '<td><input type="checkbox" name="remlink[]" value="'.$taskid.'" /></td>' : '').
333 echo $GLOBALS['HTML']->listTableBottom();
335 echo "\n<hr /><p style=\"text-align:right;\">";
336 printf(_('Average completion rate: %d%%'), (int)($totalPercentage/$taskcount));
337 echo "</p>\n"; echo '</td></tr>';
341 function renderFiles($group_id, $ah) {
343 $file_list =& $ah->getFiles();
344 $count=count($file_list);
347 echo '<tr><td colspan="2">';
348 echo '<b>'._("Attachments").':</b>'.'<br/>';
350 $title_arr[] = _('Size');
351 $title_arr[] = _('Name');
352 $title_arr[] = _('Date');
353 $title_arr[] = _('By');
354 $title_arr[] = _('Download');
355 echo $GLOBALS['HTML']->listTableTop($title_arr);
357 foreach ($file_list as $file) {
359 echo '<td>'.human_readable_bytes($file->getSize()).'</td>';
360 echo '<td>'.htmlspecialchars($file->getName()).'</td>';
361 echo '<td>'.date(_('Y-m-d H:i'), $file->getDate()).'</td>';
362 echo '<td>'.$file->getSubmittedUnixName().'</td>';
363 echo '<td><a href="/tracker/download.php/'.$group_id.'/'. $this->getID().'/'. $ah->getID() .'/'.$file->getID().'/'.$file->getName() .'">'. htmlspecialchars($file->getName()) .'</a></td>';
364 // <td><input type="checkbox" name="delete_file[]" value="'. $file->getID() .'">'._("Delete").' </td>
368 echo $GLOBALS['HTML']->listTableBottom();
376 * @return string HTML template.
378 function getRenderHTML($types=array(), $mode='') {
379 // Use template only for the browse (not for query or mass update)
380 if (($mode === 'DISPLAY' || $mode === 'DETAIL' || $mode === 'UPDATE')
381 && $this->data_array['custom_renderer']) {
382 return preg_replace('/<!--(\S+.*?)-->/','{$\\1}',$this->data_array['custom_renderer']);
384 return $this->generateRenderHTML($types, $mode);
391 * @return string HTML template.
393 function generateRenderHTML($types=array(), $mode) {
394 $efarr = $this->getExtraFields($types);
395 //each two columns, we'll reset this and start a new row
398 <!-- Start Extra Fields Rendering -->
402 $keys=array_keys($efarr);
404 if ($count == 0) return '';
406 for ($k=0; $k<$count; $k++) {
409 // Do not show the required star in query mode (creating/updating a query).
410 $is_required = ($mode == 'QUERY' || $mode == 'DISPLAY') ? 0 : $efarr[$i]['is_required'];
411 $name = $efarr[$i]['field_name'].($is_required ? utils_requiredField() : '').': ';
412 $name = '<strong>'.$name.'</strong>';
414 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT) {
417 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
419 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) {
422 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
424 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO) {
427 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
429 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
430 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
432 //text fields might be really wide, so need a row to themselves.
433 if (($col_count == 1) && ($efarr[$i]['attribute1'] > 30)) {
443 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
445 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
447 //text areas might be really wide, so need a row to themselves.
448 if (($col_count == 1) && ($efarr[$i]['attribute2'] > 30)) {
458 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
460 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
463 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
465 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
468 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
470 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
472 //text fields might be really wide, so need a row to themselves.
473 if (($col_count == 1) && ($efarr[$i]['attribute1'] > 30)) {
483 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
487 //we've done two columns - if there are more to do, start a new row
488 if (($col_count == 2) && ($k != $count-1)) {
495 if ($col_count == 1) {
501 <!-- End Extra Fields Rendering -->';
506 * renderSelect - this function builds pop up
509 * @param int The ID of this field.
510 * @param string The item that should be checked
511 * @param string Whether to show the '100 row'
512 * @param string What to call the '100 row'
513 * @return box and choices
515 function renderSelect ($extra_field_id,$checked='xzxz',$show_100=false,$text_100='none',$show_any=false,$text_any='Any', $allowed=false) {
516 if ($text_100 == 'none'){
519 $arr = $this->getExtraFieldElements($extra_field_id);
522 for ($i=0; $i<count($arr); $i++) {
523 $keys[$i]=$arr[$i]['element_id'];
524 $vals[$i]=$arr[$i]['element_name'];
526 return html_build_select_box_from_arrays ($keys,$vals,'extra_fields['.$extra_field_id.']',$checked,$show_100,$text_100,$show_any,$text_any, $allowed);
530 * renderRadio - this function builds radio buttons.
532 * @param int The ID of this field.
533 * @param string The item that should be checked
534 * @param string Whether to show the '100 row'
535 * @param string What to call the '100 row'
536 * @return radio buttons
538 function renderRadio ($extra_field_id,$checked='xzxz',$show_100=false,$text_100='none',$show_any=false,$text_any='Any') {
539 $arr = $this->getExtraFieldElements($extra_field_id);
542 for ($i=0; $i<count($arr); $i++) {
543 $keys[$i]=$arr[$i]['element_id'];
544 $vals[$i]=$arr[$i]['element_name'];
546 return html_build_radio_buttons_from_arrays ($keys,$vals,'extra_fields['.$extra_field_id.']',$checked,$show_100,$text_100,$show_any,$text_any);
550 * renderCheckbox - this function builds checkboxes.
552 * @param int The ID of this field.
553 * @param array The items that should be checked
554 * @param string Whether to show the '100 row'
555 * @param string What to call the '100 row'
556 * @return radio buttons
558 function renderCheckbox ($extra_field_id,$checked=array(),$show_100=false,$text_100='none') {
559 if ($text_100 == 'none'){
562 if (!$checked || !is_array($checked)) {
565 $arr = $this->getExtraFieldElements($extra_field_id);
569 <input type="checkbox" name="extra_fields['.$extra_field_id.'][]" value="100" '.
570 ((in_array(100,$checked)) ? 'checked="checked"' : '').'/> '.$text_100.'<br />';
572 for ($i=0; $i<count($arr); $i++) {
574 <input type="checkbox" name="extra_fields['.$extra_field_id.'][]" value="'.$arr[$i]['element_id'].'" '.
575 ((in_array($arr[$i]['element_id'],$checked)) ? 'checked="checked"' : '').'/> '.$arr[$i]['element_name'].'<br />';
581 * renderMultiSelectBox - this function builds checkboxes.
583 * @param int The ID of this field.
584 * @param array The items that should be checked
585 * @param string Whether to show the '100 row'
586 * @param string What to call the '100 row'
587 * @return radio multiselectbox
589 function renderMultiSelectBox ($extra_field_id,$checked=array(),$show_100=false,$text_100='none') {
590 $arr = $this->getExtraFieldElements($extra_field_id);
594 if (!is_array($checked)) {
595 $checked = explode(',',$checked);
599 $arr = $this->getExtraFieldElements($extra_field_id);
600 for ($i=0; $i<count($arr); $i++) {
601 $keys[]=$arr[$i]['element_id'];
602 $vals[]=$arr[$i]['element_name'];
604 $size = min( count($arr)+1, 15);
605 return html_build_multiple_select_box_from_arrays($keys,$vals,"extra_fields[$extra_field_id][]",$checked,$size,$show_100,$text_100);
609 * renderTextField - this function builds a text field.
611 * @param int The ID of this field.
612 * @param string The data for this field.
613 * @return text area and data.
615 function renderTextField ($extra_field_id,$contents,$size,$maxlength) {
617 <input type="text" name="extra_fields['.$extra_field_id.']" value="'.$contents.'" size="'.$size.'" maxlength="'.$maxlength.'"/>';
621 * renderRelationField - this function builds a relation field.
623 * @param int The ID of this field.
624 * @param string The data for this field.
625 * @return text area and data.
627 function renderRelationField ($extra_field_id,$contents,$size,$maxlength) {
628 $arr = $this->getExtraFieldElements($extra_field_id);
629 for ($i=0; $i<count($arr); $i++) {
630 $keys[$i]=$arr[$i]['element_id'];
631 $vals[$i]=$arr[$i]['element_name'];
633 // Convert artifact id to links.
634 $html_contents = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1','title')", $contents);
635 $edit_contents = $this->renderTextField ($extra_field_id,$contents,$size,$maxlength);
636 $edit_tips = '<br/><span class="tips">'._('Tip: Enter a space-separated list of artifact ids ([#NNN] also accepted)').'</span>';
638 <div id="edit'.$extra_field_id.'" style="display: none;">'.$edit_contents.$edit_tips.'</div>
639 <div id="show'.$extra_field_id.'" style="display: block;">'.$html_contents.'</div>';
643 * renderTextArea - this function builds a text area.
645 * @param int The ID of this field.
646 * @param string The data for this field.
647 * @return text area and data.
649 function renderTextArea ($extra_field_id,$contents,$rows,$cols) {
651 <textarea name="extra_fields['.$extra_field_id.']" rows="'.$rows.'" cols="'.$cols.'">'.$contents.'</textarea>';
654 function technicianBox ($name='assigned_to[]',$checked='xzxz',$show_100=true,$text_100='none',$extra_id='-1',$extra_name='',$multiple=false) {
655 if ($text_100=='none'){
656 $text_100=_('Nobody');
659 $engine = RBACEngine::getInstance () ;
660 $techs = $engine->getUsersByAllowedAction ('tracker', $this->getID(), 'tech') ;
665 sortUserList($techs);
667 foreach ($techs as $tech) {
668 $ids[] = $tech->getID() ;
669 $names[] = $tech->getRealName() ;
672 if ($extra_id != '-1') {
674 $names[]=$extra_name;
678 if (!is_array($checked)) {
679 $checked = explode(',',$checked);
681 $size = min( count($ids)+1, 15);
682 return html_build_multiple_select_box_from_arrays ($ids,$names,$name,$checked,$size,$show_100,$text_100);
684 return html_build_select_box_from_arrays ($ids,$names,$name,$checked,$show_100,$text_100);
688 function submitterBox ($name='submitted_by[]',$checked='xzxz',$show_100=true,$text_100='none',$extra_id='-1',$extra_name='',$multiple=false) {
689 if ($text_100=='none'){
690 $text_100=_('Nobody');
692 $result = $this->getSubmitters();
693 $ids =& util_result_column_to_array($result,0);
694 $names =& util_result_column_to_array($result,1);
695 if ($extra_id != '-1') {
697 $names[]=$extra_name;
701 if (!is_array($checked)) {
702 $checked = explode(',',$checked);
704 $size = min( count($ids)+1, 15);
705 return html_build_multiple_select_box_from_arrays ($ids,$names,$name,$checked,$size,$show_100,$text_100);
707 return html_build_select_box_from_arrays ($ids,$names,$name,$checked,$show_100,$text_100);
711 function cannedResponseBox ($name='canned_response',$checked='xzxz') {
712 return html_build_select_box ($this->getCannedResponses(),$name,$checked);
716 * statusBox - show the statuses - automatically shows the "custom statuses" if they exist
720 function statusBox ($name='status_id',$checked='xzxz',$show_100=false,$text_100='none') {
721 if ($text_100=='none'){
724 return html_build_select_box($this->getStatuses(),$name,$checked,$show_100,$text_100);
731 // c-file-style: "bsd"