1<?php
2# MantisBT - A PHP based bugtracking system
3
4# MantisBT is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 2 of the License, or
7# (at your option) any later version.
8#
9# MantisBT is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * This include file prints out the bug information
19 *
20 * @package MantisBT
21 * @copyright Copyright 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
22 * @copyright Copyright 2002  MantisBT Team - mantisbt-dev@lists.sourceforge.net
23 * @link http://www.mantisbt.org
24 *
25 * @uses access_api.php
26 * @uses authentication_api.php
27 * @uses bug_api.php
28 * @uses category_api.php
29 * @uses columns_api.php
30 * @uses compress_api.php
31 * @uses config_api.php
32 * @uses constant_inc.php
33 * @uses current_user_api.php
34 * @uses custom_field_api.php
35 * @uses date_api.php
36 * @uses event_api.php
37 * @uses gpc_api.php
38 * @uses helper_api.php
39 * @uses html_api.php
40 * @uses lang_api.php
41 * @uses prepare_api.php
42 * @uses print_api.php
43 * @uses project_api.php
44 * @uses string_api.php
45 * @uses tag_api.php
46 * @uses utility_api.php
47 * @uses version_api.php
48 */
49
50if( !defined( 'BUG_VIEW_INC_ALLOW' ) ) {
51	return;
52}
53
54require_api( 'access_api.php' );
55require_api( 'authentication_api.php' );
56require_api( 'bug_api.php' );
57require_api( 'category_api.php' );
58require_api( 'columns_api.php' );
59require_api( 'compress_api.php' );
60require_api( 'config_api.php' );
61require_api( 'constant_inc.php' );
62require_api( 'current_user_api.php' );
63require_api( 'custom_field_api.php' );
64require_api( 'date_api.php' );
65require_api( 'event_api.php' );
66require_api( 'gpc_api.php' );
67require_api( 'helper_api.php' );
68require_api( 'html_api.php' );
69require_api( 'lang_api.php' );
70require_api( 'prepare_api.php' );
71require_api( 'print_api.php' );
72require_api( 'project_api.php' );
73require_api( 'string_api.php' );
74require_api( 'tag_api.php' );
75require_api( 'utility_api.php' );
76require_api( 'version_api.php' );
77
78require_css( 'status_config.php' );
79
80$f_issue_id = gpc_get_int( 'id' );
81$f_history = gpc_get_bool( 'history', config_get( 'history_default_visible' ) );
82
83# compat variables for included pages
84$f_bug_id = $f_issue_id;
85$t_bug = $t_bug = bug_get( $f_bug_id, true );
86$t_data = array(
87	'query' => array( 'id' => $f_issue_id ),
88	'options' => array( 'force_readonly' => $t_force_readonly )
89);
90
91$t_cmd = new IssueViewPageCommand( $t_data );
92$t_result = $t_cmd->execute();
93
94$t_issue = $t_result['issue'];
95$t_issue_view = $t_result['issue_view'];
96$t_flags = $t_result['flags'];
97
98compress_enable();
99
100if( $t_show_page_header ) {
101	layout_page_header( bug_format_summary( $f_issue_id, SUMMARY_CAPTION ), null, 'view-issue-page' );
102	layout_page_begin( 'view_all_bug_page.php' );
103}
104
105$t_action_button_position = config_get( 'action_button_position' );
106
107$t_bugslist = gpc_get_cookie( config_get_global( 'bug_list_cookie' ), false );
108
109$t_top_buttons_enabled = !$t_force_readonly && ( $t_action_button_position == POSITION_TOP || $t_action_button_position == POSITION_BOTH );
110$t_bottom_buttons_enabled = !$t_force_readonly && ( $t_action_button_position == POSITION_BOTTOM || $t_action_button_position == POSITION_BOTH );
111
112#
113# Start of Template
114#
115
116echo '<div class="col-md-12 col-xs-12">';
117echo '<div class="widget-box widget-color-blue2">';
118echo '<div class="widget-header widget-header-small">';
119echo '<h4 class="widget-title lighter">';
120print_icon( 'fa-bars', 'ace-icon' );
121echo string_display_line( $t_issue_view['form_title'] );
122echo '</h4>';
123echo '</div>';
124
125echo '<div class="widget-body">';
126
127echo '<div class="widget-toolbox padding-8 clearfix noprint">';
128echo '<div class="btn-group pull-left">';
129
130# Send Bug Reminder
131if( $t_flags['reminder_can_add'] ) {
132	print_small_button( 'bug_reminder_page.php?bug_id=' . $f_issue_id, lang_get( 'bug_reminder' ) );
133}
134
135if( isset( $t_issue_view['wiki_link'] ) ) {
136	print_small_button( $t_issue_view['wiki_link'], lang_get( 'wiki' ) );
137}
138
139# TODO: should be moved to command
140foreach ( $t_issue_view['links'] as $t_plugin => $t_hooks ) {
141	foreach( $t_hooks as $t_hook ) {
142		if( is_array( $t_hook ) ) {
143			foreach( $t_hook as $t_label => $t_href ) {
144				if( is_numeric( $t_label ) ) {
145					print_bracket_link_prepared( $t_href );
146				} else {
147					print_small_button( $t_href, $t_label );
148				}
149			}
150		} elseif( !empty( $t_hook ) ) {
151			print_bracket_link_prepared( $t_hook );
152		}
153	}
154}
155
156# Jump to Bugnotes
157print_small_button( '#bugnotes', lang_get( 'jump_to_bugnotes' ) );
158
159# Display or Jump to History
160if( $t_flags['history_show'] ) {
161	if( $f_history ) {
162		$t_history_link = '#history';
163		$t_history_label = lang_get( 'jump_to_history' );
164	} else {
165		$t_history_link = 'view.php?id=' . $f_issue_id . '&history=1#history';
166		$t_history_label = lang_get( 'display_history' );
167	}
168	print_small_button( $t_history_link, $t_history_label );
169}
170
171echo '</div>';
172
173# prev/next links
174echo '<div class="btn-group pull-right">';
175if( $t_bugslist ) {
176	$t_bugslist = explode( ',', $t_bugslist );
177	$t_index = array_search( $f_issue_id, $t_bugslist );
178	if( false !== $t_index ) {
179		if( isset( $t_bugslist[$t_index-1] ) ) {
180			print_small_button( 'view.php?id='.$t_bugslist[$t_index-1], '&lt;&lt;' );
181		}
182
183		if( isset( $t_bugslist[$t_index+1] ) ) {
184			print_small_button( 'view.php?id='.$t_bugslist[$t_index+1], '&gt;&gt;' );
185		}
186	}
187}
188echo '</div>';
189echo '</div>';
190
191echo '<div class="widget-main no-padding">';
192echo '<div class="table-responsive">';
193echo '<table class="table table-bordered table-condensed">';
194
195if( $t_top_buttons_enabled ) {
196	echo '<thead><tr class="bug-nav">';
197	echo '<tr class="top-buttons noprint">';
198	echo '<td colspan="6">';
199	bug_view_action_buttons( $f_issue_id, $t_flags );
200	echo '</td>';
201	echo '</tr>';
202	echo '</thead>';
203}
204
205if( $t_bottom_buttons_enabled ) {
206	echo '<tfoot>';
207	echo '<tr class="noprint"><td colspan="6">';
208	bug_view_action_buttons( $f_issue_id, $t_flags );
209	echo '</td></tr>';
210	echo '</tfoot>';
211}
212
213echo '<tbody>';
214
215if( $t_flags['id_show'] || $t_flags['project_show'] || $t_flags['category_show'] ||
216    $t_flags['view_state_show'] || $t_flags['created_at_show'] || $t_flags['updated_at_show']
217) {
218
219	# Labels
220	echo '<tr class="bug-header">';
221	echo '<th class="bug-id category" width="15%">', $t_flags['id_show'] ? lang_get( 'id' ) : '', '</th>';
222	echo '<th class="bug-project category" width="20%">', $t_flags['project_show'] ? lang_get( 'email_project' ) : '', '</th>';
223	echo '<th class="bug-category category" width="15%">', $t_flags['category_show'] ? lang_get( 'category' ) : '', '</th>';
224	echo '<th class="bug-view-status category" width="15%">', $t_flags['view_state_show'] ? lang_get( 'view_status' ) : '', '</th>';
225	echo '<th class="bug-date-submitted category" width="15%">', $t_flags['created_at_show'] ? lang_get( 'date_submitted' ) : '', '</th>';
226	echo '<th class="bug-last-modified category" width="20%">', $t_flags['updated_at_show'] ? lang_get( 'last_update' ) : '','</th>';
227	echo '</tr>';
228
229	echo '<tr class="bug-header-data">';
230
231	# Bug ID
232	echo '<td class="bug-id">', $t_flags['id_show'] ? $t_issue_view['id_formatted'] : '', '</td>';
233
234	# Project
235	echo '<td class="bug-project">', $t_flags['project_show'] && isset( $t_issue['project']['name'] ) ? string_display_line( $t_issue['project']['name'] ) : '', '</td>';
236
237	# Category
238	echo '<td class="bug-category">',
239		$t_flags['category_show'] && isset( $t_issue['category']['name'] )
240			? string_display_line( $t_issue['category']['name'] )
241			: '',
242		'</td>';
243
244	# View Status
245	echo '<td class="bug-view-status">', $t_flags['view_state_show'] && isset( $t_issue['view_state']['label'] ) ? string_display_line( $t_issue['view_state']['label'] ) : '', '</td>';
246
247	# Date Submitted
248	echo '<td class="bug-date-submitted">', $t_flags['created_at_show'] ? $t_issue_view['created_at'] : '', '</td>';
249
250	# Date Updated
251	echo '<td class="bug-last-modified">',  $t_flags['updated_at_show'] ? $t_issue_view['updated_at'] : '', '</td>';
252
253	echo '</tr>';
254
255	# spacer
256	echo '<tr class="spacer"><td colspan="6"></td></tr>';
257	echo '<tr class="hidden"></tr>';
258}
259
260#
261# Reporter, Handler, Due Date
262#
263
264if( $t_flags['reporter_show'] || $t_flags['handler_show'] || $t_flags['due_date_show'] ) {
265	echo '<tr>';
266
267	$t_spacer = 0;
268
269	# Reporter
270	if( $t_flags['reporter_show'] ) {
271		echo '<th class="bug-reporter category">', lang_get( 'reporter' ), '</th>';
272		echo '<td class="bug-reporter">';
273		print_user_with_subject( $t_issue['reporter']['id'], $f_issue_id );
274		echo '</td>';
275	} else {
276		$t_spacer += 2;
277	}
278
279	# Handler
280	if( $t_flags['handler_show'] ) {
281		echo '<th class="bug-assigned-to category">', lang_get( 'assigned_to' ), '</th>';
282		echo '<td class="bug-assigned-to">';
283		if( isset( $t_issue['handler'] ) ) {
284			print_user_with_subject( $t_issue['handler']['id'], $f_issue_id );
285		}
286		echo '</td>';
287	} else {
288		$t_spacer += 2;
289	}
290
291	# Due Date
292	if( $t_flags['due_date_show'] ) {
293		echo '<th class="bug-due-date category">', lang_get( 'due_date' ), '</th>';
294
295		$t_css = 'bug-due-date';
296		if( $t_issue_view['overdue'] !== false ) {
297			$t_css .= ' due-' . $t_issue_view['overdue'];
298		}
299		echo '<td class="' . $t_css . '">', $t_issue_view['due_date'], '</td>';
300	} else {
301		$t_spacer += 2;
302	}
303
304	if( $t_spacer > 0 ) {
305		echo '<td colspan="', $t_spacer, '">&#160;</td>';
306	}
307
308	echo '</tr>';
309}
310
311#
312# Priority, Severity, Reproducibility
313#
314
315if( $t_flags['priority_show'] || $t_flags['severity_show'] || $t_flags['reproducibility_show'] ) {
316	echo '<tr>';
317
318	$t_spacer = 0;
319
320	# Priority
321	if( $t_flags['priority_show'] ) {
322		echo '<th class="bug-priority category">', lang_get( 'priority' ), '</th>';
323		echo '<td class="bug-priority">', string_display_line( $t_issue['priority']['label'] ), '</td>';
324	} else {
325		$t_spacer += 2;
326	}
327
328	# Severity
329	if( $t_flags['severity_show'] ) {
330		echo '<th class="bug-severity category">', lang_get( 'severity' ), '</th>';
331		echo '<td class="bug-severity">', string_display_line( $t_issue['severity']['label'] ), '</td>';
332	} else {
333		$t_spacer += 2;
334	}
335
336	# Reproducibility
337	if( $t_flags['reproducibility_show'] ) {
338		echo '<th class="bug-reproducibility category">', lang_get( 'reproducibility' ), '</th>';
339		echo '<td class="bug-reproducibility">', string_display_line( $t_issue['reproducibility']['label'] ), '</td>';
340	} else {
341		$t_spacer += 2;
342	}
343
344	# spacer
345	if( $t_spacer > 0 ) {
346		echo '<td colspan="', $t_spacer, '">&#160;</td>';
347	}
348
349	echo '</tr>';
350}
351
352#
353# Status, Resolution
354#
355
356if( $t_flags['status_show'] || $t_flags['resolution_show'] ) {
357	echo '<tr>';
358
359	$t_spacer = 2;
360
361	# Status
362	if( $t_flags['status_show'] ) {
363		echo '<th class="bug-status category">', lang_get( 'status' ), '</th>';
364
365		# choose color based on status
366		$t_status_css = html_get_status_css_fg( $t_issue['status']['id'] );
367
368		echo '<td class="bug-status">';
369		print_icon( 'fa-square', 'fa-status-box ' . $t_status_css );
370		echo ' ' . string_display_line( $t_issue['status']['label'] ), '</td>';
371	} else {
372		$t_spacer += 2;
373	}
374
375	# Resolution
376	if( $t_flags['resolution_show'] ) {
377		echo '<th class="bug-resolution category">', lang_get( 'resolution' ), '</th>';
378		echo '<td class="bug-resolution">', string_display_line( $t_issue['resolution']['label'] ), '</td>';
379	} else {
380		$t_spacer += 2;
381	}
382
383	# spacer
384	if( $t_spacer > 0 ) {
385		echo '<td colspan="', $t_spacer, '">&#160;</td>';
386	}
387
388	echo '</tr>';
389}
390
391#
392# Projection, ETA
393#
394
395if( $t_flags['projection_show'] || $t_flags['eta_show'] ) {
396	echo '<tr>';
397
398	$t_spacer = 2;
399
400	if( $t_flags['projection_show'] ) {
401		# Projection
402		echo '<th class="bug-projection category">', lang_get( 'projection' ), '</th>';
403		echo '<td class="bug-projection">', string_display_line( $t_issue['projection']['label'] ), '</td>';
404	} else {
405		$t_spacer += 2;
406	}
407
408	# ETA
409	if( $t_flags['eta_show'] ) {
410		echo '<th class="bug-eta category">', lang_get( 'eta' ), '</th>';
411		echo '<td class="bug-eta">', string_display_line( $t_issue['eta']['label'] ), '</td>';
412	} else {
413		$t_spacer += 2;
414	}
415
416	echo '<td colspan="', $t_spacer, '">&#160;</td>';
417	echo '</tr>';
418}
419
420#
421# Platform, OS, OS Version
422#
423
424if( ( $t_flags['profiles_platform_show'] && isset( $t_issue['platform'] ) && !is_blank( $t_issue['platform'] ) ) ||
425	( $t_flags['profiles_os_show'] && isset( $t_issue['os'] ) && !is_blank( $t_issue['os'] ) ) ||
426    ( $t_flags['profiles_os_build_show'] && isset( $t_issue['os_build'] ) && !is_blank( $t_issue['os_build'] ) ) ) {
427	$t_spacer = 0;
428
429	echo '<tr>';
430
431	# Platform
432	if( $t_flags['profiles_platform_show'] && isset( $t_issue['platform'] ) && !is_blank( $t_issue['platform'] ) ) {
433		echo '<th class="bug-platform category">', lang_get( 'platform' ), '</th>';
434		echo '<td class="bug-platform">', string_display_line( $t_issue['platform'] ), '</td>';
435	} else {
436		$t_spacer += 2;
437	}
438
439	# Operating System
440	if( $t_flags['profiles_os_show'] && isset( $t_issue['os'] ) && !is_blank( $t_issue['os'] ) ) {
441		echo '<th class="bug-os category">', lang_get( 'os' ), '</th>';
442		echo '<td class="bug-os">', string_display_line( $t_issue['os'] ), '</td>';
443	} else {
444		$t_spacer += 2;
445	}
446
447	# OS Version
448	if( $t_flags['profiles_os_build_show'] && isset( $t_issue['os_build'] ) && !is_blank( $t_issue['os_build'] ) ) {
449		echo '<th class="bug-os-build category">', lang_get( 'os_build' ), '</th>';
450		echo '<td class="bug-os-build">', string_display_line( $t_issue['os_build'] ), '</td>';
451	} else {
452		$t_spacer += 2;
453	}
454
455	if( $t_spacer > 0 ) {
456		echo '<td colspan="', $t_spacer, '">&#160;</td>';
457	}
458
459	echo '</tr>';
460}
461
462#
463# Product Version, Product Build
464#
465
466if( ( $t_flags['versions_product_version_show'] && isset( $t_issue['version'] ) ) ||
467    ( $t_flags['versions_product_build_show'] && isset( $t_issue['build'] ) ) ) {
468	$t_spacer = 2;
469
470	echo '<tr>';
471
472	# Product Version
473	if( $t_flags['versions_product_version_show'] && isset( $t_issue['version'] ) ) {
474		echo '<th class="bug-product-version category">', lang_get( 'product_version' ), '</th>';
475		echo '<td class="bug-product-version">', string_display_line( $t_issue['version']['name'] ), '</td>';
476	} else {
477		$t_spacer += 2;
478	}
479
480	# Product Build
481	if( $t_flags['versions_product_build_show'] && isset( $t_issue['build'] ) ) {
482		echo '<th class="bug-product-build category">', lang_get( 'product_build' ), '</th>';
483		echo '<td class="bug-product-build">', string_display_line( $t_issue['build'] ), '</td>';
484	} else {
485		$t_spacer += 2;
486	}
487
488	# spacer
489	echo '<td colspan="', $t_spacer, '">&#160;</td>';
490
491	echo '</tr>';
492}
493
494#
495# Target Version, Fixed In Version
496#
497
498if( ( $t_flags['versions_target_version_show'] && isset( $t_issue['target_version'] ) ) ||
499    ( $t_flags['versions_fixed_in_version_show'] && isset( $t_issue['fixed_in_version'] ) ) ) {
500	$t_spacer = 2;
501
502	echo '<tr>';
503
504	# target version
505	if( $t_flags['versions_target_version_show'] && isset( $t_issue['target_version'] ) ) {
506		# Target Version
507		echo '<th class="bug-target-version category">', lang_get( 'target_version' ), '</th>';
508		echo '<td class="bug-target-version">', string_display_line( $t_issue['target_version']['name'] ), '</td>';
509	} else {
510		$t_spacer += 2;
511	}
512
513	# fixed in version
514	if( $t_flags['versions_fixed_in_version_show'] && isset( $t_issue['fixed_in_version'] ) ) {
515		echo '<th class="bug-fixed-in-version category">', lang_get( 'fixed_in_version' ), '</th>';
516		echo '<td class="bug-fixed-in-version">', string_display_line( $t_issue['fixed_in_version']['name'] ), '</td>';
517	} else {
518		$t_spacer += 2;
519	}
520
521	# spacer
522	echo '<td colspan="', $t_spacer, '">&#160;</td>';
523
524	echo '</tr>';
525}
526
527#
528# Bug Details Event Signal
529#
530
531event_signal( 'EVENT_VIEW_BUG_DETAILS', array( $f_issue_id ) );
532
533# spacer
534echo '<tr class="spacer"><td colspan="6"></td></tr>';
535echo '<tr class="hidden"></tr>';
536
537#
538# Bug Details (screen wide fields)
539#
540
541# Summary
542if( $t_flags['summary_show'] && isset( $t_issue['summary'] ) ) {
543	echo '<tr>';
544	echo '<th class="bug-summary category">', lang_get( 'summary' ), '</th>';
545	echo '<td class="bug-summary" colspan="5">', string_display_line( bug_format_id( $f_issue_id ) . ': ' . $t_issue['summary'] ), '</td>';
546	echo '</tr>';
547}
548
549# Description
550if( $t_flags['description_show'] && isset( $t_issue['description'] ) ) {
551	echo '<tr>';
552	echo '<th class="bug-description category">', lang_get( 'description' ), '</th>';
553	echo '<td class="bug-description" colspan="5">', string_display_links( $t_issue['description'] ), '</td>';
554	echo '</tr>';
555}
556
557# Steps to Reproduce
558if( $t_flags['steps_to_reproduce_show'] && isset( $t_issue['steps_to_reproduce'] ) ) {
559	echo '<tr>';
560	echo '<th class="bug-steps-to-reproduce category">', lang_get( 'steps_to_reproduce' ), '</th>';
561	echo '<td class="bug-steps-to-reproduce" colspan="5">', string_display_links( $t_issue['steps_to_reproduce'] ), '</td>';
562	echo '</tr>';
563}
564
565# Additional Information
566if( $t_flags['additional_information_show'] && isset( $t_issue['additional_information'] ) ) {
567	echo '<tr>';
568	echo '<th class="bug-additional-information category">', lang_get( 'additional_information' ), '</th>';
569	echo '<td class="bug-additional-information" colspan="5">', string_display_links( $t_issue['additional_information'] ), '</td>';
570	echo '</tr>';
571}
572
573# Tagging
574if( $t_flags['tags_show'] ) {
575	echo '<tr>';
576	echo '<th class="bug-tags category">', lang_get( 'tags' ), '</th>';
577	echo '<td class="bug-tags" colspan="5">';
578	tag_display_attached( $f_issue_id );
579	echo '</td></tr>';
580}
581
582# Attach Tags
583if( $t_flags['tags_can_attach'] ) {
584	echo '<tr class="noprint">';
585	echo '<th class="bug-attach-tags category">', lang_get( 'tag_attach_long' ), '</th>';
586	echo '<td class="bug-attach-tags" colspan="5">';
587	print_tag_attach_form( $f_issue_id );
588	echo '</td></tr>';
589}
590
591# spacer
592echo '<tr class="spacer"><td colspan="6"></td></tr>';
593echo '<tr class="hidden"></tr>';
594
595# Custom Fields
596if( isset( $t_issue['custom_fields'] ) ) {
597	foreach( $t_issue['custom_fields'] as $t_custom_field ) {
598		$t_def = custom_field_get_definition( $t_custom_field['field']['id'] );
599
600		echo '<tr>';
601		echo '<th class="bug-custom-field category">', string_display_line( lang_get_defaulted( $t_def['name'] ) ), '</th>';
602		echo '<td class="bug-custom-field" colspan="5">';
603		print_custom_field_value( $t_def, $t_custom_field['field']['id'], $f_issue_id );
604		echo '</td></tr>';
605	}
606
607	# spacer
608	echo '<tr class="spacer"><td colspan="6"></td></tr>';
609	echo '<tr class="hidden"></tr>';
610}
611
612echo '</tbody></table>';
613echo '</div></div></div></div></div>';
614
615# User list sponsoring the bug
616if( $t_flags['sponsorships_show'] ) {
617	define( 'BUG_SPONSORSHIP_LIST_VIEW_INC_ALLOW', true );
618	include( $t_mantis_dir . 'bug_sponsorship_list_view_inc.php' );
619}
620
621# Bug Relationships
622if( $t_flags['relationships_show'] ) {
623	bug_view_relationship_view_box( $f_issue_id, /* can_update */ $t_flags['relationships_can_update'] );
624}
625
626# User list monitoring the bug
627if( $t_flags['monitor_show'] ) {
628	echo '<div class="col-md-12 col-xs-12">';
629	echo '<a id="monitors"></a>';
630	echo '<div class="space-10"></div>';
631
632	$t_collapse_block = is_collapsed( 'monitoring' );
633	$t_block_css = $t_collapse_block ? 'collapsed' : '';
634	$t_block_icon = $t_collapse_block ? 'fa-chevron-down' : 'fa-chevron-up';
635	?>
636	<div id="monitoring" class="widget-box widget-color-blue2 <?php echo $t_block_css ?>">
637		<div class="widget-header widget-header-small">
638			<h4 class="widget-title lighter">
639				<?php print_icon( 'fa-users', 'ace-icon' ); ?>
640				<?php echo lang_get( 'users_monitoring_bug' ) ?>
641			</h4>
642			<div class="widget-toolbar">
643				<a data-action="collapse" href="#">
644					<?php print_icon( $t_block_icon, '1 ace-icon bigger-125' ); ?>
645				</a>
646			</div>
647		</div>
648
649		<div class="widget-body">
650			<div class="widget-main no-padding">
651
652				<div class="table-responsive">
653					<table class="table table-bordered table-condensed table-striped">
654	<tr>
655		<th class="category" width="15%">
656			<?php echo lang_get( 'monitoring_user_list' ); ?>
657		</th>
658		<td>
659	<?php
660			if( !isset( $t_issue['monitors'] ) || count( $t_issue['monitors'] ) == 0 ) {
661				echo lang_get( 'no_users_monitoring_bug' );
662			} else {
663				$t_first_user = true;
664				foreach( $t_issue['monitors'] as $t_monitor_user ) {
665					if( $t_first_user ) {
666						$t_first_user = false;
667					} else {
668						echo ', ';
669					}
670
671					print_user( $t_monitor_user['id'] );
672					if( $t_flags['monitor_can_delete'] ) {
673						echo ' <a class="btn btn-xs btn-primary btn-white btn-round" '
674							. 'href="' . helper_mantis_url( 'bug_monitor_delete.php' )
675							. '?bug_id=' . $f_issue_id . '&amp;user_id=' . $t_monitor_user['id']
676							. htmlspecialchars(form_security_param( 'bug_monitor_delete' ))
677							. '">'
678							. icon_get( 'fa-times' )
679							. '</a>';
680					}
681				 }
682			}
683
684			if( $t_flags['monitor_can_add'] ) {
685	?>
686			<br /><br />
687			<form method="get" action="bug_monitor_add.php" class="form-inline noprint">
688			<?php echo form_security_field( 'bug_monitor_add' ) ?>
689				<input type="hidden" name="bug_id" value="<?php echo (integer)$f_issue_id; ?>" />
690				<input type="text" class="input-sm" id="bug_monitor_list_user_to_add" name="user_to_add" />
691				<input type="submit" class="btn btn-primary btn-sm btn-white btn-round" value="<?php echo lang_get( 'add' ) ?>" />
692			</form>
693			<?php } ?>
694		</td>
695	</tr>
696	</table>
697	</div>
698	</div>
699	</div>
700	</div>
701	</div>
702
703	<?php
704}
705
706# Bugnotes and "Add Note" box
707if( 'ASC' == current_user_get_pref( 'bugnote_order' ) ) {
708	define( 'BUGNOTE_VIEW_INC_ALLOW', true );
709	include( $t_mantis_dir . 'bugnote_view_inc.php' );
710
711	if( !$t_force_readonly ) {
712		define( 'BUGNOTE_ADD_INC_ALLOW', true );
713		include( $t_mantis_dir . 'bugnote_add_inc.php' );
714	}
715} else {
716	if( !$t_force_readonly ) {
717		define( 'BUGNOTE_ADD_INC_ALLOW', true );
718		include( $t_mantis_dir . 'bugnote_add_inc.php' );
719	}
720
721	define( 'BUGNOTE_VIEW_INC_ALLOW', true );
722	include( $t_mantis_dir . 'bugnote_view_inc.php' );
723}
724
725# Allow plugins to display stuff after notes
726event_signal( 'EVENT_VIEW_BUG_EXTRA', array( $f_issue_id ) );
727
728# Time tracking statistics
729if( config_get( 'time_tracking_enabled' ) &&
730	access_has_bug_level( config_get( 'time_tracking_view_threshold' ), $f_issue_id ) ) {
731	define( 'BUGNOTE_STATS_INC_ALLOW', true );
732	include( $t_mantis_dir . 'bugnote_stats_inc.php' );
733}
734
735# History
736if( $t_flags['history_show'] && $f_history ) {
737?>
738	<div class="col-md-12 col-xs-12">
739		<a id="history"></a>
740		<div class="space-10"></div>
741
742	<?php
743		$t_collapse_block = is_collapsed( 'history' );
744		$t_block_css = $t_collapse_block ? 'collapsed' : '';
745		$t_block_icon = $t_collapse_block ? 'fa-chevron-down' : 'fa-chevron-up';
746		$t_history = history_get_events_array( $f_issue_id );
747	?>
748	<div id="history" class="widget-box widget-color-blue2 <?php echo $t_block_css ?>">
749	<div class="widget-header widget-header-small">
750		<h4 class="widget-title lighter">
751			<?php print_icon( 'fa-history', 'ace-icon' ); ?>
752			<?php echo lang_get( 'bug_history' ) ?>
753		</h4>
754		<div class="widget-toolbar">
755			<a data-action="collapse" href="#">
756				<?php print_icon( $t_block_icon, '1 ace-icon bigger-125' ); ?>
757			</a>
758		</div>
759	</div>
760	<div class="widget-body">
761	<div class="widget-main no-padding">
762	<div class="table-responsive">
763	<table class="table table-bordered table-condensed table-hover table-striped">
764		<thead>
765			<tr>
766				<th class="small-caption">
767					<?php echo lang_get( 'date_modified' ) ?>
768				</th>
769				<th class="small-caption">
770					<?php echo lang_get( 'username' ) ?>
771				</th>
772				<th class="small-caption">
773					<?php echo lang_get( 'field' ) ?>
774				</th>
775				<th class="small-caption">
776					<?php echo lang_get( 'change' ) ?>
777				</th>
778			</tr>
779		</thead>
780
781		<tbody>
782	<?php
783		foreach( $t_history as $t_item ) {
784	?>
785			<tr>
786				<td class="small-caption">
787					<?php echo $t_item['date'] ?>
788				</td>
789				<td class="small-caption">
790					<?php print_user( $t_item['userid'] ) ?>
791				</td>
792				<td class="small-caption">
793					<?php echo string_display_line( $t_item['note'] ) ?>
794				</td>
795				<td class="small-caption">
796					<?php echo ( $t_item['raw'] ? string_display_line_links( $t_item['change'] ) : $t_item['change'] ) ?>
797				</td>
798			</tr>
799	<?php
800		} # end for loop
801	?>
802		</tbody>
803	</table>
804	</div>
805	</div>
806	</div>
807	</div>
808	</div>
809
810	<?php
811}
812
813layout_page_end();
814
815/**
816 * return formatted string with all the details on the requested relationship
817 * @param integer             $p_bug_id       A bug identifier.
818 * @param BugRelationshipData $p_relationship A bug relationship object.
819 * @param boolean             $p_html_preview Whether to include style/hyperlinks - if preview is false, we prettify the output.
820 * @param boolean             $p_show_project Show Project details.
821 * @return string
822 */
823function bug_view_relationship_get_details( $p_bug_id, BugRelationshipData $p_relationship, $p_html_preview = false, $p_show_project = false ) {
824	if( $p_bug_id == $p_relationship->src_bug_id ) {
825		# root bug is in the source side, related bug in the destination side
826		$t_related_project_id = $p_relationship->dest_bug_id;
827		$t_related_project_name = project_get_name( $p_relationship->dest_project_id );
828		$t_related_bug_id = $p_relationship->dest_bug_id;
829		$t_relationship_descr = relationship_get_description_src_side( $p_relationship->type );
830	} else {
831		# root bug is in the dest side, related bug in the source side
832		$t_related_project_id = $p_relationship->src_bug_id;
833		$t_related_bug_id = $p_relationship->src_bug_id;
834		$t_related_project_name = project_get_name( $p_relationship->src_project_id );
835		$t_relationship_descr = relationship_get_description_dest_side( $p_relationship->type );
836	}
837
838	# related bug not existing...
839	if( !bug_exists( $t_related_bug_id ) ) {
840		return '';
841	}
842
843	# user can access to the related bug at least as a viewer
844	if( !access_has_bug_level( config_get( 'view_bug_threshold', null, null, $t_related_project_id ), $t_related_bug_id ) ) {
845		return '';
846	}
847
848	if( $p_html_preview == false ) {
849		$t_td = '<td>';
850	} else {
851		$t_td = '<td class="print">';
852	}
853
854	# get the information from the related bug and prepare the link
855	$t_bug = bug_get( $t_related_bug_id, false );
856	$t_status_string = get_enum_element( 'status', $t_bug->status, auth_get_current_user_id(), $t_bug->project_id );
857	$t_resolution_string = get_enum_element( 'resolution', $t_bug->resolution, auth_get_current_user_id(), $t_bug->project_id );
858
859	$t_relationship_info_html = $t_td . string_no_break( $t_relationship_descr ) . '&#160;</td>';
860	if( $p_html_preview == false ) {
861		# choose color based on status
862		$t_status_css = html_get_status_css_fg( $t_bug->status, auth_get_current_user_id(), $t_bug->project_id );
863		$t_relationship_info_html .= '<td><a href="' . string_get_bug_view_url( $t_related_bug_id ) . '">' . string_display_line( bug_format_id( $t_related_bug_id ) ) . '</a></td>';
864		$t_relationship_info_html .= '<td>' . icon_get( 'fa-square', 'fa-status-box ' . $t_status_css );
865		$t_relationship_info_html .= ' <span class="issue-status" title="' . string_attribute( $t_resolution_string ) . '">' . string_display_line( $t_status_string ) . '</span></td>';
866	} else {
867		$t_relationship_info_html .= $t_td . string_display_line( bug_format_id( $t_related_bug_id ) ) . '</td>';
868		$t_relationship_info_html .= $t_td . string_display_line( $t_status_string ) . '&#160;</td>';
869	}
870
871	# get the handler name of the related bug
872	$t_relationship_info_html .= $t_td;
873	if( $t_bug->handler_id > 0 ) {
874		$t_relationship_info_html .= string_no_break( prepare_user_name( $t_bug->handler_id ) );
875	}
876
877	$t_relationship_info_html .= '&#160;</td>';
878
879	# add project name
880	if( $p_show_project ) {
881		$t_relationship_info_html .= $t_td . string_display_line( $t_related_project_name ) . '&#160;</td>';
882	}
883
884	# add summary
885	$t_relationship_info_html .= $t_td . string_display_line_links( $t_bug->summary );
886	if( VS_PRIVATE == $t_bug->view_state ) {
887		$t_relationship_info_html .= icon_get( 'fa-lock', '', lang_get( 'private' ) );
888	}
889
890	# add delete link if bug not read only and user has access level
891	if( !bug_is_readonly( $p_bug_id ) && !current_user_is_anonymous() && ( $p_html_preview == false ) ) {
892		if( access_has_bug_level( config_get( 'update_bug_threshold' ), $p_bug_id ) ) {
893			$t_relationship_info_html .= ' <a class="red noprint zoom-130"'
894				. 'href="bug_relationship_delete.php?bug_id=' . $p_bug_id
895				. '&amp;rel_id=' . $p_relationship->id
896				. htmlspecialchars( form_security_param( 'bug_relationship_delete' ) )
897				. '">'
898				. icon_get( 'fa-trash-o', 'ace-icon bigger-115' )
899				. '</a>';
900		}
901	}
902
903	$t_relationship_info_html .= '&#160;</td>';
904	$t_relationship_info_html = '<tr>' . $t_relationship_info_html . '</tr>';
905
906	return $t_relationship_info_html;
907}
908
909/**
910 * print ALL the RELATIONSHIPS OF A SPECIFIC BUG
911 * @param integer $p_bug_id A bug identifier.
912 * @return string
913 */
914function bug_view_relationship_get_summary_html( $p_bug_id ) {
915	$t_summary = '';
916
917	# A variable that will be set by the following call to indicate if relationships belong
918	# to multiple projects.
919	$t_show_project = false;
920
921	$t_relationship_all = relationship_get_all( $p_bug_id, $t_show_project );
922	$t_relationship_all_count = count( $t_relationship_all );
923
924	# prepare the relationships table
925	for( $i = 0; $i < $t_relationship_all_count; $i++ ) {
926		$t_summary .= bug_view_relationship_get_details( $p_bug_id, $t_relationship_all[$i], /* html_preview */ false, $t_show_project );
927	}
928
929	if( !is_blank( $t_summary ) ) {
930		if( relationship_can_resolve_bug( $p_bug_id ) == false ) {
931			$t_summary .= '<tr><td colspan="' . ( 5 + $t_show_project ) . '"><strong>' .
932				lang_get( 'relationship_warning_blocking_bugs_not_resolved' ) . '</strong></td></tr>';
933		}
934		$t_summary = '<table class="table table-bordered table-condensed table-hover">' . $t_summary . '</table>';
935	}
936
937	return $t_summary;
938}
939
940/**
941 * print HTML relationship form
942 * @param integer $p_bug_id A bug identifier.
943 * @param bool $p_can_update Can update relationships?
944 * @return void
945 */
946function bug_view_relationship_view_box( $p_bug_id, $p_can_update ) {
947	$t_relationships_html = bug_view_relationship_get_summary_html( $p_bug_id );
948
949	if( !$p_can_update && empty( $t_relationships_html ) ) {
950		return;
951	}
952
953	$t_relationship_graph = ON == config_get( 'relationship_graph_enable' );
954	$t_event_buttons = event_signal( 'EVENT_MENU_ISSUE_RELATIONSHIP', $p_bug_id );
955	$t_show_top_div = $p_can_update || $t_relationship_graph || !empty( $t_event_buttons );
956?>
957	<div class="col-md-12 col-xs-12">
958	<div class="space-10"></div>
959<?php
960	$t_collapse_block = is_collapsed( 'relationships' );
961	$t_block_css = $t_collapse_block ? 'collapsed' : '';
962	$t_block_icon = $t_collapse_block ? 'fa-chevron-down' : 'fa-chevron-up';
963?>
964	<div id="relationships" class="widget-box widget-color-blue2 <?php echo $t_block_css ?>">
965	<div class="widget-header widget-header-small">
966		<h4 class="widget-title lighter">
967			<?php print_icon( 'fa-sitemap', 'ace-icon' ); ?>
968			<?php echo lang_get( 'bug_relationships' ) ?>
969		</h4>
970		<div class="widget-toolbar">
971			<a data-action="collapse" href="#">
972				<?php print_icon( $t_block_icon, '1 ace-icon bigger-125' ); ?>
973			</a>
974		</div>
975	</div>
976	<div class="widget-body">
977<?php
978	if( $t_show_top_div ) {
979?>
980		<div class="widget-toolbox padding-8 clearfix">
981<?php
982		# Default relationship buttons
983		$t_buttons = array();
984		if( $t_relationship_graph ) {
985			$t_buttons[lang_get( 'relation_graph' )] =
986				'bug_relationship_graph.php?bug_id=' . $p_bug_id . '&graph=relation';
987			$t_buttons[lang_get( 'dependency_graph' )] =
988				'bug_relationship_graph.php?bug_id=' . $p_bug_id . '&graph=dependency';
989		}
990
991		# Plugin-added buttons
992		foreach( $t_event_buttons as $t_plugin => $t_plugin_buttons ) {
993			foreach( $t_plugin_buttons as $t_callback => $t_callback_buttons ) {
994				if( is_array( $t_callback_buttons ) ) {
995					$t_buttons = array_merge( $t_buttons, $t_callback_buttons );
996				}
997			}
998		}
999?>
1000		<div class="btn-group pull-right noprint">
1001<?php
1002		# Print the buttons, if any
1003		foreach( $t_buttons as $t_label => $t_url ) {
1004			print_small_button( $t_url, $t_label );
1005		}
1006?>
1007		</div>
1008
1009<?php
1010		if( $p_can_update ) {
1011?>
1012		<form method="post" action="bug_relationship_add.php" class="form-inline noprint">
1013		<?php echo form_security_field( 'bug_relationship_add' ) ?>
1014		<input type="hidden" name="src_bug_id" value="<?php echo $p_bug_id?>" />
1015		<label class="inline"><?php echo lang_get( 'this_bug' ) ?>&#160;&#160;</label>
1016		<?php print_relationship_list_box( config_get( 'default_bug_relationship' ) )?>
1017		<input type="text" class="input-sm" name="dest_bug_id" value="" />
1018		<input type="submit" class="btn btn-primary btn-sm btn-white btn-round" name="add_relationship" value="<?php echo lang_get( 'add' )?>" />
1019		</form>
1020<?php
1021		} # can update
1022?>
1023		</div>
1024<?php
1025	} # show top div
1026?>
1027
1028		<div class="widget-main no-padding">
1029			<div class="table-responsive">
1030				<?php echo $t_relationships_html; ?>
1031			</div>
1032		</div>
1033	</div>
1034	</div>
1035	</div>
1036<?php
1037}
1038
1039/**
1040 * Print Change Status to: button
1041 * This code is similar to print_status_option_list except
1042 * there is no masking, except for the current state
1043 *
1044 * @param BugData $p_bug A valid bug object.
1045 * @return void
1046 */
1047function bug_view_button_bug_change_status( BugData $p_bug ) {
1048	$t_current_access = access_get_project_level( $p_bug->project_id );
1049
1050	$t_enum_list = get_status_option_list(
1051		$t_current_access,
1052		$p_bug->status,
1053		false,
1054		# Add close if user is bug's reporter, still has rights to report issues
1055		# (to prevent users downgraded to viewers from updating issues) and
1056		# reporters are allowed to close their own issues
1057		(  bug_is_user_reporter( $p_bug->id, auth_get_current_user_id() )
1058		&& access_has_bug_level( config_get( 'report_bug_threshold' ), $p_bug->id )
1059		&& ON == config_get( 'allow_reporter_close' )
1060		),
1061		$p_bug->project_id );
1062
1063	if( count( $t_enum_list ) > 0 ) {
1064		# resort the list into ascending order after noting the key from the first element (the default)
1065		$t_default = key( $t_enum_list );
1066		ksort( $t_enum_list );
1067
1068		echo '<form method="post" action="bug_change_status_page.php" class="form-inline">';
1069		# CSRF protection not required here - form does not result in modifications
1070
1071		$t_button_text = lang_get( 'bug_status_to_button' );
1072		echo '<input type="submit" class="btn btn-primary btn-sm btn-white btn-round" value="' . $t_button_text . '" />';
1073
1074		echo ' <select name="new_status" class="input-sm">';
1075
1076		# space at beginning of line is important
1077		foreach( $t_enum_list as $t_key => $t_val ) {
1078			echo '<option value="' . $t_key . '" ';
1079			check_selected( $t_key, $t_default );
1080			echo '>' . $t_val . '</option>';
1081		}
1082		echo '</select>';
1083
1084		$t_bug_id = string_attribute( $p_bug->id );
1085		echo '<input type="hidden" name="id" value="' . $t_bug_id . '" />' . "\n";
1086		echo '<input type="hidden" name="change_type" value="' . BUG_UPDATE_TYPE_CHANGE_STATUS . '" />' . "\n";
1087
1088		echo '</form>' . "\n";
1089	}
1090}
1091
1092/**
1093 * Print Assign To: combo box of possible handlers
1094 * @param BugData $p_bug Bug object.
1095 * @return void
1096 */
1097function bug_view_button_bug_assign_to( BugData $p_bug ) {
1098	$t_current_user_id = auth_get_current_user_id();
1099	$t_options = array();
1100	$t_default_assign_to = null;
1101
1102	if( ( $p_bug->handler_id != $t_current_user_id )
1103		&& access_has_bug_level( config_get( 'handle_bug_threshold' ), $p_bug->id, $t_current_user_id )
1104	) {
1105		$t_options[] = array(
1106			$t_current_user_id,
1107			'[' . lang_get( 'myself' ) . ']',
1108		);
1109		$t_default_assign_to = $t_current_user_id;
1110	}
1111
1112	if( ( $p_bug->handler_id != $p_bug->reporter_id )
1113		&& user_exists( $p_bug->reporter_id )
1114		&& access_has_bug_level( config_get( 'handle_bug_threshold' ), $p_bug->id, $p_bug->reporter_id )
1115	) {
1116		$t_options[] = array(
1117			$p_bug->reporter_id,
1118			'[' . lang_get( 'reporter' ) . ']',
1119		);
1120
1121		if( $t_default_assign_to === null ) {
1122			$t_default_assign_to = $p_bug->reporter_id;
1123		}
1124	}
1125
1126	echo '<form method="post" action="bug_update.php" class="form-inline">';
1127	echo form_security_field( 'bug_update' );
1128	echo '<input type="hidden" name="last_updated" value="' . $p_bug->last_updated . '" />';
1129	echo '<input type="hidden" name="action_type" value="' . BUG_UPDATE_TYPE_ASSIGN . '" />';
1130
1131	$t_button_text = lang_get( 'bug_assign_to_button' );
1132	echo '<input type="submit" class="btn btn-primary btn-sm btn-white btn-round" value="' . $t_button_text . '" />';
1133
1134	echo ' <select class="input-sm" name="handler_id">';
1135
1136	# space at beginning of line is important
1137
1138	$t_already_selected = false;
1139
1140	foreach( $t_options as $t_entry ) {
1141		$t_id = (int)$t_entry[0];
1142		$t_caption = string_attribute( $t_entry[1] );
1143
1144		# if current user and reporter can't be selected, then select the first
1145		# user in the list.
1146		if( $t_default_assign_to === null ) {
1147			$t_default_assign_to = $t_id;
1148		}
1149
1150		echo '<option value="' . $t_id . '" ';
1151
1152		if( ( $t_id == $t_default_assign_to ) && !$t_already_selected ) {
1153			check_selected( $t_id, $t_default_assign_to );
1154			$t_already_selected = true;
1155		}
1156
1157		echo '>' . $t_caption . '</option>';
1158	}
1159
1160	# allow un-assigning if already assigned.
1161	if( $p_bug->handler_id != 0 ) {
1162		echo '<option value="0"></option>';
1163	}
1164
1165	# 0 means currently selected
1166	print_assign_to_option_list( 0, $p_bug->project_id );
1167	echo '</select>';
1168
1169	$t_bug_id = string_attribute( $p_bug->id );
1170	echo '<input type="hidden" name="bug_id" value="' . $t_bug_id . '" />' . "\n";
1171
1172	echo '</form>' . "\n";
1173}
1174
1175/**
1176 * Print all buttons for view bug pages
1177 * @param integer $p_bug_id A valid bug identifier.
1178 * @param array $p_flags Flags from issue view command
1179 * @return void
1180 */
1181function bug_view_action_buttons( $p_bug_id, $p_flags ) {
1182	$t_bug = bug_get( $p_bug_id );
1183
1184	echo '<div class="btn-group">';
1185	# UPDATE button
1186	if( $p_flags['can_update'] ) {
1187		echo '<div class="pull-left padding-right-8">';
1188		html_button( string_get_bug_update_page(), lang_get( 'edit' ), array( 'bug_id' => $p_bug_id ) );
1189		echo '</div>';
1190	}
1191
1192	# ASSIGN button
1193	if( $p_flags['can_assign'] ) {
1194		echo '<div class="pull-left padding-right-8">';
1195		bug_view_button_bug_assign_to( $t_bug );
1196		echo '</div>';
1197	}
1198
1199	# Change status button/dropdown
1200	if( $p_flags['can_change_status'] ) {
1201		echo '<div class="pull-left padding-right-8">';
1202		bug_view_button_bug_change_status( $t_bug );
1203		echo '</div>';
1204	}
1205
1206	# Unmonitor
1207	if( $p_flags['can_unmonitor'] ) {
1208		echo '<div class="pull-left padding-right-2">';
1209		html_button( 'bug_monitor_delete.php', lang_get( 'unmonitor_bug_button' ), array( 'bug_id' => $p_bug_id ) );
1210		echo '</div>';
1211	}
1212
1213	# Monitor
1214	if( $p_flags['can_monitor'] ) {
1215		echo '<div class="pull-left padding-right-2">';
1216		html_button( 'bug_monitor_add.php', lang_get( 'monitor_bug_button' ), array( 'bug_id' => $p_bug_id ) );
1217		echo '</div>';
1218	}
1219
1220	# Stick
1221	if( $p_flags['can_sticky'] ) {
1222		echo '<div class="pull-left padding-right-2">';
1223		html_button( 'bug_stick.php', lang_get( 'stick_bug_button' ), array( 'bug_id' => $p_bug_id, 'action' => 'stick' ) );
1224		echo '</div>';
1225	}
1226
1227	# Unstick
1228	if( $p_flags['can_unsticky'] ) {
1229		echo '<div class="pull-left padding-right-2">';
1230		html_button( 'bug_stick.php', lang_get( 'unstick_bug_button' ), array( 'bug_id' => $p_bug_id, 'action' => 'unstick' ) );
1231		echo '</div>';
1232	}
1233
1234	# CLONE button
1235	if( $p_flags['can_clone'] ) {
1236		echo '<div class="pull-left padding-right-2">';
1237		html_button( string_get_bug_report_url(), lang_get( 'create_child_bug_button' ), array( 'm_id' => $p_bug_id ) );
1238		echo '</div>';
1239	}
1240
1241	# REOPEN button
1242	if( $p_flags['can_reopen'] ) {
1243		echo '<div class="pull-left padding-right-2">';
1244		$t_reopen_status = config_get( 'bug_reopen_status', null, null, $t_bug->project_id );
1245		html_button(
1246			'bug_change_status_page.php',
1247			lang_get( 'reopen_bug_button' ),
1248			array( 'id' => $t_bug->id, 'new_status' => $t_reopen_status, 'change_type' => BUG_UPDATE_TYPE_REOPEN ) );
1249		echo '</div>';
1250	}
1251
1252	# CLOSE button
1253	if( $p_flags['can_close'] ) {
1254		$t_closed_status = config_get( 'bug_closed_status_threshold', null, null, $t_bug->project_id );
1255		echo '<div class="pull-left padding-right-2">';
1256		html_button(
1257			'bug_change_status_page.php',
1258			lang_get( 'close' ),
1259			array( 'id' => $t_bug->id, 'new_status' => $t_closed_status, 'change_type' => BUG_UPDATE_TYPE_CLOSE ) );
1260		echo '</div>';
1261	}
1262
1263	# MOVE button
1264	if( $p_flags['can_move'] ) {
1265		echo '<div class="pull-left padding-right-2">';
1266		html_button( 'bug_actiongroup_page.php', lang_get( 'move' ), array( 'bug_arr[]' => $p_bug_id, 'action' => 'MOVE' ) );
1267		echo '</div>';
1268	}
1269
1270	# DELETE button
1271	if( $p_flags['can_delete'] ) {
1272		echo '<div class="pull-left padding-right-2">';
1273		html_button( 'bug_actiongroup_page.php', lang_get( 'delete' ), array( 'bug_arr[]' => $p_bug_id, 'action' => 'DELETE' ) );
1274		echo '</div>';
1275	}
1276
1277	helper_call_custom_function( 'print_bug_view_page_custom_buttons', array( $p_bug_id ) );
1278
1279	echo '</div>';
1280}
1281
1282