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 (forge_check_perm ('tracker',$this->getID(),'submit')) {
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 $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);
146 * renderExtraFields - ???
148 * @param array $selected
149 * @param bool $show_100
150 * @param string $text_100
151 * @param bool $show_any
152 * @param string $text_any
153 * @param array $types
154 * @param bool $status_show_100
155 * @param string $mode
157 function renderExtraFields($selected = array(),
158 $show_100 = false, $text_100 = 'none',
159 $show_any = false, $text_any = 'Any',
161 $status_show_100 = false,
163 $efarr = $this->getExtraFields($types);
164 //each two columns, we'll reset this and start a new row
166 $template = $this->getRenderHTML($types, $mode);
168 if ($mode=='QUERY') {
169 $keys=array_keys($efarr);
170 for ($k=0; $k<count($keys); $k++) {
172 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT ||
173 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX ||
174 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO ||
175 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS ||
176 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
177 $efarr[$i]['field_type'] = ARTIFACT_EXTRAFIELDTYPE_MULTISELECT;
179 $efarr[$i]['field_type'] = ARTIFACT_EXTRAFIELDTYPE_TEXT;
184 // 'DISPLAY' mode is for rendering in 'read-only' mode (for detail view).
185 if ($mode === 'DISPLAY') {
186 $keys=array_keys($efarr);
187 for ($k=0; $k<count($keys); $k++) {
191 if (!isset($selected[$efarr[$i]['extra_field_id']]))
192 $selected[$efarr[$i]['extra_field_id']] = '';
194 $value = @$selected[$efarr[$i]['extra_field_id']];
196 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT ||
197 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX ||
198 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO ||
199 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS ||
200 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
204 $arr = $this->getExtraFieldElements($efarr[$i]['extra_field_id']);
206 // Convert the values (ids) to names in the ids order.
208 for ($j=0; $j<count($arr); $j++) {
209 if (is_array($value)) {
210 if (in_array($arr[$j]['element_id'],$value))
211 $new[]= $arr[$j]['element_name'];
212 } elseif ($arr[$j]['element_id'] === $value) {
213 $new[] = $arr[$j]['element_name'];
216 $value = join('<br />', $new);
218 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
219 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
220 $value = preg_replace('/((http|https|ftp):\/\/\S+)/',
221 "<a href=\"\\1\" target=\"_blank\">\\1</a>", $value);
222 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
223 // Convert artifact id to links.
224 $value = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1')", $value);
226 $template = str_replace('{$PostName:'.$efarr[$i]['field_name'].'}', $post_name, $template);
227 $template = str_replace('{$'.$efarr[$i]['field_name'].'}', $value, $template);
233 $keys = array_keys($efarr);
234 for ($k = 0; $k < count($keys); $k++) {
238 if (!isset($selected[$efarr[$i]['extra_field_id']]))
239 $selected[$efarr[$i]['extra_field_id']] = '';
241 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT) {
242 $str = $this->renderSelect($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100,$show_any,$text_any);
244 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) {
246 $str = $this->renderCheckbox($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100);
248 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO) {
250 $str = $this->renderRadio($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100,$show_any,$text_any);
252 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
253 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
255 $str = $this->renderTextField($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
256 if ($mode == 'QUERY') {
257 $post_name = ' <i>'._('(%% for wildcards)').'</i> ';
260 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
262 $str = $this->renderTextArea($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
263 if ($mode == 'QUERY') {
264 $post_name = ' <i>'._('(%% for wildcards)').'</i>';
267 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
269 $str = $this->renderMultiSelectBox ($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$show_100,$text_100);
271 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
273 // Get the allowed values from the workflow.
274 $atw = new ArtifactWorkflow($this, $efarr[$i]['extra_field_id']);
276 // Special treatement for the initial step (Submit).
277 // In this case, the initial value is the first value.
278 if ($selected === true) {
279 $selected_node = 100;
280 } elseif (isset($selected[$efarr[$i]['extra_field_id']]) && $selected[$efarr[$i]['extra_field_id']]) {
281 $selected_node = $selected[$efarr[$i]['extra_field_id']];
283 $selected_node = 100;
286 $allowed = $atw->getNextNodes($selected_node);
287 $allowed[] = $selected_node;
288 $str = $this->renderSelect($efarr[$i]['extra_field_id'],$selected_node,$status_show_100,$text_100,$show_any,$text_any, $allowed);
290 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
292 $str = $this->renderRelationField($efarr[$i]['extra_field_id'],$selected[$efarr[$i]['extra_field_id']],$efarr[$i]['attribute1'],$efarr[$i]['attribute2']);
293 if ($mode == 'UPDATE') {
294 $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')"));
297 $template = str_replace('{$PostName:'.$efarr[$i]['field_name'].'}',$post_name,$template);
298 $template = str_replace('{$'.$efarr[$i]['field_name'].'}',$str,$template);
300 if($template != NULL){
305 function renderRelatedTasks($group, $ah) {
307 if (!$group->usesPM()) {
311 $taskcount = db_numrows($ah->getRelatedTasks());
312 db_result_reset($ah->getRelatedTasks());
314 if (forge_check_perm('tracker_admin', $ah->ArtifactType->Group->getID())) {
320 $totalPercentage = 0;
322 if ($taskcount > 0) {
323 echo '<tr><td colspan="2">';
324 echo '<b>'._("Related Tasks")._(':').'</b><br/>';
325 $title_arr = array();
326 $title_arr[] = _('Task Id and Summary');
327 $title_arr[] = _('Progress');
328 $title_arr[] = _('Start Date');
329 $title_arr[] = _('End Date');
330 $title_arr[] = _('Status');
331 (($is_admin) ? $title_arr[]=_('Remove Relation') : '');
332 echo $GLOBALS['HTML']->listTableTop($title_arr);
334 for ($i = 0; $i < $taskcount; $i++) {
335 $taskinfo = db_fetch_array($ah->relatedtasks, $i);
336 $totalPercentage += $taskinfo['percent_complete'];
337 $taskid = $taskinfo['project_task_id'];
338 $projectid = $taskinfo['group_project_id'];
339 $groupid = $taskinfo['group_id'];
340 $summary = util_unconvert_htmlspecialchars($taskinfo['summary']);
341 $startdate = date(_('Y-m-d H:i'), $taskinfo['start_date']);
342 $enddate = date(_('Y-m-d H:i'), $taskinfo['end_date']);
343 $status = $taskinfo['status_name'];
345 <td><a href="/pm/task.php?func=detailtask&project_task_id='.$taskid.'&group_id='.$groupid.'&group_project_id='.$projectid.'">[T'.$taskid.'] '.$summary.'</a></td>
346 <td><div class="percentbar" style="width: 100px;">
347 <div style="width:'.round($taskinfo['percent_complete']).'px;"></div></div></td>
348 <td>'.$startdate.'</td>
349 <td>'.$enddate.'</td>
350 <td>'.$status.' ('.$taskinfo['percent_complete'].'%)</td>'.
351 (($is_admin) ? '<td><input type="checkbox" name="remlink[]" value="'.$taskid.'" /></td>' : '').
354 echo $GLOBALS['HTML']->listTableBottom();
356 echo "\n<hr /><p style=\"text-align:right;\">";
357 printf(_('Average completion rate: %d%%'), (int)($totalPercentage/$taskcount));
363 function renderFiles($group_id, $ah) {
365 $file_list =& $ah->getFiles();
366 $count=count($file_list);
369 echo '<tr><td colspan="2">';
370 echo '<b>'._("Attachments")._(':').'</b>'.'<br/>';
372 $title_arr[] = _('Size');
373 $title_arr[] = _('Name');
374 $title_arr[] = _('Date');
375 $title_arr[] = _('By');
376 $title_arr[] = _('Download');
377 echo $GLOBALS['HTML']->listTableTop($title_arr);
379 foreach ($file_list as $file) {
381 echo '<td>'.human_readable_bytes($file->getSize()).'</td>';
382 echo '<td>'.htmlspecialchars($file->getName()).'</td>';
383 echo '<td>'.date(_('Y-m-d H:i'), $file->getDate()).'</td>';
384 echo '<td>'.$file->getSubmittedUnixName().'</td>';
385 echo '<td><a href="/tracker/download.php/'.$group_id.'/'. $this->getID().'/'. $ah->getID() .'/'.$file->getID().'/'.$file->getName() .'">'. htmlspecialchars($file->getName()) .'</a></td>';
386 // <td><input type="checkbox" name="delete_file[]" value="'. $file->getID() .'">'._("Delete").' </td>
390 echo $GLOBALS['HTML']->listTableBottom();
398 * @param array $types
399 * @param string $mode
400 * @return string HTML template.
402 function getRenderHTML($types=array(), $mode='') {
403 // Use template only for the browse (not for query or mass update)
404 if (($mode === 'DISPLAY' || $mode === 'DETAIL' || $mode === 'UPDATE')
405 && $this->data_array['custom_renderer']) {
406 return preg_replace('/<!--(\S+.*?)-->/','{$\\1}',$this->data_array['custom_renderer']);
408 return $this->generateRenderHTML($types, $mode);
415 * @param array $types
416 * @param string $mode Display mode (QUERY OR DISPLAY)
417 * @return string HTML template.
419 function generateRenderHTML($types=array(), $mode) {
420 $efarr = $this->getExtraFields($types);
421 //each two columns, we'll reset this and start a new row
424 <!-- Start Extra Fields Rendering -->
428 $keys=array_keys($efarr);
430 if ($count == 0) return '';
432 for ($k=0; $k<$count; $k++) {
435 // Do not show the required star in query mode (creating/updating a query).
436 $is_required = ($mode == 'QUERY' || $mode == 'DISPLAY') ? 0 : $efarr[$i]['is_required'];
437 $name = $efarr[$i]['field_name'].($is_required ? utils_requiredField() : '')._(': ');
438 $name = '<strong>'.$name.'</strong>';
440 if ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_SELECT) {
443 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
445 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) {
448 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
450 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RADIO) {
453 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
455 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXT ||
456 $efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_INTEGER) {
458 //text fields might be really wide, so need a row to themselves.
459 if (($col_count == 1) && ($efarr[$i]['attribute1'] > 30)) {
469 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
471 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_TEXTAREA) {
473 //text areas might be really wide, so need a row to themselves.
474 if (($col_count == 1) && ($efarr[$i]['attribute2'] > 30)) {
484 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
486 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_MULTISELECT) {
489 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
491 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
494 <td class="halfwidth top">'.$name.'<br />{$'.$efarr[$i]['field_name'].'}</td>';
496 } elseif ($efarr[$i]['field_type'] == ARTIFACT_EXTRAFIELDTYPE_RELATION) {
498 //text fields might be really wide, so need a row to themselves.
499 if (($col_count == 1) && ($efarr[$i]['attribute1'] > 30)) {
509 <td style="width:'.(50*$colspan).'%" colspan="'.$colspan.'" class="top">'.$name.'{$PostName:'.$efarr[$i]['field_name'].'}<br />{$'.$efarr[$i]['field_name'].'}</td>';
513 //we've done two columns - if there are more to do, start a new row
514 if (($col_count == 2) && ($k != $count-1)) {
521 if ($col_count == 1) {
527 <!-- End Extra Fields Rendering -->';
532 * renderSelect - this function builds pop up box with choices.
534 * @param int $extra_field_id The ID of this field.
535 * @param string $checked The item that should be checked
536 * @param bool|string $show_100 Whether to show the '100 row'
537 * @param string $text_100 What to call the '100 row'
538 * @param bool $show_any
539 * @param string $text_any
540 * @param bool $allowed
541 * @return string HTML code for the box and choices
543 function renderSelect ($extra_field_id,$checked='xzxz',$show_100=false,$text_100='none',$show_any=false,$text_any='Any', $allowed=false) {
544 if ($text_100 == 'none'){
547 $arr = $this->getExtraFieldElements($extra_field_id);
550 for ($i=0; $i<count($arr); $i++) {
551 $keys[$i]=$arr[$i]['element_id'];
552 $vals[$i]=$arr[$i]['element_name'];
554 return html_build_select_box_from_arrays ($keys,$vals,'extra_fields['.$extra_field_id.']',$checked,$show_100,$text_100,$show_any,$text_any, $allowed);
558 * renderRadio - this function builds radio buttons.
560 * @param int $extra_field_id The $int ID of this field.
561 * @param string $checked The $string item that should be checked
562 * @param bool $show_100 Whether $string to show the '100 row'
563 * @param string $text_100 What $string to call the '100 row'
564 * @param bool $show_any
565 * @param string $text_any
566 * @return string HTML code using radio buttons
568 function renderRadio ($extra_field_id,$checked='xzxz',$show_100=false,$text_100='none',$show_any=false,$text_any='Any') {
569 $arr = $this->getExtraFieldElements($extra_field_id);
572 for ($i=0; $i<count($arr); $i++) {
573 $keys[$i]=$arr[$i]['element_id'];
574 $vals[$i]=$arr[$i]['element_name'];
576 return html_build_radio_buttons_from_arrays ($keys,$vals,'extra_fields['.$extra_field_id.']',$checked,$show_100,$text_100,$show_any,$text_any);
580 * renderCheckbox - this function builds checkboxes.
582 * @param int $extra_field_id The ID of this field.
583 * @param array $checked The items that should be checked
584 * @param bool|string $show_100 Whether to show the '100 row'
585 * @param string $text_100 What to call the '100 row'
586 * @return string radio buttons
588 function renderCheckbox ($extra_field_id,$checked=array(),$show_100=false,$text_100='none') {
589 if ($text_100 == 'none'){
592 if (!$checked || !is_array($checked)) {
595 $arr = $this->getExtraFieldElements($extra_field_id);
599 <input type="checkbox" name="extra_fields['.$extra_field_id.'][]" value="100" '.
600 ((in_array(100,$checked)) ? 'checked="checked"' : '').'/> '.$text_100.'<br />';
602 for ($i=0; $i<count($arr); $i++) {
604 <input type="checkbox" name="extra_fields['.$extra_field_id.'][]" value="'.$arr[$i]['element_id'].'" '.
605 ((in_array($arr[$i]['element_id'],$checked)) ? 'checked="checked"' : '').'/> '.$arr[$i]['element_name'].'<br />';
611 * renderMultiSelectBox - this function builds checkboxes.
613 * @param int $extra_field_id The ID of this field.
614 * @param array $checked The items that should be checked
615 * @param bool|string $show_100 Whether to show the '100 row'
616 * @param string $text_100 What to call the '100 row'
617 * @return string radio multiselectbox
619 function renderMultiSelectBox ($extra_field_id,$checked=array(),$show_100=false,$text_100='none') {
623 if (!is_array($checked)) {
624 $checked = explode(',',$checked);
628 $arr = $this->getExtraFieldElements($extra_field_id);
629 for ($i=0; $i<count($arr); $i++) {
630 $keys[]=$arr[$i]['element_id'];
631 $vals[]=$arr[$i]['element_name'];
633 $size = min( count($arr)+1, 15);
634 return html_build_multiple_select_box_from_arrays($keys,$vals,"extra_fields[$extra_field_id][]",$checked,$size,$show_100,$text_100);
638 * renderTextField - this function builds a text field.
640 * @param int $extra_field_id The ID of this field.
641 * @param string $contents The data for this field.
642 * @param string $size
643 * @param string $maxlength
644 * @return string HTML code of corresponding input tag.
646 function renderTextField ($extra_field_id, $contents, $size, $maxlength) {
648 <input type="text" name="extra_fields['.$extra_field_id.']" value="'.$contents.'" size="'.$size.'" maxlength="'.$maxlength.'"/>';
652 * renderRelationField - this function builds a relation field.
654 * @param int $extra_field_id The ID of this field.
655 * @param string $contents The data for this field.
656 * @param string $size
657 * @param string $maxlength
658 * @return string text area and data.
660 function renderRelationField ($extra_field_id,$contents,$size,$maxlength) {
661 $arr = $this->getExtraFieldElements($extra_field_id);
662 for ($i=0; $i<count($arr); $i++) {
663 $keys[$i]=$arr[$i]['element_id'];
664 $vals[$i]=$arr[$i]['element_name'];
666 // Convert artifact id to links.
667 $html_contents = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1','title')", $contents);
668 $edit_contents = $this->renderTextField ($extra_field_id,$contents,$size,$maxlength);
669 $edit_tips = '<br/><span class="tips">'._('Tip: Enter a space-separated list of artifact ids ([#NNN] also accepted)').'</span>';
671 <div id="edit'.$extra_field_id.'" style="display: none;">'.$edit_contents.$edit_tips.'</div>
672 <div id="show'.$extra_field_id.'" style="display: block;">'.$html_contents.'</div>';
676 * renderTextArea - this function builds a text area.
678 * @param int $extra_field_id The ID of this field.
679 * @param string $contents The data for this field.
680 * @param string $rows
681 * @param string $cols
682 * @return string text area and data.
684 function renderTextArea ($extra_field_id,$contents,$rows,$cols) {
686 <textarea name="extra_fields['.$extra_field_id.']" rows="'.$rows.'" cols="'.$cols.'">'.$contents.'</textarea>';
689 function technicianBox ($name='assigned_to[]',$checked='xzxz',$show_100=true,$text_100='none',$extra_id='-1',$extra_name='',$multiple=false) {
690 if ($text_100=='none'){
691 $text_100=_('Nobody');
694 $engine = RBACEngine::getInstance () ;
695 $techs = $engine->getUsersByAllowedAction ('tracker', $this->getID(), 'tech') ;
700 sortUserList($techs);
702 foreach ($techs as $tech) {
703 $ids[] = $tech->getID() ;
704 $names[] = $tech->getRealName() ;
707 if ($extra_id != '-1') {
709 $names[]=$extra_name;
713 if (!is_array($checked)) {
714 $checked = explode(',',$checked);
716 $size = min( count($ids)+1, 15);
717 return html_build_multiple_select_box_from_arrays ($ids,$names,$name,$checked,$size,$show_100,$text_100);
719 return html_build_select_box_from_arrays ($ids,$names,$name,$checked,$show_100,$text_100);
723 function submitterBox ($name='submitted_by[]',$checked='xzxz',$show_100=true,$text_100='none',$extra_id='-1',$extra_name='',$multiple=false) {
724 if ($text_100=='none'){
725 $text_100=_('Nobody');
727 $result = $this->getSubmitters();
728 $ids =& util_result_column_to_array($result,0);
729 $names =& util_result_column_to_array($result,1);
730 if ($extra_id != '-1') {
732 $names[]=$extra_name;
736 if (!is_array($checked)) {
737 $checked = explode(',',$checked);
739 $size = min( count($ids)+1, 15);
740 return html_build_multiple_select_box_from_arrays ($ids,$names,$name,$checked,$size,$show_100,$text_100);
742 return html_build_select_box_from_arrays ($ids,$names,$name,$checked,$show_100,$text_100);
746 function cannedResponseBox ($name='canned_response',$checked='xzxz') {
747 return html_build_select_box ($this->getCannedResponses(),$name,$checked);
751 * statusBox - show the statuses - automatically shows the "custom statuses" if they exist
755 function statusBox ($name='status_id',$checked='xzxz',$show_100=false,$text_100='none') {
756 if ($text_100=='none'){
759 return html_build_select_box($this->getStatuses(),$name,$checked,$show_100,$text_100);
766 // c-file-style: "bsd"