PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/mantisbt-1.2.8/core/html_api.php

#
PHP | 1692 lines | 1035 code | 227 blank | 430 comment | 217 complexity | 20e42bc57c01dd0b73de91c4dec993c1 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0

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. # MantisBT is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # MantisBT is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with MantisBT. If not, see <http://www.gnu.org/licenses/>.
  15. /**
  16. * These functions control the display of each page
  17. *
  18. * This is the call order of these functions, should you need to figure out
  19. * which to modify or which to leave out.
  20. *
  21. * html_page_top1
  22. * html_begin
  23. * html_head_begin
  24. * html_css
  25. * html_content_type
  26. * html_rss_link
  27. * (html_meta_redirect)
  28. * html_title
  29. * html_page_top2
  30. * html_page_top2a
  31. * html_head_end
  32. * html_body_begin
  33. * html_header
  34. * html_top_banner
  35. * html_login_info
  36. * (print_project_menu_bar)
  37. * print_menu
  38. *
  39. * ...Page content here...
  40. *
  41. * html_page_bottom1
  42. * (print_menu)
  43. * html_page_bottom1a
  44. * html_bottom_banner
  45. * html_footer
  46. * html_body_end
  47. * html_end
  48. *
  49. * @package CoreAPI
  50. * @subpackage HTMLAPI
  51. * @copyright Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org
  52. * @copyright Copyright (C) 2002 - 2011 MantisBT Team - mantisbt-dev@lists.sourceforge.net
  53. * @link http://www.mantisbt.org
  54. * @uses lang_api.php
  55. */
  56. /**
  57. * requires current_user_api
  58. */
  59. require_once( 'current_user_api.php' );
  60. /**
  61. * requires string_api
  62. */
  63. require_once( 'string_api.php' );
  64. /**
  65. * requires bug_api
  66. */
  67. require_once( 'bug_api.php' );
  68. /**
  69. * requires project_api
  70. */
  71. require_once( 'project_api.php' );
  72. /**
  73. * requires helper_api
  74. */
  75. require_once( 'helper_api.php' );
  76. /**
  77. * requires authentication_api
  78. */
  79. require_once( 'authentication_api.php' );
  80. /**
  81. * requires user_api
  82. */
  83. require_once( 'user_api.php' );
  84. /**
  85. * requires rss_api
  86. */
  87. require_once( 'rss_api.php' );
  88. /**
  89. * requires php_api
  90. */
  91. require_once( 'php_api.php' );
  92. $g_rss_feed_url = null;
  93. $g_robots_meta = '';
  94. # flag for error handler to skip header menus
  95. $g_error_send_page_header = true;
  96. # Projax library disabled by default. It will be enabled if projax_api.php
  97. # is included. But it must be included after html_api.php
  98. $g_enable_projax = false;
  99. /**
  100. * Sets the url for the rss link associated with the current page.
  101. * null: means no feed (default).
  102. * @param string $p_rss_feed_url rss feed url
  103. * @return null
  104. */
  105. function html_set_rss_link( $p_rss_feed_url ) {
  106. if( OFF != config_get( 'rss_enabled' ) ) {
  107. global $g_rss_feed_url;
  108. $g_rss_feed_url = $p_rss_feed_url;
  109. }
  110. }
  111. /**
  112. * This method must be called before the html_page_top* methods. It marks the page as not
  113. * for indexing.
  114. * @return null
  115. */
  116. function html_robots_noindex() {
  117. global $g_robots_meta;
  118. $g_robots_meta = 'noindex,follow';
  119. }
  120. /**
  121. * Prints the link that allows auto-detection of the associated feed.
  122. * @return null
  123. */
  124. function html_rss_link() {
  125. global $g_rss_feed_url;
  126. if( $g_rss_feed_url !== null ) {
  127. echo '<link rel="alternate" type="application/rss+xml" title="RSS" href="', $g_rss_feed_url, '" />';
  128. }
  129. }
  130. /**
  131. * Prints a <script> tag to include a javascript file.
  132. * This includes either minimal or development file from /javascript depending on whether mantis is set for debug/production use
  133. * @param string $p_filename
  134. * @return null
  135. */
  136. function html_javascript_link( $p_filename) {
  137. if( config_get_global( 'minimal_jscss' ) ) {
  138. echo '<script type="text/javascript" src="', helper_mantis_url( 'javascript/min/' . $p_filename ), '"></script>' . "\n";
  139. } else {
  140. echo '<script type="text/javascript" src="', helper_mantis_url( 'javascript/dev/' . $p_filename ), '"></script>' . "\n";
  141. }
  142. }
  143. /**
  144. * Defines the top of a HTML page
  145. * @param string $p_page_title html page title
  146. * @param string $p_redirect_url url to redirect to if necessary
  147. * @return null
  148. */
  149. function html_page_top( $p_page_title = null, $p_redirect_url = null ) {
  150. html_page_top1( $p_page_title );
  151. if ( $p_redirect_url !== null ) {
  152. html_meta_redirect( $p_redirect_url );
  153. }
  154. html_page_top2();
  155. }
  156. /**
  157. * Print the part of the page that comes before meta redirect tags should be inserted
  158. * @param string $p_page_title page title
  159. * @return null
  160. */
  161. function html_page_top1( $p_page_title = null ) {
  162. html_begin();
  163. html_head_begin();
  164. html_css();
  165. html_content_type();
  166. include( config_get( 'meta_include_file' ) );
  167. global $g_robots_meta;
  168. if ( !is_blank( $g_robots_meta ) ) {
  169. echo "\t", '<meta name="robots" content="', $g_robots_meta, '" />', "\n";
  170. }
  171. html_rss_link();
  172. $t_favicon_image = config_get( 'favicon_image' );
  173. if( !is_blank( $t_favicon_image ) ) {
  174. echo "\t", '<link rel="shortcut icon" href="', helper_mantis_url( $t_favicon_image ), '" type="image/x-icon" />', "\n";
  175. }
  176. // Advertise the availability of the browser search plug-ins.
  177. echo "\t", '<link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Text Search" href="' . string_sanitize_url( 'browser_search_plugin.php?type=text', true) . '" />';
  178. echo "\t", '<link rel="search" type="application/opensearchdescription+xml" title="MantisBT: Issue Id" href="' . string_sanitize_url( 'browser_search_plugin.php?type=id', true) . '" />';
  179. html_title( $p_page_title );
  180. html_head_javascript();
  181. }
  182. /**
  183. * Print the part of the page that comes after meta tags, but before the actual page content
  184. * @return null
  185. */
  186. function html_page_top2() {
  187. html_page_top2a();
  188. if( !db_is_connected() ) {
  189. return;
  190. }
  191. if( auth_is_user_authenticated() ) {
  192. html_login_info();
  193. if( ON == config_get( 'show_project_menu_bar' ) ) {
  194. print_project_menu_bar();
  195. echo '<br />';
  196. }
  197. }
  198. print_menu();
  199. event_signal( 'EVENT_LAYOUT_CONTENT_BEGIN' );
  200. }
  201. /**
  202. * Print the part of the page that comes after meta tags and before the
  203. * actual page content, but without login info or menus. This is used
  204. * directly during the login process and other times when the user may
  205. * not be authenticated
  206. * @return null
  207. */
  208. function html_page_top2a() {
  209. global $g_error_send_page_header;
  210. html_head_end();
  211. html_body_begin();
  212. $g_error_send_page_header = false;
  213. html_header();
  214. html_top_banner();
  215. }
  216. /**
  217. * Print the part of the page that comes below the page content
  218. * $p_file should always be the __FILE__ variable. This is passed to show source
  219. * @param string $p_file should always be the __FILE__ variable. This is passed to show source
  220. * @return null
  221. */
  222. function html_page_bottom( $p_file = null ) {
  223. html_page_bottom1( $p_file );
  224. }
  225. /**
  226. * Print the part of the page that comes below the page content
  227. * $p_file should always be the __FILE__ variable. This is passed to show source
  228. * @param string $p_file should always be the __FILE__ variable. This is passed to show source
  229. * @return null
  230. */
  231. function html_page_bottom1( $p_file = null ) {
  232. if( !db_is_connected() ) {
  233. return;
  234. }
  235. event_signal( 'EVENT_LAYOUT_CONTENT_END' );
  236. if( config_get( 'show_footer_menu' ) ) {
  237. echo '<br />';
  238. print_menu();
  239. }
  240. html_page_bottom1a( $p_file );
  241. }
  242. /**
  243. * Print the part of the page that comes below the page content but leave off
  244. * the menu. This is used during the login process and other times when the
  245. * user may not be authenticated.
  246. * @param string $p_file should always be the __FILE__ variable.
  247. * @return null
  248. */
  249. function html_page_bottom1a( $p_file = null ) {
  250. if( null === $p_file ) {
  251. $p_file = basename( $_SERVER['SCRIPT_NAME'] );
  252. }
  253. html_bottom_banner();
  254. html_footer();
  255. html_body_end();
  256. html_end();
  257. }
  258. /**
  259. * (1) Print the document type and the opening <html> tag
  260. * @return null
  261. */
  262. function html_begin() {
  263. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', "\n";
  264. echo '<html>', "\n";
  265. }
  266. /**
  267. * (2) Begin the <head> section
  268. * @return null
  269. */
  270. function html_head_begin() {
  271. echo '<head>', "\n";
  272. }
  273. /**
  274. * (3) Print the content-type
  275. * @return null
  276. */
  277. function html_content_type() {
  278. echo "\t", '<meta http-equiv="Content-type" content="text/html; charset=utf-8" />', "\n";
  279. }
  280. /**
  281. * (4) Print the window title
  282. * @param string $p_page_title window title
  283. * @return null
  284. */
  285. function html_title( $p_page_title = null ) {
  286. $t_page_title = string_html_specialchars( $p_page_title );
  287. $t_title = string_html_specialchars( config_get( 'window_title' ) );
  288. echo "\t", '<title>';
  289. if( empty( $t_page_title ) ) {
  290. echo $t_title;
  291. } else {
  292. if( empty( $t_title ) ) {
  293. echo $t_page_title;
  294. } else {
  295. echo $t_page_title . ' - ' . $t_title;
  296. }
  297. }
  298. echo '</title>', "\n";
  299. }
  300. /**
  301. * (5) Print the link to include the css file
  302. * @return null
  303. */
  304. function html_css() {
  305. $t_css_url = config_get( 'css_include_file' );
  306. echo "\t", '<link rel="stylesheet" type="text/css" href="', string_sanitize_url( helper_mantis_url( $t_css_url ), true ), '" />', "\n";
  307. # Add right-to-left css if needed
  308. if( lang_get( 'directionality' ) == 'rtl' ) {
  309. $t_css_rtl_url = config_get( 'css_rtl_include_file' );
  310. echo "\t", '<link rel="stylesheet" type="text/css" href="', string_sanitize_url( helper_mantis_url( $t_css_rtl_url ), true ), '" />', "\n";
  311. }
  312. # fix for NS 4.x css
  313. echo "\t", '<script type="text/javascript"><!--', "\n";
  314. echo "\t\t", 'if(document.layers) {document.write("<style>td{padding:0px;}<\/style>")}', "\n";
  315. echo "\t", '// --></script>', "\n";
  316. }
  317. /**
  318. * (6) Print an HTML meta tag to redirect to another page
  319. * This function is optional and may be called by pages that need a redirect.
  320. * $p_time is the number of seconds to wait before redirecting.
  321. * If we have handled any errors on this page and the 'stop_on_errors' config
  322. * option is turned on, return false and don't redirect.
  323. *
  324. * @param string $p_url The page to redirect: has to be a relative path
  325. * @param integer $p_time seconds to wait for before redirecting
  326. * @param boolean $p_sanitize apply string_sanitize_url to passed url
  327. * @return boolean
  328. */
  329. function html_meta_redirect( $p_url, $p_time = null, $p_sanitize = true ) {
  330. if( ON == config_get_global( 'stop_on_errors' ) && error_handled() ) {
  331. return false;
  332. }
  333. if( null === $p_time ) {
  334. $p_time = current_user_get_pref( 'redirect_delay' );
  335. }
  336. $t_url = config_get( 'path' );
  337. if( $p_sanitize ) {
  338. $t_url .= string_sanitize_url( $p_url );
  339. } else {
  340. $t_url .= $p_url;
  341. }
  342. $t_url = htmlspecialchars( $t_url );
  343. echo "\t<meta http-equiv=\"Refresh\" content=\"$p_time;URL=$t_url\" />\n";
  344. return true;
  345. }
  346. /**
  347. * (6a) Javascript...
  348. * @return null
  349. */
  350. function html_head_javascript() {
  351. if( ON == config_get( 'use_javascript' ) ) {
  352. html_javascript_link( 'common.js' );
  353. echo '<script type="text/javascript">var loading_lang = "' . lang_get( 'loading' ) . '";</script>';
  354. html_javascript_link( 'ajax.js' );
  355. global $g_enable_projax;
  356. if( $g_enable_projax ) {
  357. html_javascript_link( 'projax/prototype.js' );
  358. html_javascript_link( 'projax/scriptaculous.js' );
  359. }
  360. }
  361. }
  362. /**
  363. * (7) End the <head> section
  364. * @return null
  365. */
  366. function html_head_end() {
  367. event_signal( 'EVENT_LAYOUT_RESOURCES' );
  368. echo '</head>', "\n";
  369. }
  370. /**
  371. * (8) Begin the <body> section
  372. * @return null
  373. */
  374. function html_body_begin() {
  375. echo '<body>', "\n";
  376. event_signal( 'EVENT_LAYOUT_BODY_BEGIN' );
  377. }
  378. /**
  379. * (9) Print the title displayed at the top of the page
  380. * @return null
  381. */
  382. function html_header() {
  383. $t_title = config_get( 'page_title' );
  384. if( !is_blank( $t_title ) ) {
  385. echo '<div class="center"><span class="pagetitle">', string_display( $t_title ), '</span></div>', "\n";
  386. }
  387. }
  388. /**
  389. * (10) Print a user-defined banner at the top of the page if there is one.
  390. * @return null
  391. */
  392. function html_top_banner() {
  393. $t_page = config_get( 'top_include_page' );
  394. $t_logo_image = config_get( 'logo_image' );
  395. $t_logo_url = config_get( 'logo_url' );
  396. if( is_blank( $t_logo_image ) ) {
  397. $t_show_logo = false;
  398. } else {
  399. $t_show_logo = true;
  400. if( is_blank( $t_logo_url ) ) {
  401. $t_show_url = false;
  402. } else {
  403. $t_show_url = true;
  404. }
  405. }
  406. if( !is_blank( $t_page ) && file_exists( $t_page ) && !is_dir( $t_page ) ) {
  407. include( $t_page );
  408. } else if( $t_show_logo ) {
  409. if( is_page_name( 'login_page' ) ) {
  410. $t_align = 'center';
  411. } else {
  412. $t_align = 'left';
  413. }
  414. echo '<div align="', $t_align, '">';
  415. if( $t_show_url ) {
  416. echo '<a href="', config_get( 'logo_url' ), '">';
  417. }
  418. echo '<img border="0" alt="Mantis Bug Tracker" src="' . helper_mantis_url( config_get( 'logo_image' ) ) . '" />';
  419. if( $t_show_url ) {
  420. echo '</a>';
  421. }
  422. echo '</div>';
  423. }
  424. event_signal( 'EVENT_LAYOUT_PAGE_HEADER' );
  425. }
  426. /**
  427. * (11) Print the user's account information
  428. * Also print the select box where users can switch projects
  429. * @return null
  430. */
  431. function html_login_info() {
  432. $t_username = current_user_get_field( 'username' );
  433. $t_access_level = get_enum_element( 'access_levels', current_user_get_access_level() );
  434. $t_now = date( config_get( 'complete_date_format' ) );
  435. $t_realname = current_user_get_field( 'realname' );
  436. echo '<table class="hide">';
  437. echo '<tr>';
  438. echo '<td class="login-info-left">';
  439. if( current_user_is_anonymous() ) {
  440. $t_return_page = $_SERVER['SCRIPT_NAME'];
  441. if( isset( $_SERVER['QUERY_STRING'] ) ) {
  442. $t_return_page .= '?' . $_SERVER['QUERY_STRING'];
  443. }
  444. $t_return_page = string_url( $t_return_page );
  445. echo lang_get( 'anonymous' ) . ' | <a href="' . helper_mantis_url( 'login_page.php?return=' . $t_return_page ) . '">' . lang_get( 'login_link' ) . '</a>';
  446. if( config_get_global( 'allow_signup' ) == ON ) {
  447. echo ' | <a href="' . helper_mantis_url( 'signup_page.php' ) . '">' . lang_get( 'signup_link' ) . '</a>';
  448. }
  449. } else {
  450. echo lang_get( 'logged_in_as' ), ": <span class=\"italic\">", string_html_specialchars( $t_username ), "</span> <span class=\"small\">";
  451. echo is_blank( $t_realname ) ? "($t_access_level)" : "(" . string_html_specialchars( $t_realname ) . " - $t_access_level)";
  452. echo "</span>";
  453. }
  454. echo '</td>';
  455. echo '<td class="login-info-middle">';
  456. echo "<span class=\"italic\">$t_now</span>";
  457. echo '</td>';
  458. echo '<td class="login-info-right">';
  459. $t_show_project_selector = true;
  460. if( count( current_user_get_accessible_projects() ) == 1 ) {
  461. // >1
  462. $t_project_ids = current_user_get_accessible_projects();
  463. $t_project_id = (int) $t_project_ids[0];
  464. if( count( current_user_get_accessible_subprojects( $t_project_id ) ) == 0 ) {
  465. $t_show_project_selector = false;
  466. }
  467. }
  468. if( $t_show_project_selector ) {
  469. echo '<form method="post" name="form_set_project" action="' . helper_mantis_url( 'set_project.php' ) . '">';
  470. # CSRF protection not required here - form does not result in modifications
  471. echo lang_get( 'email_project' ), ': ';
  472. if( ON == config_get( 'show_extended_project_browser' ) ) {
  473. print_extended_project_browser( helper_get_current_project_trace() );
  474. } else {
  475. if( ON == config_get( 'use_javascript' ) ) {
  476. echo '<select name="project_id" class="small" onchange="document.forms.form_set_project.submit();">';
  477. } else {
  478. echo '<select name="project_id" class="small">';
  479. }
  480. print_project_option_list( join( ';', helper_get_current_project_trace() ), true, null, true );
  481. echo '</select> ';
  482. }
  483. echo '<input type="submit" class="button-small" value="' . lang_get( 'switch' ) . '" />';
  484. echo '</form>';
  485. }
  486. if( OFF != config_get( 'rss_enabled' ) ) {
  487. # Link to RSS issues feed for the selected project, including authentication details.
  488. echo '<a href="' . htmlspecialchars( rss_get_issues_feed_url() ) . '">';
  489. echo '<img src="' . helper_mantis_url( 'images/rss.png' ) . '" alt="' . lang_get( 'rss' ) . '" style="border-style: none; margin: 5px; vertical-align: middle;" />';
  490. echo '</a>';
  491. }
  492. echo '</td>';
  493. echo '</tr>';
  494. echo '</table>';
  495. }
  496. /**
  497. * (12) Print a user-defined banner at the bottom of the page if there is one.
  498. * @return null
  499. */
  500. function html_bottom_banner() {
  501. $t_page = config_get( 'bottom_include_page' );
  502. if( !is_blank( $t_page ) && file_exists( $t_page ) && !is_dir( $t_page ) ) {
  503. include( $t_page );
  504. }
  505. }
  506. /**
  507. * (13) Print the page footer information
  508. * @param string $p_file
  509. * @return null
  510. */
  511. function html_footer( $p_file = null ) {
  512. global $g_queries_array, $g_request_time;
  513. # If a user is logged in, update their last visit time.
  514. # We do this at the end of the page so that:
  515. # 1) we can display the user's last visit time on a page before updating it
  516. # 2) we don't invalidate the user cache immediately after fetching it
  517. # 3) don't do this on the password verification or update page, as it causes the
  518. # verification comparison to fail
  519. if ( auth_is_user_authenticated() && !current_user_is_anonymous() && !( is_page_name( 'verify.php' ) || is_page_name( 'account_update.php' ) ) ) {
  520. $t_user_id = auth_get_current_user_id();
  521. user_update_last_visit( $t_user_id );
  522. }
  523. echo "\t", '<br />', "\n";
  524. echo "\t", '<hr size="1" />', "\n";
  525. echo '<table border="0" width="100%" cellspacing="0" cellpadding="0"><tr valign="top"><td>';
  526. if( ON == config_get( 'show_version' ) ) {
  527. $t_version_suffix = config_get_global( 'version_suffix' );
  528. echo "\t", '<span class="timer"><a href="http://www.mantisbt.org/" title="Free Web Based Bug Tracker">MantisBT ', MANTIS_VERSION, ( $t_version_suffix ? " $t_version_suffix" : '' ), '</a>', '[<a href="http://www.mantisbt.org/" title="Free Web Based Bug Tracker" target="_blank">^</a>]</span>', "\n";
  529. }
  530. echo "\t", '<address>Copyright &copy; 2000 - 2011 MantisBT Group</address>', "\n";
  531. # only display webmaster email is current user is not the anonymous user
  532. if( !is_page_name( 'login_page.php' ) && auth_is_user_authenticated() && !current_user_is_anonymous() ) {
  533. echo "\t", '<address><a href="mailto:', config_get( 'webmaster_email' ), '">', config_get( 'webmaster_email' ), '</a></address>', "\n";
  534. }
  535. event_signal( 'EVENT_LAYOUT_PAGE_FOOTER' );
  536. # print timings
  537. if( ON == config_get( 'show_timer' ) ) {
  538. echo '<span class="italic">Time: ' . number_format( microtime(true) - $g_request_time, 4 ) . ' seconds.</span><br />';
  539. echo sprintf( lang_get( 'memory_usage_in_kb' ), number_format( memory_get_peak_usage() / 1024 ) ), '<br />';
  540. }
  541. # print db queries that were run
  542. if( helper_show_queries() ) {
  543. $t_count = count( $g_queries_array );
  544. echo "\t";
  545. echo sprintf( lang_get( 'total_queries_executed' ), $t_count );
  546. echo "<br />\n";
  547. if( ON == config_get( 'show_queries_list' ) ) {
  548. $t_unique_queries = 0;
  549. $t_shown_queries = array();
  550. for( $i = 0;$i < $t_count;$i++ ) {
  551. if( !in_array( $g_queries_array[$i][0], $t_shown_queries ) ) {
  552. $t_unique_queries++;
  553. $g_queries_array[$i][3] = false;
  554. array_push( $t_shown_queries, $g_queries_array[$i][0] );
  555. } else {
  556. $g_queries_array[$i][3] = true;
  557. }
  558. }
  559. echo "\t";
  560. echo sprintf( lang_get( 'unique_queries_executed' ), $t_unique_queries );
  561. echo "\t", '<table>', "\n";
  562. $t_total = 0;
  563. for( $i = 0;$i < $t_count;$i++ ) {
  564. $t_time = $g_queries_array[$i][1];
  565. $t_caller = $g_queries_array[$i][2];
  566. $t_total += $t_time;
  567. $t_style_tag = '';
  568. if( true == $g_queries_array[$i][3] ) {
  569. $t_style_tag = ' style="color: red;"';
  570. }
  571. echo "\t", '<tr valign="top"><td', $t_style_tag, '>', ( $i + 1 ), '</td>';
  572. echo '<td', $t_style_tag, '>', $t_time, '</td>';
  573. echo '<td', $t_style_tag, '><span style="color: gray;">', $t_caller, '</span><br />', string_html_specialchars( $g_queries_array[$i][0] ), '</td></tr>', "\n";
  574. }
  575. # @@@ Note sure if we should localize them given that they are debug info. Will add if requested by users.
  576. echo "\t", '<tr><td></td><td>', $t_total, '</td><td>SQL Queries Total Time</td></tr>', "\n";
  577. echo "\t", '<tr><td></td><td>', round( microtime(true) - $g_request_time, 4 ), '</td><td>Page Request Total Time</td></tr>', "\n";
  578. echo "\t", '</table>', "\n";
  579. }
  580. }
  581. echo '</td><td>', "\n\t", '<div align="right">';
  582. echo '<a href="http://www.mantisbt.org" title="Free Web Based Bug Tracker"><img src="' . helper_mantis_url( 'images/mantis_logo_button.gif' ) . '" width="88" height="35" alt="Powered by Mantis Bugtracker" border="0" /></a>';
  583. echo '</div>', "\n", '</td></tr></table>', "\n";
  584. }
  585. /**
  586. * (14) End the <body> section
  587. * @return null
  588. */
  589. function html_body_end() {
  590. event_signal( 'EVENT_LAYOUT_BODY_END' );
  591. echo '</body>', "\n";
  592. }
  593. /**
  594. * (15) Print the closing <html> tag
  595. * @return null
  596. */
  597. function html_end() {
  598. echo '</html>', "\n";
  599. }
  600. /**
  601. * Prepare an array of additional menu options from a config variable
  602. * @param string $p_config config name
  603. * @return array
  604. */
  605. function prepare_custom_menu_options( $p_config ) {
  606. $t_custom_menu_options = config_get( $p_config );
  607. $t_options = array();
  608. foreach( $t_custom_menu_options as $t_custom_option ) {
  609. $t_access_level = $t_custom_option[1];
  610. if( access_has_project_level( $t_access_level ) ) {
  611. $t_caption = string_html_specialchars( lang_get_defaulted( $t_custom_option[0] ) );
  612. $t_link = string_attribute( $t_custom_option[2] );
  613. $t_options[] = "<a href=\"$t_link\">$t_caption</a>";
  614. }
  615. }
  616. return $t_options;
  617. }
  618. /**
  619. * Print the main menu
  620. * @return null
  621. */
  622. function print_menu() {
  623. if( auth_is_user_authenticated() ) {
  624. $t_protected = current_user_get_field( 'protected' );
  625. $t_current_project = helper_get_current_project();
  626. echo '<table class="width100" cellspacing="0">';
  627. echo '<tr>';
  628. echo '<td class="menu">';
  629. $t_menu_options = array();
  630. # Main Page
  631. $t_menu_options[] = '<a href="' . helper_mantis_url( 'main_page.php' ) . '">' . lang_get( 'main_link' ) . '</a>';
  632. # Plugin / Event added options
  633. $t_event_menu_options = event_signal( 'EVENT_MENU_MAIN_FRONT' );
  634. foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  635. foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  636. if( is_array( $t_callback_menu_options ) ) {
  637. $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  638. } else {
  639. if ( !is_null( $t_callback_menu_options ) ) {
  640. $t_menu_options[] = $t_callback_menu_options;
  641. }
  642. }
  643. }
  644. }
  645. # My View
  646. $t_menu_options[] = '<a href="' . helper_mantis_url( 'my_view_page.php">' ) . lang_get( 'my_view_link' ) . '</a>';
  647. # View Bugs
  648. $t_menu_options[] = '<a href="' . helper_mantis_url( 'view_all_bug_page.php">' ) . lang_get( 'view_bugs_link' ) . '</a>';
  649. # Report Bugs
  650. if( access_has_project_level( config_get( 'report_bug_threshold' ) ) ) {
  651. $t_menu_options[] = string_get_bug_report_link();
  652. }
  653. # Changelog Page
  654. if( access_has_project_level( config_get( 'view_changelog_threshold' ) ) ) {
  655. $t_menu_options[] = '<a href="' . helper_mantis_url( 'changelog_page.php">' ) . lang_get( 'changelog_link' ) . '</a>';
  656. }
  657. # Roadmap Page
  658. if( access_has_project_level( config_get( 'roadmap_view_threshold' ) ) ) {
  659. $t_menu_options[] = '<a href="' . helper_mantis_url( 'roadmap_page.php">' ) . lang_get( 'roadmap_link' ) . '</a>';
  660. }
  661. # Summary Page
  662. if( access_has_project_level( config_get( 'view_summary_threshold' ) ) ) {
  663. $t_menu_options[] = '<a href="' . helper_mantis_url( 'summary_page.php">' ) . lang_get( 'summary_link' ) . '</a>';
  664. }
  665. # Project Documentation Page
  666. if( ON == config_get( 'enable_project_documentation' ) ) {
  667. $t_menu_options[] = '<a href="' . helper_mantis_url( 'proj_doc_page.php">' ) . lang_get( 'docs_link' ) . '</a>';
  668. }
  669. # Project Wiki
  670. if( config_get_global( 'wiki_enable' ) == ON ) {
  671. $t_menu_options[] = '<a href="' . helper_mantis_url( 'wiki.php?type=project&amp;id=' ) . $t_current_project . '">' . lang_get( 'wiki' ) . '</a>';
  672. }
  673. # Plugin / Event added options
  674. $t_event_menu_options = event_signal( 'EVENT_MENU_MAIN' );
  675. foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  676. foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  677. if( is_array( $t_callback_menu_options ) ) {
  678. $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  679. } else {
  680. if ( !is_null( $t_callback_menu_options ) ) {
  681. $t_menu_options[] = $t_callback_menu_options;
  682. }
  683. }
  684. }
  685. }
  686. # Manage Users (admins) or Manage Project (managers) or Manage Custom Fields
  687. if( access_has_global_level( config_get( 'manage_site_threshold' ) ) ) {
  688. $t_link = helper_mantis_url( 'manage_overview_page.php' );
  689. $t_menu_options[] = "<a href=\"$t_link\">" . lang_get( 'manage_link' ) . '</a>';
  690. } else {
  691. $t_show_access = min( config_get( 'manage_user_threshold' ), config_get( 'manage_project_threshold' ), config_get( 'manage_custom_fields_threshold' ) );
  692. if( access_has_global_level( $t_show_access ) || access_has_any_project( $t_show_access ) ) {
  693. $t_current_project = helper_get_current_project();
  694. if( access_has_global_level( config_get( 'manage_user_threshold' ) ) ) {
  695. $t_link = helper_mantis_url( 'manage_user_page.php' );
  696. } else {
  697. if( access_has_project_level( config_get( 'manage_project_threshold' ), $t_current_project ) && ( $t_current_project <> ALL_PROJECTS ) ) {
  698. $t_link = helper_mantis_url( 'manage_proj_edit_page.php?project_id=' ) . $t_current_project;
  699. } else {
  700. $t_link = helper_mantis_url( 'manage_proj_page.php' );
  701. }
  702. }
  703. $t_menu_options[] = "<a href=\"$t_link\">" . lang_get( 'manage_link' ) . '</a>';
  704. }
  705. }
  706. # News Page
  707. if ( news_is_enabled() && access_has_project_level( config_get( 'manage_news_threshold' ) ) ) {
  708. # Admin can edit news for All Projects (site-wide)
  709. if( ALL_PROJECTS != helper_get_current_project() || current_user_is_administrator() ) {
  710. $t_menu_options[] = '<a href="' . helper_mantis_url( 'news_menu_page.php">' ) . lang_get( 'edit_news_link' ) . '</a>';
  711. } else {
  712. $t_menu_options[] = '<a href="' . helper_mantis_url( 'login_select_proj_page.php">' ) . lang_get( 'edit_news_link' ) . '</a>';
  713. }
  714. }
  715. # Account Page (only show accounts that are NOT protected)
  716. if( OFF == $t_protected ) {
  717. $t_menu_options[] = '<a href="' . helper_mantis_url( 'account_page.php">' ) . lang_get( 'account_link' ) . '</a>';
  718. }
  719. # Add custom options
  720. $t_custom_options = prepare_custom_menu_options( 'main_menu_custom_options' );
  721. $t_menu_options = array_merge( $t_menu_options, $t_custom_options );
  722. # Time Tracking / Billing
  723. if( config_get( 'time_tracking_enabled' ) && access_has_global_level( config_get( 'time_tracking_reporting_threshold' ) ) ) {
  724. $t_menu_options[] = '<a href="' . helper_mantis_url( 'billing_page.php">' ) . lang_get( 'time_tracking_billing_link' ) . '</a>';
  725. }
  726. # Logout (no if anonymously logged in)
  727. if( !current_user_is_anonymous() ) {
  728. $t_menu_options[] = '<a href="' . helper_mantis_url( 'logout_page.php">' ) . lang_get( 'logout_link' ) . '</a>';
  729. }
  730. echo implode( $t_menu_options, ' | ' );
  731. echo '</td>';
  732. echo '<td class="menu right nowrap">';
  733. echo '<form method="post" action="' . helper_mantis_url( 'jump_to_bug.php">' );
  734. # CSRF protection not required here - form does not result in modifications
  735. if( ON == config_get( 'use_javascript' ) ) {
  736. $t_bug_label = lang_get( 'issue_id' );
  737. echo "<input type=\"text\" name=\"bug_id\" size=\"10\" class=\"small\" value=\"$t_bug_label\" onfocus=\"if (this.value == '$t_bug_label') this.value = ''\" onblur=\"if (this.value == '') this.value = '$t_bug_label'\" />&#160;";
  738. } else {
  739. echo "<input type=\"text\" name=\"bug_id\" size=\"10\" class=\"small\" />&#160;";
  740. }
  741. echo '<input type="submit" class="button-small" value="' . lang_get( 'jump' ) . '" />&#160;';
  742. echo '</form>';
  743. echo '</td>';
  744. echo '</tr>';
  745. echo '</table>';
  746. }
  747. }
  748. /**
  749. * Print the menu bar with a list of projects to which the user has access
  750. * @return null
  751. */
  752. function print_project_menu_bar() {
  753. $t_project_ids = current_user_get_accessible_projects();
  754. echo '<table class="width100" cellspacing="0">';
  755. echo '<tr>';
  756. echo '<td class="menu">';
  757. echo '<a href="' . helper_mantis_url( 'set_project.php?project_id=' . ALL_PROJECTS ) . '">' . lang_get( 'all_projects' ) . '</a>';
  758. foreach( $t_project_ids as $t_id ) {
  759. echo ' | <a href="' . helper_mantis_url( 'set_project.php?project_id=' . $t_id ) . '">' . string_html_specialchars( project_get_field( $t_id, 'name' ) ) . '</a>';
  760. print_subproject_menu_bar( $t_id, $t_id . ';' );
  761. }
  762. echo '</td>';
  763. echo '</tr>';
  764. echo '</table>';
  765. }
  766. /**
  767. * Print the menu bar with a list of projects to which the user has access
  768. * @return null
  769. */
  770. function print_subproject_menu_bar( $p_project_id, $p_parents = '' ) {
  771. $t_subprojects = current_user_get_accessible_subprojects( $p_project_id );
  772. $t_char = ':';
  773. foreach( $t_subprojects as $t_subproject ) {
  774. 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>';
  775. print_subproject_menu_bar( $t_subproject, $p_parents . $t_subproject . ';' );
  776. $t_char = ',';
  777. }
  778. }
  779. /**
  780. * Print the menu for the graph summary section
  781. * @return null
  782. */
  783. function print_summary_submenu() {
  784. echo '<div align="center">';
  785. # Plugin / Event added options
  786. $t_event_menu_options = event_signal( 'EVENT_SUBMENU_SUMMARY' );
  787. $t_menu_options = array();
  788. foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  789. foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  790. if( is_array( $t_callback_menu_options ) ) {
  791. $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  792. } else {
  793. if ( !is_null( $t_callback_menu_options ) ) {
  794. $t_menu_options[] = $t_callback_menu_options;
  795. }
  796. }
  797. }
  798. }
  799. // Plugins menu items
  800. // TODO: this would be a call to print_pracket_link but the events returns cooked links so we cant
  801. foreach( $t_menu_options as $t_menu_item ) {
  802. echo '<span class="bracket-link">[&#160;';
  803. echo $t_menu_item;
  804. echo '&#160;]</span> ';
  805. }
  806. echo '</div>';
  807. }
  808. /**
  809. * Print the menu for the manage section
  810. *
  811. * @param string $p_page specifies the current page name so it's link can be disabled
  812. * @return null
  813. */
  814. function print_manage_menu( $p_page = '' ) {
  815. $t_manage_user_page = 'manage_user_page.php';
  816. $t_manage_project_menu_page = 'manage_proj_page.php';
  817. $t_manage_custom_field_page = 'manage_custom_field_page.php';
  818. $t_manage_plugin_page = 'manage_plugin_page.php';
  819. $t_manage_config_page = 'adm_config_report.php';
  820. $t_manage_prof_menu_page = 'manage_prof_menu_page.php';
  821. $t_manage_tags_page = 'manage_tags_page.php';
  822. switch( $p_page ) {
  823. case $t_manage_user_page:
  824. $t_manage_user_page = '';
  825. break;
  826. case $t_manage_project_menu_page:
  827. $t_manage_project_menu_page = '';
  828. break;
  829. case $t_manage_custom_field_page:
  830. $t_manage_custom_field_page = '';
  831. break;
  832. case $t_manage_config_page:
  833. $t_manage_config_page = '';
  834. break;
  835. case $t_manage_plugin_page:
  836. $t_manage_plugin_page = '';
  837. break;
  838. case $t_manage_prof_menu_page:
  839. $t_manage_prof_menu_page = '';
  840. break;
  841. case $t_manage_tags_page:
  842. $t_manage_tags_page = '';
  843. break;
  844. }
  845. echo '<div align="center"><p>';
  846. if( access_has_global_level( config_get( 'manage_user_threshold' ) ) ) {
  847. print_bracket_link( helper_mantis_url( $t_manage_user_page ), lang_get( 'manage_users_link' ) );
  848. }
  849. if( access_has_project_level( config_get( 'manage_project_threshold' ) ) ) {
  850. print_bracket_link( helper_mantis_url( $t_manage_project_menu_page ), lang_get( 'manage_projects_link' ) );
  851. }
  852. if( access_has_global_level( config_get( 'tag_edit_threshold' ) ) ) {
  853. print_bracket_link( helper_mantis_url( $t_manage_tags_page ), lang_get( 'manage_tags_link' ) );
  854. }
  855. if( access_has_global_level( config_get( 'manage_custom_fields_threshold' ) ) ) {
  856. print_bracket_link( helper_mantis_url( $t_manage_custom_field_page ), lang_get( 'manage_custom_field_link' ) );
  857. }
  858. if( access_has_global_level( config_get( 'manage_global_profile_threshold' ) ) ) {
  859. print_bracket_link( helper_mantis_url( $t_manage_prof_menu_page ), lang_get( 'manage_global_profiles_link' ) );
  860. }
  861. if( access_has_global_level( config_get( 'manage_plugin_threshold' ) ) ) {
  862. print_bracket_link( helper_mantis_url( $t_manage_plugin_page ), lang_get( 'manage_plugin_link' ) );
  863. }
  864. if( access_has_project_level( config_get( 'view_configuration_threshold' ) ) ) {
  865. print_bracket_link( helper_mantis_url( $t_manage_config_page ), lang_get( 'manage_config_link' ) );
  866. }
  867. # Plugin / Event added options
  868. $t_event_menu_options = event_signal( 'EVENT_MENU_MANAGE' );
  869. $t_menu_options = array();
  870. foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  871. foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  872. if( is_array( $t_callback_menu_options ) ) {
  873. $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  874. } else {
  875. if ( !is_null( $t_callback_menu_options ) ) {
  876. $t_menu_options[] = $t_callback_menu_options;
  877. }
  878. }
  879. }
  880. }
  881. // Plugins menu items
  882. foreach( $t_menu_options as $t_menu_item ) {
  883. print_bracket_link_prepared( $t_menu_item );
  884. }
  885. echo '</p></div>';
  886. }
  887. /**
  888. * Print the menu for the manage configuration section
  889. * @param string $p_page specifies the current page name so it's link can be disabled
  890. * @return null
  891. */
  892. function print_manage_config_menu( $p_page = '' ) {
  893. $t_configuration_report = 'adm_config_report.php';
  894. $t_permissions_summary_report = 'adm_permissions_report.php';
  895. $t_manage_work_threshold = 'manage_config_work_threshold_page.php';
  896. $t_manage_email = 'manage_config_email_page.php';
  897. $t_manage_workflow = 'manage_config_workflow_page.php';
  898. $t_manage_columns = 'manage_config_columns_page.php';
  899. switch( $p_page ) {
  900. case $t_configuration_report:
  901. $t_configuration_report = '';
  902. break;
  903. case $t_permissions_summary_report:
  904. $t_permissions_summary_report = '';
  905. break;
  906. case $t_manage_work_threshold:
  907. $t_manage_work_threshold = '';
  908. break;
  909. case $t_manage_email:
  910. $t_manage_email = '';
  911. break;
  912. case $t_manage_workflow:
  913. $t_manage_workflow = '';
  914. break;
  915. case $t_manage_columns:
  916. $t_manage_columns = '';
  917. break;
  918. }
  919. echo '<br /><div align="center">';
  920. if( access_has_project_level( config_get( 'view_configuration_threshold' ) ) ) {
  921. print_bracket_link( helper_mantis_url( $t_configuration_report ), lang_get_defaulted( 'configuration_report' ) );
  922. print_bracket_link( helper_mantis_url( $t_permissions_summary_report ), lang_get( 'permissions_summary_report' ) );
  923. print_bracket_link( helper_mantis_url( $t_manage_work_threshold ), lang_get( 'manage_threshold_config' ) );
  924. print_bracket_link( helper_mantis_url( $t_manage_workflow ), lang_get( 'manage_workflow_config' ) );
  925. print_bracket_link( helper_mantis_url( $t_manage_email ), lang_get( 'manage_email_config' ) );
  926. print_bracket_link( $t_manage_columns, lang_get( 'manage_columns_config' ) );
  927. }
  928. # Plugin / Event added options
  929. $t_event_menu_options = event_signal( 'EVENT_MENU_MANAGE_CONFIG' );
  930. $t_menu_options = array();
  931. foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  932. foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  933. if( is_array( $t_callback_menu_options ) ) {
  934. $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  935. } else {
  936. if ( !is_null( $t_callback_menu_options ) ) {
  937. $t_menu_options[] = $t_callback_menu_options;
  938. }
  939. }
  940. }
  941. }
  942. // Plugins menu items
  943. foreach( $t_menu_options as $t_menu_item ) {
  944. print_bracket_link_prepared( $t_menu_item );
  945. }
  946. echo '</div>';
  947. }
  948. /**
  949. * Print the menu for the account section
  950. * @param string $p_page specifies the current page name so it's link can be disabled
  951. * @return null
  952. */
  953. function print_account_menu( $p_page = '' ) {
  954. $t_account_page = 'account_page.php';
  955. $t_account_prefs_page = 'account_prefs_page.php';
  956. $t_account_profile_menu_page = 'account_prof_menu_page.php';
  957. $t_account_sponsor_page = 'account_sponsor_page.php';
  958. $t_account_manage_columns_page = 'account_manage_columns_page.php';
  959. switch( $p_page ) {
  960. case $t_account_page:
  961. $t_account_page = '';
  962. break;
  963. case $t_account_prefs_page:
  964. $t_account_prefs_page = '';
  965. break;
  966. case $t_account_profile_menu_page:
  967. $t_account_profile_menu_page = '';
  968. break;
  969. case $t_account_sponsor_page:
  970. $t_account_sponsor_page = '';
  971. break;
  972. case $t_account_manage_columns_page:
  973. $t_account_manage_columns_page = '';
  974. break;
  975. }
  976. print_bracket_link( $t_account_page, lang_get( 'account_link' ) );
  977. print_bracket_link( $t_account_prefs_page, lang_get( 'change_preferences_link' ) );
  978. print_bracket_link( $t_account_manage_columns_page, lang_get( 'manage_columns_config' ) );
  979. if( config_get ( 'enable_profiles' ) == ON && access_has_project_level( config_get( 'add_profile_threshold' ) ) ) {
  980. print_bracket_link( helper_mantis_url( $t_account_profile_menu_page ), lang_get( 'manage_profiles_link' ) );
  981. }
  982. if( config_get( 'enable_sponsorship' ) == ON && access_has_project_level( config_get( 'view_sponsorship_total_threshold' ) ) && !current_user_is_anonymous() ) {
  983. print_bracket_link( helper_mantis_url( $t_account_sponsor_page ), lang_get( 'my_sponsorship' ) );
  984. }
  985. # Plugin / Event added options
  986. $t_event_menu_options = event_signal( 'EVENT_MENU_ACCOUNT' );
  987. $t_menu_options = array();
  988. foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  989. foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  990. if( is_array( $t_callback_menu_options ) ) {
  991. $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  992. } else {
  993. if ( !is_null( $t_callback_menu_options ) ) {
  994. $t_menu_options[] = $t_callback_menu_options;
  995. }
  996. }
  997. }
  998. }
  999. // Plugins menu items
  1000. // TODO: this would be a call to print_pracket_link but the events returns cooked links so we cant
  1001. foreach( $t_menu_options as $t_menu_item ) {
  1002. echo '<span class="bracket-link">[&#160;';
  1003. echo $t_menu_item;
  1004. echo '&#160;]</span> ';
  1005. }
  1006. }
  1007. /**
  1008. * Print the menu for the docs section
  1009. * @param string $p_page specifies the current page name so it's link can be disabled
  1010. * @return null
  1011. */
  1012. function print_doc_menu( $p_page = '' ) {
  1013. $t_documentation_html = config_get( 'manual_url' );
  1014. $t_proj_doc_page = 'proj_doc_page.php';
  1015. $t_proj_doc_add_page = 'proj_doc_add_page.php';
  1016. switch( $p_page ) {
  1017. case $t_documentation_html:
  1018. $t_documentation_html = '';
  1019. break;
  1020. case $t_proj_doc_page:
  1021. $t_proj_doc_page = '';
  1022. break;
  1023. case $t_proj_doc_add_page:
  1024. $t_proj_doc_add_page = '';
  1025. break;
  1026. }
  1027. print_bracket_link( $t_documentation_html, lang_get( 'user_documentation' ) );
  1028. print_bracket_link( helper_mantis_url( $t_proj_doc_page ), lang_get( 'project_documentation' ) );
  1029. if( file_allow_project_upload() ) {
  1030. print_bracket_link( helper_mantis_url( $t_proj_doc_add_page ), lang_get( 'add_file' ) );
  1031. }
  1032. }
  1033. /**
  1034. * Print the menu for the summary section
  1035. * @param string $p_page specifies the current page name so it's link can be disabled
  1036. * @return null
  1037. */
  1038. function print_summary_menu( $p_page = '' ) {
  1039. echo '<div align="center">';
  1040. print_bracket_link( 'print_all_bug_page.php', lang_get( 'print_all_bug_page_link' ) );
  1041. print_bracket_link( helper_mantis_url( 'summary_page.php' ), lang_get( 'summary_link' ) );
  1042. # Plugin / Event added options
  1043. $t_event_menu_options = event_signal( 'EVENT_MENU_SUMMARY' );
  1044. $t_menu_options = array();
  1045. foreach( $t_event_menu_options as $t_plugin => $t_plugin_menu_options ) {
  1046. foreach( $t_plugin_menu_options as $t_callback => $t_callback_menu_options ) {
  1047. if( is_array( $t_callback_menu_options ) ) {
  1048. $t_menu_options = array_merge( $t_menu_options, $t_callback_menu_options );
  1049. } else {
  1050. if ( !is_null( $t_callback_menu_options ) ) {
  1051. $t_menu_options[] = $t_callback_menu_options;
  1052. }
  1053. }
  1054. }
  1055. }
  1056. // Plugins menu items
  1057. // TODO: this would be a call to print_pracket_link but the events returns cooked links so we cant
  1058. foreach( $t_menu_options as $t_menu_item ) {
  1059. echo '<span class="bracket-link">[&#160;';
  1060. echo $t_menu_item;
  1061. echo '&#160;]</span> ';
  1062. }
  1063. echo '</div>';
  1064. }
  1065. /**
  1066. * Print the color legend for the status colors
  1067. * @param string
  1068. * @return null
  1069. */
  1070. function html_status_legend() {
  1071. echo '<br />';
  1072. echo '<table class="width100" cellspacing="1">';
  1073. echo '<tr>';
  1074. $t_status_array = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
  1075. $t_status_names = MantisEnum::getAssocArrayIndexedByValues( lang_get( 'status_enum_string' ) );
  1076. $enum_count = count( $t_status_array );
  1077. # read through the list and eliminate unused ones for the selected project
  1078. # assumes that all status are are in the enum array
  1079. $t_workflow = config_get( 'status_enum_workflow' );
  1080. if( !empty( $t_workflow ) ) {
  1081. foreach( $t_status_array as $t_status => $t_name ) {
  1082. if( !isset( $t_workflow[$t_status] ) ) {
  1083. # drop elements that are not in the workflow
  1084. unset( $t_status_array[$t_status] );
  1085. }
  1086. }
  1087. }
  1088. # draw the status bar
  1089. $width = (int)( 100 / count( $t_status_array ) );
  1090. foreach( $t_status_array as $t_status => $t_name ) {
  1091. $t_val = $t_status_names[$t_status];
  1092. $t_color = get_status_color( $t_status );
  1093. echo "<td class=\"small-caption\" width=\"$width%\" bgcolor=\"$t_color\">$t_val</td>";
  1094. }
  1095. echo '</tr>';
  1096. echo '</table>';
  1097. if( ON == config_get( 'status_percentage_legend' ) ) {
  1098. html_status_percentage_legend();
  1099. }
  1100. }
  1101. /**
  1102. * Print the legend for the status percentage
  1103. * @return null
  1104. */
  1105. function html_status_percentage_legend() {
  1106. $t_mantis_bug_table = db_get_table( 'mantis_bug_table' );
  1107. $t_project_id = helper_get_current_project();
  1108. $t_user_id = auth_get_current_user_id();
  1109. # checking if it's a per project statistic or all projects
  1110. $t_specific_where = helper_project_specific_where( $t_project_id, $t_user_id );
  1111. $query = "SELECT status, COUNT(*) AS number
  1112. FROM $t_mantis_bug_table
  1113. WHERE $t_specific_where";
  1114. if ( !access_has_project_level( config_get( 'private_bug_threshold' ) ) ) {
  1115. $query .= ' AND view_state < ' . VS_PRIVATE;
  1116. }
  1117. $query .= ' GROUP BY status';
  1118. $result = db_query_bound( $query );
  1119. $t_bug_count = 0;
  1120. $t_status_count_array = array();
  1121. while( $row = db_fetch_array( $result ) ) {
  1122. $t_status_count_array[$row['status']] = $row['number'];
  1123. $t_bug_count += $row['number'];
  1124. }
  1125. $t_enum_values = MantisEnum::getValues( config_get( 'status_enum_string' ) );
  1126. $enum_count = count( $t_enum_values );
  1127. if( $t_bug_count > 0 ) {
  1128. echo '<br />';
  1129. echo '<table class="width100" cellspacing="1">';
  1130. echo '<tr>';
  1131. echo '<td class="form-title" colspan="' . $enum_count . '">' . lang_get( 'issue_status_percentage' ) . '</td>';
  1132. echo '</tr>';
  1133. echo '<tr>';
  1134. foreach ( $t_enum_values as $t_status ) {
  1135. $t_color = get_status_color( $t_status );
  1136. if ( !isset( $t_status_count_array[$t_status] ) ) {
  1137. $t_status_count_array[$t_status] = 0;
  1138. }
  1139. $width = round(( $t_status_count_array[$t_status] / $t_bug_count ) * 100 );
  1140. if( $width > 0 ) {
  1141. echo "<td class=\"small-caption-center\" width=\"$width%\" bgcolor=\"$t_color\">$width%</td>";
  1142. }
  1143. }
  1144. echo '</tr>';
  1145. echo '</table>';
  1146. }
  1147. }
  1148. /**
  1149. * Print an html button inside a form
  1150. * @param string $p_action
  1151. * @param string $p_buttion_text
  1152. * @param array $p_fields
  1153. * @param string $p_method
  1154. * @return null
  1155. */
  1156. function html_button( $p_action, $p_button_text, $p_fields = null, $p_method = 'post' ) {
  1157. $t_form_name = explode( '.php', $p_action, 2 );
  1158. $p_action = urlencode( $p_action );
  1159. $p_button_text = string_attribute( $p_button_text );
  1160. if( null === $p_fields ) {
  1161. $p_fields = array();
  1162. }
  1163. if( utf8_strtolower( $p_method ) == 'get' ) {
  1164. $t_method = 'get';
  1165. } else {
  1166. $t_method = 'post';
  1167. }
  1168. echo "<form method=\"$t_method\" action=\"$p_action\">\n";
  1169. # Add a CSRF token only when the form is being sent via the POST method
  1170. if ( $t_method == 'post' ) {
  1171. echo form_security_field( $t_form_name[0] );
  1172. }
  1173. foreach( $p_fields as $key => $val ) {
  1174. $key = string_attribute( $key );
  1175. $val = string_attribute( $val );
  1176. echo " <input type=\"hidden\" name=\"$key\" value=\"$val\" />\n";
  1177. }
  1178. echo " <input type=\"submit\" class=\"button\" value=\"$p_button_text\" />\n";
  1179. echo "</form>\n";
  1180. }
  1181. /**
  1182. * Print a button to update the given bug
  1183. * @param int $p_bug_id
  1184. * @return null
  1185. */
  1186. function html_button_bug_update( $p_bug_id ) {
  1187. if( access_has_bug_level( config_get( 'update_bug_threshold' ), $p_bug_id ) ) {
  1188. html_button( string_get_bug_update_page(), lang_get( 'update_bug_button' ), array( 'bug_id' => $p_bug_id ) );
  1189. }
  1190. }
  1191. /**
  1192. * Print Change Status to: button
  1193. * This code is similar to print_status_option_list except
  1194. * there is no masking, except for the current state
  1195. *
  1196. * @param int $p_bug_id
  1197. * @return null
  1198. */
  1199. function html_button_bug_change_status( $p_bug_id ) {
  1200. $t_bug_project_id = bug_get_field( $p_bug_id, 'project_id' );
  1201. $t_bug_current_state = bug_get_field( $p_bug_id, 'status' );
  1202. $t_current_access = access_get_project_level( $t_bug_project_id );
  1203. $t_enum_list = get_status_option_list( $t_current_access, $t_bug_current_state, false, ( bug_get_field( $p_bug_id, 'reporter_id' ) == auth_get_current_user_id() && ( ON == config_get( 'allow_reporter_close' ) ) ), $t_bug_project_id );
  1204. if( count( $t_enum_list ) > 0 ) {
  1205. # resort the list into ascending order after noting the key from the first element (the default)
  1206. $t_default_arr = each( $t_enum_list );
  1207. $t_default = $t_default_arr['key'];
  1208. ksort( $t_enum_list );
  1209. reset( $t_enum_list );
  1210. echo "<form method=\"post\" action=\"bug_change_status_page.php\">";
  1211. # CSRF protection not required here - form does not result in modifications
  1212. $t_button_text = lang_get( 'bug_status_to_button' );
  1213. echo "<input type=\"submit\" class=\"button\" value=\"$t_button_text\" />";
  1214. echo " <select name=\"new_status\">";
  1215. # space at beginning of line is important
  1216. foreach( $t_enum_list as $key => $val ) {
  1217. echo "<option value=\"$key\" ";
  1218. check_selected( $key, $t_default );
  1219. echo ">$val</option>";
  1220. }
  1221. echo '</select>';
  1222. $t_bug_id = string_attribute( $p_bug_id );
  1223. echo "<input type=\"hidden\" name=\"id\" value=\"$t_bug_id\" />\n";
  1224. echo "</form>\n";
  1225. }
  1226. }
  1227. /**
  1228. * Print Assign To: combo box of possible handlers
  1229. * @param int $p_bug_id
  1230. * @return null
  1231. */
  1232. function html_button_bug_assign_to( $p_bug_id ) {
  1233. # make sure status is allowed of assign would cause auto-set-status
  1234. $t_status = bug_get_field( $p_bug_id, 'status' );
  1235. # workflow implementation
  1236. if( ON == config_get( 'auto_set_status_to_assigned' ) && !bug_check_workflow( $t_status, config_get( 'bug_assigned_status' ) ) ) {
  1237. # workflow
  1238. return;
  1239. }
  1240. # make sure current user has access to modify bugs.
  1241. if( !access_has_bug_level( config_get( 'update_bug_assign_threshold', config_get( 'update_bug_threshold' ) ), $p_bug_id ) ) {
  1242. return;
  1243. }
  1244. $t_reporter_id = bug_get_field( $p_bug_id, 'reporter_id' );
  1245. $t_handler_id = bug_get_field( $p_bug_id, 'handler_id' );
  1246. $t_current_user_id = auth_get_current_user_id();
  1247. $t_new_status = ( ON == config_get( 'auto_set_status_to_assigned' ) ) ? config_get( 'bug_assigned_status' ) : $t_status;
  1248. $t_options = array();
  1249. $t_default_assign_to = null;
  1250. if(( $t_handler_id != $t_current_user_id ) && ( access_has_bug_level( config_get( 'handle_bug_threshold' ), $p_bug_id, $t_current_user_id ) ) ) {
  1251. $t_options[] = array(
  1252. $t_current_user_id,
  1253. '[' . lang_get( 'myself' ) . ']',
  1254. );
  1255. $t_default_assign_to = $t_current_user_id;
  1256. }
  1257. if(( $t_handler_id != $t_reporter_id ) && user_exists( $t_reporter_id ) && ( access_has_bug_level( config_get( 'handle_bug_threshold' ), $p_bug_id, $t_reporter_id ) ) ) {
  1258. $t_options[] = array(
  1259. $t_reporter_id,
  1260. '[' . lang_get( 'reporter' ) . ']',
  1261. );
  1262. if( $t_default_assign_to === null ) {
  1263. $t_default_assign_to = $t_reporter_id;
  1264. }
  1265. }
  1266. echo "<form method=\"post\" action=\"bug_assign.php\">";
  1267. echo form_security_field( 'bug_assign' );
  1268. $t_button_text = lang_get( 'bug_assign_to_button' );
  1269. echo "<input type=\"submit\" class=\"button\" value=\"$t_button_text\" />";
  1270. echo " <select name=\"handler_id\">";
  1271. # space at beginning of line is important
  1272. $t_already_selected = false;
  1273. foreach( $t_options as $t_entry ) {
  1274. $t_id = string_attribute( $t_entry[0] );
  1275. $t_caption = string_attribute( $t_entry[1] );
  1276. # if current user and reporter can't be selected, then select the first
  1277. # user in the list.
  1278. if( $t_default_assign_to === null ) {
  1279. $t_default_assign_to = $t_id;
  1280. }
  1281. echo '<option value="' . $t_id . '" ';
  1282. if(( $t_id == $t_default_assign_to ) && !$t_already_selected ) {
  1283. check_selected( $t_id, $t_default_assign_to );
  1284. $t_already_selected = true;
  1285. }
  1286. echo '>' . $t_caption . '</option>';
  1287. }
  1288. # allow un-assigning if already assigned.
  1289. if( $t_handler_id != 0 ) {
  1290. echo "<option value=\"0\"></option>";
  1291. }
  1292. $t_project_id = bug_get_field( $p_bug_id, 'project_id' );
  1293. # 0 means currently selected
  1294. print_assign_to_option_list( 0, $t_project_id );
  1295. echo "</select>";
  1296. $t_bug_id = string_attribute( $p_bug_id );
  1297. echo "<input type=\"hidden\" name=\"bug_id\" value=\"$t_bug_id\" />\n";
  1298. echo "</form>\n";
  1299. }
  1300. /**
  1301. * Print a button to move the given bug to a different project
  1302. * @param int $p_bug_id
  1303. * @return null
  1304. */
  1305. function html_button_bug_move( $p_bug_id ) {
  1306. if( access_has_bug_level( config_get( 'move_bug_threshold' ), $p_bug_id ) ) {
  1307. html_button( 'bug_actiongroup_page.php', lang_get( 'move_bug_button' ), array( 'bug_arr[]' => $p_bug_id, 'action' => 'MOVE' ) );
  1308. }
  1309. }
  1310. /**
  1311. * Print a button to move the given bug to a different project
  1312. * @param int $p_bug_id
  1313. * @return null
  1314. */
  1315. function html_button_bug_create_child( $p_bug_id ) {
  1316. if( access_has_bug_level( config_get( 'update_bug_threshold' ), $p_bug_id ) ) {
  1317. html_button( string_get_bug_report_url(), lang_get( 'create_child_bug_button' ), array( 'm_id' => $p_bug_id ) );
  1318. }
  1319. }
  1320. /**
  1321. * Print a button to reopen the given bug
  1322. * @param int $p_bug_id
  1323. * @return null
  1324. */
  1325. function html_button_bug_reopen( $p_bug_id ) {
  1326. $t_status = bug_get

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