PageRenderTime 40ms CodeModel.GetById 3ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 1ms

/core/html_api.php

https://github.com/Kirill/mantisbt
PHP | 1824 lines | 1323 code | 177 blank | 324 comment | 175 complexity | 46644b081401533b3dd763dfa59367b4 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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 * HTML API
  19 *
  20 * These functions control the HTML output of each page.
  21 *
  22 * This is the call order of these functions, should you need to figure out
  23 * which to modify or which to leave out:
  24 *
  25 * html_page_top1
  26 * 	html_begin
  27 * 	html_head_begin
  28 * 	html_css
  29 * 	html_content_type
  30 * 	html_rss_link
  31 * 	(html_meta_redirect)
  32 * 	html_title
  33 * html_page_top2
  34 * 	html_page_top2a
  35 * 	html_head_end
  36 * 	html_body_begin
  37 * 	html_top_banner
  38 * 	html_login_info
  39 * 	(print_project_menu_bar)
  40 * 	print_menu
  41 *
  42 * ...Page content here...
  43 *
  44 * html_page_bottom1
  45 * 	(print_menu)
  46 * 	html_page_bottom1a
  47 * 	html_bottom_banner
  48 * 	html_footer
  49 * 	html_body_end
  50 * html_end
  51 *
  52 * @package CoreAPI
  53 * @subpackage HTMLAPI
  54 * @copyright Copyright 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
  55 * @copyright Copyright 2002  MantisBT Team - mantisbt-dev@lists.sourceforge.net
  56 * @link http://www.mantisbt.org
  57 *
  58 * @uses access_api.php
  59 * @uses authentication_api.php
  60 * @uses bug_api.php
  61 * @uses config_api.php
  62 * @uses constant_inc.php
  63 * @uses current_user_api.php
  64 * @uses database_api.php
  65 * @uses error_api.php
  66 * @uses event_api.php
  67 * @uses file_api.php
  68 * @uses filter_api.php
  69 * @uses filter_constants_inc.php
  70 * @uses form_api.php
  71 * @uses helper_api.php
  72 * @uses lang_api.php
  73 * @uses news_api.php
  74 * @uses php_api.php
  75 * @uses print_api.php
  76 * @uses project_api.php
  77 * @uses rss_api.php
  78 * @uses string_api.php
  79 * @uses user_api.php
  80 * @uses utility_api.php
  81 */
  82
  83require_api( 'access_api.php' );
  84require_api( 'authentication_api.php' );
  85require_api( 'bug_api.php' );
  86require_api( 'config_api.php' );
  87require_api( 'constant_inc.php' );
  88require_api( 'current_user_api.php' );
  89require_api( 'database_api.php' );
  90require_api( 'error_api.php' );
  91require_api( 'event_api.php' );
  92require_api( 'file_api.php' );
  93require_api( 'filter_api.php' );
  94require_api( 'filter_constants_inc.php' );
  95require_api( 'form_api.php' );
  96require_api( 'helper_api.php' );
  97require_api( 'lang_api.php' );
  98require_api( 'news_api.php' );
  99require_api( 'php_api.php' );
 100require_api( 'print_api.php' );
 101require_api( 'project_api.php' );
 102require_api( 'rss_api.php' );
 103require_api( 'string_api.php' );
 104require_api( 'user_api.php' );
 105require_api( 'utility_api.php' );
 106
 107$g_rss_feed_url = null;
 108
 109$g_robots_meta = '';
 110
 111# flag for error handler to skip header menus
 112$g_error_send_page_header = true;
 113
 114$g_stylesheets_included = array();
 115$g_scripts_included = array();
 116
 117/**
 118 * Sets the url for the rss link associated with the current page.
 119 * null: means no feed (default).
 120 * @param string $p_rss_feed_url rss feed url
 121 * @return null
 122 */
 123function html_set_rss_link( $p_rss_feed_url ) {
 124	if( OFF != config_get( 'rss_enabled' ) ) {
 125		global $g_rss_feed_url;
 126		$g_rss_feed_url = $p_rss_feed_url;
 127	}
 128}
 129
 130/**
 131 * This method must be called before the html_page_top* methods.  It marks the page as not
 132 * for indexing.
 133 * @return null
 134 */
 135function html_robots_noindex() {
 136	global $g_robots_meta;
 137	$g_robots_meta = 'noindex,follow';
 138}
 139
 140/**
 141 * Prints the link that allows auto-detection of the associated feed.
 142 * @return null
 143 */
 144function html_rss_link() {
 145	global $g_rss_feed_url;
 146
 147	if( $g_rss_feed_url !== null ) {
 148		echo '<link rel="alternate" type="application/rss+xml" title="RSS" href="' . string_attribute( $g_rss_feed_url ) . "\" />\n";
 149	}
 150}
 151
 152/**
 153 * Prints a <script> tag to include a JavaScript file.
 154 * @param string $p_filename Name of JavaScript file (with extension) to include
 155 * @return null
 156 */
 157function html_javascript_link( $p_filename) {
 158	echo "\t", '<script type="text/javascript" src="', helper_mantis_url( 'javascript/' . $p_filename ), '"></script>' . "\n";
 159}
 160
 161/**
 162 * Defines the top of a HTML page
 163 * @param string $p_page_title html page title
 164 * @param string $p_redirect_url url to redirect to if necessary
 165 * @return null
 166 */
 167function html_page_top( $p_page_title = null, $p_redirect_url = null ) {
 168	html_page_top1( $p_page_title );
 169	if ( $p_redirect_url !== null ) {
 170		html_meta_redirect( $p_redirect_url );
 171	}
 172	html_page_top2();
 173}
 174
 175/**
 176 * Print the part of the page that comes before meta redirect tags should be inserted
 177 * @param string $p_page_title page title
 178 * @return null
 179 */
 180function html_page_top1( $p_page_title = null ) {
 181	html_begin();
 182	html_head_begin();
 183	html_css();
 184	html_content_type();
 185	include( config_get( 'meta_include_file' ) );
 186
 187	global $g_robots_meta;
 188	if ( !is_blank( $g_robots_meta ) ) {
 189		echo "\t", '<meta name="robots" content="', $g_robots_meta, '" />', "\n";
 190	}
 191
 192	html_rss_link();
 193
 194	$t_favicon_image = config_get( 'favicon_image' );
 195	if( !is_blank( $t_favicon_image ) ) {
 196		echo "\t", '<link rel="shortcut icon" href="', helper_mantis_url( $t_favicon_image ), '" type="image/x-icon" />', "\n";
 197	}
 198
 199	// Advertise the availability of the browser search plug-ins.
 200	echo "\t", '<link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Text Search" href="' . string_sanitize_url( 'browser_search_plugin.php?type=text', true) . '" />' . "\n";
 201	echo "\t", '<link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Issue Id" href="' . string_sanitize_url( 'browser_search_plugin.php?type=id', true) . '" />' . "\n";
 202
 203	html_title( $p_page_title );
 204	html_head_javascript();
 205}
 206
 207/**
 208 * Print the part of the page that comes after meta tags, but before the actual page content
 209 * @return null
 210 */
 211function html_page_top2() {
 212	html_page_top2a();
 213
 214	if( !db_is_connected() ) {
 215		return;
 216	}
 217
 218	if( auth_is_user_authenticated() ) {
 219		html_login_info();
 220
 221		if( ON == config_get( 'show_project_menu_bar' ) ) {
 222			print_project_menu_bar();
 223			echo '<br />';
 224		}
 225	}
 226	print_menu();
 227	echo '<div id="content">', "\n";
 228	event_signal( 'EVENT_LAYOUT_CONTENT_BEGIN' );
 229}
 230
 231/**
 232 * Print the part of the page that comes after meta tags and before the
 233 *  actual page content, but without login info or menus.  This is used
 234 *  directly during the login process and other times when the user may
 235 *  not be authenticated
 236 * @return null
 237 */
 238function html_page_top2a() {
 239	global $g_error_send_page_header;
 240
 241	html_head_end();
 242	html_body_begin();
 243	$g_error_send_page_header = false;
 244	html_top_banner();
 245}
 246
 247/**
 248 * Print the part of the page that comes below the page content
 249 * $p_file should always be the __FILE__ variable. This is passed to show source
 250 * @param string $p_file should always be the __FILE__ variable. This is passed to show source
 251 * @return null
 252 */
 253function html_page_bottom( $p_file = null ) {
 254	html_page_bottom1( $p_file );
 255}
 256
 257/**
 258 * Print the part of the page that comes below the page content
 259 * $p_file should always be the __FILE__ variable. This is passed to show source
 260 * @param string $p_file should always be the __FILE__ variable. This is passed to show source
 261 * @return null
 262 */
 263function html_page_bottom1( $p_file = null ) {
 264	if( !db_is_connected() ) {
 265		return;
 266	}
 267
 268	event_signal( 'EVENT_LAYOUT_CONTENT_END' );
 269	echo '</div>', "\n";
 270	if( config_get( 'show_footer_menu' ) ) {
 271		echo '<br />';
 272		print_menu();
 273	}
 274
 275	html_page_bottom1a( $p_file );
 276}
 277
 278/**
 279 * Print the part of the page that comes below the page content but leave off
 280 *  the menu.  This is used during the login process and other times when the
 281 *  user may not be authenticated.
 282 * @param string $p_file should always be the __FILE__ variable.
 283 * @return null
 284 */
 285function html_page_bottom1a( $p_file = null ) {
 286	if( null === $p_file ) {
 287		$p_file = basename( $_SERVER['SCRIPT_NAME'] );
 288	}
 289
 290	html_bottom_banner();
 291	html_footer();
 292	html_body_end();
 293	html_end();
 294}
 295
 296/**
 297 * (1) Print the document type and the opening <html> tag
 298 * @return null
 299 */
 300function html_begin() {
 301	echo '<!DOCTYPE html>', "\n";
 302	echo '<html>', "\n";
 303}
 304
 305/**
 306 * (2) Begin the <head> section
 307 * @return null
 308 */
 309function html_head_begin() {
 310	echo '<head>', "\n";
 311}
 312
 313/**
 314 * (3) Print the content-type
 315 * @return null
 316 */
 317function html_content_type() {
 318	echo "\t", '<meta http-equiv="Content-type" content="text/html; charset=utf-8" />', "\n";
 319}
 320
 321/**
 322 * (4) Print the window title
 323 * @param string $p_page_title window title
 324 * @return null
 325 */
 326function html_title( $p_page_title = null ) {
 327	$t_page_title = string_html_specialchars( $p_page_title );
 328	$t_title = string_html_specialchars( config_get( 'window_title' ) );
 329	echo "\t", '<title>';
 330	if( empty( $t_page_title ) ) {
 331		echo $t_title;
 332	} else {
 333		if( empty( $t_title ) ) {
 334			echo $t_page_title;
 335		} else {
 336			echo $t_page_title . ' - ' . $t_title;
 337		}
 338	}
 339	echo '</title>', "\n";
 340}
 341
 342function require_css( $p_stylesheet_path ) {
 343	global $g_stylesheets_included;
 344	$g_stylesheets_included[$p_stylesheet_path] = $p_stylesheet_path;
 345}
 346
 347/**
 348 * (5) Print the link to include the css file
 349 * @return null
 350 */
 351function html_css() {
 352	global $g_stylesheets_included;
 353	html_css_link( config_get( 'css_include_file' ) );
 354	html_css_link( 'jquery-ui-1.8.20.custom.css' );
 355	html_css_link( 'common_config.php' );
 356	# Add right-to-left css if needed
 357	if ( lang_get( 'directionality' ) == 'rtl' ) {
 358		html_css_link( config_get( 'css_rtl_include_file' ) );
 359	}
 360	foreach ( $g_stylesheets_included as $t_stylesheet_path ) {
 361		html_css_link ( $t_stylesheet_path );
 362	}
 363}
 364
 365/**
 366 * Prints a css link
 367 * @return null
 368 */
 369function html_css_link( $p_filename ) {
 370	echo "\t", '<link rel="stylesheet" type="text/css" href="', string_sanitize_url( helper_mantis_url( 'css/' . $p_filename ), true ), '" />' . "\n";
 371}
 372
 373
 374/**
 375 * (6) Print an HTML meta tag to redirect to another page
 376 * This function is optional and may be called by pages that need a redirect.
 377 * $p_time is the number of seconds to wait before redirecting.
 378 * If we have handled any errors on this page and the 'stop_on_errors' config
 379 *  option is turned on, return false and don't redirect.
 380 *
 381 * @param string $p_url The page to redirect: has to be a relative path
 382 * @param integer $p_time seconds to wait for before redirecting
 383 * @param boolean $p_sanitize apply string_sanitize_url to passed url
 384 * @return boolean
 385 */
 386function html_meta_redirect( $p_url, $p_time = null, $p_sanitize = true ) {
 387	if( ON == config_get_global( 'stop_on_errors' ) && error_handled() ) {
 388		return false;
 389	}
 390
 391	if( null === $p_time ) {
 392		$p_time = current_user_get_pref( 'redirect_delay' );
 393	}
 394
 395	$t_url = config_get( 'path' );
 396	if( $p_sanitize ) {
 397		$t_url .= string_sanitize_url( $p_url );
 398	} else {
 399		$t_url .= $p_url;
 400	}
 401
 402	$t_url = htmlspecialchars( $t_url );
 403
 404	echo "\t<meta http-equiv=\"Refresh\" content=\"$p_time;URL=$t_url\" />\n";
 405
 406	return true;
 407}
 408
 409function require_js( $p_script_path ) {
 410	global $g_scripts_included;
 411	$g_scripts_included[$p_script_path] = $p_script_path;
 412}
 413
 414/**
 415 * (6a) Javascript...
 416 * @return null
 417 */
 418function html_head_javascript() {
 419	if ( config_get( 'use_javascript' ) ) {
 420		global $g_scripts_included;
 421		echo "\t<script type=\"text/javascript\" src=\"" . helper_mantis_url( 'javascript_config.php' ) . '"></script>' . "\n";
 422		echo "\t<script type=\"text/javascript\" src=\"" . helper_mantis_url( 'javascript_translations.php' ) . '"></script>' . "\n";
 423		html_javascript_link( 'jquery-1.7.2.min.js' );
 424		html_javascript_link( 'jquery-ui-1.8.20.custom.min.js' );
 425		html_javascript_link( 'common.js' );
 426		foreach ( $g_scripts_included as $t_script_path ) {
 427			html_javascript_link( $t_script_path );
 428		}
 429	}
 430}
 431
 432/**
 433 * (7) End the <head> section
 434 * @return null
 435 */
 436function html_head_end() {
 437	event_signal( 'EVENT_LAYOUT_RESOURCES' );
 438
 439	echo '</head>', "\n";
 440}
 441
 442/**
 443 * (8) Begin the <body> section
 444 * @return null
 445 */
 446function html_body_begin() {
 447    $t_centered_page = is_page_name( 'login_page' ) || is_page_name( 'signup_page' ) || is_page_name( 'signup' ) || is_page_name( 'lost_pwd_page' );
 448
 449    echo '<body>', "\n";
 450
 451    if ( $t_centered_page ) {
 452        echo '<div id="mantis" class="centered_page">', "\n";
 453    } else {
 454        echo '<div id="mantis">', "\n";
 455    }
 456
 457	event_signal( 'EVENT_LAYOUT_BODY_BEGIN' );
 458}
 459
 460/**
 461 * (9) Print a user-defined banner at the top of the page if there is one.
 462 * @return null
 463 */
 464function html_top_banner() {
 465	$t_page = config_get( 'top_include_page' );
 466	$t_logo_image = config_get( 'logo_image' );
 467	$t_logo_url = config_get( 'logo_url' );
 468
 469	if( is_blank( $t_logo_image ) ) {
 470		$t_show_logo = false;
 471	} else {
 472		$t_show_logo = true;
 473		if( is_blank( $t_logo_url ) ) {
 474			$t_show_url = false;
 475		} else {
 476			$t_show_url = true;
 477		}
 478	}
 479
 480	if( !is_blank( $t_page ) && file_exists( $t_page ) && !is_dir( $t_page ) ) {
 481		include( $t_page );
 482	} else if( $t_show_logo ) {
 483		echo '<div id="banner">';
 484		if( $t_show_url ) {
 485			echo '<a id="logo-link" href="', config_get( 'logo_url' ), '">';
 486		}
 487		$t_alternate_text = string_html_specialchars( config_get( 'window_title' ) );
 488		echo '<img id="logo-image" alt="', $t_alternate_text, '" src="' . helper_mantis_url( $t_logo_image ) . '" />';
 489		if( $t_show_url ) {
 490			echo '</a>';
 491		}
 492		echo '</div>';
 493	}
 494
 495	event_signal( 'EVENT_LAYOUT_PAGE_HEADER' );
 496}
 497
 498/**
 499 * (10) Print the user's account information
 500 * Also print the select box where users can switch projects
 501 * @return null
 502 */
 503function html_login_info() {
 504	$t_username = current_user_get_field( 'username' );
 505	$t_access_level = get_enum_element( 'access_levels', current_user_get_access_level() );
 506	$t_now = date( config_get( 'complete_date_format' ) );
 507	$t_realname = current_user_get_field( 'realname' );
 508
 509	# Login information
 510	echo '<div id="login-info">';
 511	if( current_user_is_anonymous() ) {
 512		$t_return_page = $_SERVER['SCRIPT_NAME'];
 513		if( isset( $_SERVER['QUERY_STRING'] ) ) {
 514			$t_return_page .= '?' . $_SERVER['QUERY_STRING'];
 515		}
 516
 517		$t_return_page = string_url( $t_return_page );
 518
 519		echo '<span id="logged-anon-label">' . lang_get( 'anonymous' ) . '</span>';
 520		echo '<span id="login-link"><a href="' . helper_mantis_url( 'login_page.php?return=' . $t_return_page ) . '">' . lang_get( 'login_link' ) . '</a></span>';
 521		if( config_get_global( 'allow_signup' ) == ON ) {
 522			echo '<span id="signup-link"><a href="' . helper_mantis_url( 'signup_page.php' ) . '">' . lang_get( 'signup_link' ) . '</a></span>';
 523		}
 524	} else {
 525		echo '<span id="logged-in-label">' . lang_get( 'logged_in_as' ) . '</span>';
 526		echo '<span id="logged-in-user">' . string_html_specialchars( $t_username ) . '</span>';
 527		echo '<span id="logged-in">';
 528		echo !is_blank( $t_realname ) ?  '<span id="logged-in-realname">' . string_html_specialchars( $t_realname ) . '</span>' : '';
 529		echo '<span id="logged-in-accesslevel" class="' . $t_access_level . '">' . $t_access_level . '</span>';
 530		echo '</span>';
 531	}
 532	echo '</div>';
 533
 534	# RSS feed
 535	if( OFF != config_get( 'rss_enabled' ) ) {
 536		echo '<div id="rss-feed">';
 537		# Link to RSS issues feed for the selected project, including authentication details.
 538		echo '<a href="' . htmlspecialchars( rss_get_issues_feed_url() ) . '">';
 539		echo '<img src="' . helper_mantis_url( 'images/rss.png' ) . '" alt="' . lang_get( 'rss' ) . '" title="' . lang_get( 'rss' ) . '" />';
 540		echo '</a>';
 541		echo '</div>';
 542	}
 543
 544	# Project Selector (hidden if only one project visisble to user)
 545	$t_show_project_selector = true;
 546	$t_project_ids = current_user_get_accessible_projects();
 547	if( count( $t_project_ids ) == 1 ) {
 548		$t_project_id = (int) $t_project_ids[0];
 549		if( count( current_user_get_accessible_subprojects( $t_project_id ) ) == 0 ) {
 550			$t_show_project_selector = false;
 551		}
 552	}
 553
 554	if( $t_show_project_selector ) {
 555		echo '<div id="project-selector">';
 556		echo '<form method="post" id="form-set-project" action="' . helper_mantis_url( 'set_project.php' ) . '">';
 557		echo '<fieldset id="project-selector">';
 558		# CSRF protection not required here - form does not result in modifications
 559
 560		echo '<label for="form-set-project-id">' . lang_get( 'email_project' ) . '</label>';
 561		echo '<select id="form-set-project-id" name="project_id">';
 562		print_project_option_list( join( ';', helper_get_current_project_trace() ), true, null, true );
 563		echo '</select> ';
 564		echo '<input type="submit" class="button" value="' . lang_get( 'switch' ) . '" />';
 565		echo '</fieldset>';
 566		echo '</form>';
 567		echo '</div>';
 568	} else {
 569		# User has only one project, set it as both current and default
 570		if( ALL_PROJECTS == helper_get_current_project() ) {
 571			helper_set_current_project( $t_project_id );
 572
 573			if ( !current_user_is_protected() ) {
 574				current_user_set_default_project( $t_project_id );
 575			}
 576
 577			# Force reload of current page, except if we got here after
 578			# creating the first project
 579			$t_redirect_url = str_replace( config_get( 'short_path' ), '', $_SERVER['REQUEST_URI'] );
 580			if( 'manage_proj_create.php' != $t_redirect_url ) {
 581				html_meta_redirect( $t_redirect_url, 0, false );
 582			}
 583		}
 584	}
 585
 586	# Current time
 587	echo '<div id="current-time">' . $t_now . '</div>';
 588}
 589
 590/**
 591 * (11) Print a user-defined banner at the bottom of the page if there is one.
 592 * @return null
 593 */
 594function html_bottom_banner() {
 595	$t_page = config_get( 'bottom_include_page' );
 596
 597	if( !is_blank( $t_page ) && file_exists( $t_page ) && !is_dir( $t_page ) ) {
 598		include( $t_page );
 599	}
 600}
 601
 602/**
 603 * A function that outputs that an operation was successful and provides a redirect link.
 604 * @param $p_redirect_url  The url to redirect to.
 605 */
 606function html_operation_successful( $p_redirect_url, $p_message = '' ) {
 607    echo '<div class="success-msg">';
 608
 609    if ( !is_blank( $p_message ) ) {
 610        echo $p_message . '<br />';
 611    }
 612
 613    echo lang_get( 'operation_successful' ).'<br />';
 614    print_bracket_link( $p_redirect_url, lang_get( 'proceed' ) );
 615    echo '</div>';
 616}
 617
 618/**
 619 * (13) Print the page footer information
 620 * @param string $p_file
 621 * @return null
 622 */
 623function html_footer( $p_file = null ) {
 624	global $g_queries_array, $g_request_time;
 625
 626	# If a user is logged in, update their last visit time.
 627	# We do this at the end of the page so that:
 628	#  1) we can display the user's last visit time on a page before updating it
 629	#  2) we don't invalidate the user cache immediately after fetching it
 630	#  3) don't do this on the password verification or update page, as it causes the
 631	#    verification comparison to fail
 632	if ( auth_is_user_authenticated() && !current_user_is_anonymous() && !( is_page_name( 'verify.php' ) || is_page_name( 'account_update.php' ) ) ) {
 633		$t_user_id = auth_get_current_user_id();
 634		user_update_last_visit( $t_user_id );
 635	}
 636
 637	echo "<div id=\"footer\">\n";
 638	echo "\t<hr />\n";
 639
 640	# We don't have a button anymore, so for now we will only show the resized
 641	# version of the logo when not on login page.
 642	if ( !is_page_name( 'login_page' ) ) {
 643		echo "\t<div id=\"powered-by-mantisbt-logo\">\n";
 644		$t_mantisbt_logo_url = helper_mantis_url( 'images/mantis_logo.png' );
 645		echo "\t\t<a href=\"http://www.mantisbt.org\" ".
 646			"title=\"Mantis Bug Tracker: a free and open source web based bug tracking system.\">" .
 647			"<img src=\"$t_mantisbt_logo_url\" width=\"102\" height=\"35\" " .
 648				"alt=\"Powered by Mantis Bug Tracker: a free and open source web based bug tracking system.\" />" .
 649			"</a>\n";
 650		echo "\t</div>\n";
 651	}
 652
 653	# Show optional user-specificed custom copyright statement
 654	$t_copyright_statement = config_get( 'copyright_statement' );
 655	if ( $t_copyright_statement ) {
 656		echo "\t<address id=\"user-copyright\">$t_copyright_statement</address>\n";
 657	}
 658
 659	# Show MantisBT version and copyright statement
 660	$t_version_suffix = '';
 661	$t_copyright_years = '';
 662	if ( config_get( 'show_version' ) ) {
 663		$t_version_suffix = htmlentities( ' ' . MANTIS_VERSION . config_get_global( 'version_suffix' ) );
 664		$t_copyright_years = ' 2000 - ' . date('Y');
 665	}
 666	echo "\t",
 667		'<address id="mantisbt-copyright">Powered by ',
 668		'<a href="http://www.mantisbt.org/" title="Mantis Bug Tracker: a free and open source web based bug tracking system.">',
 669		"Mantis Bug Tracker</a> (MantisBT)$t_version_suffix. ",
 670		"Copyright &copy;$t_copyright_years MantisBT contributors. ",
 671		'Licensed under the terms of the ',
 672		'<a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" title="GNU General Public License (GPL) version 2">',
 673		'GNU General Public License (GPL) version 2</a> or a later version.',
 674		"</address>\n";
 675
 676	# Show contact information
 677	$t_webmaster_contact_information = sprintf( lang_get( 'webmaster_contact_information' ), string_html_specialchars( config_get( 'webmaster_email' ) ) );
 678	echo "\t<address id=\"webmaster-contact-information\">$t_webmaster_contact_information</address>\n";
 679
 680	event_signal( 'EVENT_LAYOUT_PAGE_FOOTER' );
 681
 682	# Print horizontal rule if any debugging stats follow
 683	if ( config_get( 'show_timer' ) || config_get( 'show_memory_usage' ) || config_get( 'show_queries_count' ) ) {
 684		echo "\t<hr />\n";
 685	}
 686
 687	# Print the page execution time
 688	if ( config_get( 'show_timer' ) ) {
 689		$t_page_execution_time = sprintf( lang_get( 'page_execution_time' ), number_format( microtime( true ) - $g_request_time, 4 ) );
 690		echo "\t<p id=\"page-execution-time\">$t_page_execution_time</p>\n";
 691	}
 692
 693	# Print the page memory usage
 694	if ( config_get( 'show_memory_usage' ) ) {
 695		$t_page_memory_usage = sprintf( lang_get( 'memory_usage_in_kb' ), number_format( memory_get_peak_usage() / 1024 ) );
 696		echo "\t<p id=\"page-memory-usage\">$t_page_memory_usage</p>\n";
 697	}
 698
 699	# Determine number of unique queries executed
 700	if ( config_get( 'show_queries_count' ) ) {
 701		$t_total_queries_count = count( $g_queries_array );
 702		$t_unique_queries_count = 0;
 703		$t_total_query_execution_time = 0;
 704		$t_unique_queries = array();
 705		for ( $i = 0; $i < $t_total_queries_count; $i++ ) {
 706			if ( !in_array( $g_queries_array[$i][0], $t_unique_queries ) ) {
 707				$t_unique_queries_count++;
 708				$g_queries_array[$i][3] = false;
 709				array_push( $t_unique_queries, $g_queries_array[$i][0] );
 710			} else {
 711				$g_queries_array[$i][3] = true;
 712			}
 713			$t_total_query_execution_time += $g_queries_array[$i][1];
 714		}
 715
 716		$t_total_queries_executed = sprintf( lang_get( 'total_queries_executed' ), $t_total_queries_count );
 717		echo "\t<p id=\"total-queries-count\">$t_total_queries_executed</p>\n";
 718		if ( config_get_global( 'db_log_queries' ) ) {
 719			$t_unique_queries_executed = sprintf( lang_get( 'unique_queries_executed' ), $t_unique_queries_count );
 720			echo "\t<p id=\"unique-queries-count\">$t_unique_queries_executed</p>\n";
 721		}
 722		$t_total_query_time = sprintf( lang_get( 'total_query_execution_time' ), $t_total_query_execution_time );
 723		echo "\t<p id=\"total-query-execution-time\">$t_total_query_time</p>\n";
 724	}
 725
 726	# Print table of log events
 727	log_print_to_page();
 728
 729	echo "</div>\n";
 730}
 731
 732/**
 733 * (14) End the <body> section
 734 * @return null
 735 */
 736function html_body_end() {
 737	event_signal( 'EVENT_LAYOUT_BODY_END' );
 738
 739	echo '</div>', "\n";
 740
 741	echo '</body>', "\n";
 742}
 743
 744/**
 745 * (15) Print the closing <html> tag
 746 * @return null
 747 */
 748function html_end() {
 749	echo '</html>', "\n";
 750}
 751
 752/**
 753 * Prepare an array of additional menu options from a config variable
 754 * @param string $p_config config name
 755 * @return array
 756 */
 757function prepare_custom_menu_options( $p_config ) {
 758	$t_custom_menu_options = config_get( $p_config );
 759	$t_options = array();
 760
 761	foreach( $t_custom_menu_options as $t_custom_option ) {
 762		$t_access_level = $t_custom_option[1];
 763		if( access_has_project_level( $t_access_level ) ) {
 764			$t_caption = string_html_specialchars( lang_get_defaulted( $t_custom_option[0] ) );
 765			$t_link = string_attribute( $t_custom_option[2] );
 766			$t_options[] = "<a href=\"$t_link\">$t_caption</a>";
 767		}
 768	}
 769
 770	return $t_options;
 771}
 772
 773/**
 774 * Print the main menu
 775 * @return null
 776 */
 777function print_menu() {
 778	if( auth_is_user_authenticated() ) {
 779		$t_protected = current_user_get_field( 'protected' );
 780		$t_current_project = helper_get_current_project();
 781
 782		$t_menu_options = array();
 783
 784		# Main Page
 785		$t_menu_options[] = '<a href="' . helper_mantis_url( 'main_page.php' ) . '">' . lang_get( 'main_link' ) . '</a>';
 786
 787		# Plugin / Event added options
 788		$t_event_menu_options = event_signal( 'EVENT_MENU_MAIN_FRONT' );
 789		foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
 790			foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
 791				if( is_array( $t_callback_menu_options ) ) {
 792					$t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
 793				} else {
 794					if ( !is_null( $t_callback_menu_options ) ) {
 795						$t_menu_options[] = $t_callback_menu_options;
 796					}
 797				}
 798			}
 799		}
 800
 801		# My View
 802		$t_menu_options[] = '<a href="' . helper_mantis_url( 'my_view_page.php">' ) . lang_get( 'my_view_link' ) . '</a>';
 803
 804		# View Bugs
 805		$t_menu_options[] = '<a href="' . helper_mantis_url( 'view_all_bug_page.php">' ) . lang_get( 'view_bugs_link' ) . '</a>';
 806
 807		# Report Bugs
 808		if( access_has_project_level( config_get( 'report_bug_threshold' ) ) ) {
 809			$t_menu_options[] = string_get_bug_report_link();
 810		}
 811
 812		# Changelog Page
 813		if( access_has_project_level( config_get( 'view_changelog_threshold' ) ) ) {
 814			$t_menu_options[] = '<a href="' . helper_mantis_url( 'changelog_page.php">' ) . lang_get( 'changelog_link' ) . '</a>';
 815		}
 816
 817		# Roadmap Page
 818		if( access_has_project_level( config_get( 'roadmap_view_threshold' ) ) ) {
 819			$t_menu_options[] = '<a href="' . helper_mantis_url( 'roadmap_page.php">' ) . lang_get( 'roadmap_link' ) . '</a>';
 820		}
 821
 822		# Summary Page
 823		if( access_has_project_level( config_get( 'view_summary_threshold' ) ) ) {
 824			$t_menu_options[] = '<a href="' . helper_mantis_url( 'summary_page.php">' ) . lang_get( 'summary_link' ) . '</a>';
 825		}
 826
 827		# Project Documentation Page
 828		if( ON == config_get( 'enable_project_documentation' ) ) {
 829			$t_menu_options[] = '<a href="' . helper_mantis_url( 'proj_doc_page.php">' ) . lang_get( 'docs_link' ) . '</a>';
 830		}
 831
 832		# Project Wiki
 833		if( config_get_global( 'wiki_enable' ) == ON ) {
 834			$t_menu_options[] = '<a href="' . helper_mantis_url( 'wiki.php?type=project&amp;id=' ) . $t_current_project . '">' . lang_get( 'wiki' ) . '</a>';
 835		}
 836
 837		# Plugin / Event added options
 838		$t_event_menu_options = event_signal( 'EVENT_MENU_MAIN' );
 839		foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
 840			foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
 841				if( is_array( $t_callback_menu_options ) ) {
 842					$t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
 843				} else {
 844					if ( !is_null( $t_callback_menu_options ) ) {
 845						$t_menu_options[] = $t_callback_menu_options;
 846					}
 847				}
 848			}
 849		}
 850
 851		# Manage Users (admins) or Manage Project (managers) or Manage Custom Fields
 852		if( access_has_global_level( config_get( 'manage_site_threshold' ) ) ) {
 853			$t_link = helper_mantis_url( 'manage_overview_page.php' );
 854			$t_menu_options[] = '<a class="manage-menu-link" href="' . $t_link . '">' . lang_get( 'manage_link' ) . '</a>';
 855		} else {
 856			$t_show_access = min( config_get( 'manage_user_threshold' ), config_get( 'manage_project_threshold' ), config_get( 'manage_custom_fields_threshold' ) );
 857			if( access_has_global_level( $t_show_access ) || access_has_any_project( $t_show_access ) ) {
 858				$t_current_project = helper_get_current_project();
 859				if( access_has_global_level( config_get( 'manage_user_threshold' ) ) ) {
 860					$t_link = helper_mantis_url( 'manage_user_page.php' );
 861				} else {
 862					if( access_has_project_level( config_get( 'manage_project_threshold' ), $t_current_project ) && ( $t_current_project <> ALL_PROJECTS ) ) {
 863						$t_link = helper_mantis_url( 'manage_proj_edit_page.php?project_id=' ) . $t_current_project;
 864					} else {
 865						$t_link = helper_mantis_url( 'manage_proj_page.php' );
 866					}
 867				}
 868				$t_menu_options[] = "<a href=\"$t_link\">" . lang_get( 'manage_link' ) . '</a>';
 869			}
 870		}
 871
 872		# News Page
 873		if ( news_is_enabled() && access_has_project_level( config_get( 'manage_news_threshold' ) ) ) {
 874
 875			# Admin can edit news for All Projects (site-wide)
 876			if( ALL_PROJECTS != helper_get_current_project() || current_user_is_administrator() ) {
 877				$t_menu_options[] = '<a href="' . helper_mantis_url( 'news_menu_page.php">' ) . lang_get( 'edit_news_link' ) . '</a>';
 878			} else {
 879				$t_menu_options[] = '<a href="' . helper_mantis_url( 'login_select_proj_page.php">' ) . lang_get( 'edit_news_link' ) . '</a>';
 880			}
 881		}
 882
 883		# Account Page (only show accounts that are NOT protected)
 884		if( OFF == $t_protected ) {
 885			$t_menu_options[] = '<a class="account-menu-link" href="' . helper_mantis_url( 'account_page.php">' ) . lang_get( 'account_link' ) . '</a>';
 886		}
 887
 888		# Add custom options
 889		$t_custom_options = prepare_custom_menu_options( 'main_menu_custom_options' );
 890		$t_menu_options = array_merge( $t_menu_options, $t_custom_options );
 891
 892		# Time Tracking / Billing
 893		if( config_get( 'time_tracking_enabled' ) && access_has_global_level( config_get( 'time_tracking_reporting_threshold' ) ) ) {
 894			$t_menu_options[] = '<a href="' . helper_mantis_url( 'billing_page.php">' ) . lang_get( 'time_tracking_billing_link' ) . '</a>';
 895		}
 896
 897		# Logout (no if anonymously logged in)
 898		if( !current_user_is_anonymous() ) {
 899			$t_menu_options[] = '<a id="logout-link" href="' . helper_mantis_url( 'logout_page.php">' ) . lang_get( 'logout_link' ) . '</a>';
 900		}
 901
 902		# Display main menu
 903		echo "\n" . '<div class="main-menu">'. "\n";
 904
 905		# Menu items
 906		echo '<ul id="menu-items">' . "\n";
 907		echo "\t<li>" . implode( $t_menu_options, "</li>\n\t<li>" ) . "</li>\n";
 908		echo "</ul>\n";
 909
 910		# Bug Jump form
 911		echo '<div id="bug-jump" >';
 912		echo '<form method="post" class="bug-jump-form" action="' . helper_mantis_url( 'jump_to_bug.php' ) . '">';
 913		echo '<fieldset class="bug-jump">';
 914		# CSRF protection not required here - form does not result in modifications
 915		echo '<input type="hidden" name="bug_label" value="' . lang_get( 'issue_id' ) . '" />';
 916		echo '<input type="text" name="bug_id" size="4" />&#160;';
 917		echo '<input type="submit" value="' . lang_get( 'jump' ) . '" />&#160;';
 918		echo '</fieldset>';
 919		echo '</form>';
 920		echo "</div>\n";
 921
 922		echo "</div>\n";
 923	}
 924}
 925
 926/**
 927 * Print the menu bar with a list of projects to which the user has access
 928 * @return null
 929 */
 930function print_project_menu_bar() {
 931	$t_project_ids = current_user_get_accessible_projects();
 932
 933	echo '<table class="width100" cellspacing="0">';
 934	echo '<tr>';
 935	echo '<td class="menu">';
 936	echo '<a href="' . helper_mantis_url( 'set_project.php?project_id=' . ALL_PROJECTS ) . '">' . lang_get( 'all_projects' ) . '</a>';
 937
 938	foreach( $t_project_ids as $t_id ) {
 939		echo ' | <a href="' . helper_mantis_url( 'set_project.php?project_id=' . $t_id ) . '">' . string_html_specialchars( project_get_field( $t_id, 'name' ) ) . '</a>';
 940		print_subproject_menu_bar( $t_id, $t_id . ';' );
 941	}
 942
 943	echo '</td>';
 944	echo '</tr>';
 945	echo '</table>';
 946}
 947
 948/**
 949 * Print the menu bar with a list of projects to which the user has access
 950 * @return null
 951 */
 952function print_subproject_menu_bar( $p_project_id, $p_parents = '' ) {
 953	$t_subprojects = current_user_get_accessible_subprojects( $p_project_id );
 954	$t_char = ':';
 955	foreach( $t_subprojects as $t_subproject ) {
 956		echo $t_char . ' <a href="' . helper_mantis_url( 'set_project.php?project_id=' . $p_parents . $t_subproject ) . '">' . string_html_specialchars( project_get_field( $t_subproject, 'name' ) ) . '</a>';
 957		print_subproject_menu_bar( $t_subproject, $p_parents . $t_subproject . ';' );
 958		$t_char = ',';
 959	}
 960}
 961
 962/**
 963 * Print the menu for the graph summary section
 964 * @return null
 965 */
 966function print_summary_submenu() {
 967	# Plugin / Event added options
 968	$t_event_menu_options = event_signal( 'EVENT_SUBMENU_SUMMARY' );
 969	$t_menu_options = array();
 970	foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
 971		foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
 972			if( is_array( $t_callback_menu_options ) ) {
 973				$t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
 974			} else {
 975				if ( !is_null( $t_callback_menu_options ) ) {
 976					$t_menu_options[] = $t_callback_menu_options;
 977				}
 978			}
 979		}
 980	}
 981
 982	echo '<div id="summary-submenu">';
 983	echo '<ul class="menu">';
 984	// Plugins menu items - these are cooked links
 985	foreach ( $t_menu_options as $t_menu_item ) {
 986		echo '<li>', $t_menu_item, '</li>';
 987	}
 988	echo '</ul>';
 989	echo '</div>';
 990}
 991
 992/**
 993 * Print the menu for the manage section
 994 *
 995 * @param string $p_page specifies the current page name so it's link can be disabled
 996 * @return null
 997 */
 998function print_manage_menu( $p_page = '' ) {
 999	$t_pages = array();
1000	if( access_has_global_level( config_get( 'manage_user_threshold' ) ) ) {
1001		$t_pages['manage_user_page.php'] = array( 'url'   => 'manage_user_page.php', 'label' => 'manage_users_link' );
1002	}
1003	if( access_has_project_level( config_get( 'manage_project_threshold' ) ) ) {
1004		$t_pages['manage_proj_page.php'] = array( 'url'   => 'manage_proj_page.php', 'label' => 'manage_projects_link' );
1005	}
1006	if( access_has_global_level( config_get( 'tag_edit_threshold' ) ) ) {
1007		$t_pages['manage_tags_page.php'] = array( 'url'   => 'manage_tags_page.php', 'label' => 'manage_tags_link' );
1008	}
1009	if( access_has_global_level( config_get( 'manage_custom_fields_threshold' ) ) ) {
1010		$t_pages['manage_custom_field_page.php'] = array( 'url'   => 'manage_custom_field_page.php', 'label' => 'manage_custom_field_link' );
1011	}
1012	if( access_has_global_level( config_get( 'manage_global_profile_threshold' ) ) ) {
1013		$t_pages['manage_prof_menu_page.php'] = array( 'url'   => 'manage_prof_menu_page.php', 'label' => 'manage_global_profiles_link' );
1014	}
1015	if( access_has_global_level( config_get( 'manage_plugin_threshold' ) ) ) {
1016		$t_pages['manage_plugin_page.php'] = array( 'url'   => 'manage_plugin_page.php', 'label' => 'manage_plugin_link' );
1017	}
1018
1019	if ( access_has_project_level( config_get( 'manage_configuration_threshold' ) ) ) {
1020		if ( access_has_global_level( config_get( 'view_configuration_threshold' ) ) ) {
1021			$t_pages['adm_config_report.php'] = array( 'url'   => 'adm_config_report.php', 'label' => 'manage_config_link' );
1022		} else {
1023			$t_pages['adm_permissions_report.php'] = array( 'url'   => 'adm_permissions_report.php', 'label' => 'manage_config_link' );
1024		}
1025	}
1026	# Remove the link from the current page
1027	if ( isset( $t_pages[$p_page] ) ) {
1028		$t_pages[$p_page]['url'] = '';
1029	}
1030
1031	# Plugin / Event added options
1032	$t_event_menu_options = event_signal( 'EVENT_MENU_MANAGE' );
1033	$t_menu_options = array();
1034	foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
1035		foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
1036			if( is_array( $t_callback_menu_options ) ) {
1037				$t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
1038			} else {
1039				if ( !is_null( $t_callback_menu_options ) ) {
1040					$t_menu_options[] = $t_callback_menu_options;
1041				}
1042			}
1043		}
1044	}
1045
1046	echo "\n" . '<div id="manage-menu">' . "\n";
1047	echo '<ul class="menu">';
1048	foreach( $t_pages AS $t_page ) {
1049		if( $t_page['url'] == '' ) {
1050			echo '<li>', lang_get( $t_page['label'] ), '</li>';
1051		} else {
1052			echo '<li><a href="'. helper_mantis_url( $t_page['url'] ) .'">' . lang_get( $t_page['label'] ) . '</a></li>';
1053		}
1054	}
1055
1056	// Plugins menu items - these are cooked links
1057	foreach( $t_menu_options as $t_menu_item ) {
1058		echo '<li>', $t_menu_item, '</li>';
1059	}
1060
1061	echo '</ul>';
1062	echo '</div>';
1063}
1064
1065/**
1066 * Print the menu for the manage configuration section
1067 * @param string $p_page specifies the current page name so it's link can be disabled
1068 * @return null
1069 */
1070function print_manage_config_menu( $p_page = '' ) {
1071	if ( !access_has_project_level( config_get( 'manage_configuration_threshold' ) ) ) {
1072		return;
1073	}
1074
1075	$t_pages = array();
1076
1077	if ( access_has_global_level( config_get( 'view_configuration_threshold' ) ) ) {
1078		$t_pages['adm_config_report.php'] = array( 'url'   => 'adm_config_report.php',
1079		                                           'label' => 'configuration_report' );
1080	}
1081
1082	$t_pages['adm_permissions_report.php'] = array( 'url'   => 'adm_permissions_report.php',
1083	                                                'label' => 'permissions_summary_report' );
1084
1085	$t_pages['manage_config_work_threshold_page.php'] = array( 'url'   => 'manage_config_work_threshold_page.php',
1086	                                                           'label' => 'manage_threshold_config' );
1087
1088	$t_pages['manage_config_workflow_page.php'] = array( 'url'   => 'manage_config_workflow_page.php',
1089	                                                     'label' => 'manage_workflow_config' );
1090
1091	if ( config_get( 'relationship_graph_enable' ) ) {
1092		$t_pages['manage_config_workflow_graph_page.php'] = array( 'url'   => 'manage_config_workflow_graph_page.php',
1093		                                                           'label' => 'manage_workflow_graph' );
1094	}
1095
1096	$t_pages['manage_config_email_page.php'] = array( 'url'   => 'manage_config_email_page.php',
1097	                                                  'label' => 'manage_email_config' );
1098
1099	$t_pages['manage_config_columns_page.php'] = array( 'url'   => 'manage_config_columns_page.php',
1100	                                                    'label' => 'manage_columns_config' );
1101
1102	# Remove the link from the current page
1103	if ( isset( $t_pages[$p_page] ) ) {
1104		$t_pages[$p_page]['url'] = '';
1105	}
1106
1107	# Plugin / Event added options
1108	$t_event_menu_options = event_signal( 'EVENT_MENU_MANAGE_CONFIG' );
1109	$t_menu_options = array();
1110	foreach ( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
1111		foreach ( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
1112			if ( is_array( $t_callback_menu_options ) ) {
1113				$t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
1114			} else {
1115				if ( !is_null( $t_callback_menu_options ) ) {
1116					$t_menu_options[] = $t_callback_menu_options;
1117				}
1118			}
1119		}
1120	}
1121
1122	echo '<div id="manage-config-menu">';
1123	echo '<ul class="menu">';
1124	foreach ( $t_pages as $t_page ) {
1125		if( $t_page['url'] == '' ) {
1126			echo '<li>', lang_get( $t_page['label'] ), '</li>';
1127		} else {
1128			echo '<li><a href="'. helper_mantis_url( $t_page['url'] ) .'">' . lang_get( $t_page['label'] ) . '</a></li>';
1129		}
1130	}
1131
1132	foreach ( $t_menu_options as $t_menu_item ) {
1133		echo '<li>', $t_menu_item, '</li>';
1134	}
1135
1136	echo '</ul>';
1137	echo '</div>';
1138}
1139
1140/**
1141 * Print the menu for the account section
1142 * @param string $p_page specifies the current page name so it's link can be disabled
1143 * @return null
1144 */
1145function print_account_menu( $p_page = '' ) {
1146	$t_pages['account_page.php'] = array( 'url'=>'account_page.php', 'label'=>'account_link' );
1147	$t_pages['account_prefs_page.php'] = array( 'url'=>'account_prefs_page.php', 'label'=>'change_preferences_link' );
1148	$t_pages['account_manage_columns_page.php'] = array( 'url'=>'account_manage_columns_page.php', 'label'=>'manage_columns_config' );
1149
1150	if( config_get ( 'enable_profiles' ) == ON && access_has_project_level( config_get( 'add_profile_threshold' ) ) ) {
1151		$t_pages['account_prof_menu_page.php'] = array( 'url'=>'account_prof_menu_page.php', 'label'=>'manage_profiles_link' );
1152	}
1153
1154	if( config_get( 'enable_sponsorship' ) == ON && access_has_project_level( config_get( 'view_sponsorship_total_threshold' ) ) && !current_user_is_anonymous() ) {
1155		$t_pages['account_sponsor_page.php'] = array( 'url'=>'account_sponsor_page.php', 'label'=>'my_sponsorship' );
1156	}
1157
1158	# Remove the link from the current page
1159	if ( isset( $t_pages[$p_page] ) ) {
1160		$t_pages[$p_page]['url'] = '';
1161	}
1162
1163	# Plugin / Event added options
1164	$t_event_menu_options = event_signal( 'EVENT_MENU_ACCOUNT' );
1165	$t_menu_options = array();
1166	foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
1167		foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
1168			if( is_array( $t_callback_menu_options ) ) {
1169				$t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
1170			} else {
1171				if ( !is_null( $t_callback_menu_options ) ) {
1172					$t_menu_options[] = $t_callback_menu_options;
1173				}
1174			}
1175		}
1176	}
1177
1178	echo '<div id="account-menu">';
1179	echo '<ul class="menu">';
1180	foreach ( $t_pages as $t_page ) {
1181		if( $t_page['url'] == '' ) {
1182			echo '<li><span>', lang_get( $t_page['label'] ), '</span></li>';
1183		} else {
1184			echo '<li><a href="'. helper_mantis_url( $t_page['url'] ) .'">' . lang_get( $t_page['label'] ) . '</a></li>';
1185		}
1186	}
1187
1188	// Plugins menu items - these are cooked links
1189	foreach ( $t_menu_options as $t_menu_item ) {
1190		echo '<li>', $t_menu_item, '</li>';
1191	}
1192	echo '</ul>';
1193	echo '</div>';
1194}
1195
1196/**
1197 * Print the menu for the docs section
1198 * @param string $p_page specifies the current page name so it's link can be disabled
1199 * @return null
1200 */
1201function print_doc_menu( $p_page = '' ) {
1202	$t_documentation_html = config_get( 'manual_url' );
1203	$t_pages[$t_documentation_html] = array( 'url'=>$t_documentation_html, 'label'=>'user_documentation' );
1204	$t_pages['proj_doc_page.php'] = array( 'url'=>'proj_doc_page.php', 'label'=>'project_documentation' );
1205	if( file_allow_project_upload() ) {
1206		$t_pages['proj_doc_add_page.php'] = array( 'url'=>'proj_doc_add_page.php', 'label'=>'add_file' );
1207	}
1208
1209	# Remove the link from the current page
1210	if ( isset( $t_pages[$p_page] ) ) {
1211		$t_pages[$p_page]['url'] = '';
1212	}
1213
1214	echo '<div id="doc-menu">';
1215	echo '<ul class="menu">';
1216	foreach ( $t_pages as $t_page ) {
1217		if( $t_page['url'] == '' ) {
1218			echo '<li>', lang_get( $t_page['label'] ), '</li>';
1219		} else {
1220			echo '<li><a href="'. helper_mantis_url( $t_page['url'] ) .'">' . lang_get( $t_page['label'] ) . '</a></li>';
1221		}
1222	}
1223	echo '</ul>';
1224	echo '</div>';
1225}
1226
1227/**
1228 * Print the menu for the summary section
1229 * @param string $p_page specifies the current page name so it's link can be disabled
1230 * @return null
1231 */
1232function print_summary_menu( $p_page = '' ) {
1233	# Plugin / Event added options
1234	$t_event_menu_options = event_signal( 'EVENT_MENU_SUMMARY' );
1235	$t_menu_options = array();
1236	foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
1237		foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
1238			if( is_array( $t_callback_menu_options ) ) {
1239				$t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
1240			} else {
1241				if ( !is_null( $t_callback_menu_options ) ) {
1242					$t_menu_options[] = $t_callback_menu_options;
1243				}
1244			}
1245		}
1246	}
1247
1248	$t_pages['print_all_bug_page.php'] = array( 'url'=>'print_all_bug_page.php', 'label'=>'print_all_bug_page_link' );
1249	$t_pages['summary_page.php'] = array( 'url'=>'summary_page.php', 'label'=>'summary_link' );
1250	# Remove the link from the current page
1251	if ( isset( $t_pages[$p_page] ) ) {
1252		$t_pages[$p_page]['url'] = '';
1253	}
1254
1255	echo '<div id="summary-menu">';
1256	echo '<ul class="menu">';
1257
1258	foreach ( $t_pages as $t_page ) {
1259		if( $t_page['url'] == '' ) {
1260			echo '<li>', lang_get( $t_page['label'] ), '</li>';
1261		} else {
1262			echo '<li><a href="'. helper_mantis_url( $t_page['url'] ) .'">' . lang_get( $t_page['label'] ) . '</a></li>';
1263		}
1264	}
1265
1266	// Plugins menu items - these are cooked links
1267	foreach ( $t_menu_options as $t_menu_item ) {
1268		echo '<li>', $t_menu_item, '</li>';
1269	}
1270	echo '</ul>';
1271	echo '</div>';
1272}
1273
1274/**
1275 * Print the color legend for the status colors
1276 * @param string
1277 * @return null
1278 */
1279function html_status_legend() {
1280	# Don't show the legend if only one status is selected by the current filter
1281	$t_current_filter = current_user_get_bug_filter();
1282	if ( $t_current_filter === false ) {
1283		$t_current_filter = filter_get_default();
1284	}
1285	$t_simple_filter = $t_current_filter['_view_type'] == 'simple';
1286	if( $t_simple_filter ) {
1287		if( !filter_field_is_any( $t_current_filter[FILTER_PROPERTY_STATUS][0] ) ) {
1288			return null;
1289		}
1290	}
1291
1292	$t_status_array = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
1293	$t_status_names = MantisEnum::getAssocArrayIndexedByValues( lang_get( 'status_enum_string' ) );
1294	$enum_count = count( $t_status_array );
1295
1296	# read through the list and eliminate unused ones for the selected project
1297	# assumes that all status are are in the enum array
1298	$t_workflow = config_get( 'status_enum_workflow' );
1299	if( !empty( $t_workflow ) ) {
1300		foreach( $t_status_array as $t_status => $t_name ) {
1301			if( !isset( $t_workflow[$t_status] ) ) {
1302
1303				# drop elements that are not in the workflow
1304				unset( $t_status_array[$t_status] );
1305			}
1306		}
1307	}
1308
1309	# Remove status values that won't appear as a result of the current filter
1310	foreach( $t_status_array as $t_status => $t_name ) {
1311		if( $t_simple_filter ) {
1312			if( !filter_field_is_none( $t_current_filter[FILTER_PROPERTY_HIDE_STATUS][0] ) &&
1313				$t_status >= $t_current_filter[FILTER_PROPERTY_HIDE_STATUS][0] ) {
1314				unset( $t_status_array[$t_status] );
1315			}
1316		} else {
1317			if( !in_array( META_FILTER_ANY, $t_current_filter[FILTER_PROPERTY_STATUS] ) &&
1318				!in_array( $t_status, $t_current_filter[FILTER_PROPERTY_STATUS] ) ) {
1319				unset( $t_status_array[$t_status] );
1320			}
1321		}
1322	}
1323
1324	# If there aren't at least two statuses showable by the current filter,
1325	# don't draw the status bar
1326	if( count( $t_status_array ) <= 1 ) {
1327		return null;
1328	}
1329
1330	echo '<br />';
1331	echo '<table class="status-legend width100" cellspacing="1">';
1332	echo '<tr>';
1333
1334	# draw the status bar
1335	$width = (int)( 100 / count( $t_status_array ) );
1336	$t_status_enum_string = config_get('status_enum_string' );
1337	foreach( $t_status_array as $t_status => $t_name ) {
1338		$t_val = isset( $t_status_names[$t_status] ) ? $t_status_names[$t_status] : $t_status_array[$t_status];
1339		$t_status_label = MantisEnum::getLabel( $t_status_enum_string, $t_status );
1340		$use_link_in_status = config_get( 'status_legend_link_filter' );
1341
1342		echo "<td class=\"small-caption $t_status_label-color\">";
1343		if ( $use_link_in_status ) {
1344			echo "<a class=\"subtle\" href=\"view_all_set.php?type=1&amp;temporary=y&amp;show_status=$t_status\">";
1345		}
1346		echo "$t_val";
1347		if ( $use_link_in_status ) {
1348			echo "</a>";
1349		}
1350		echo "</td>";
1351	}
1352
1353	echo '</tr>';
1354	echo '</table>';
1355	if( ON == config_get( 'status_percentage_legend' ) ) {
1356		html_status_percentage_legend();
1357	}
1358}
1359
1360/**
1361 * Print the legend for the status percentage
1362 * @return null
1363 */
1364function html_status_percentage_legend() {
1365	$t_status_percents = get_percentage_by_status();
1366	$t_status_enum_string = config_get('status_enum_string' );
1367	$t_enum_values = MantisEnum::getValues( $t_status_enum_string );
1368	$enum_count = count( $t_enum_values );
1369
1370	$t_bug_count = array_sum( $t_status_percents );
1371
1372	if( $t_bug_count > 0 ) {
1373		echo '<br />';
1374		echo '<table class="width100" cellspacing="1">';
1375		echo '<tr>';
1376		echo '<td class="form-title" colspan="' . $enum_count . '">' . lang_get( 'issue_status_percentage' ) . '</td>';
1377		echo '</tr>';
1378		echo '<tr>';
1379		
1380		$use_link_in_status = config_get( 'status_legend_link_filter' );
1381		
1382		foreach ( $t_enum_values as $t_status ) {
1383			$t_percent = ( isset( $t_status_percents[$t_status] ) ?  $t_status_percents[$t_status] : 0 );
1384
1385			if( $t_percent > 0 ) {
1386				$t_status_label = MantisEnum::getLabel( $t_status_enum_string, $t_status );
1387				echo "<td class=\"small-caption-center $t_status_label-color $t_status_label-percentage\">$t_percent%</td>";
1388			}
1389		}
1390
1391		echo '</tr>';
1392		echo '</table>';
1393	}
1394}
1395
1396/**
1397 * Print an html button inside a form
1398 * @param string $p_action
1399 * @param string $p_button_text
1400 * @param array $p_fields
1401 * @param string $p_method
1402 * @return null
1403 */
1404function html_button( $p_action, $p_button_text, $p_fields = null, $p_method = 'post' ) {
1405	$t_form_name = explode( '.php', $p_action, 2 );
1406	$p_action = urlencode( $p_action );
1407	$p_button_text = string_attribute( $p_button_text );
1408	if( null === $p_fields ) {
1409		$p_fields = array();
1410	}
1411
1412	if( utf8_strtolower( $p_method ) == 'get' ) {
1413		$t_method = 'get';
1414	} else {
1415		$t_method = 'post';
1416	}
1417
1418	echo "<form method=\"$t_method\" action=\"$p_action\" class=\"action-button\">\n";
1419	echo "\t<fieldset>";
1420	# Add a CSRF token only when the form is being sent via the POST method
1421	if ( $t_method == 'post' ) {
1422		echo form_security_field( $t_form_name[0] );
1423	}
1424
1425	foreach( $p_fields as $key => $val ) {
1426		$key = string_attribute( $key );
1427		$val = string_attribute( $val );
1428
1429		echo "\t\t<input type=\"hidden\" name=\"$key\" value=\"$val\" />\n";
1430	}
1431
1432	echo "\t\t<input type=\"submit\" class=\"button\" value=\"$p_button_text\" />\n";
1433	echo "\t</fieldset>";
1434	echo "</form>\n";
1435}
1436
1437/**
1438 * Print a button to update the given bug
1439 * @param int $p_bug_id
1440 * @return null
1441 */
1442function html_button_bug_update( $p_bug_id ) {
1443	if( access_has_bug_level( config_get( 'update_bug_threshold' ), $p_bug_id ) ) {
1444		html_button( string_get_bug_update_page(), lang_get( 'update_bug_button' ), array( 'bug_id' => $p_bug_id ) );
1445	}
1446}
1447
1448/**
1449 * Print Change Status to: button
1450 * This code is similar to print_status_option_list except
1451 * there is no masking, except for the current state
1452 *
1453 * @param BugData $p_bug Bug object
1454 * @return null
1455 */
1456function html_button_bug_change_status( $p_bug ) {
1457	$t_current_access = access_get_project_level( $p_bug->project_id );
1458
1459	# User must have rights to change status to use this button
1460	if( !access_has_bug_level( config_get( 'update_bug_status_threshold' ), $p_bug->id ) ) {
1461		return;
1462	}
1463
1464	$t_enum_list = get_status_option_list(
1465		$t_current_access,
1466		$p_bug->status,
1467		false,
1468		# Add close if user is bug's reporter, still has rights to report issues
1469		# (to prevent users downgraded to viewers from updating issues) and
1470		# reporters are allowed to close their own issues
1471		(  bug_is_user_reporter( $p_bug->id, auth_get_current_user_id() )
1472		&& access_has_bug_level( config_get( 'report_bug_threshold' ), $p_bug->id )
1473		&& ON == config_get( 'allow_reporter_close' )
1474		),
1475		$p_bug->project_id );
1476
1477	if( count( $t_enum_list ) > 0 ) {
1478
1479		# resort the list into ascending order after noting the key from the first element (the default)
1480		$t_default_arr = each( $t_enum_list );
1481		$t_default = $t_default_arr['key'];
1482		ksort( $t_enum_list );
1483		reset( $…

Large files files are truncated, but you can click here to view the full file