[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/core/ -> html_api.php (source)

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


Generated: Thu Jul 28 15:48:31 2011 Cross-referenced by PHPXref 0.7