3 * FusionForge Generic Tracker facility
5 * Copyright 1999-2001 (c) VA Linux Systems
6 * Copyright (C) 2011-2012 Alain Peyrat - Alcatel-Lucent
7 * Copyright 2011, Franck Villaume - Capgemini
8 * Copyright 2015-2017,2019, Franck Villaume - TrivialDev
9 * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
10 * http://fusionforge.org
12 * This file is part of FusionForge. FusionForge is free software;
13 * you can redistribute it and/or modify it under the terms of the
14 * GNU General Public License as published by the Free Software
15 * Foundation; either version 2 of the Licence, or (at your option)
18 * FusionForge is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 require_once $gfcommon.'tracker/Artifact.class.php';
29 require_once $gfcommon.'include/utils_crossref.php';
31 class ArtifactHtml extends Artifact {
34 * showDetails - show details preformatted (like followups)
36 * @param bool $editable is the detail editable or not? default is false.
37 * @param array $editattrs
40 function showDetails($editable = false, $editattrs = array()) {
41 global $HTML, $gfcommon;
43 $result = $this->getDetails();
44 $result_html = util_gen_cross_ref($result, $this->ArtifactType->Group->getID());
45 $parsertype = forge_get_config('tracker_parser_type');
46 switch ($parsertype) {
48 require_once $gfcommon.'include/Markdown.include.php';
49 $result_html = FF_Markdown($result_html);
52 $result_html = nl2br($result_html);
56 if ($editable === true) {
57 $title_arr[] = '<div style="width:100%; line-height: 20px;">' .
58 '<div style="float:left;">' . _('Detailed description')._(':') .utils_requiredField().'</div>' .
59 '<div>' . $HTML->getEditFilePic(_('Edit this message'), _('Edit this message'), array('class' => 'mini_buttons tip-ne', 'onclick'=>"switch2edit(this, 'showdescription', 'editdescription')")) . '</div>' .
62 $title_arr[] = _('Detailed description');
64 $return .= $HTML->listTableTop($title_arr, array(), 'full');
65 $return .= $HTML->multiTableRow(array('id' => 'editdescription', 'style' => 'display:none'), array(array(html_e('textarea', array_merge($editattrs, array('id' => 'tracker-description', 'required' => 'required', 'name' => 'description', 'rows' => 20, 'style' => 'box-sizing: box-border; width: 99%;', 'title' => util_html_secure(html_get_tooltip_description('description')))), $result), 'style' => 'display: block; box-sizing:border-box;')));
66 $return .= $HTML->multiTableRow(array('id' => 'showdescription'), array(array($result_html)));
67 $return .= $HTML->listTableBottom();
71 function showMessages() {
74 if (session_loggedin()) {
75 $u = session_get_user();
76 $order = $u->getPreference('tracker_messages_order');
78 if (!isset($order) || !$order) {
81 $result = $this->getMessages($order);
82 $rows = db_numrows($result);
86 $title_arr[]=_('Message');
96 <script type="text/javascript">/* <![CDATA[ */
97 function show_edit_button(id) {
98 var element = document.getElementById(id);
99 if (element) element.style.display = "block";
101 function hide_edit_button(id) {
102 var element = document.getElementById(id);
103 if (element) element.style.display = "none";
106 $return .= '<img style="display: none;" id="img_order" src="" alt="" />';
107 $thArray = array('<a name="sort" href="#sort" class="sortheader" onclick="thead = true;ts_resortTable(this, 0);submitOrder();return false;">'._('Message').'<span id="order_span" sortdir="'.$order.'" class="sortarrow"> <img src="/images/sort_'.$img_order.'.gif" alt="'.$char_order.'" /></span></a>');
108 $return .= $HTML->listTableTop($thArray, array(), 'listing full sortable', 'messages_list');
110 for ($i=0; $i < $rows; $i++) {
111 $return .= '<tr onmouseover="show_edit_button(\'edit_bt_'.$i.'\')" onmouseout="hide_edit_button(\'edit_bt_'.$i.'\')" ><td>';
113 $params = array('user_id' => db_result($result,$i,'user_id'), 'size' => 's', 'content' => '');
114 plugin_hook_by_reference("user_logo", $params);
115 $return .= $params['content'];
117 $return .= '<span style="float:left">';
118 $return .= _('Date')._(': ').
119 date(_('Y-m-d H:i'), db_result($result, $i, 'adddate')) .'<br />'.
121 if(db_result($result, $i, 'user_id') == 100) {
122 $return .= db_result($result, $i, 'realname');
124 $return .= util_make_link_u(db_result($result, $i, 'user_name'), db_result($result, $i, 'user_id'), db_result($result, $i, 'realname'));
126 $return .= '</span>';
128 $return .= '<p style="clear: both;padding-top: 1em;">';
129 $text = db_result($result, $i, 'body');
130 $text = util_gen_cross_ref($text, $this->ArtifactType->Group->getID());
131 $parsertype = forge_get_config('tracker_parser_type');
132 switch ($parsertype) {
134 require_once $gfcommon.'include/Markdown.include.php';
135 $text = FF_Markdown($text);
138 $text = nl2br($text);
142 $return .= '</td></tr>';
145 $return .= $HTML->listTableBottom();
148 $return .= $HTML->information(_('No comments have been posted'));
153 function showHistory() {
155 $result = $this->getHistory();
156 $rows= db_numrows($result);
162 $title_arr[] = _('Field');
163 $title_arr[] = _('Old Value');
164 //$title_arr[] = _('New Value');
165 $title_arr[] = _('Date');
166 $title_arr[] = _('By');
168 $return .= $HTML->listTableTop($title_arr);
170 $artifactType =& $this->getArtifactType();
172 for ($i=0; $i < $rows; $i++) {
173 $field=db_result($result, $i, 'field_name');
175 <tr><td>'.$field.'</td><td>';
177 if ($field == 'status_id') {
179 $return .= $artifactType->getStatusName(db_result($result, $i, 'old_value'));
181 } elseif ($field == 'assigned_to') {
183 $return .= user_getname(db_result($result, $i, 'old_value'));
185 } elseif ($field == 'close_date') {
186 if (db_result($result, $i, 'old_value')) {
187 $return .= date(_('Y-m-d H:i'),db_result($result, $i, 'old_value'));
189 $return .= '<i>'._('None').'</i>';
193 $return .= db_result($result, $i, 'old_value');
197 '<td>'. date(_('Y-m-d H:i'),db_result($result, $i, 'entrydate')) .'</td>';
198 $user = user_get_object_by_name(db_result($result, $i, 'user_name'));
199 if ($user && is_object($user)) {
200 $return .= '<td>'.util_display_user($user->getUnixName(), $user->getID(), $user->getRealName()).'</td></tr>';
202 $return .= '<td>'.db_result($result, $i, 'user_name').'</td></tr>';
206 $return .= $HTML->listTableBottom();
209 $return .= $HTML->information(_('No changes have been made to this item'));
214 function showRelations() {
216 $result=$this->getRelations();
217 $rows= db_numrows($result);
220 $return = '<table class="fullwidth">
225 while ($arr = db_fetch_array($result)) {
226 if (forge_check_perm('tracker', $arr['group_artifact_id'], 'read')) {
227 $title = $arr['group_name']._(': ').$arr['name'];
228 if ($title != $current) {
229 $return .= $end.'<strong>'.$title.'</strong>';
231 $end = '<br /><br />';
233 $text = '[#'.$arr['artifact_id'].']';
234 $url = '/tracker/?func=detail&aid='.$arr['artifact_id'].'&group_id='.$arr['group_id'].'&atid='.$arr['group_artifact_id'];
235 $arg['title'] = util_html_secure($arr['summary']);
236 if ($arr['status_id'] == 2) {
237 $arg['class'] = 'artifact_closed';
239 $return .= '<br/> ';
240 $return .= util_make_link($url, $text, $arg).' '.util_make_link($url, $arr['summary']).' <i>('._('Relation')._(': ').$arr['field_name'].')</i>';
247 $return .= $HTML->information(_('No relations found.'));
252 function showChildren() {
256 if (!forge_check_perm('tracker', $atid, 'submit')) {
259 $children = $this->getChildren();
260 $rows= count($children);
263 $return = ' <table class="children fullwidth">
268 foreach ($children as $arr) {
269 if (forge_check_perm('tracker', $arr['group_artifact_id'], 'read')) {
270 $title = $arr['group_name']._(': ').$arr['name'];
271 if ($title != $current) {
272 $return .= $end.'<strong>'.$title.'</strong>';
274 $end = '<br /><br />';
276 $text = '[#'.$arr['artifact_id'].']';
277 $url = '/tracker/a_follow.php/'.$arr['artifact_id'];
278 $arg['title'] = util_html_secure($arr['summary']);
279 if ($arr['status_id'] == 2) {
280 $arg['class'] = 'artifact_closed';
282 $return .= html_ao('span',array('id'=>'child'.$arr['artifact_id']));
283 $return .= '<br/> ';
284 $return .= util_make_link($url, $text, $arg).' '.util_make_link($url, $arr['summary']);
286 $return .= $HTML->getMinusPic(_('Click to remove child'), _('Click to remove child'), array('class'=>'removechild', 'data-id'=>$arr['artifact_id']));
288 $return .= html_ac(html_ap()-1);
298 function showParent() {
302 if (!forge_check_perm('tracker', $atid, 'submit')) {
305 $parentId = $this->getParent();
308 $parent = artifact_get_object($parentId);
309 $return = $HTML->listTableTop(array(), array(), 'parent fullwidth', 'parent'.$parent->getID()).'
312 $parentAt = $parent->getArtifactType();
313 if (forge_check_perm('tracker', $parentAt->getID(), 'read')) {
314 $parentG = $parentAt->getGroup();
315 $title = $parentG->getPublicName()._(': ').$parentAt->getName();
316 $return .= '<strong>'.$title.'</strong>';
317 $text = '[#'.$parent->getID().']';
318 $url = '/tracker/a_follow.php/'.$parent->getID();
319 $arg['title'] = util_html_secure($parent->getSummary());
320 if ($parent->getStatusID() == 2) {
321 $arg['class'] = 'artifact_closed';
323 $return .= html_ao('span');
324 $return .= '<br/> ';
325 $return .= util_make_link($url, $text, $arg).' '.util_make_link($url, $parent->getSummary());
327 $return .= $HTML->getMinusPic(_('Click to remove parent'), _('Click to remove parent'), array('class'=>'removeparent', 'data-id'=>$parent->getID()));
329 $return .= html_ac(html_ap()-1);
332 </tr>'.$HTML->listTableBottom();
334 $return = ' <table class="parent fullwidth"></table>';
339 function showDependencies() {
343 if (!forge_check_perm('tracker', $atid, 'submit')) {
347 $ef_parent = $this->getArtifactType()->getExtraFields(array(ARTIFACT_EXTRAFIELDTYPE_PARENT));
348 if (count($ef_parent)) {
349 $return .= html_e('input', array('type'=>'hidden','id'=>'aid', 'value'=>$this->getID()));
350 $return .= html_ao('div',array('class'=>'fullwidth'));
351 $return .= html_e('strong',array(),_('Parent')).html_e('br');
352 $return .= $this->showParent();
354 if ($this->hasParent()) {
355 $return .= html_ao('div',array('class'=>'fullwidth addparent hide'));
357 $return .= html_ao('div',array('class'=>'fullwidth addparent'));
359 $return .= html_e('input', array('type'=>'text', 'id'=>'parent_id', 'value'=>'', 'size'=>20, 'maxlength'=>80, 'pattern'=>'^(?!'.$this->getID().'$)\d*$'));
360 $return .= $HTML->getAddPic(_('Click to add parent'), _('Click to add parent'), array('class'=>'addparent')).html_e('br');
361 $return .= html_ac(html_ap()-1);
363 $return .= html_ac(html_ap()-1).html_e('br');
364 $return .= html_ao('div',array('class'=>'fullwidth'));
365 $return .= html_e('strong',array(),_('Children')).html_e('br');
366 $return .= $this->showChildren();
368 $return .= html_ao('div',array('class'=>'fullwidth addchild'));
369 $return .= html_e('input', array('type'=>'text', 'id'=>'child_id', 'value'=>'', 'size'=>20, 'maxlength'=>80, 'pattern'=>'^(?!'.$this->getID().'$)\d*$'));
370 $return .= $HTML->getAddPic(_('Click to add child'), _('Click to add child'), array('class'=>'addchild'));
371 $return .= html_ac(html_ap()-1);
373 $return .= html_ac(html_ap()-1);
375 $return .= $HTML->information(_('No dependency'));
384 // c-file-style: "bsd"