[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/core/ -> columns_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   * Columns API
  19   *
  20   * @package CoreAPI
  21   * @subpackage ColumnsAPI
  22   * @copyright Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
  23   * @copyright Copyright (C) 2002 - 2011  MantisBT Team - mantisbt-dev@lists.sourceforge.net
  24   * @link http://www.mantisbt.org
  25   *
  26   * @uses access_api.php
  27   * @uses bug_api.php
  28   * @uses category_api.php
  29   * @uses config_api.php
  30   * @uses constant_inc.php
  31   * @uses custom_field_api.php
  32   * @uses date_api.php
  33   * @uses error_api.php
  34   * @uses event_api.php
  35   * @uses file_api.php
  36   * @uses helper_api.php
  37   * @uses icon_api.php
  38   * @uses lang_api.php
  39   * @uses prepare_api.php
  40   * @uses print_api.php
  41   * @uses project_api.php
  42   * @uses sponsorship_api.php
  43   * @uses string_api.php
  44   */
  45  
  46  require_api( 'access_api.php' );
  47  require_api( 'bug_api.php' );
  48  require_api( 'category_api.php' );
  49  require_api( 'columns_api.php' );
  50  require_api( 'config_api.php' );
  51  require_api( 'constant_inc.php' );
  52  require_api( 'custom_field_api.php' );
  53  require_api( 'date_api.php' );
  54  require_api( 'error_api.php' );
  55  require_api( 'event_api.php' );
  56  require_api( 'file_api.php' );
  57  require_api( 'helper_api.php' );
  58  require_api( 'icon_api.php' );
  59  require_api( 'lang_api.php' );
  60  require_api( 'prepare_api.php' );
  61  require_api( 'print_api.php' );
  62  require_api( 'project_api.php' );
  63  require_api( 'sponsorship_api.php' );
  64  require_api( 'string_api.php' );
  65  
  66  /**
  67   * Filters an array of columns based on configuration options.  The filtering can remove
  68   * columns whose features are disabled.
  69   *
  70   * @param array(string) $p_columns  The columns proposed for display.
  71   * @return array(string) The columns array after removing the disabled features.
  72   */
  73  function columns_filter_disabled( $p_columns ) {
  74      $t_columns = array();
  75      $t_enable_profiles = ( config_get( 'enable_profiles' ) == ON );
  76  
  77      foreach ( $p_columns as $t_column ) {
  78          switch( $t_column ) {
  79              case 'os':
  80              case 'os_build':
  81              case 'platform':
  82                  if( ! $t_enable_profiles ) {
  83                      continue 2;
  84                  }
  85                  /* don't filter */
  86                  break;
  87  
  88              case 'eta':
  89                  if( config_get( 'enable_eta' ) == OFF ) {
  90                      continue 2;
  91                  }
  92                  break;
  93  
  94              case 'projection':
  95                  if( config_get( 'enable_projection' ) == OFF ) {
  96                      continue 2;
  97                  }
  98                  break;
  99  
 100              case 'build':
 101                  if( config_get( 'enable_product_build' ) == OFF ) {
 102                      continue 2;
 103                  }
 104                  break;
 105  
 106              default:
 107                  /* don't filter */
 108                  break;
 109          }
 110          $t_columns[] = $t_column;
 111      } /* continued 2 */
 112  
 113      return $t_columns;
 114  }
 115  
 116  /**
 117   * Get a list of standard columns.
 118   */
 119  function columns_get_standard() {
 120      $t_reflection = new ReflectionClass('BugData');
 121      $t_columns = $t_reflection->getDefaultProperties();
 122  
 123      $t_columns['selection'] = null;
 124      $t_columns['edit'] = null;
 125  
 126      # Overdue icon column (icons appears if an issue is beyond due_date)
 127      $t_columns['overdue'] = null;
 128  
 129      if( OFF == config_get( 'enable_profiles' ) ) {
 130          unset( $t_columns['os'] );
 131          unset( $t_columns['os_build'] );
 132          unset( $t_columns['platform'] );
 133      }
 134  
 135      if( config_get( 'enable_eta' ) == OFF ) {
 136          unset( $t_columns['eta'] );
 137      }
 138  
 139      if( config_get( 'enable_projection' ) == OFF ) {
 140          unset( $t_columns['projection'] );
 141      }
 142  
 143      if( config_get( 'enable_product_build' ) == OFF ) {
 144          unset( $t_columns['build'] );
 145      }
 146  
 147      if( config_get( 'enable_sponsorship' ) == OFF ) {
 148          unset( $t_columns['sponsorship_total'] );
 149      }
 150  
 151      # The following fields are used internally and don't make sense as columns
 152      unset( $t_columns['_stats'] );
 153      unset( $t_columns['profile_id'] );
 154      unset( $t_columns['sticky'] );
 155      unset( $t_columns['loading'] );
 156  
 157      # legacy field
 158      unset( $t_columns['duplicate_id'] );
 159  
 160      return array_keys($t_columns);
 161  }
 162  
 163  /**
 164   * Allow plugins to define a set of class-based columns, and register/load
 165   * them here to be used by columns_api.
 166   * @return array Mapping of column name to column object
 167   */
 168  function columns_get_plugin_columns() {
 169      static $s_column_array = null;
 170  
 171      if ( is_null( $s_column_array ) ) {
 172          $s_column_array = array();
 173  
 174          $t_all_plugin_columns = event_signal( 'EVENT_FILTER_COLUMNS' );
 175          foreach( $t_all_plugin_columns as $t_plugin => $t_plugin_columns ) {
 176              foreach( $t_plugin_columns as $t_callback => $t_plugin_column_array ) {
 177                  if ( is_array( $t_plugin_column_array ) ) {
 178                      foreach( $t_plugin_column_array as $t_column_class ) {
 179                          if ( class_exists( $t_column_class ) && is_subclass_of( $t_column_class, 'MantisColumn' ) ) {
 180                              $t_column_object = new $t_column_class();
 181                              $t_column_name = utf8_strtolower( $t_plugin . '_' . $t_column_object->column );
 182                              $s_column_array[ $t_column_name ] = $t_column_object;
 183                          }
 184                      }
 185                  }
 186              }
 187          }
 188      }
 189  
 190      return $s_column_array;
 191  }
 192  
 193  /**
 194   * Allow plugin columns to pre-cache data for a set of issues
 195   * rather than requiring repeated queries for each issue.
 196   * @param array Bug objects
 197   */
 198  function columns_plugin_cache_issue_data( $p_bugs ) {
 199      $t_columns = columns_get_plugin_columns();
 200  
 201      foreach( $t_columns as $t_column_object ) {
 202          $t_column_object->cache( $p_bugs );
 203      }
 204  }
 205  
 206  /**
 207   * Get all accessible columns for the current project / current user..
 208   * @param int $p_project_id project id
 209   * @return array array of columns
 210   * @access public
 211   */
 212  function columns_get_all( $p_project_id = null ) {
 213      $t_columns = columns_get_standard();
 214  
 215      # add plugin columns
 216      $t_columns = array_merge( $t_columns, array_keys( columns_get_plugin_columns() ) );
 217  
 218      # Add project custom fields to the array.  Only add the ones for which the current user has at least read access.
 219      if( $p_project_id === null ) {
 220          $t_project_id = helper_get_current_project();
 221      } else {
 222          $t_project_id = $p_project_id;
 223      }
 224  
 225      $t_related_custom_field_ids = custom_field_get_linked_ids( $t_project_id );
 226      foreach( $t_related_custom_field_ids as $t_id ) {
 227          if( !custom_field_has_read_access_by_project_id( $t_id, $t_project_id ) ) {
 228              continue;
 229          }
 230  
 231          $t_def = custom_field_get_definition( $t_id );
 232          $t_columns[] = 'custom_' . $t_def['name'];
 233      }
 234  
 235      return $t_columns;
 236  }
 237  
 238  /**
 239   * Checks if the specified column is an extended column.  Extended columns are native columns that are
 240   * associated with the issue but are saved in mantis_bug_text_table.
 241   * @param string $p_column The column name
 242   * @return bool true for extended; false otherwise.
 243   * @access public
 244   */
 245  function column_is_extended( $p_column ) {
 246      switch( $p_column ) {
 247          case 'description':
 248          case 'steps_to_reproduce':
 249          case 'additional_information':
 250              return true;
 251          default:
 252              return false;
 253      }
 254  }
 255  
 256  /**
 257   * Given a column name from the array of columns to be included in a view, this method checks if
 258   * the column is a custom column and if so returns its name.  Note that for custom fields, then
 259   * provided names will have the "custom_" prefix, where the returned ones won't have the prefix.
 260   *
 261   * @param string $p_column Column name.
 262   * @return string The custom field column name or null if the specific column is not a custom field or invalid column.
 263   * @access public
 264   */
 265  function column_get_custom_field_name( $p_column ) {
 266      if( strncmp( $p_column, 'custom_', 7 ) === 0 ) {
 267          return utf8_substr( $p_column, 7 );
 268      }
 269  
 270      return null;
 271  }
 272  
 273  /**
 274   * Converts a string of comma separate column names to an array.
 275   * @param string $p_string - Comma separate column name (not case sensitive)
 276   * @return array The array with all column names lower case.
 277   * @access public
 278   */
 279  function columns_string_to_array( $p_string ) {
 280      $t_string = utf8_strtolower( $p_string );
 281  
 282      $t_columns = explode( ',', $t_string );
 283      $t_count = count($t_columns);
 284  
 285      for($i = 0; $i < $t_count; $i++) {
 286          $t_columns[$i] = trim($t_columns[$i]);
 287      }
 288  
 289      return $t_columns;
 290  }
 291  
 292  /**
 293   * Gets the localized title for the specified column.  The column can be native or custom.
 294   * The custom fields must contain the 'custom_' prefix.
 295   * @param string $p_column - The column name.
 296   * @return string The column localized name.
 297   * @access public
 298   */
 299  function column_get_title( $p_column ) {
 300      $t_custom_field = column_get_custom_field_name( $p_column );
 301      if( $t_custom_field !== null ) {
 302          $t_field_id = custom_field_get_id_from_name( $t_custom_field );
 303  
 304          if( $t_field_id === false ) {
 305              $t_custom_field = '@' . $t_custom_field . '@';
 306          } else {
 307              $t_def = custom_field_get_definition( $t_field_id );
 308              $t_custom_field = lang_get_defaulted( $t_def['name'] );
 309          }
 310  
 311          return $t_custom_field;
 312      }
 313  
 314      $t_plugin_columns = columns_get_plugin_columns();
 315      if ( isset( $t_plugin_columns[ $p_column ] ) ) {
 316          $t_column_object = $t_plugin_columns[ $p_column ];
 317          return $t_column_object->title;
 318      }
 319  
 320      switch( $p_column ) {
 321          case 'attachment_count':
 322              return lang_get( 'attachments' );
 323          case 'bugnotes_count':
 324              return '#';
 325          case 'category_id':
 326              return lang_get( 'category' );
 327          case 'edit':
 328              return '';
 329          case 'handler_id':
 330              return lang_get( 'assigned_to' );
 331          case 'last_updated':
 332              return lang_get( 'updated' );
 333          case 'os_build':
 334              return lang_get( 'os_version' );
 335          case 'project_id':
 336              return lang_get( 'email_project' );
 337          case 'reporter_id':
 338              return lang_get( 'reporter' );
 339          case 'selection':
 340              return '';
 341          case 'sponsorship_total':
 342              return sponsorship_get_currency();
 343          case 'version':
 344              return lang_get( 'product_version' );
 345          case 'view_state':
 346              return lang_get( 'view_status' );
 347          default:
 348              return lang_get_defaulted( $p_column );
 349      }
 350  }
 351  
 352  /**
 353   * Checks an array of columns for duplicate or invalid fields.
 354   * @param string $p_field_name - The logic name of the array being validated.  Used when triggering errors.
 355   * @param array $p_columns_to_validate - The array of columns to validate.
 356   * @param array $p_columns_all - The list of all valid columns.
 357   * @return bool
 358   * @access public
 359   */
 360  function columns_ensure_valid( $p_field_name, $p_columns_to_validate, $p_columns_all ) {
 361      $t_columns_all_lower = array_map( 'utf8_strtolower', $p_columns_all );
 362  
 363      # Check for invalid fields
 364      foreach( $p_columns_to_validate as $t_column ) {
 365          if( !in_array( utf8_strtolower( $t_column ), $t_columns_all_lower ) ) {
 366              error_parameters( $p_field_name, $t_column );
 367              trigger_error( ERROR_COLUMNS_INVALID, ERROR );
 368              return false;
 369          }
 370      }
 371  
 372      # Check for duplicate fields
 373      $t_columns_no_duplicates = array();
 374      foreach( $p_columns_to_validate as $t_column ) {
 375          $t_column_lower = utf8_strtolower( $t_column );
 376          if( in_array( $t_column, $t_columns_no_duplicates ) ) {
 377              error_parameters( $p_field_name, $t_column );
 378              trigger_error( ERROR_COLUMNS_DUPLICATE, ERROR );
 379          } else {
 380              $t_columns_no_duplicates[] = $t_column_lower;
 381          }
 382      }
 383  
 384      return true;
 385  }
 386  
 387  /**
 388   * Validates an array of column names and removes ones that are not valid.  The validation
 389   * is not case sensitive.
 390   *
 391   * @param array $p_columns - The array of column names to be validated.
 392   * @param array $p_columns_all - The array of all valid column names.
 393   * @return array The array of valid column names found in $p_columns.
 394   * @access public
 395   */
 396  function columns_remove_invalid( $p_columns, $p_columns_all ) {
 397      $t_columns_all_lower = array_values( array_map( 'utf8_strtolower', $p_columns_all ) );
 398      $t_columns = array();
 399  
 400      foreach( $p_columns as $t_column ) {
 401          if( in_array( utf8_strtolower( $t_column ), $t_columns_all_lower ) ) {
 402              $t_columns[] = $t_column;
 403          }
 404      }
 405  
 406      return $t_columns;
 407  }
 408  
 409  /**
 410   *
 411   * @param string sort
 412   * @param string direction
 413   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 414   * @return null
 415   * @access public
 416   */
 417  function print_column_title_selection( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 418      echo '<th class="column-selection"> &#160; </th>';
 419  }
 420  
 421  /**
 422   *
 423   * @param string sort
 424   * @param string direction
 425   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 426   * @return null
 427   * @access public
 428   */
 429  function print_column_title_edit( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 430      echo '<th class="column-edit"> &#160; </th>';
 431  }
 432  
 433  /**
 434   *
 435   * @param string sort
 436   * @param string direction
 437   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 438   * @return null
 439   * @access public
 440   */
 441  function print_column_title_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 442      echo '<th class="column-id">';
 443      print_view_bug_sort_link( lang_get( 'id' ), 'id', $p_sort, $p_dir, $p_columns_target );
 444      print_sort_icon( $p_dir, $p_sort, 'id' );
 445      echo '</th>';
 446  }
 447  
 448  /**
 449   *
 450   * @param string sort
 451   * @param string direction
 452   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 453   * @return null
 454   * @access public
 455   */
 456  function print_column_title_project_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 457      echo '<th class="column-project">';
 458      print_view_bug_sort_link( lang_get( 'email_project' ), 'project_id', $p_sort, $p_dir, $p_columns_target );
 459      print_sort_icon( $p_dir, $p_sort, 'project_id' );
 460      echo '</th>';
 461  }
 462  
 463  /**
 464   *
 465   * @param string sort
 466   * @param string direction
 467   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 468   * @return null
 469   * @access public
 470   */
 471  function print_column_title_reporter_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 472      echo '<th class="column-reporter">';
 473      print_view_bug_sort_link( lang_get( 'reporter' ), 'reporter_id', $p_sort, $p_dir, $p_columns_target );
 474      print_sort_icon( $p_dir, $p_sort, 'reporter_id' );
 475      echo '</th>';
 476  }
 477  
 478  /**
 479   *
 480   * @param string sort
 481   * @param string direction
 482   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 483   * @return null
 484   * @access public
 485   */
 486  function print_column_title_handler_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 487      echo '<th class="column-assigned-to">';
 488      print_view_bug_sort_link( lang_get( 'assigned_to' ), 'handler_id', $p_sort, $p_dir, $p_columns_target );
 489      print_sort_icon( $p_dir, $p_sort, 'handler_id' );
 490      echo '</th>';
 491  }
 492  
 493  /**
 494   *
 495   * @param string sort
 496   * @param string direction
 497   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 498   * @return null
 499   * @access public
 500   */
 501  function print_column_title_priority( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 502      echo '<th class="column-priority">';
 503      print_view_bug_sort_link( lang_get( 'priority_abbreviation' ), 'priority', $p_sort, $p_dir, $p_columns_target );
 504      print_sort_icon( $p_dir, $p_sort, 'priority' );
 505      echo '</th>';
 506  }
 507  
 508  /**
 509   *
 510   * @param string sort
 511   * @param string direction
 512   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 513   * @return null
 514   * @access public
 515   */
 516  function print_column_title_reproducibility( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 517      echo '<th class="column-reproducibility">';
 518      print_view_bug_sort_link( lang_get( 'reproducibility' ), 'reproducibility', $p_sort, $p_dir, $p_columns_target );
 519      print_sort_icon( $p_dir, $p_sort, 'reproducibility' );
 520      echo '</th>';
 521  }
 522  
 523  /**
 524   *
 525   * @param string sort
 526   * @param string direction
 527   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 528   * @return null
 529   * @access public
 530   */
 531  function print_column_title_projection( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 532      echo '<th class="column-projection">';
 533      print_view_bug_sort_link( lang_get( 'projection' ), 'projection', $p_sort, $p_dir, $p_columns_target );
 534      print_sort_icon( $p_dir, $p_sort, 'projection' );
 535      echo '</th>';
 536  }
 537  
 538  /**
 539   *
 540   * @param string sort
 541   * @param string direction
 542   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 543   * @return null
 544   * @access public
 545   */
 546  function print_column_title_eta( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 547      echo '<th class="column-eta">';
 548      print_view_bug_sort_link( lang_get( 'eta' ), 'eta', $p_sort, $p_dir, $p_columns_target );
 549      print_sort_icon( $p_dir, $p_sort, 'eta' );
 550      echo '</th>';
 551  }
 552  
 553  /**
 554   *
 555   * @param string sort
 556   * @param string direction
 557   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 558   * @return null
 559   * @access public
 560   */
 561  function print_column_title_resolution( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 562      echo '<th>';
 563      print_view_bug_sort_link( lang_get( 'resolution' ), 'resolution', $p_sort, $p_dir, $p_columns_target );
 564      print_sort_icon( $p_dir, $p_sort, 'resolution' );
 565      echo '</th>';
 566  }
 567  
 568  /**
 569   *
 570   * @param string sort
 571   * @param string direction
 572   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 573   * @return null
 574   * @access public
 575   */
 576  function print_column_title_fixed_in_version( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 577      echo '<th>';
 578      print_view_bug_sort_link( lang_get( 'fixed_in_version' ), 'fixed_in_version', $p_sort, $p_dir, $p_columns_target );
 579      print_sort_icon( $p_dir, $p_sort, 'fixed_in_version' );
 580      echo '</th>';
 581  }
 582  
 583  /**
 584   *
 585   * @param string sort
 586   * @param string direction
 587   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 588   * @return null
 589   * @access public
 590   */
 591  function print_column_title_target_version( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 592      echo '<td>';
 593      print_view_bug_sort_link( lang_get( 'target_version' ), 'target_version', $p_sort, $p_dir, $p_columns_target );
 594      print_sort_icon( $p_dir, $p_sort, 'target_version' );
 595      echo '</td>';
 596  }
 597  
 598  /**
 599   *
 600   * @param string sort
 601   * @param string direction
 602   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 603   * @return null
 604   * @access public
 605   */
 606  function print_column_title_view_state( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 607      global $t_icon_path;
 608      echo '<th class="column-view-state">';
 609      $t_view_state_text = lang_get( 'view_status' );
 610      $t_view_state_icon = '<img src="' . $t_icon_path . 'protected.gif" alt="' . $t_view_state_text . '" title="' . $t_view_state_text . '" />';
 611      print_view_bug_sort_link( $t_view_state_icon, 'view_state', $p_sort, $p_dir, $p_columns_target );
 612      print_sort_icon( $p_dir, $p_sort, 'view_state' );
 613      echo '</th>';
 614  }
 615  
 616  /**
 617   *
 618   * @param string sort
 619   * @param string direction
 620   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 621   * @return null
 622   * @access public
 623   */
 624  function print_column_title_os( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 625      echo '<td>';
 626      print_view_bug_sort_link( lang_get( 'os' ), 'os', $p_sort, $p_dir, $p_columns_target );
 627      print_sort_icon( $p_dir, $p_sort, 'os' );
 628      echo '</td>';
 629  }
 630  
 631  /**
 632   *
 633   * @param string sort
 634   * @param string direction
 635   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 636   * @return null
 637   * @access public
 638   */
 639  function print_column_title_os_build( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 640      echo '<td>';
 641      print_view_bug_sort_link( lang_get( 'os_version' ), 'os_build', $p_sort, $p_dir, $p_columns_target );
 642      print_sort_icon( $p_dir, $p_sort, 'os_build' );
 643      echo '</td>';
 644  }
 645  
 646  /**
 647   *
 648   * @param string sort
 649   * @param string direction
 650   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 651   * @return null
 652   * @access public
 653   */
 654  function print_column_title_build( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 655      if( $p_columns_target != COLUMNS_TARGET_CSV_PAGE ) {
 656          echo '<th class="column-build">';
 657          print_view_bug_sort_link( lang_get( 'build' ), 'build', $p_sort, $p_dir, $p_columns_target );
 658          print_sort_icon( $p_dir, $p_sort, 'build' );
 659          echo '</th>';
 660      } else {
 661          echo lang_get( 'build' );
 662      }
 663  }
 664  
 665  /**
 666   *
 667   * @param string sort
 668   * @param string direction
 669   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 670   * @return null
 671   * @access public
 672   */
 673  function print_column_title_platform( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 674      echo '<th class="column-platform">';
 675      print_view_bug_sort_link( lang_get( 'platform' ), 'platform', $p_sort, $p_dir, $p_columns_target );
 676      print_sort_icon( $p_dir, $p_sort, 'platform' );
 677      echo '</th>';
 678  }
 679  
 680  /**
 681   *
 682   * @param string sort
 683   * @param string direction
 684   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 685   * @return null
 686   * @access public
 687   */
 688  function print_column_title_version( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 689      echo '<th class="column-version">';
 690      print_view_bug_sort_link( lang_get( 'product_version' ), 'version', $p_sort, $p_dir, $p_columns_target );
 691      print_sort_icon( $p_dir, $p_sort, 'version' );
 692      echo '</th>';
 693  }
 694  
 695  /**
 696   *
 697   * @param string sort
 698   * @param string direction
 699   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 700   * @return null
 701   * @access public
 702   */
 703  function print_column_title_date_submitted( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 704      echo '<th class="column-date-submitted">';
 705      print_view_bug_sort_link( lang_get( 'date_submitted' ), 'date_submitted', $p_sort, $p_dir, $p_columns_target );
 706      print_sort_icon( $p_dir, $p_sort, 'date_submitted' );
 707      echo '</th>';
 708  }
 709  
 710  /**
 711   *
 712   * @param string sort
 713   * @param string direction
 714   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 715   * @return null
 716   * @access public
 717   */
 718  function print_column_title_attachment_count( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 719      global $t_icon_path;
 720      $t_attachment_count_text = lang_get( 'attachment_count' );
 721      $t_attachment_count_icon = "<img src=\"$t_icon_path}attachment.png\" alt=\"$t_attachment_count_text\" title=\"$t_attachment_count_text\" />";
 722      echo "\t<th class=\"column-attachments\">$t_attachment_count_icon</th>\n";
 723  }
 724  
 725  /**
 726   *
 727   * @param string sort
 728   * @param string direction
 729   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 730   * @return null
 731   * @access public
 732   */
 733  function print_column_title_category( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 734      echo '<th class="column-category">';
 735      print_view_bug_sort_link( lang_get( 'category' ), 'category', $p_sort, $p_dir, $p_columns_target );
 736      print_sort_icon( $p_dir, $p_sort, 'category' );
 737      echo '</th>';
 738  }
 739  
 740  /**
 741   *
 742   * @param string sort
 743   * @param string direction
 744   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 745   * @return null
 746   * @access public
 747   */
 748  function print_column_title_sponsorship_total( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 749      echo "\t<th class=\"column-sponsorship\">";
 750      print_view_bug_sort_link( sponsorship_get_currency(), 'sponsorship_total', $p_sort, $p_dir, $p_columns_target );
 751      print_sort_icon( $p_dir, $p_sort, 'sponsorship_total' );
 752      echo "</th>\n";
 753  }
 754  
 755  /**
 756   *
 757   * @param string sort
 758   * @param string direction
 759   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 760   * @return null
 761   * @access public
 762   */
 763  function print_column_title_severity( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 764      echo '<th class="column-severity">';
 765      print_view_bug_sort_link( lang_get( 'severity' ), 'severity', $p_sort, $p_dir, $p_columns_target );
 766      print_sort_icon( $p_dir, $p_sort, 'severity' );
 767      echo '</th>';
 768  }
 769  
 770  /**
 771   *
 772   * @param string sort
 773   * @param string direction
 774   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 775   * @return null
 776   * @access public
 777   */
 778  function print_column_title_status( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 779      echo '<th class="column-status">';
 780      print_view_bug_sort_link( lang_get( 'status' ), 'status', $p_sort, $p_dir, $p_columns_target );
 781      print_sort_icon( $p_dir, $p_sort, 'status' );
 782      echo '</th>';
 783  }
 784  
 785  /**
 786   *
 787   * @param string sort
 788   * @param string direction
 789   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 790   * @return null
 791   * @access public
 792   */
 793  function print_column_title_last_updated( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 794      echo '<th class="column-last-modified">';
 795      print_view_bug_sort_link( lang_get( 'updated' ), 'last_updated', $p_sort, $p_dir, $p_columns_target );
 796      print_sort_icon( $p_dir, $p_sort, 'last_updated' );
 797      echo '</th>';
 798  }
 799  
 800  /**
 801   *
 802   * @param string sort
 803   * @param string direction
 804   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 805   * @return null
 806   * @access public
 807   */
 808  function print_column_title_summary( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 809      echo '<td>';
 810      print_view_bug_sort_link( lang_get( 'summary' ), 'summary', $p_sort, $p_dir, $p_columns_target );
 811      print_sort_icon( $p_dir, $p_sort, 'summary' );
 812      echo '</td>';
 813  }
 814  
 815  /**
 816   *
 817   * @param string sort
 818   * @param string direction
 819   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 820   * @return null
 821   * @access public
 822   */
 823  function print_column_title_bugnotes_count( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 824      echo '<th class="column-bugnotes-count"> # </th>';
 825  }
 826  
 827  /**
 828   *
 829   * @param string sort
 830   * @param string direction
 831   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 832   * @return null
 833   * @access public
 834   */
 835  function print_column_title_description( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 836      echo '<th class="column-description">';
 837      echo lang_get( 'description' );
 838      echo '</th>';
 839  }
 840  
 841  /**
 842   *
 843   * @param string sort
 844   * @param string direction
 845   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 846   * @return null
 847   * @access public
 848   */
 849  function print_column_title_steps_to_reproduce( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 850      echo '<th class="column-steps-to-reproduce">';
 851      echo lang_get( 'steps_to_reproduce' );
 852      echo '</th>';
 853  }
 854  
 855  /**
 856   *
 857   * @param string sort
 858   * @param string direction
 859   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 860   * @return null
 861   * @access public
 862   */
 863  function print_column_title_additional_information( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 864      echo '<th class="column-additional-information">';
 865      echo lang_get( 'additional_information' );
 866      echo '</th>';
 867  }
 868  
 869  function print_column_title_overdue( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 870      global $t_icon_path;
 871      echo '<th class="column-overdue">';
 872      $t_overdue_text = lang_get( 'overdue' );
 873      $t_overdue_icon = '<img src="' . $t_icon_path . 'overdue.png" alt="' . $t_overdue_text . '" title="' . $t_overdue_text . '" />';
 874      print_view_bug_sort_link( $t_overdue_icon, 'due_date', $p_sort, $p_dir, $p_columns_target );
 875      print_sort_icon( $p_dir, $p_sort, 'due_date' );
 876      echo '</th>';
 877  }
 878  
 879  /**
 880   *
 881   * @param BugData $p_bug bug obect
 882   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 883   * @return null
 884   * @access public
 885   */
 886  function print_column_selection( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 887      global $g_checkboxes_exist;
 888  
 889      echo '<td class="column-selection">';
 890      if( access_has_any_project( config_get( 'report_bug_threshold', null, null, $p_bug->project_id ) ) ||
 891          # !TODO: check if any other projects actually exist for the bug to be moved to
 892          access_has_project_level( config_get( 'move_bug_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 893          # !TODO: factor in $g_auto_set_status_to_assigned == ON
 894          access_has_project_level( config_get( 'update_bug_assign_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 895          access_has_project_level( config_get( 'update_bug_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 896          access_has_project_level( config_get( 'delete_bug_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 897          # !TODO: check to see if the bug actually has any different selectable workflow states
 898          access_has_project_level( config_get( 'update_bug_status_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 899          access_has_project_level( config_get( 'set_bug_sticky_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 900          access_has_project_level( config_get( 'change_view_status_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 901          access_has_project_level( config_get( 'add_bugnote_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 902          access_has_project_level( config_get( 'tag_attach_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
 903          access_has_project_level( config_get( 'roadmap_update_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ) {
 904          $g_checkboxes_exist = true;
 905          printf( "<input type=\"checkbox\" name=\"bug_arr[]\" value=\"%d\" />", $p_bug->id );
 906      } else {
 907          echo "&#160;";
 908      }
 909      echo '</td>';
 910  }
 911  
 912  /**
 913   * Print column title for a specific custom column.
 914   * @param object Column object
 915   * @param string sort
 916   * @param string direction
 917   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 918   * @access public
 919   */
 920  function print_column_title_plugin( $p_column, $p_column_object, $p_sort, $p_dir, $p_columns_target=COLUMNS_TARGET_VIEW_PAGE ) {
 921      echo '<th class="column-plugin">';
 922      if ( $p_column_object->sortable ) {
 923          print_view_bug_sort_link( string_display_line( $p_column_object->title ), $p_column, $p_sort, $p_dir, $p_columns_target );
 924          print_sort_icon( $p_dir, $p_sort, $p_column );
 925      } else {
 926          echo string_display_line( $p_column_object->title );
 927      }
 928      echo '</th>';
 929  }
 930  
 931  /**
 932   * Print custom column content for a specific bug.
 933   * @param object Column object
 934   * @param BugData $p_bug bug obect
 935   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 936   * @access public
 937   */
 938  function print_column_plugin( $p_column_object, $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 939      if ( $p_columns_target != COLUMNS_TARGET_CSV_PAGE ) {
 940          echo '<td class="column-plugin">';
 941          $p_column_object->display( $p_bug, $p_columns_target );
 942          echo '</td>';
 943      } else {
 944          $p_column_object->display( $p_bug, $p_columns_target );
 945      }
 946  }
 947  
 948  /**
 949   *
 950   * @param BugData $p_bug bug obect
 951   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 952   * @return null
 953   * @access public
 954   */
 955  function print_column_edit( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 956      global $t_icon_path, $t_update_bug_threshold;
 957  
 958      echo '<td class="column-edit">';
 959  
 960      if( !bug_is_readonly( $p_bug->id ) && access_has_bug_level( config_get( 'update_bug_threshold' ), $p_bug->id ) ) {
 961          echo '<a href="' . string_get_bug_update_url( $p_bug->id ) . '">';
 962          echo '<img width="16" height="16" src="' . $t_icon_path . 'update.png';
 963          echo '" alt="' . lang_get( 'update_bug_button' ) . '"';
 964          echo ' title="' . lang_get( 'update_bug_button' ) . '" /></a>';
 965      } else {
 966          echo '&#160;';
 967      }
 968  
 969      echo '</td>';
 970  }
 971  
 972  /**
 973   *
 974   * @param BugData $p_bug bug obect
 975   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 976   * @return null
 977   * @access public
 978   */
 979  function print_column_priority( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 980      echo '<td class="column-priority">';
 981      if( ON == config_get( 'show_priority_text' ) ) {
 982          print_formatted_priority_string( $p_bug->status, $p_bug->priority );
 983      } else {
 984          print_status_icon( $p_bug->priority );
 985      }
 986      echo '</td>';
 987  }
 988  
 989  /**
 990   *
 991   * @param BugData $p_bug bug obect
 992   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 993   * @return null
 994   * @access public
 995   */
 996  function print_column_id( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 997      echo '<td class="column-id">';
 998      print_bug_link( $p_bug->id, false );
 999      echo '</td>';
1000  }
1001  
1002  /**
1003   *
1004   * @param BugData $p_bug bug obect
1005   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1006   * @return null
1007   * @access public
1008   */
1009  function print_column_sponsorship_total( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1010      echo "\t<td class=\"right column-sponsorship\">";
1011  
1012      if( $p_bug->sponsorship_total > 0 ) {
1013          $t_sponsorship_amount = sponsorship_format_amount( $p_bug->sponsorship_total );
1014          echo string_no_break( $t_sponsorship_amount );
1015      }
1016  
1017      echo "</td>\n";
1018  }
1019  
1020  /**
1021   *
1022   * @param BugData $p_bug bug obect
1023   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1024   * @return null
1025   * @access public
1026   */
1027  function print_column_bugnotes_count( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1028      global $t_filter;
1029  
1030      # grab the bugnote count
1031      $t_bugnote_stats = bug_get_bugnote_stats( $p_bug->id );
1032      if( NULL !== $t_bugnote_stats ) {
1033          $bugnote_count = $t_bugnote_stats['count'];
1034          $v_bugnote_updated = $t_bugnote_stats['last_modified'];
1035      } else {
1036          $bugnote_count = 0;
1037      }
1038  
1039      echo '<td class="center column-bugnotes-count">';
1040      if( $bugnote_count > 0 ) {
1041          $t_show_in_bold = $v_bugnote_updated > strtotime( '-' . $t_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] . ' hours' );
1042          if( $t_show_in_bold ) {
1043              echo '<span class="bold">';
1044          }
1045          print_link( string_get_bug_view_url( $p_bug->id ) . "&nbn=$bugnote_count#bugnotes", $bugnote_count );
1046          if( $t_show_in_bold ) {
1047              echo '</span>';
1048          }
1049      } else {
1050          echo '&#160;';
1051      }
1052  
1053      echo '</td>';
1054  }
1055  
1056  /**
1057   *
1058   * @param BugData $p_bug bug obect
1059   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1060   * @return null
1061   * @access public
1062   */
1063  function print_column_attachment_count( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1064      global $t_icon_path;
1065  
1066      # Check for attachments
1067      # TODO: factor in the allow_view_own_attachments configuration option
1068      # instead of just using a global check.
1069      $t_attachment_count = 0;
1070      if( file_can_view_bug_attachments( $p_bug->id, null ) ) {
1071          $t_attachment_count = file_bug_attachment_count( $p_bug->id );
1072      }
1073  
1074      echo '<td class="center column-attachments">';
1075  
1076      if ( $t_attachment_count > 0 ) {
1077          $t_href = string_get_bug_view_url( $p_bug->id ) . '#attachments';
1078          $t_href_title = sprintf( lang_get( 'view_attachments_for_issue' ), $t_attachment_count, $p_bug->id );
1079          if ( config_get( 'show_attachment_indicator' ) ) {
1080              $t_alt_text = $t_attachment_count . lang_get( 'word_separator' ) . lang_get( 'attachments' );
1081              echo "<a href=\"$t_href\" title=\"$t_href_title\"><img src=\"$t_icon_path}attachment.png\" alt=\"$t_alt_text\" title=\"$t_alt_text\" /></a>";
1082          } else {
1083              echo "<a href=\"$t_href\" title=\"$t_href_title\">$t_attachment_count</a>";
1084          }
1085      } else {
1086          echo ' &#160; ';
1087      }
1088  
1089      echo "</td>\n";
1090  }
1091  
1092  /**
1093   *
1094   * @param BugData $p_bug bug obect
1095   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1096   * @return null
1097   * @access public
1098   */
1099  function print_column_category_id( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1100      global $t_sort, $t_dir;
1101  
1102      # grab the project name
1103      $t_project_name = project_get_field( $p_bug->project_id, 'name' );
1104  
1105      echo '<td class="center column-category">';
1106  
1107      # type project name if viewing 'all projects' or if issue is in a subproject
1108       if( ON == config_get( 'show_bug_project_links' ) && helper_get_current_project() != $p_bug->project_id ) {
1109          echo '<small class="project">[';
1110          print_view_bug_sort_link( string_display_line( $t_project_name ), 'project_id', $t_sort, $t_dir, $p_columns_target );
1111          echo ']</small><br />';
1112      }
1113  
1114      echo string_display_line( category_full_name( $p_bug->category_id, false ) );
1115  
1116      echo '</td>';
1117  }
1118  
1119  /**
1120   *
1121   * @param BugData $p_bug bug obect
1122   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1123   * @return null
1124   * @access public
1125   */
1126  function print_column_severity( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1127      echo '<td class="center column-severity">';
1128      print_formatted_severity_string( $p_bug->status, $p_bug->severity );
1129      echo '</td>';
1130  }
1131  
1132  /**
1133   *
1134   * @param BugData $p_bug bug obect
1135   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1136   * @return null
1137   * @access public
1138   */
1139  function print_column_eta( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1140      echo '<td class="center column-eta">', get_enum_element( 'eta', $p_bug->eta ), '</td>';
1141  }
1142  
1143  /**
1144   *
1145   * @param BugData $p_bug bug object
1146   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1147   * @return null
1148   * @access public
1149   */
1150  function print_column_projection( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1151      echo '<td class="center column-projection">', get_enum_element( 'projection', $p_bug->projection ), '</td>';
1152  }
1153  
1154  /**
1155   *
1156   * @param BugData $p_bug bug obect
1157   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1158   * @return null
1159   * @access public
1160   */
1161  function print_column_reproducibility( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1162      echo '<td class="center column-reproducibility">', get_enum_element( 'reproducibility', $p_bug->reproducibility ), '</td>';
1163  }
1164  
1165  /**
1166   *
1167   * @param BugData $p_bug bug obect
1168   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1169   * @return null
1170   * @access public
1171   */
1172  function print_column_resolution( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1173      echo '<td class="center column-resolution">', get_enum_element( 'resolution', $p_bug->resolution ), '</td>';
1174  }
1175  
1176  /**
1177   *
1178   * @param BugData $p_bug bug obect
1179   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1180   * @return null
1181   * @access public
1182   */
1183  function print_column_status( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1184      echo '<td class="center column-status">';
1185      printf( '<span class="issue-status" title="%s">%s</span>', get_enum_element( 'resolution', $p_bug->resolution ), get_enum_element( 'status', $p_bug->status ) );
1186  
1187      # print username instead of status
1188      if(( ON == config_get( 'show_assigned_names' ) ) && ( $p_bug->handler_id > 0 ) && ( access_has_project_level( config_get( 'view_handler_threshold' ), $p_bug->project_id ) ) ) {
1189          printf( ' (%s)', prepare_user_name( $p_bug->handler_id ) );
1190      }
1191      echo '</td>';
1192  }
1193  
1194  /**
1195   *
1196   * @param BugData $p_bug bug obect
1197   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1198   * @return null
1199   * @access public
1200   */
1201  function print_column_handler_id( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1202      echo '<td class="center column-assigned-to">';
1203  
1204      # In case of a specific project, if the current user has no access to the field, then it would have been excluded from the
1205      # list of columns to view.  In case of ALL_PROJECTS, then we need to check the access per row.
1206      if( $p_bug->handler_id > 0 && ( helper_get_current_project() != ALL_PROJECTS || access_has_project_level( config_get( 'view_handler_threshold' ), $p_bug->project_id ) ) ) {
1207          echo prepare_user_name( $p_bug->handler_id );
1208      }
1209  
1210      echo '</td>';
1211  }
1212  
1213  /**
1214   *
1215   * @param BugData $p_bug bug obect
1216   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1217   * @return null
1218   * @access public
1219   */
1220  function print_column_reporter_id( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1221      echo '<td class="center column-reporter">';
1222      echo prepare_user_name( $p_bug->reporter_id );
1223      echo '</td>';
1224  }
1225  
1226  /**
1227   *
1228   * @param BugData $p_bug bug obect
1229   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1230   * @return null
1231   * @access public
1232   */
1233  function print_column_project_id( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1234      echo '<td class="center column-project-id">';
1235      echo string_display_line( project_get_name( $p_bug->project_id ) );
1236      echo '</td>';
1237  }
1238  
1239  /**
1240   *
1241   * @param BugData $p_bug bug obect
1242   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1243   * @return null
1244   * @access public
1245   */
1246  function print_column_last_updated( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1247      global $t_filter;
1248  
1249      $t_last_updated = string_display_line( date( config_get( 'short_date_format' ), $p_bug->last_updated ) );
1250  
1251      echo '<td class="center column-last-modified">';
1252      if( $p_bug->last_updated > strtotime( '-' . $t_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] . ' hours' ) ) {
1253          printf( '<span class="bold">%s</span>', $t_last_updated );
1254      } else {
1255          echo $t_last_updated;
1256      }
1257      echo '</td>';
1258  }
1259  
1260  /**
1261   *
1262   * @param BugData $p_bug bug obect
1263   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1264   * @return null
1265   * @access public
1266   */
1267  function print_column_date_submitted( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1268      $t_date_submitted = string_display_line( date( config_get( 'short_date_format' ), $p_bug->date_submitted ) );
1269  
1270      echo '<td class="center column-date-submitted">', $t_date_submitted, '</td>';
1271  }
1272  
1273  /**
1274   *
1275   * @param BugData $p_bug bug obect
1276   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1277   * @return null
1278   * @access public
1279   */
1280  function print_column_summary( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1281      if( $p_columns_target == COLUMNS_TARGET_CSV_PAGE ) {
1282          $t_summary = string_attribute( $p_bug->summary );
1283      } else {
1284          $t_summary = string_display_line_links( $p_bug->summary );
1285      }
1286  
1287      echo '<td class="left column-summary">' . $t_summary . '</td>';
1288  }
1289  
1290  /**
1291   *
1292   * @param BugData $p_bug bug obect
1293   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1294   * @return null
1295   * @access public
1296   */
1297  function print_column_description( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1298      $t_description = string_display_links( $p_bug->description );
1299  
1300      echo '<td class="left column-description">', $t_description, '</td>';
1301  }
1302  
1303  /**
1304   *
1305   * @param BugData $p_bug bug obect
1306   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1307   * @return null
1308   * @access public
1309   */
1310  function print_column_steps_to_reproduce( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1311      $t_steps_to_reproduce = string_display_links( $p_bug->steps_to_reproduce );
1312  
1313      echo '<td class="left column-steps-to-reproduce">', $t_steps_to_reproduce, '</td>';
1314  }
1315  
1316  /**
1317   *
1318   * @param BugData $p_bug bug obect
1319   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1320   * @return null
1321   * @access public
1322   */
1323  function print_column_additional_information( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1324      $t_additional_information = string_display_links( $p_bug->additional_information );
1325  
1326      echo '<td class="left column-additional-information">', $t_additional_information, '</td>';
1327  }
1328  
1329  /**
1330   *
1331   * @param BugData $p_bug bug obect
1332   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1333   * @return null
1334   * @access public
1335   */
1336  function print_column_target_version( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1337      echo '<td class="column-target-version">';
1338  
1339      # In case of a specific project, if the current user has no access to the field, then it would have been excluded from the
1340      # list of columns to view.  In case of ALL_PROJECTS, then we need to check the access per row.
1341      if( helper_get_current_project() != ALL_PROJECTS || access_has_project_level( config_get( 'roadmap_view_threshold' ), $p_bug->project_id ) ) {
1342          echo string_display_line( $p_bug->target_version );
1343      }
1344  
1345      echo '</td>';
1346  }
1347  
1348  /**
1349   *
1350   * @param BugData $p_bug bug object
1351   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1352   * @return null
1353   * @access public
1354   */
1355  function print_column_view_state( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1356      global $t_icon_path;
1357  
1358      echo '<td class="column-view-state">';
1359  
1360      if( VS_PRIVATE == $p_bug->view_state ) {
1361          $t_view_state_text = lang_get( 'private' );
1362          echo '<img src="' . $t_icon_path . 'protected.gif" alt="' . $t_view_state_text . '" title="' . $t_view_state_text . '" />';
1363      } else {
1364          echo '&#160;';
1365      }
1366  
1367      echo '</td>';
1368  }
1369  
1370  /**
1371   *
1372   * @param BugData $p_bug bug object
1373   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1374   * @return null
1375   * @access public
1376   */
1377  function print_column_due_date( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1378      if ( !access_has_bug_level( config_get( 'due_date_view_threshold' ), $p_bug->id ) ||
1379          date_is_null( $p_bug->due_date ) ) {
1380          echo '<td class="column-due-date">&#160;</td>';
1381          return;
1382      }
1383  
1384      if ( bug_is_overdue( $p_bug->id ) ) {
1385          echo '<td class="column-due-date overdue">';
1386      } else {
1387          echo '<td>';
1388      }
1389  
1390      echo string_display_line( date( config_get( 'short_date_format' ), $p_bug->due_date ) );
1391  
1392      echo '</td>';
1393  }
1394  
1395  /**
1396   *
1397   * @param BugData $p_bug bug object
1398   * @param int $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
1399   * @return null
1400   * @access public
1401   */
1402  function print_column_overdue( $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
1403      global $t_icon_path;
1404  
1405      echo '<td class="column-overdue">';
1406  
1407      if ( access_has_bug_level( config_get( 'due_date_view_threshold' ), $p_bug->id ) &&
1408          !date_is_null( $p_bug->due_date ) &&
1409          bug_is_overdue( $p_bug->id ) ) {
1410          $t_overdue_text = lang_get( 'overdue' );
1411          $t_overdue_text_hover = $t_overdue_text . '. Due date was: ' . string_display_line( date( config_get( 'short_date_format' ), $p_bug->due_date ) );
1412          echo '<img src="' . $t_icon_path . 'overdue.png" alt="' . $t_overdue_text . '" title="' . $t_overdue_text_hover . '" />';
1413      } else {
1414          echo '&#160;';
1415      }
1416  
1417      echo '</td>';
1418  }


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